* You can now change a MIME type's name as well as its preferred application.

* The menu field will now show the app's signature initially as well, if it's
  part of the item's label (wasn't picked up before, because BMenuItem::SetMarked()
  was called before the signature was added to the label).


git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@16359 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
Axel Dörfler 2006-02-12 14:27:22 +00:00
parent d940ea1189
commit 3069c9573a
4 changed files with 211 additions and 24 deletions

View File

@ -28,9 +28,24 @@
const uint32 kMsgTypeSelected = 'typs';
const uint32 kMsgAddType = 'atyp';
const uint32 kMsgRemoveType = 'rtyp';
const uint32 kMsgExtensionSelected = 'exts';
const uint32 kMsgExtensionInvoked = 'exti';
const uint32 kMsgAddExtension = 'aext';
const uint32 kMsgRemoveExtension = 'rext';
const uint32 kMsgAttributeSelected = 'atrs';
const uint32 kMsgAttributeInvoked = 'atri';
const uint32 kMsgAddAttribute = 'aatr';
const uint32 kMsgRemoveAttribute = 'ratr';
const uint32 kMsgPreferredAppChosen = 'papc';
const uint32 kMsgSelectPreferredApp = 'slpa';
const uint32 kMsgSamePreferredAppAs = 'spaa';
const uint32 kMsgTypeEntered = 'type';
const struct type_map {
@ -412,15 +427,16 @@ FileTypesWindow::FileTypesWindow(BRect frame)
topView->SetViewColor(ui_color(B_PANEL_BACKGROUND_COLOR));
AddChild(topView);
BButton* button = new BButton(rect, "add", "Add" B_UTF8_ELLIPSIS, NULL,
B_FOLLOW_BOTTOM);
BButton* button = new BButton(rect, "add", "Add" B_UTF8_ELLIPSIS,
new BMessage(kMsgAddType), B_FOLLOW_BOTTOM);
button->ResizeToPreferred();
button->MoveTo(8.0f, topView->Bounds().bottom - 8.0f - button->Bounds().Height());
topView->AddChild(button);
rect = button->Frame();
rect.OffsetBy(rect.Width() + 8.0f, 0.0f);
fRemoveTypeButton = new BButton(rect, "remove", "Remove", NULL, B_FOLLOW_BOTTOM);
fRemoveTypeButton = new BButton(rect, "remove", "Remove",
new BMessage(kMsgRemoveType), B_FOLLOW_BOTTOM);
fRemoveTypeButton->ResizeToPreferred();
topView->AddChild(fRemoveTypeButton);
@ -476,12 +492,12 @@ FileTypesWindow::FileTypesWindow(BRect frame)
innerRect.left = innerRect.right - button->StringWidth("Remove") - 16.0f;
innerRect.bottom = innerRect.top + button->Bounds().Height();
fAddExtensionButton = new BButton(innerRect, "add ext", "Add" B_UTF8_ELLIPSIS,
NULL, B_FOLLOW_RIGHT);
new BMessage(kMsgAddExtension), B_FOLLOW_RIGHT);
box->AddChild(fAddExtensionButton);
innerRect.OffsetBy(0, innerRect.Height() + 4.0f);
fRemoveExtensionButton = new BButton(innerRect, "remove ext", "Remove", NULL,
B_FOLLOW_RIGHT);
fRemoveExtensionButton = new BButton(innerRect, "remove ext", "Remove",
new BMessage(kMsgRemoveExtension), B_FOLLOW_RIGHT);
box->AddChild(fRemoveExtensionButton);
innerRect.right = innerRect.left - 10.0f - B_V_SCROLL_BAR_WIDTH;
@ -492,6 +508,8 @@ FileTypesWindow::FileTypesWindow(BRect frame)
fExtensionListView = new BListView(innerRect, "listview ext",
B_SINGLE_SELECTION_LIST, B_FOLLOW_LEFT_RIGHT);
fExtensionListView->SetSelectionMessage(new BMessage(kMsgExtensionSelected));
fExtensionListView->SetInvocationMessage(new BMessage(kMsgExtensionInvoked));
scrollView = new BScrollView("scrollview ext", fExtensionListView,
B_FOLLOW_LEFT_RIGHT, B_FRAME_EVENTS | B_WILL_DRAW, false, true);
box->AddChild(scrollView);
@ -519,7 +537,7 @@ FileTypesWindow::FileTypesWindow(BRect frame)
innerRect.OffsetBy(0, fInternalNameControl->Bounds().Height() + 5.0f);
fTypeNameControl = new BTextControl(innerRect, "type", "Type Name:", "",
NULL, B_FOLLOW_LEFT_RIGHT);
new BMessage(kMsgTypeEntered), B_FOLLOW_LEFT_RIGHT);
fTypeNameControl->SetDivider(labelWidth);
fTypeNameControl->SetAlignment(B_ALIGN_RIGHT, B_ALIGN_LEFT);
box->AddChild(fTypeNameControl);
@ -538,13 +556,13 @@ 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();
fSameAsButton = new BButton(innerRect, "same as", "Same As" B_UTF8_ELLIPSIS, NULL,
B_FOLLOW_RIGHT);
fSameAsButton = new BButton(innerRect, "same as", "Same As" B_UTF8_ELLIPSIS,
new BMessage(kMsgSamePreferredAppAs), B_FOLLOW_RIGHT);
box->AddChild(fSameAsButton);
innerRect.OffsetBy(-innerRect.Width() - 6.0f, 0.0f);
fSelectButton = new BButton(innerRect, "select", "Select" B_UTF8_ELLIPSIS, NULL,
B_FOLLOW_RIGHT);
fSelectButton = new BButton(innerRect, "select", "Select" B_UTF8_ELLIPSIS,
new BMessage(kMsgSelectPreferredApp), B_FOLLOW_RIGHT);
box->AddChild(fSelectButton);
menu = new BPopUpMenu("preferred");
@ -581,13 +599,13 @@ 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();
fAddAttributeButton = new BButton(innerRect, "add attr", "Add" B_UTF8_ELLIPSIS, NULL,
B_FOLLOW_RIGHT);
fAddAttributeButton = new BButton(innerRect, "add attr", "Add" B_UTF8_ELLIPSIS,
new BMessage(kMsgAddAttribute), B_FOLLOW_RIGHT);
box->AddChild(fAddAttributeButton);
innerRect.OffsetBy(0, innerRect.Height() + 4.0f);
fRemoveAttributeButton = new BButton(innerRect, "remove attr", "Remove",
NULL, B_FOLLOW_RIGHT);
new BMessage(kMsgRemoveAttribute), B_FOLLOW_RIGHT);
box->AddChild(fRemoveAttributeButton);
innerRect.right = innerRect.left - 10.0f - B_V_SCROLL_BAR_WIDTH;
@ -598,6 +616,8 @@ FileTypesWindow::FileTypesWindow(BRect frame)
fAttributeListView = new AttributeListView(innerRect, "listview attr",
B_FOLLOW_ALL);
fAttributeListView->SetSelectionMessage(new BMessage(kMsgAttributeSelected));
fAttributeListView->SetInvocationMessage(new BMessage(kMsgAttributeInvoked));
scrollView = new BScrollView("scrollview attr", fAttributeListView,
B_FOLLOW_ALL, B_FRAME_EVENTS | B_WILL_DRAW, false, true);
box->AddChild(scrollView);
@ -738,6 +758,7 @@ FileTypesWindow::_UpdatePreferredApps(BMimeType* type)
bool lastItemSame = false;
const char* lastSignature = NULL;
BMenuItem* last = NULL;
BMenuItem* select = NULL;
for (int32 index = 0; index < menu->CountItems(); index++) {
BMenuItem* item = menu->ItemAt(index);
@ -749,7 +770,7 @@ FileTypesWindow::_UpdatePreferredApps(BMimeType* type)
continue;
if (!strcasecmp(signature, preferred))
item->SetMarked(true);
select = item;
if (last == NULL || strcmp(last->Label(), item->Label())) {
if (lastItemSame)
@ -770,6 +791,12 @@ FileTypesWindow::_UpdatePreferredApps(BMimeType* type)
if (lastItemSame)
_AddSignature(last, lastSignature);
if (select != NULL) {
// We don't select the item earlier, so that the menu field can
// pick up the signature as well as label.
select->SetMarked(true);
}
}
@ -779,13 +806,18 @@ FileTypesWindow::_SetType(BMimeType* type)
bool enabled = type != NULL;
if (type != NULL) {
if (fCurrentType == *type)
return;
fCurrentType.SetTo(type->Type());
fInternalNameControl->SetText(type->Type());
char description[B_MIME_TYPE_LENGTH];
if (type->GetShortDescription(description) != B_OK)
description[0] = '\0';
fTypeNameControl->SetText(description);
} else {
fCurrentType.Unset();
fInternalNameControl->SetText(NULL);
fTypeNameControl->SetText(NULL);
}
@ -831,6 +863,8 @@ FileTypesWindow::MessageReceived(BMessage* message)
break;
}
// File Extensions group
case kMsgExtensionSelected:
{
int32 index;
@ -841,6 +875,43 @@ FileTypesWindow::MessageReceived(BMessage* message)
break;
}
case kMsgExtensionInvoked:
puts("ext");
break;
case kMsgAddExtension:
puts("add ext");
break;
case kMsgRemoveExtension:
puts("remove ext");
break;
// Description group
case kMsgTypeEntered:
{
fCurrentType.SetShortDescription(fTypeNameControl->Text());
MimeTypeItem* item = dynamic_cast<MimeTypeItem*>(
fTypeListView->ItemAt(fTypeListView->CurrentSelection()));
if (item != NULL)
fTypeListView->UpdateItem(item);
break;
}
// Preferred Application group
case kMsgPreferredAppChosen:
{
const char* signature;
if (message->FindString("signature", &signature) == B_OK)
fCurrentType.SetPreferredApp(signature);
break;
}
// Extra Attributes group
case kMsgAttributeSelected:
{
int32 index;
@ -851,6 +922,18 @@ FileTypesWindow::MessageReceived(BMessage* message)
break;
}
case kMsgAttributeInvoked:
puts("attr");
break;
case kMsgAddAttribute:
puts("add attr");
break;
case kMsgRemoveAttribute:
puts("remove attr");
break;
default:
BWindow::MessageReceived(message);
}

