Some more work on the FileTypes preferences application; it still doesn't do anything,
but it will now show you the installed MIME types, and their properties (though the "Extra Attributes" group is still not maintained at all). git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@16351 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
@@ -52,7 +52,7 @@ FileTypes::FileTypes()
|
||||
fWindowCount(0)
|
||||
{
|
||||
fFilePanel = new BFilePanel();
|
||||
fTypesWindowFrame = BRect(80.0f, 80.0f, 540.0f, 440.0f);
|
||||
fTypesWindowFrame = BRect(80.0f, 80.0f, 600.0f, 480.0f);
|
||||
// TODO: read from settings
|
||||
}
|
||||
|
||||
|
||||
@@ -6,8 +6,10 @@
|
||||
|
||||
#include "FileTypes.h"
|
||||
#include "FileTypesWindow.h"
|
||||
#include "MimeTypeListView.h"
|
||||
|
||||
#include <Application.h>
|
||||
#include <Bitmap.h>
|
||||
#include <Box.h>
|
||||
#include <Button.h>
|
||||
#include <ListView.h>
|
||||
@@ -15,12 +17,120 @@
|
||||
#include <MenuField.h>
|
||||
#include <MenuItem.h>
|
||||
#include <Mime.h>
|
||||
#include <OutlineListView.h>
|
||||
#include <PopUpMenu.h>
|
||||
#include <ScrollView.h>
|
||||
#include <TextControl.h>
|
||||
|
||||
#include <be_apps/Tracker/RecentItems.h>
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
|
||||
const uint32 kMsgTypeSelected = 'typs';
|
||||
|
||||
|
||||
class IconView : public BControl {
|
||||
public:
|
||||
IconView(BRect rect, const char* name, BMessage* message);
|
||||
virtual ~IconView();
|
||||
|
||||
void SetTo(BMimeType* type);
|
||||
|
||||
virtual void Draw(BRect updateRect);
|
||||
|
||||
#if 0
|
||||
virtual void MouseDown(BPoint where);
|
||||
virtual void MouseMoved(BPoint where, uint32 transit,
|
||||
BMessage* dragMessage);
|
||||
#endif
|
||||
|
||||
private:
|
||||
BBitmap* fIcon;
|
||||
};
|
||||
|
||||
|
||||
IconView::IconView(BRect rect, const char* name, BMessage* message)
|
||||
: BControl(rect, name, NULL, message,
|
||||
B_FOLLOW_LEFT | B_FOLLOW_TOP, B_WILL_DRAW),
|
||||
fIcon(NULL)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
IconView::~IconView()
|
||||
{
|
||||
delete fIcon;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
IconView::SetTo(BMimeType* type)
|
||||
{
|
||||
bool hadIcon = fIcon != NULL;
|
||||
|
||||
if (type != NULL) {
|
||||
if (fIcon == NULL)
|
||||
fIcon = new BBitmap(BRect(0, 0, B_LARGE_ICON - 1, B_LARGE_ICON - 1), B_CMAP8);
|
||||
|
||||
if (type->GetIcon(fIcon, B_LARGE_ICON) == B_OK) {
|
||||
Invalidate();
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
delete fIcon;
|
||||
fIcon = NULL;
|
||||
|
||||
if (hadIcon)
|
||||
Invalidate();
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
IconView::Draw(BRect updateRect)
|
||||
{
|
||||
if (fIcon != NULL) {
|
||||
SetDrawingMode(B_OP_ALPHA);
|
||||
DrawBitmap(fIcon, BPoint(0, 0));
|
||||
} else if (IsEnabled()) {
|
||||
BRect rect = Bounds();
|
||||
|
||||
rgb_color light = tint_color(ViewColor(), B_LIGHTEN_MAX_TINT);
|
||||
rgb_color shadow = tint_color(ViewColor(), B_DARKEN_3_TINT);
|
||||
|
||||
BeginLineArray(8);
|
||||
|
||||
AddLine(BPoint(rect.left, rect.bottom),
|
||||
BPoint(rect.left, rect.top), shadow);
|
||||
AddLine(BPoint(rect.left + 1.0f, rect.top),
|
||||
BPoint(rect.right, rect.top), shadow);
|
||||
AddLine(BPoint(rect.left + 1.0f, rect.bottom),
|
||||
BPoint(rect.right, rect.bottom), light);
|
||||
AddLine(BPoint(rect.right, rect.bottom - 1.0f),
|
||||
BPoint(rect.right, rect.top + 1.0f), light);
|
||||
|
||||
rect.InsetBy(1.0, 1.0);
|
||||
|
||||
AddLine(BPoint(rect.left, rect.bottom),
|
||||
BPoint(rect.left, rect.top), light);
|
||||
AddLine(BPoint(rect.left + 1.0f, rect.top),
|
||||
BPoint(rect.right, rect.top), light);
|
||||
AddLine(BPoint(rect.left + 1.0f, rect.bottom),
|
||||
BPoint(rect.right, rect.bottom), shadow);
|
||||
AddLine(BPoint(rect.right, rect.bottom - 1.0f),
|
||||
BPoint(rect.right, rect.top + 1.0f), shadow);
|
||||
|
||||
EndLineArray();
|
||||
} else {
|
||||
SetHighColor(ViewColor());
|
||||
FillRect(updateRect);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// #pragma mark -
|
||||
|
||||
|
||||
FileTypesWindow::FileTypesWindow(BRect frame)
|
||||
: BWindow(frame, "FileTypes", B_TITLED_WINDOW,
|
||||
@@ -69,18 +179,23 @@ FileTypesWindow::FileTypesWindow(BRect frame)
|
||||
topView->AddChild(button);
|
||||
|
||||
rect = button->Frame();
|
||||
rect.OffsetBy(rect.Width() + 6.0f, 0.0f);
|
||||
button = new BButton(rect, "remove", "Remove", NULL, B_FOLLOW_BOTTOM);
|
||||
button->ResizeToPreferred();
|
||||
topView->AddChild(button);
|
||||
rect.OffsetBy(rect.Width() + 8.0f, 0.0f);
|
||||
fRemoveTypeButton = new BButton(rect, "remove", "Remove", NULL, B_FOLLOW_BOTTOM);
|
||||
fRemoveTypeButton->ResizeToPreferred();
|
||||
topView->AddChild(fRemoveTypeButton);
|
||||
|
||||
rect.bottom = rect.top - 10.0f;
|
||||
rect.top = 10.0f;
|
||||
rect.left = 10.0f;
|
||||
rect.right -= B_V_SCROLL_BAR_WIDTH + 2.0f;
|
||||
BListView* listView = new BListView(rect, "listview", B_SINGLE_SELECTION_LIST,
|
||||
if (rect.right < 180)
|
||||
rect.right = 180;
|
||||
|
||||
fTypeListView = new MimeTypeListView(rect, "listview",
|
||||
B_FOLLOW_LEFT | B_FOLLOW_TOP_BOTTOM);
|
||||
BScrollView* scrollView = new BScrollView("scrollview", listView,
|
||||
fTypeListView->SetSelectionMessage(new BMessage(kMsgTypeSelected));
|
||||
|
||||
BScrollView* scrollView = new BScrollView("scrollview", fTypeListView,
|
||||
B_FOLLOW_LEFT | B_FOLLOW_TOP_BOTTOM, B_FRAME_EVENTS | B_WILL_DRAW, false, true);
|
||||
topView->AddChild(scrollView);
|
||||
|
||||
@@ -102,10 +217,10 @@ FileTypesWindow::FileTypesWindow(BRect frame)
|
||||
|
||||
BRect innerRect = BRect(0.0f, 0.0f, B_LARGE_ICON - 1.0f, B_LARGE_ICON - 1.0f);
|
||||
innerRect.OffsetTo((rect.Width() - innerRect.Width()) / 2.0f,
|
||||
(rect.Height() - innerRect.Height()) / 2.0f);
|
||||
BBox* iconBox = new BBox(innerRect, "icon box", B_FOLLOW_LEFT | B_FOLLOW_TOP,
|
||||
B_PLAIN_BORDER);
|
||||
box->AddChild(iconBox);
|
||||
fontHeight.ascent / 2.0f
|
||||
+ (rect.Height() - fontHeight.ascent / 2.0f - innerRect.Height()) / 2.0f);
|
||||
fIconView = new IconView(innerRect, "icon box", NULL);
|
||||
box->AddChild(fIconView);
|
||||
|
||||
// "File Extensions" group
|
||||
|
||||
@@ -120,22 +235,23 @@ FileTypesWindow::FileTypesWindow(BRect frame)
|
||||
innerRect.top += ceilf(fontHeight.ascent);
|
||||
innerRect.left = innerRect.right - button->StringWidth("Remove") - 16.0f;
|
||||
innerRect.bottom = innerRect.top + button->Bounds().Height();
|
||||
button = new BButton(innerRect, "add ext", "Add" B_UTF8_ELLIPSIS, NULL,
|
||||
B_FOLLOW_RIGHT);
|
||||
box->AddChild(button);
|
||||
fAddExtensionButton = new BButton(innerRect, "add ext", "Add" B_UTF8_ELLIPSIS,
|
||||
NULL, B_FOLLOW_RIGHT);
|
||||
box->AddChild(fAddExtensionButton);
|
||||
|
||||
innerRect.OffsetBy(0, innerRect.Height() + 4.0f);
|
||||
button = new BButton(innerRect, "remove ext", "Remove", NULL, B_FOLLOW_RIGHT);
|
||||
box->AddChild(button);
|
||||
fRemoveExtensionButton = new BButton(innerRect, "remove ext", "Remove", NULL,
|
||||
B_FOLLOW_RIGHT);
|
||||
box->AddChild(fRemoveExtensionButton);
|
||||
|
||||
innerRect.right = innerRect.left - 10.0f - B_V_SCROLL_BAR_WIDTH;
|
||||
innerRect.left = 10.0f;
|
||||
innerRect.top = 8.0f + ceilf(fontHeight.ascent);
|
||||
innerRect.bottom -= 2.0f;
|
||||
// take scrollview border into account
|
||||
listView = new BListView(innerRect, "listview ext", B_SINGLE_SELECTION_LIST,
|
||||
B_FOLLOW_LEFT_RIGHT);
|
||||
scrollView = new BScrollView("scrollview ext", listView,
|
||||
fExtensionListView = new BListView(innerRect, "listview ext",
|
||||
B_SINGLE_SELECTION_LIST, B_FOLLOW_LEFT_RIGHT);
|
||||
scrollView = new BScrollView("scrollview ext", fExtensionListView,
|
||||
B_FOLLOW_LEFT_RIGHT, B_FRAME_EVENTS | B_WILL_DRAW, false, true);
|
||||
box->AddChild(scrollView);
|
||||
|
||||
@@ -151,21 +267,21 @@ FileTypesWindow::FileTypesWindow(BRect frame)
|
||||
innerRect = box->Bounds().InsetByCopy(8.0f, 6.0f);
|
||||
innerRect.top += ceilf(fontHeight.ascent);
|
||||
innerRect.bottom = innerRect.top + button->Bounds().Height();
|
||||
BTextControl* control = new BTextControl(innerRect, "internal", "Internal Name:", "",
|
||||
fInternalNameControl = new BTextControl(innerRect, "internal", "Internal Name:", "",
|
||||
NULL, B_FOLLOW_LEFT_RIGHT);
|
||||
labelWidth = control->StringWidth(control->Label()) + 2.0f;
|
||||
control->SetDivider(labelWidth);
|
||||
control->SetAlignment(B_ALIGN_RIGHT, B_ALIGN_LEFT);
|
||||
control->SetEnabled(false);
|
||||
box->ResizeBy(0, control->Bounds().Height() * 2.0f);
|
||||
box->AddChild(control);
|
||||
labelWidth = fInternalNameControl->StringWidth(fInternalNameControl->Label()) + 2.0f;
|
||||
fInternalNameControl->SetDivider(labelWidth);
|
||||
fInternalNameControl->SetAlignment(B_ALIGN_RIGHT, B_ALIGN_LEFT);
|
||||
fInternalNameControl->SetEnabled(false);
|
||||
box->ResizeBy(0, fInternalNameControl->Bounds().Height() * 2.0f);
|
||||
box->AddChild(fInternalNameControl);
|
||||
|
||||
innerRect.OffsetBy(0, control->Bounds().Height() + 5.0f);
|
||||
control = new BTextControl(innerRect, "type", "Type Name:", "",
|
||||
innerRect.OffsetBy(0, fInternalNameControl->Bounds().Height() + 5.0f);
|
||||
fTypeNameControl = new BTextControl(innerRect, "type", "Type Name:", "",
|
||||
NULL, B_FOLLOW_LEFT_RIGHT);
|
||||
control->SetDivider(labelWidth);
|
||||
control->SetAlignment(B_ALIGN_RIGHT, B_ALIGN_LEFT);
|
||||
box->AddChild(control);
|
||||
fTypeNameControl->SetDivider(labelWidth);
|
||||
fTypeNameControl->SetAlignment(B_ALIGN_RIGHT, B_ALIGN_LEFT);
|
||||
box->AddChild(fTypeNameControl);
|
||||
|
||||
// "Preferred Application" group
|
||||
|
||||
@@ -181,14 +297,14 @@ FileTypesWindow::FileTypesWindow(BRect frame)
|
||||
innerRect.top += ceilf(fontHeight.ascent);
|
||||
innerRect.left = innerRect.right - button->StringWidth("Same As" B_UTF8_ELLIPSIS) - 24.0f;
|
||||
innerRect.bottom = innerRect.top + button->Bounds().Height();
|
||||
button = new BButton(innerRect, "same as", "Same As" B_UTF8_ELLIPSIS, NULL,
|
||||
fSameAsButton = new BButton(innerRect, "same as", "Same As" B_UTF8_ELLIPSIS, NULL,
|
||||
B_FOLLOW_RIGHT);
|
||||
box->AddChild(button);
|
||||
box->AddChild(fSameAsButton);
|
||||
|
||||
innerRect.OffsetBy(-innerRect.Width() - 6.0f, 0.0f);
|
||||
button = new BButton(innerRect, "select", "Select" B_UTF8_ELLIPSIS, NULL,
|
||||
fSelectButton = new BButton(innerRect, "select", "Select" B_UTF8_ELLIPSIS, NULL,
|
||||
B_FOLLOW_RIGHT);
|
||||
box->AddChild(button);
|
||||
box->AddChild(fSelectButton);
|
||||
|
||||
menu = new BPopUpMenu("preferred");
|
||||
menu->AddItem(item = new BMenuItem("None", NULL));
|
||||
@@ -196,13 +312,13 @@ FileTypesWindow::FileTypesWindow(BRect frame)
|
||||
|
||||
innerRect.right = innerRect.left - 6.0f;
|
||||
innerRect.left = 8.0f;
|
||||
BMenuField* menuField = new BMenuField(innerRect, "preferred", NULL, menu,
|
||||
fPreferredField = new BMenuField(innerRect, "preferred", NULL, menu,
|
||||
B_FOLLOW_LEFT_RIGHT);
|
||||
float width, height;
|
||||
menuField->GetPreferredSize(&width, &height);
|
||||
menuField->ResizeTo(innerRect.Width(), height);
|
||||
menuField->MoveBy(0.0f, (innerRect.Height() - height) / 2.0f);
|
||||
box->AddChild(menuField);
|
||||
fPreferredField->GetPreferredSize(&width, &height);
|
||||
fPreferredField->ResizeTo(innerRect.Width(), height);
|
||||
fPreferredField->MoveBy(0.0f, (innerRect.Height() - height) / 2.0f);
|
||||
box->AddChild(fPreferredField);
|
||||
|
||||
// "Extra Attributes" group
|
||||
|
||||
@@ -216,21 +332,22 @@ FileTypesWindow::FileTypesWindow(BRect frame)
|
||||
innerRect.top += ceilf(fontHeight.ascent);
|
||||
innerRect.left = innerRect.right - button->StringWidth("Remove") - 16.0f;
|
||||
innerRect.bottom = innerRect.top + button->Bounds().Height();
|
||||
button = new BButton(innerRect, "add attr", "Add" B_UTF8_ELLIPSIS, NULL,
|
||||
fAddAttributeButton = new BButton(innerRect, "add attr", "Add" B_UTF8_ELLIPSIS, NULL,
|
||||
B_FOLLOW_RIGHT);
|
||||
box->AddChild(button);
|
||||
box->AddChild(fAddAttributeButton);
|
||||
|
||||
innerRect.OffsetBy(0, innerRect.Height() + 4.0f);
|
||||
button = new BButton(innerRect, "remove attr", "Remove", NULL, B_FOLLOW_RIGHT);
|
||||
box->AddChild(button);
|
||||
fRemoveAttributeButton = new BButton(innerRect, "remove attr", "Remove",
|
||||
NULL, B_FOLLOW_RIGHT);
|
||||
box->AddChild(fRemoveAttributeButton);
|
||||
|
||||
innerRect.right = innerRect.left - 10.0f - B_V_SCROLL_BAR_WIDTH;
|
||||
innerRect.left = 10.0f;
|
||||
innerRect.top = 8.0f + ceilf(fontHeight.ascent);
|
||||
innerRect.bottom = box->Bounds().bottom - 10.0f;
|
||||
// take scrollview border into account
|
||||
listView = new BListView(innerRect, "listview attr", B_SINGLE_SELECTION_LIST,
|
||||
B_FOLLOW_ALL);
|
||||
BListView* listView = new BListView(innerRect, "listview attr",
|
||||
B_SINGLE_SELECTION_LIST, B_FOLLOW_ALL);
|
||||
scrollView = new BScrollView("scrollview attr", listView,
|
||||
B_FOLLOW_ALL, B_FRAME_EVENTS | B_WILL_DRAW, false, true);
|
||||
box->AddChild(scrollView);
|
||||
@@ -238,6 +355,8 @@ FileTypesWindow::FileTypesWindow(BRect frame)
|
||||
SetSizeLimits(rightRect.left + 72.0f + font.StringWidth("File Extensions"), 32767.0f,
|
||||
rect.top + 2.0f * button->Bounds().Height() + fontHeight.ascent + 32.0f
|
||||
+ menuBar->Bounds().Height(), 32767.0f);
|
||||
|
||||
_SetType(NULL);
|
||||
}
|
||||
|
||||
|
||||
@@ -246,10 +365,145 @@ FileTypesWindow::~FileTypesWindow()
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
FileTypesWindow::_UpdateExtensions(BMimeType* type)
|
||||
{
|
||||
// clear list
|
||||
|
||||
for (int32 i = fExtensionListView->CountItems(); i-- > 0;) {
|
||||
delete fExtensionListView->ItemAt(i);
|
||||
}
|
||||
fExtensionListView->MakeEmpty();
|
||||
|
||||
// fill it again
|
||||
|
||||
if (type == NULL)
|
||||
return;
|
||||
|
||||
BMessage extensions;
|
||||
if (type->GetFileExtensions(&extensions) != B_OK)
|
||||
return;
|
||||
|
||||
const char* extension;
|
||||
int32 i = 0;
|
||||
while (extensions.FindString("extensions", i++, &extension) == B_OK) {
|
||||
char dotExtension[B_FILE_NAME_LENGTH];
|
||||
snprintf(dotExtension, B_FILE_NAME_LENGTH, ".%s", extension);
|
||||
|
||||
fExtensionListView->AddItem(new BStringItem(dotExtension));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
FileTypesWindow::_UpdatePreferredApps(BMimeType* type)
|
||||
{
|
||||
// clear menu
|
||||
|
||||
BMenu* menu = fPreferredField->Menu();
|
||||
for (int32 i = menu->CountItems(); i-- > 1;) {
|
||||
delete menu->RemoveItem(i);
|
||||
}
|
||||
|
||||
// fill it again
|
||||
|
||||
menu->ItemAt(0)->SetMarked(true);
|
||||
|
||||
BMessage applications;
|
||||
if (type == NULL || type->GetSupportingApps(&applications) != B_OK)
|
||||
return;
|
||||
|
||||
char preferred[B_MIME_TYPE_LENGTH];
|
||||
if (type->GetPreferredApp(preferred) != B_OK)
|
||||
preferred[0] = '\0';
|
||||
|
||||
int32 lastFullSupport;
|
||||
if (applications.FindInt32("be:sub", &lastFullSupport) != B_OK)
|
||||
lastFullSupport = -1;
|
||||
|
||||
const char* signature;
|
||||
int32 i = 0;
|
||||
while (applications.FindString("applications", i, &signature) == B_OK) {
|
||||
char name[B_FILE_NAME_LENGTH];
|
||||
BMenuItem *item;
|
||||
|
||||
BMimeType applicationType(signature);
|
||||
if (applicationType.GetShortDescription(name) == B_OK)
|
||||
item = new BMenuItem(name, NULL);
|
||||
else
|
||||
item = new BMenuItem(signature, NULL);
|
||||
|
||||
// Add type separator
|
||||
if (i == 0 || i == lastFullSupport)
|
||||
menu->AddSeparatorItem();
|
||||
|
||||
if (!strcasecmp(signature, preferred))
|
||||
item->SetMarked(true);
|
||||
|
||||
menu->AddItem(item);
|
||||
i++;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
FileTypesWindow::_SetType(BMimeType* type)
|
||||
{
|
||||
bool enabled = type != NULL;
|
||||
|
||||
if (type != NULL) {
|
||||
fInternalNameControl->SetText(type->Type());
|
||||
|
||||
char description[B_MIME_TYPE_LENGTH];
|
||||
if (type->GetShortDescription(description) != B_OK)
|
||||
description[0] = '\0';
|
||||
fTypeNameControl->SetText(description);
|
||||
} else {
|
||||
fInternalNameControl->SetText(NULL);
|
||||
fTypeNameControl->SetText(NULL);
|
||||
}
|
||||
|
||||
_UpdateExtensions(type);
|
||||
_UpdatePreferredApps(type);
|
||||
fIconView->SetTo(type);
|
||||
|
||||
fIconView->SetEnabled(enabled);
|
||||
|
||||
fTypeNameControl->SetEnabled(enabled);
|
||||
fPreferredField->SetEnabled(enabled);
|
||||
|
||||
fRemoveTypeButton->SetEnabled(enabled);
|
||||
|
||||
fSelectButton->SetEnabled(enabled);
|
||||
fSameAsButton->SetEnabled(enabled);
|
||||
|
||||
fAddExtensionButton->SetEnabled(enabled);
|
||||
fRemoveExtensionButton->SetEnabled(false);
|
||||
|
||||
fAddAttributeButton->SetEnabled(enabled);
|
||||
fRemoveAttributeButton->SetEnabled(false);
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
FileTypesWindow::MessageReceived(BMessage* message)
|
||||
{
|
||||
BWindow::MessageReceived(message);
|
||||
switch (message->what) {
|
||||
case kMsgTypeSelected:
|
||||
int32 index;
|
||||
if (message->FindInt32("index", &index) == B_OK) {
|
||||
MimeTypeItem* item = (MimeTypeItem*)fTypeListView->ItemAt(index);
|
||||
if (item != NULL) {
|
||||
BMimeType type(item->Type());
|
||||
_SetType(&type);
|
||||
} else
|
||||
_SetType(NULL);
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
BWindow::MessageReceived(message);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -8,6 +8,15 @@
|
||||
|
||||
#include <Window.h>
|
||||
|
||||
class BButton;
|
||||
class BListView;
|
||||
class BMenuField;
|
||||
class BMimeType;
|
||||
class BOutlineListView;
|
||||
class BTextControl;
|
||||
|
||||
class IconView;
|
||||
|
||||
|
||||
class FileTypesWindow : public BWindow {
|
||||
public:
|
||||
@@ -15,10 +24,33 @@ class FileTypesWindow : public BWindow {
|
||||
virtual ~FileTypesWindow();
|
||||
|
||||
virtual void MessageReceived(BMessage* message);
|
||||
|
||||
virtual bool QuitRequested();
|
||||
|
||||
private:
|
||||
private:
|
||||
void _UpdateExtensions(BMimeType* type);
|
||||
void _UpdatePreferredApps(BMimeType* type);
|
||||
void _SetType(BMimeType* type);
|
||||
|
||||
private:
|
||||
BOutlineListView* fTypeListView;
|
||||
BButton* fRemoveTypeButton;
|
||||
|
||||
IconView* fIconView;
|
||||
|
||||
BListView* fExtensionListView;
|
||||
BButton* fAddExtensionButton;
|
||||
BButton* fRemoveExtensionButton;
|
||||
|
||||
BTextControl* fInternalNameControl;
|
||||
BTextControl* fTypeNameControl;
|
||||
|
||||
BMenuField* fPreferredField;
|
||||
BButton* fSelectButton;
|
||||
BButton* fSameAsButton;
|
||||
|
||||
BButton* fAddAttributeButton;
|
||||
BButton* fRemoveAttributeButton;
|
||||
|
||||
};
|
||||
|
||||
#endif // FILE_TYPES_WINDOW_H
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
SubDir HAIKU_TOP src preferences filetypes ;
|
||||
|
||||
SetSubDirSupportedPlatformsBeOSCompatible ;
|
||||
AddSubDirSupportedPlatforms libbe_test ;
|
||||
|
||||
SubDirSysHdrs $(SUBDIR) ;
|
||||
@@ -7,6 +8,7 @@ SubDirSysHdrs $(SUBDIR) ;
|
||||
Preference FileTypes :
|
||||
FileTypes.cpp
|
||||
FileTypesWindow.cpp
|
||||
MimeTypeListView.cpp
|
||||
: be tracker
|
||||
: FileTypes.rdef FileTypes.icons.rdef
|
||||
;
|
||||
|
||||
@@ -0,0 +1,207 @@
|
||||
/*
|
||||
* Copyright 2006, Axel Dörfler, axeld@pinc-software.de. All rights reserved.
|
||||
* Distributed under the terms of the MIT License.
|
||||
*/
|
||||
|
||||
|
||||
#include "MimeTypeListView.h"
|
||||
|
||||
#include <Mime.h>
|
||||
|
||||
|
||||
// TODO: lazy type collecting (super types only at startup)
|
||||
|
||||
|
||||
bool
|
||||
mimetype_is_application_signature(BMimeType& type)
|
||||
{
|
||||
char preferredApp[B_MIME_TYPE_LENGTH];
|
||||
|
||||
// The preferred application of an application is the same
|
||||
// as its signature.
|
||||
|
||||
return type.GetPreferredApp(preferredApp) == B_OK
|
||||
&& !strcasecmp(type.Type(), preferredApp);
|
||||
}
|
||||
|
||||
|
||||
// #pragma mark -
|
||||
|
||||
|
||||
MimeTypeItem::MimeTypeItem(BMimeType& type, bool flat)
|
||||
: BStringItem(type.Type(), !flat && type.IsSupertypeOnly() ? 1 : 0, false),
|
||||
fType(type.Type())
|
||||
{
|
||||
_SetTo(type);
|
||||
}
|
||||
|
||||
|
||||
MimeTypeItem::MimeTypeItem(const char* type, bool flat)
|
||||
: BStringItem(type, !flat && strchr(type, '/') != NULL ? 1 : 0, false),
|
||||
fType(type)
|
||||
{
|
||||
BMimeType mimeType(type);
|
||||
_SetTo(mimeType);
|
||||
}
|
||||
|
||||
|
||||
MimeTypeItem::~MimeTypeItem()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
MimeTypeItem::DrawItem(BView* owner, BRect itemRect, bool drawEverything)
|
||||
{
|
||||
BFont font;
|
||||
|
||||
if (IsSupertypeOnly()) {
|
||||
owner->GetFont(&font);
|
||||
BFont boldFont(font);
|
||||
boldFont.SetFace(B_BOLD_FACE);
|
||||
owner->SetFont(&boldFont);
|
||||
}
|
||||
|
||||
BStringItem::DrawItem(owner, itemRect, drawEverything);
|
||||
|
||||
if (IsSupertypeOnly())
|
||||
owner->SetFont(&font);
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
MimeTypeItem::_SetTo(BMimeType& type)
|
||||
{
|
||||
fIsSupertype = type.IsSupertypeOnly();
|
||||
|
||||
if (IsSupertypeOnly()) {
|
||||
// this is a super type
|
||||
fSupertype = type.Type();
|
||||
return;
|
||||
}
|
||||
|
||||
const char* subType = strchr(type.Type(), '/');
|
||||
fSupertype.SetTo(type.Type(), subType - type.Type());
|
||||
fSubtype.SetTo(subType + 1);
|
||||
// omit the slash
|
||||
|
||||
char description[B_MIME_TYPE_LENGTH];
|
||||
if (type.GetShortDescription(description) == B_OK)
|
||||
SetText(description);
|
||||
else
|
||||
SetText(Subtype());
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
MimeTypeItem::AddSubtype()
|
||||
{
|
||||
BString text = Text();
|
||||
text.Append(" (");
|
||||
text.Append(fSubtype);
|
||||
text.Append(")");
|
||||
|
||||
SetText(text.String());
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
MimeTypeItem::Compare(const BListItem* a, const BListItem* b)
|
||||
{
|
||||
const MimeTypeItem* typeA = dynamic_cast<const MimeTypeItem*>(a);
|
||||
const MimeTypeItem* typeB = dynamic_cast<const MimeTypeItem*>(b);
|
||||
|
||||
if (typeA != NULL && typeB != NULL) {
|
||||
int compare = strcasecmp(typeA->Supertype(), typeB->Supertype());
|
||||
if (compare != 0)
|
||||
return compare;
|
||||
}
|
||||
|
||||
const BStringItem* stringA = dynamic_cast<const BStringItem*>(a);
|
||||
const BStringItem* stringB = dynamic_cast<const BStringItem*>(b);
|
||||
|
||||
if (stringA != NULL && stringB != NULL)
|
||||
return strcasecmp(stringA->Text(), stringB->Text());
|
||||
|
||||
return (int)(a - b);
|
||||
}
|
||||
|
||||
|
||||
// #pragma mark -
|
||||
|
||||
|
||||
MimeTypeListView::MimeTypeListView(BRect rect, const char* name,
|
||||
uint32 resizingMode)
|
||||
: BOutlineListView(rect, name, B_SINGLE_SELECTION_LIST, resizingMode)
|
||||
{
|
||||
_CollectTypes();
|
||||
}
|
||||
|
||||
|
||||
MimeTypeListView::~MimeTypeListView()
|
||||
{
|
||||
// free items, stupid BOutlineListView doesn't do this itself
|
||||
|
||||
for (int32 i = FullListCountItems(); i-- > 0;) {
|
||||
delete FullListItemAt(i);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
MimeTypeListView::_CollectTypes()
|
||||
{
|
||||
BMessage superTypes;
|
||||
if (BMimeType::GetInstalledSupertypes(&superTypes) != B_OK)
|
||||
return;
|
||||
|
||||
const char* superType;
|
||||
int32 index = 0;
|
||||
while (superTypes.FindString("super_types", index++, &superType) == B_OK) {
|
||||
BStringItem* superTypeItem = new MimeTypeItem(superType);
|
||||
AddItem(superTypeItem);
|
||||
|
||||
BMessage types;
|
||||
if (BMimeType::GetInstalledTypes(superType, &types) != B_OK)
|
||||
continue;
|
||||
|
||||
const char* type;
|
||||
int32 typeIndex = 0;
|
||||
while (types.FindString("types", typeIndex++, &type) == B_OK) {
|
||||
BMimeType mimeType(type);
|
||||
|
||||
if (mimetype_is_application_signature(mimeType))
|
||||
continue;
|
||||
|
||||
BStringItem* typeItem = new MimeTypeItem(mimeType);
|
||||
AddUnder(typeItem, superTypeItem);
|
||||
}
|
||||
}
|
||||
|
||||
FullListSortItems(&MimeTypeItem::Compare);
|
||||
|
||||
// make double entries unique
|
||||
|
||||
bool lastItemSame = false;
|
||||
MimeTypeItem* last = NULL;
|
||||
|
||||
for (index = 0; index < FullListCountItems(); index++) {
|
||||
MimeTypeItem* item = dynamic_cast<MimeTypeItem*>(FullListItemAt(index));
|
||||
if (item == NULL)
|
||||
continue;
|
||||
|
||||
if (last == NULL || MimeTypeItem::Compare(last, item)) {
|
||||
if (lastItemSame)
|
||||
last->AddSubtype();
|
||||
|
||||
lastItemSame = false;
|
||||
last = item;
|
||||
continue;
|
||||
}
|
||||
|
||||
lastItemSame = true;
|
||||
last->AddSubtype();
|
||||
last = item;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,54 @@
|
||||
/*
|
||||
* Copyright 2006, Axel Dörfler, axeld@pinc-software.de. All rights reserved.
|
||||
* Distributed under the terms of the MIT License.
|
||||
*/
|
||||
#ifndef MIME_TYPE_LIST_VIEW_H
|
||||
#define MIME_TYPE_LIST_VIEW_H
|
||||
|
||||
|
||||
#include <OutlineListView.h>
|
||||
#include <String.h>
|
||||
|
||||
class BMimeType;
|
||||
|
||||
|
||||
class MimeTypeItem : public BStringItem {
|
||||
public:
|
||||
MimeTypeItem(BMimeType& type, bool flat = false);
|
||||
MimeTypeItem(const char* type, bool flat = false);
|
||||
virtual ~MimeTypeItem();
|
||||
|
||||
virtual void DrawItem(BView* owner, BRect itemRect,
|
||||
bool drawEverything = false);
|
||||
|
||||
const char* Type() const { return fType.String(); }
|
||||
const char* Subtype() const { return fSubtype.String(); }
|
||||
const char* Supertype() const { return fSupertype.String(); }
|
||||
bool IsSupertypeOnly() const { return fIsSupertype; }
|
||||
|
||||
void AddSubtype();
|
||||
|
||||
static int Compare(const BListItem* a, const BListItem* b);
|
||||
|
||||
private:
|
||||
void _SetTo(BMimeType& type);
|
||||
|
||||
BString fSupertype;
|
||||
BString fSubtype;
|
||||
BString fType;
|
||||
bool fIsSupertype;
|
||||
};
|
||||
|
||||
class MimeTypeListView : public BOutlineListView {
|
||||
public:
|
||||
MimeTypeListView(BRect rect, const char* name,
|
||||
uint32 resizingMode = B_FOLLOW_LEFT | B_FOLLOW_TOP);
|
||||
virtual ~MimeTypeListView();
|
||||
|
||||
private:
|
||||
void _CollectTypes();
|
||||
};
|
||||
|
||||
bool mimetype_is_application_signature(BMimeType& type);
|
||||
|
||||
#endif // MIME_TYPE_LIST_VIEW_H
|
||||
Reference in New Issue
Block a user