From 89fe2e175ea025304e167719c798aa63a9e45559 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Axel=20D=C3=B6rfler?= Date: Fri, 20 Apr 2007 17:05:56 +0000 Subject: [PATCH] Completed the "display as" functionality as far as FileTypes is concerned for now. git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@20773 a95241bf-73f2-0310-859d-f6bbb57e9c96 --- .../filetypes/AttributeListView.cpp | 36 ++++- src/preferences/filetypes/AttributeListView.h | 10 +- src/preferences/filetypes/AttributeWindow.cpp | 147 +++++++++++++++--- src/preferences/filetypes/AttributeWindow.h | 5 +- src/preferences/filetypes/FileTypes.rdef | 2 +- 5 files changed, 175 insertions(+), 25 deletions(-) diff --git a/src/preferences/filetypes/AttributeListView.cpp b/src/preferences/filetypes/AttributeListView.cpp index 77f86596b2..26212d3922 100644 --- a/src/preferences/filetypes/AttributeListView.cpp +++ b/src/preferences/filetypes/AttributeListView.cpp @@ -1,5 +1,5 @@ /* - * Copyright 2006, Axel Dörfler, axeld@pinc-software.de. All rights reserved. + * Copyright 2006-2007, Axel Dörfler, axeld@pinc-software.de. All rights reserved. * Distributed under the terms of the MIT License. */ @@ -22,13 +22,43 @@ const struct type_map kTypeMap[] = { {NULL, 0} }; +// TODO: in the future, have a (private) Tracker API that exports these +// as well as a nice GUI for them. +const struct display_as_map kDisplayAsMap[] = { + {"Default", NULL, {}}, + {"Rating", "rating", {B_INT32_TYPE, B_INT8_TYPE, B_INT16_TYPE}}, + {NULL, NULL, {}} +}; + static void -name_for_type(BString& string, type_code type) +add_display_as(BString& string, const char* displayAs) +{ + if (displayAs == NULL || !displayAs[0]) + return; + + BString base(displayAs); + int32 end = base.FindFirst(": "); + if (end > 0) + base.Truncate(end); + + for (int32 i = 0; kDisplayAsMap[i].name != NULL; i++) { + if (base.ICompare(kDisplayAsMap[i].identifier) == 0) { + string += ", "; + string += base; + return; + } + } +} + + +static void +name_for_type(BString& string, type_code type, const char* displayAs) { for (int32 i = 0; kTypeMap[i].name != NULL; i++) { if (kTypeMap[i].type == type) { string = kTypeMap[i].name; + add_display_as(string, displayAs); return; } } @@ -152,7 +182,7 @@ AttributeItem::DrawItem(BView* owner, BRect frame, bool drawEverything) owner->MovePenTo(frame.left + frame.Width() / 2.0f + 5.0f, owner->PenLocation().y); BString type; - name_for_type(type, fType); + name_for_type(type, fType, fDisplayAs.String()); owner->DrawString(type.String()); owner->SetHighColor(tint_color(owner->ViewColor(), B_DARKEN_1_TINT)); diff --git a/src/preferences/filetypes/AttributeListView.h b/src/preferences/filetypes/AttributeListView.h index 76c80e3cdf..3ee9323f85 100644 --- a/src/preferences/filetypes/AttributeListView.h +++ b/src/preferences/filetypes/AttributeListView.h @@ -1,5 +1,5 @@ /* - * Copyright 2006, Axel Dörfler, axeld@pinc-software.de. All rights reserved. + * Copyright 2006-2007, Axel Dörfler, axeld@pinc-software.de. All rights reserved. * Distributed under the terms of the MIT License. */ #ifndef ATTRIBUTE_LIST_VIEW_H @@ -68,6 +68,14 @@ struct type_map { extern const struct type_map kTypeMap[]; +struct display_as_map { + const char* name; + const char* identifier; + type_code supported[8]; +}; + +extern const struct display_as_map kDisplayAsMap[]; + AttributeItem *create_attribute_item(BMessage& attributes, int32 index); #endif // ATTRIBUTE_LIST_VIEW_H diff --git a/src/preferences/filetypes/AttributeWindow.cpp b/src/preferences/filetypes/AttributeWindow.cpp index c3dc1a3ddc..b7c6b4f5b7 100644 --- a/src/preferences/filetypes/AttributeWindow.cpp +++ b/src/preferences/filetypes/AttributeWindow.cpp @@ -1,5 +1,5 @@ /* - * Copyright 2006, Axel Dörfler, axeld@pinc-software.de. All rights reserved. + * Copyright 2006-2007, Axel Dörfler, axeld@pinc-software.de. All rights reserved. * Distributed under the terms of the MIT License. */ @@ -26,6 +26,7 @@ const uint32 kMsgAttributeUpdated = 'atup'; const uint32 kMsgTypeChosen = 'typc'; +const uint32 kMsgDisplayAsChosen = 'dach'; const uint32 kMsgVisibilityChanged = 'vsch'; const uint32 kMsgAlignmentChosen = 'alnc'; const uint32 kMsgAccept = 'acpt'; @@ -45,6 +46,40 @@ compare_attributes(const void* _a, const void* _b) } +static bool +compare_display_as(const char* a, const char* b) +{ + bool emptyA = a == NULL || !a[0]; + bool emptyB = b == NULL || !b[0]; + + if (emptyA && emptyB) + return true; + if (emptyA || emptyB) + return false; + + const char* end = strstr(a, ": "); + int32 lengthA = end ? end - a : strlen(a); + end = strstr(b, ": "); + int32 lengthB = end ? end - b : strlen(b); + + if (lengthA != lengthB) + return false; + + return !strncasecmp(a, b, lengthA); +} + + +static const char* +display_as_parameter(const char* special) +{ + const char* parameter = strstr(special, ": "); + if (parameter != NULL) + return parameter + 2; + + return NULL; +} + + // #pragma mark - @@ -96,7 +131,7 @@ AttributeWindow::AttributeWindow(FileTypesWindow* target, BMimeType& mimeType, topView->AddChild(fAttributeControl); fTypeMenu = new BPopUpMenu("type"); - BMenuItem* item; + BMenuItem* item = NULL; for (int32 i = 0; kTypeMap[i].name != NULL; i++) { BMessage* message = new BMessage(kMsgTypeChosen); message->AddInt32("type", kTypeMap[i].type); @@ -131,9 +166,21 @@ AttributeWindow::AttributeWindow(FileTypesWindow* target, BMimeType& mimeType, labelWidth -= 8.0f; BMenu* menu = new BPopUpMenu("display as"); - // TODO! - menu->AddItem(item = new BMenuItem("Default", NULL)); - item->SetMarked(true); + for (int32 i = 0; kDisplayAsMap[i].name != NULL; i++) { + BMessage* message = new BMessage(kMsgDisplayAsChosen); + if (kDisplayAsMap[i].identifier != NULL) { + message->AddString("identifier", kDisplayAsMap[i].identifier); + for (int32 j = 0; kDisplayAsMap[i].supported[j]; j++) { + message->AddInt32("supports", kDisplayAsMap[i].supported[j]); + } + } + + item = new BMenuItem(kDisplayAsMap[i].name, message); + menu->AddItem(item); + + if (compare_display_as(kDisplayAsMap[i].identifier, fAttribute.DisplayAs())) + item->SetMarked(true); + } rect.OffsetTo(8.0f, fVisibleCheckBox->Bounds().Height()); rect.right -= 18.0f; @@ -156,7 +203,8 @@ AttributeWindow::AttributeWindow(FileTypesWindow* target, BMimeType& mimeType, rect.OffsetBy(0.0f, menuField->Bounds().Height() + 4.0f); rect.bottom = rect.top + fPublicNameControl->Bounds().Height(); fSpecialControl = new BTextControl(rect, "special", "Special:", - NULL, NULL, B_FOLLOW_LEFT_RIGHT); + display_as_parameter(fAttribute.DisplayAs()), NULL, + B_FOLLOW_LEFT_RIGHT); fSpecialControl->SetModificationMessage(new BMessage(kMsgAttributeUpdated)); fSpecialControl->SetDivider(labelWidth); fSpecialControl->SetAlignment(B_ALIGN_RIGHT, B_ALIGN_LEFT); @@ -248,6 +296,58 @@ AttributeWindow::~AttributeWindow() } +type_code +AttributeWindow::_CurrentType() const +{ + type_code type = B_STRING_TYPE; + BMenuItem* item = fTypeMenu->FindMarked(); + if (item != NULL && item->Message() != NULL) { + int32 value; + if (item->Message()->FindInt32("type", &value) == B_OK) + type = value; + } + + return type; +} + + +BMenuItem* +AttributeWindow::_DefaultDisplayAs() const +{ + return fDisplayAsMenuField->Menu()->ItemAt(0); +} + + +void +AttributeWindow::_CheckDisplayAs() +{ + // check display as suported types + + type_code currentType = _CurrentType(); + + BMenu* menu = fDisplayAsMenuField->Menu(); + for (int32 i = menu->CountItems(); i-- > 0;) { + BMenuItem* item = menu->ItemAt(i); + bool supported = item == _DefaultDisplayAs(); + // the default type is always supported + type_code type; + for (int32 j = 0; item->Message()->FindInt32("supports", + j, (int32*)&type) == B_OK; j++) { + if (type == currentType) { + supported = true; + break; + } + } + + item->SetEnabled(supported); + if (item->IsMarked() && !supported) + menu->ItemAt(0)->SetMarked(true); + } + + fSpecialControl->SetEnabled(!_DefaultDisplayAs()->IsMarked()); +} + + void AttributeWindow::_CheckAcceptable() { @@ -275,16 +375,10 @@ AttributeWindow::_NewItemFromCurrent() { const char* newAttribute = fAttributeControl->Text(); - type_code type = B_STRING_TYPE; - BMenuItem* item = fTypeMenu->FindMarked(); - if (item != NULL && item->Message() != NULL) { - int32 value; - if (item->Message()->FindInt32("type", &value) == B_OK) - type = value; - } + type_code type = _CurrentType(); int32 alignment = B_ALIGN_LEFT; - item = fAlignmentMenuField->Menu()->FindMarked(); + BMenuItem* item = fAlignmentMenuField->Menu()->FindMarked(); if (item != NULL && item->Message() != NULL) { int32 value; if (item->Message()->FindInt32("alignment", &value) == B_OK) @@ -295,12 +389,22 @@ AttributeWindow::_NewItemFromCurrent() if (width < 0) width = 0; - char displayAs[512]; - displayAs[0] = '\0'; - //strlcpy(displayAs, fSpecialControl->Text(), sizeof(displayAs)); + BString displayAs; + item = fDisplayAsMenuField->Menu()->FindMarked(); + if (item != NULL) { + const char* identifier; + if (item->Message()->FindString("identifier", &identifier) == B_OK) { + displayAs = identifier; + + if (fSpecialControl->Text() && fSpecialControl->Text()[0]) { + displayAs += ": "; + displayAs += fSpecialControl->Text(); + } + } + } return new AttributeItem(newAttribute, - fPublicNameControl->Text(), type, displayAs, alignment, + fPublicNameControl->Text(), type, displayAs.String(), alignment, width, fVisibleCheckBox->Value() == B_CONTROL_ON, fEditableCheckBox->Value() == B_CONTROL_ON); } @@ -313,19 +417,24 @@ AttributeWindow::MessageReceived(BMessage* message) case kMsgAttributeUpdated: case kMsgAlignmentChosen: case kMsgTypeChosen: + _CheckDisplayAs(); _CheckAcceptable(); break; + case kMsgDisplayAsChosen: + fSpecialControl->SetEnabled(!_DefaultDisplayAs()->IsMarked()); + break; + case kMsgVisibilityChanged: { bool enabled = fVisibleCheckBox->Value() != B_CONTROL_OFF; fDisplayAsMenuField->SetEnabled(enabled); - //fSpecialControl->SetEnabled(enabled); fWidthControl->SetEnabled(enabled); fAlignmentMenuField->SetEnabled(enabled); fEditableCheckBox->SetEnabled(enabled); + _CheckDisplayAs(); _CheckAcceptable(); break; } diff --git a/src/preferences/filetypes/AttributeWindow.h b/src/preferences/filetypes/AttributeWindow.h index a986c8c559..71a15794a8 100644 --- a/src/preferences/filetypes/AttributeWindow.h +++ b/src/preferences/filetypes/AttributeWindow.h @@ -1,5 +1,5 @@ /* - * Copyright 2006, Axel Dörfler, axeld@pinc-software.de. All rights reserved. + * Copyright 2006-2007, Axel Dörfler, axeld@pinc-software.de. All rights reserved. * Distributed under the terms of the MIT License. */ #ifndef ATTRIBUTE_WINDOW_H @@ -32,6 +32,9 @@ class AttributeWindow : public BWindow { virtual bool QuitRequested(); private: + type_code _CurrentType() const; + BMenuItem* _DefaultDisplayAs() const; + void _CheckDisplayAs(); void _CheckAcceptable(); AttributeItem* _NewItemFromCurrent(); diff --git a/src/preferences/filetypes/FileTypes.rdef b/src/preferences/filetypes/FileTypes.rdef index 1eea1505ed..57ec0ae34b 100644 --- a/src/preferences/filetypes/FileTypes.rdef +++ b/src/preferences/filetypes/FileTypes.rdef @@ -23,7 +23,7 @@ resource app_version { internal = 1, short_info = "FileTypes", - long_info = "FileTypes ©2006 Haiku Inc." + long_info = "FileTypes ©2006-2007 Haiku Inc." };