View File

@ -6,6 +6,7 @@
#define FILE_TYPES_WINDOW_H
#include <Mime.h>
#include <Window.h>
class BButton;
@ -17,6 +18,7 @@ class BTextControl;
class AttributeListView;
class IconView;
class MimeTypeListView;
class FileTypesWindow : public BWindow {
@ -34,7 +36,9 @@ class FileTypesWindow : public BWindow {
void _SetType(BMimeType* type);
private:
BOutlineListView* fTypeListView;
BMimeType fCurrentType;
MimeTypeListView* fTypeListView;
BButton* fRemoveTypeButton;
IconView* fIconView;

View File

@ -77,6 +77,7 @@ MimeTypeItem::_SetTo(BMimeType& type)
if (IsSupertypeOnly()) {
// this is a super type
fSupertype = type.Type();
fDescription = type.Type();
return;
}
@ -85,18 +86,32 @@ MimeTypeItem::_SetTo(BMimeType& type)
fSubtype.SetTo(subType + 1);
// omit the slash
Update();
}
void
MimeTypeItem::Update()
{
BMimeType type(fType.String());
char description[B_MIME_TYPE_LENGTH];
if (type.GetShortDescription(description) == B_OK)
SetText(description);
else
SetText(Subtype());
fDescription = Text();
}
void
MimeTypeItem::AddSubtype()
{
BString text = Text();
if (fSubtype == Text())
return;
BString text = Description();
text.Append(" (");
text.Append(fSubtype);
text.Append(")");
@ -127,6 +142,28 @@ MimeTypeItem::Compare(const BListItem* a, const BListItem* b)
}
int
MimeTypeItem::CompareLabels(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->Description(), typeB->Description());
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 -
@ -178,21 +215,43 @@ MimeTypeListView::_CollectTypes()
}
}
FullListSortItems(&MimeTypeItem::Compare);
_MakeTypesUnique();
}
// make double entries unique
void
MimeTypeListView::_MakeTypesUnique(MimeTypeItem* underItem)
{
SortItemsUnder(underItem, false, &MimeTypeItem::Compare);
bool lastItemSame = false;
MimeTypeItem* last = NULL;
for (index = 0; index < FullListCountItems(); index++) {
int32 index = 0;
uint32 level = 0;
if (underItem != NULL) {
index = FullListIndexOf(underItem) + 1;
level = underItem->OutlineLevel() + 1;
}
for (; index < FullListCountItems(); index++) {
MimeTypeItem* item = dynamic_cast<MimeTypeItem*>(FullListItemAt(index));
if (item == NULL)
continue;
if (last == NULL || MimeTypeItem::Compare(last, item)) {
if (lastItemSame)
if (item->OutlineLevel() < level) {
// left sub-tree
break;
}
item->SetText(item->Description());
if (last == NULL || MimeTypeItem::CompareLabels(last, item)) {
if (lastItemSame) {
last->AddSubtype();
if (Window())
InvalidateItem(IndexOf(last));
}
lastItemSame = false;
last = item;
@ -201,10 +260,43 @@ MimeTypeListView::_CollectTypes()
lastItemSame = true;
last->AddSubtype();
if (Window())
InvalidateItem(IndexOf(last));
last = item;
}
if (lastItemSame)
if (lastItemSame) {
last->AddSubtype();
if (Window())
InvalidateItem(IndexOf(last));
}
}
void
MimeTypeListView::UpdateItem(MimeTypeItem* item)
{
int32 selected = -1;
if (IndexOf(item) == CurrentSelection())
selected = CurrentSelection();
item->Update();
_MakeTypesUnique(dynamic_cast<MimeTypeItem*>(Superitem(item)));
if (selected != -1) {
int32 index = IndexOf(item);
if (index != selected) {
Select(index);
ScrollToSelection();
}
}
if (Window())
InvalidateItem(IndexOf(item));
}
void
MimeTypeListView::RemoveItem(MimeTypeItem* item)
{
}

View File

@ -24,11 +24,14 @@ class MimeTypeItem : public BStringItem {
const char* Type() const { return fType.String(); }
const char* Subtype() const { return fSubtype.String(); }
const char* Supertype() const { return fSupertype.String(); }
const char* Description() const { return fDescription.String(); }
bool IsSupertypeOnly() const { return fIsSupertype; }
void Update();
void AddSubtype();
static int Compare(const BListItem* a, const BListItem* b);
static int CompareLabels(const BListItem* a, const BListItem* b);
private:
void _SetTo(BMimeType& type);
@ -36,6 +39,7 @@ class MimeTypeItem : public BStringItem {
BString fSupertype;
BString fSubtype;
BString fType;
BString fDescription;
bool fIsSupertype;
};
@ -45,8 +49,12 @@ class MimeTypeListView : public BOutlineListView {
uint32 resizingMode = B_FOLLOW_LEFT | B_FOLLOW_TOP);
virtual ~MimeTypeListView();
void UpdateItem(MimeTypeItem* item);
void RemoveItem(MimeTypeItem* item);
private:
void _CollectTypes();
void _MakeTypesUnique(MimeTypeItem* underItem = NULL);
};
bool mimetype_is_application_signature(BMimeType& type);