You can now create new file types and groups.
git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@16393 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
parent
5acbf1f50e
commit
879c65a301
@ -164,7 +164,7 @@ FileTypes::MessageReceived(BMessage *message)
|
||||
|
||||
case kMsgOpenFilePanel:
|
||||
// the open file panel sends us a message when it's done
|
||||
fFilePanel->Window()->SetTitle("Open File");
|
||||
fFilePanel->Window()->SetTitle("FileTypes: Open File");
|
||||
fFilePanel->SetMessage(new BMessage(B_REFS_RECEIVED));
|
||||
|
||||
if (!fFilePanel->IsShowing())
|
||||
@ -172,7 +172,7 @@ FileTypes::MessageReceived(BMessage *message)
|
||||
break;
|
||||
|
||||
case kMsgOpenSelectPanel:
|
||||
fFilePanel->Window()->SetTitle("Select Preferred Application");
|
||||
fFilePanel->Window()->SetTitle("FileTypes: Select Preferred Application");
|
||||
fFilePanel->SetMessage(new BMessage(kMsgPreferredAppOpened));
|
||||
|
||||
if (!fFilePanel->IsShowing())
|
||||
@ -184,7 +184,7 @@ FileTypes::MessageReceived(BMessage *message)
|
||||
break;
|
||||
|
||||
case kMsgOpenSameAsPanel:
|
||||
fFilePanel->Window()->SetTitle("Select Same Preferred Application As");
|
||||
fFilePanel->Window()->SetTitle("FileTypes: Select Same Preferred Application As");
|
||||
fFilePanel->SetMessage(new BMessage(kMsgSamePreferredAppAsOpened));
|
||||
|
||||
if (!fFilePanel->IsShowing())
|
||||
|
@ -7,8 +7,8 @@
|
||||
#include "FileTypes.h"
|
||||
#include "FileTypesWindow.h"
|
||||
#include "MimeTypeListView.h"
|
||||
#include "NewFileTypeWindow.h"
|
||||
|
||||
#include <Alert.h>
|
||||
#include <AppFileInfo.h>
|
||||
#include <Application.h>
|
||||
#include <Bitmap.h>
|
||||
@ -52,7 +52,6 @@ const uint32 kMsgSamePreferredAppAs = 'spaa';
|
||||
const uint32 kMsgTypeEntered = 'type';
|
||||
const uint32 kMsgDescriptionEntered = 'dsce';
|
||||
|
||||
|
||||
const struct type_map {
|
||||
const char* name;
|
||||
type_code type;
|
||||
@ -113,7 +112,7 @@ class AttributeItem : public BStringItem {
|
||||
public:
|
||||
AttributeItem(const char* name, const char* publicName, type_code type,
|
||||
int32 alignment, int32 width, bool visible, bool editable);
|
||||
~AttributeItem();
|
||||
virtual ~AttributeItem();
|
||||
|
||||
virtual void DrawItem(BView* owner, BRect itemRect,
|
||||
bool drawEverything = false);
|
||||
@ -128,9 +127,6 @@ class AttributeItem : public BStringItem {
|
||||
bool fEditable;
|
||||
};
|
||||
|
||||
static void error_alert(const char* message, status_t status = B_OK,
|
||||
alert_type type = B_WARNING_ALERT);
|
||||
|
||||
|
||||
// #pragma mark -
|
||||
|
||||
@ -187,7 +183,7 @@ name_for_type(BString& string, type_code type)
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
void
|
||||
error_alert(const char* message, status_t status, alert_type type)
|
||||
{
|
||||
char warning[512];
|
||||
@ -501,7 +497,10 @@ AttributeListView::Draw(BRect updateRect)
|
||||
|
||||
FileTypesWindow::FileTypesWindow(BRect frame)
|
||||
: BWindow(frame, "FileTypes", B_TITLED_WINDOW,
|
||||
B_NOT_ZOOMABLE | B_ASYNCHRONOUS_CONTROLS)
|
||||
B_NOT_ZOOMABLE | B_ASYNCHRONOUS_CONTROLS),
|
||||
fNewTypeWindow(NULL),
|
||||
fExtensionWindow(NULL),
|
||||
fAttributeWindow(NULL)
|
||||
{
|
||||
// add the menu
|
||||
|
||||
@ -1116,6 +1115,14 @@ FileTypesWindow::_SetType(BMimeType* type, int32 forceUpdate)
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
FileTypesWindow::PlaceSubWindow(BWindow* window)
|
||||
{
|
||||
window->MoveTo(Frame().left + (Frame().Width() - window->Frame().Width()) / 2.0f,
|
||||
Frame().top + (Frame().Height() - window->Frame().Height()) / 2.0f);
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
FileTypesWindow::MessageReceived(BMessage* message)
|
||||
{
|
||||
@ -1135,7 +1142,16 @@ FileTypesWindow::MessageReceived(BMessage* message)
|
||||
}
|
||||
|
||||
case kMsgAddType:
|
||||
puts("add type");
|
||||
{
|
||||
if (fNewTypeWindow == NULL) {
|
||||
fNewTypeWindow = new NewFileTypeWindow(this, fCurrentType.Type());
|
||||
fNewTypeWindow->Show();
|
||||
} else
|
||||
fNewTypeWindow->Activate();
|
||||
break;
|
||||
}
|
||||
case kMsgNewTypeWindowClosed:
|
||||
fNewTypeWindow = NULL;
|
||||
break;
|
||||
|
||||
case kMsgRemoveType:
|
||||
@ -1168,6 +1184,14 @@ FileTypesWindow::MessageReceived(BMessage* message)
|
||||
break;
|
||||
}
|
||||
|
||||
case kMsgSelectNewType:
|
||||
{
|
||||
const char* type;
|
||||
if (message->FindString("type", &type) == B_OK)
|
||||
fTypeListView->SelectNewType(type);
|
||||
break;
|
||||
}
|
||||
|
||||
// File Extensions group
|
||||
|
||||
case kMsgExtensionSelected:
|
||||
|
@ -6,6 +6,7 @@
|
||||
#define FILE_TYPES_WINDOW_H
|
||||
|
||||
|
||||
#include <Alert.h>
|
||||
#include <Mime.h>
|
||||
#include <Window.h>
|
||||
|
||||
@ -29,6 +30,8 @@ class FileTypesWindow : public BWindow {
|
||||
virtual void MessageReceived(BMessage* message);
|
||||
virtual bool QuitRequested();
|
||||
|
||||
void PlaceSubWindow(BWindow* window);
|
||||
|
||||
private:
|
||||
void _UpdateExtensions(BMimeType* type);
|
||||
void _AdoptPreferredApplication(BMessage* message, bool sameAs);
|
||||
@ -62,9 +65,19 @@ class FileTypesWindow : public BWindow {
|
||||
BButton* fAddAttributeButton;
|
||||
BButton* fRemoveAttributeButton;
|
||||
|
||||
BWindow* fNewTypeWindow;
|
||||
BWindow* fExtensionWindow;
|
||||
BWindow* fAttributeWindow;
|
||||
};
|
||||
|
||||
static const uint32 kMsgPreferredAppOpened = 'paOp';
|
||||
static const uint32 kMsgSamePreferredAppAsOpened = 'spaO';
|
||||
|
||||
static const uint32 kMsgSelectNewType = 'slnt';
|
||||
static const uint32 kMsgNewTypeWindowClosed = 'ntwc';
|
||||
|
||||
|
||||
extern void error_alert(const char* message, status_t status = B_OK,
|
||||
alert_type type = B_WARNING_ALERT);
|
||||
|
||||
#endif // FILE_TYPES_WINDOW_H
|
||||
|
@ -9,6 +9,7 @@ Preference FileTypes :
|
||||
FileTypes.cpp
|
||||
FileTypesWindow.cpp
|
||||
MimeTypeListView.cpp
|
||||
NewFileTypeWindow.cpp
|
||||
: be tracker
|
||||
: FileTypes.rdef FileTypes.icons.rdef
|
||||
;
|
||||
|
@ -335,6 +335,11 @@ MimeTypeListView::MessageReceived(BMessage* message)
|
||||
AddItem(item);
|
||||
|
||||
UpdateItem(item);
|
||||
|
||||
if (!fSelectNewType.ICompare(type)) {
|
||||
SelectItem(item);
|
||||
fSelectNewType = "";
|
||||
}
|
||||
break;
|
||||
}
|
||||
case B_MIME_TYPE_DELETED:
|
||||
@ -360,6 +365,57 @@ MimeTypeListView::MessageReceived(BMessage* message)
|
||||
}
|
||||
|
||||
|
||||
/*!
|
||||
\brief This method makes sure a new MIME type will be selected.
|
||||
|
||||
If it's not in the list yet, it will be selected as soon as it's
|
||||
added.
|
||||
*/
|
||||
void
|
||||
MimeTypeListView::SelectNewType(const char* type)
|
||||
{
|
||||
if (SelectType(type))
|
||||
return;
|
||||
|
||||
fSelectNewType = type;
|
||||
}
|
||||
|
||||
|
||||
bool
|
||||
MimeTypeListView::SelectType(const char* type)
|
||||
{
|
||||
MimeTypeItem* item = FindItem(type);
|
||||
if (item == NULL)
|
||||
return false;
|
||||
|
||||
SelectItem(item);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
MimeTypeListView::SelectItem(MimeTypeItem* item)
|
||||
{
|
||||
if (item == NULL) {
|
||||
Select(-1);
|
||||
return;
|
||||
}
|
||||
|
||||
// Make sure the item is visible
|
||||
|
||||
BListItem* superItem = item;
|
||||
while ((superItem = Superitem(superItem)) != NULL) {
|
||||
Expand(superItem);
|
||||
}
|
||||
|
||||
// Select it, and make it visible
|
||||
|
||||
int32 index = IndexOf(item);
|
||||
Select(index);
|
||||
ScrollToSelection();
|
||||
}
|
||||
|
||||
|
||||
MimeTypeItem*
|
||||
MimeTypeListView::FindItem(const char* type)
|
||||
{
|
||||
@ -370,7 +426,7 @@ MimeTypeListView::FindItem(const char* type)
|
||||
MimeTypeItem* item = dynamic_cast<MimeTypeItem*>(FullListItemAt(i));
|
||||
if (item == NULL)
|
||||
continue;
|
||||
|
||||
|
||||
if (!strcasecmp(item->Type(), type))
|
||||
return item;
|
||||
}
|
||||
|
@ -49,6 +49,10 @@ class MimeTypeListView : public BOutlineListView {
|
||||
uint32 resizingMode = B_FOLLOW_LEFT | B_FOLLOW_TOP);
|
||||
virtual ~MimeTypeListView();
|
||||
|
||||
void SelectNewType(const char* type);
|
||||
bool SelectType(const char* type);
|
||||
|
||||
void SelectItem(MimeTypeItem* item);
|
||||
MimeTypeItem* FindItem(const char* type);
|
||||
|
||||
void UpdateItem(MimeTypeItem* item);
|
||||
@ -62,6 +66,8 @@ class MimeTypeListView : public BOutlineListView {
|
||||
private:
|
||||
void _CollectTypes();
|
||||
void _MakeTypesUnique(MimeTypeItem* underItem = NULL);
|
||||
|
||||
BString fSelectNewType;
|
||||
};
|
||||
|
||||
bool mimetype_is_application_signature(BMimeType& type);
|
||||
|
192
src/preferences/filetypes/NewFileTypeWindow.cpp
Normal file
192
src/preferences/filetypes/NewFileTypeWindow.cpp
Normal file
@ -0,0 +1,192 @@
|
||||
/*
|
||||
* Copyright 2006, Axel Dörfler, axeld@pinc-software.de. All rights reserved.
|
||||
* Distributed under the terms of the MIT License.
|
||||
*/
|
||||
|
||||
|
||||
#include "FileTypesWindow.h"
|
||||
#include "NewFileTypeWindow.h"
|
||||
|
||||
#include <Button.h>
|
||||
#include <MenuField.h>
|
||||
#include <MenuItem.h>
|
||||
#include <Mime.h>
|
||||
#include <PopUpMenu.h>
|
||||
#include <String.h>
|
||||
#include <TextControl.h>
|
||||
|
||||
#include <string.h>
|
||||
|
||||
|
||||
const uint32 kMsgSupertypeChosen = 'sptc';
|
||||
const uint32 kMsgNewSupertypeChosen = 'nstc';
|
||||
|
||||
const uint32 kMsgNameUpdated = 'nmup';
|
||||
|
||||
const uint32 kMsgAddType = 'atyp';
|
||||
|
||||
|
||||
NewFileTypeWindow::NewFileTypeWindow(FileTypesWindow* target, const char* currentType)
|
||||
: BWindow(BRect(100, 100, 350, 200), "New File Type", B_TITLED_WINDOW,
|
||||
B_NOT_ZOOMABLE | B_NOT_V_RESIZABLE | B_ASYNCHRONOUS_CONTROLS),
|
||||
fTarget(target)
|
||||
{
|
||||
BRect rect = Bounds();
|
||||
BView* topView = new BView(rect, NULL, B_FOLLOW_ALL, B_WILL_DRAW);
|
||||
topView->SetViewColor(ui_color(B_PANEL_BACKGROUND_COLOR));
|
||||
AddChild(topView);
|
||||
|
||||
rect.InsetBy(8.0f, 8.0f);
|
||||
fNameControl = new BTextControl(rect, "internal", "Internal Name:", "",
|
||||
NULL, B_FOLLOW_LEFT_RIGHT);
|
||||
|
||||
float labelWidth = fNameControl->StringWidth(fNameControl->Label()) + 2.0f;
|
||||
fNameControl->SetModificationMessage(new BMessage(kMsgNameUpdated));
|
||||
fNameControl->SetDivider(labelWidth);
|
||||
fNameControl->SetAlignment(B_ALIGN_RIGHT, B_ALIGN_LEFT);
|
||||
|
||||
// filter out invalid characters that can't be part of a MIME type name
|
||||
BTextView* textView = fNameControl->TextView();
|
||||
const char* disallowedCharacters = "/<>@,;:\"()[]?=";
|
||||
for (int32 i = 0; disallowedCharacters[i]; i++) {
|
||||
textView->DisallowChar(disallowedCharacters[i]);
|
||||
}
|
||||
|
||||
float width, height;
|
||||
fNameControl->GetPreferredSize(&width, &height);
|
||||
fNameControl->ResizeTo(rect.Width(), height);
|
||||
fNameControl->MoveTo(8.0f, 12.0f + fNameControl->Bounds().Height());
|
||||
topView->AddChild(fNameControl);
|
||||
|
||||
fSupertypesMenu = new BPopUpMenu("supertypes");
|
||||
BMenuItem* item;
|
||||
BMessage types;
|
||||
if (BMimeType::GetInstalledSupertypes(&types) == B_OK) {
|
||||
const char* type;
|
||||
int32 i = 0;
|
||||
while (types.FindString("super_types", i++, &type) == B_OK) {
|
||||
fSupertypesMenu->AddItem(item = new BMenuItem(type,
|
||||
new BMessage(kMsgSupertypeChosen)));
|
||||
|
||||
// select super type close to the current type
|
||||
if (currentType != NULL) {
|
||||
if (!strncmp(type, currentType, strlen(type)))
|
||||
item->SetMarked(true);
|
||||
} else if (i == 1)
|
||||
item->SetMarked(true);
|
||||
}
|
||||
|
||||
if (i > 1)
|
||||
fSupertypesMenu->AddSeparatorItem();
|
||||
}
|
||||
fSupertypesMenu->AddItem(new BMenuItem("Add New Group",
|
||||
new BMessage(kMsgNewSupertypeChosen)));
|
||||
|
||||
rect.bottom = rect.top + fNameControl->Bounds().Height() + 2.0f;
|
||||
BMenuField* menuField = new BMenuField(rect, "supertypes",
|
||||
"Group:", fSupertypesMenu);
|
||||
menuField->SetDivider(labelWidth);
|
||||
menuField->SetAlignment(B_ALIGN_RIGHT);
|
||||
menuField->GetPreferredSize(&width, &height);
|
||||
menuField->ResizeTo(rect.Width(), height);
|
||||
topView->AddChild(menuField);
|
||||
|
||||
fAddButton = new BButton(rect, "add", "Add Type", new BMessage(kMsgAddType),
|
||||
B_FOLLOW_RIGHT | B_FOLLOW_BOTTOM);
|
||||
fAddButton->ResizeToPreferred();
|
||||
fAddButton->MoveTo(Bounds().Width() - 8.0f - fAddButton->Bounds().Width(),
|
||||
Bounds().Height() - 8.0f - fAddButton->Bounds().Height());
|
||||
fAddButton->SetEnabled(false);
|
||||
topView->AddChild(fAddButton);
|
||||
|
||||
BButton* button = new BButton(rect, "cancel", "Cancel",
|
||||
new BMessage(B_QUIT_REQUESTED), B_FOLLOW_RIGHT | B_FOLLOW_BOTTOM);
|
||||
button->ResizeToPreferred();
|
||||
button->MoveTo(fAddButton->Frame().left - 10.0f - button->Bounds().Width(),
|
||||
fAddButton->Frame().top);
|
||||
topView->AddChild(button);
|
||||
|
||||
ResizeTo(labelWidth * 4.0f + 24.0f, fNameControl->Bounds().Height() * 3.0f + 34.0f);
|
||||
SetSizeLimits(button->Bounds().Width() + fAddButton->Bounds().Width() + 26.0f,
|
||||
32767.0f, Frame().Height(), Frame().Height());
|
||||
|
||||
fAddButton->MakeDefault(true);
|
||||
fNameControl->MakeFocus(true);
|
||||
|
||||
target->PlaceSubWindow(this);
|
||||
}
|
||||
|
||||
|
||||
NewFileTypeWindow::~NewFileTypeWindow()
|
||||
{
|
||||
}
|
||||
|
||||
#include <stdio.h>
|
||||
void
|
||||
NewFileTypeWindow::MessageReceived(BMessage* message)
|
||||
{
|
||||
switch (message->what) {
|
||||
case kMsgSupertypeChosen:
|
||||
fAddButton->SetLabel("Add Type");
|
||||
fNameControl->SetLabel("Internal Name:");
|
||||
fNameControl->MakeFocus(true);
|
||||
break;
|
||||
|
||||
case kMsgNewSupertypeChosen:
|
||||
fAddButton->SetLabel("Add Group");
|
||||
fNameControl->SetLabel("Group Name:");
|
||||
fNameControl->MakeFocus(true);
|
||||
break;
|
||||
|
||||
case kMsgNameUpdated:
|
||||
{
|
||||
bool empty = fNameControl->Text() == NULL
|
||||
|| fNameControl->Text()[0] == '\0';
|
||||
|
||||
if (fAddButton->IsEnabled() == empty)
|
||||
fAddButton->SetEnabled(!empty);
|
||||
break;
|
||||
}
|
||||
|
||||
case kMsgAddType:
|
||||
{
|
||||
BMenuItem* item = fSupertypesMenu->FindMarked();
|
||||
if (item != NULL) {
|
||||
BString type;
|
||||
if (fSupertypesMenu->IndexOf(item) != fSupertypesMenu->CountItems() - 1) {
|
||||
// add normal type
|
||||
type = item->Label();
|
||||
type.Append("/");
|
||||
}
|
||||
|
||||
type.Append(fNameControl->Text());
|
||||
|
||||
BMimeType mimeType(type.String());
|
||||
if (mimeType.IsInstalled()) {
|
||||
error_alert("This file type already exists.");
|
||||
break;
|
||||
}
|
||||
|
||||
status_t status = mimeType.Install();
|
||||
if (status != B_OK)
|
||||
error_alert("Could not install file type", status);
|
||||
else {
|
||||
BMessage update(kMsgSelectNewType);
|
||||
update.AddString("type", type.String());
|
||||
|
||||
fTarget.SendMessage(&update);
|
||||
}
|
||||
}
|
||||
PostMessage(B_QUIT_REQUESTED);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
bool
|
||||
NewFileTypeWindow::QuitRequested()
|
||||
{
|
||||
fTarget.SendMessage(kMsgNewTypeWindowClosed);
|
||||
return true;
|
||||
}
|
32
src/preferences/filetypes/NewFileTypeWindow.h
Normal file
32
src/preferences/filetypes/NewFileTypeWindow.h
Normal file
@ -0,0 +1,32 @@
|
||||
/*
|
||||
* Copyright 2006, Axel Dörfler, axeld@pinc-software.de. All rights reserved.
|
||||
* Distributed under the terms of the MIT License.
|
||||
*/
|
||||
#ifndef NEW_FILE_TYPE_WINDOW_H
|
||||
#define NEW_FILE_TYPE_WINDOW_H
|
||||
|
||||
|
||||
#include <Messenger.h>
|
||||
#include <Window.h>
|
||||
|
||||
class BButton;
|
||||
class BMenu;
|
||||
class BTextControl;
|
||||
|
||||
|
||||
class NewFileTypeWindow : public BWindow {
|
||||
public:
|
||||
NewFileTypeWindow(FileTypesWindow* target, const char* currentType);
|
||||
virtual ~NewFileTypeWindow();
|
||||
|
||||
virtual void MessageReceived(BMessage* message);
|
||||
virtual bool QuitRequested();
|
||||
|
||||
private:
|
||||
BMessenger fTarget;
|
||||
BMenu* fSupertypesMenu;
|
||||
BTextControl* fNameControl;
|
||||
BButton* fAddButton;
|
||||
};
|
||||
|
||||
#endif // NEW_FILE_TYPE_WINDOW_H
|
Loading…
Reference in New Issue
Block a user