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:
Axel Dörfler
2006-02-11 18:46:49 +00:00
parent 1afee82631
commit 9941e6c9ea
6 changed files with 598 additions and 49 deletions
+1 -1
View File
@@ -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
}
+300 -46
View File
@@ -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);
}
}
+34 -2
View File
@@ -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
+2
View File
@@ -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