* 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:
parent
d940ea1189
commit
3069c9573a
@ -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);
|
||||
}
|
||||
|
@ -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;
|
||||
|
@ -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)
|
||||
{
|
||||
}
|
||||
|
||||
|
@ -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);
|
||||
|
Loading…
Reference in New Issue
Block a user