From 067c811fe8a97ada78c00d4ee14510b6ac0dbbfc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Stephan=20A=C3=9Fmus?= Date: Sun, 26 Feb 2006 17:37:42 +0000 Subject: [PATCH] * "Extra Attributes" can now be added as well. * Moved AttributeListView and AttributeItem into its own file. * Can now be compiled on R5 systems again. (coded by axeld) git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@16506 a95241bf-73f2-0310-859d-f6bbb57e9c96 --- .../filetypes/ApplicationTypesWindow.cpp | 9 + .../filetypes/AttributeListView.cpp | 264 ++++++++++++ src/preferences/filetypes/AttributeListView.h | 73 ++++ src/preferences/filetypes/AttributeWindow.cpp | 392 ++++++++++++++++++ src/preferences/filetypes/AttributeWindow.h | 52 +++ src/preferences/filetypes/ExtensionWindow.cpp | 9 +- src/preferences/filetypes/ExtensionWindow.h | 4 +- src/preferences/filetypes/FileTypesWindow.cpp | 248 ++--------- src/preferences/filetypes/Jamfile | 2 + src/preferences/filetypes/StringView.cpp | 10 +- 10 files changed, 826 insertions(+), 237 deletions(-) create mode 100644 src/preferences/filetypes/AttributeListView.cpp create mode 100644 src/preferences/filetypes/AttributeListView.h create mode 100644 src/preferences/filetypes/AttributeWindow.cpp create mode 100644 src/preferences/filetypes/AttributeWindow.h diff --git a/src/preferences/filetypes/ApplicationTypesWindow.cpp b/src/preferences/filetypes/ApplicationTypesWindow.cpp index daff82b5dd..e666de0194 100644 --- a/src/preferences/filetypes/ApplicationTypesWindow.cpp +++ b/src/preferences/filetypes/ApplicationTypesWindow.cpp @@ -40,6 +40,15 @@ const uint32 kMsgRemoveUninstalled = 'runs'; const char* variety_to_text(uint32 variety) { +#if defined(HAIKU_TARGET_PLATFORM_BEOS) || defined(HAIKU_TARGET_PLATFORM_BONE) +# define B_DEVELOPMENT_VERSION 0 +# define B_ALPHA_VERSION 1 +# define B_BETA_VERSION 2 +# define B_GAMMA_VERSION 3 +# define B_GOLDEN_MASTER_VERSION 4 +# define B_FINAL_VERSION 5 +#endif + switch (variety) { case B_DEVELOPMENT_VERSION: return "Development"; diff --git a/src/preferences/filetypes/AttributeListView.cpp b/src/preferences/filetypes/AttributeListView.cpp new file mode 100644 index 0000000000..77f86596b2 --- /dev/null +++ b/src/preferences/filetypes/AttributeListView.cpp @@ -0,0 +1,264 @@ +/* + * Copyright 2006, Axel Dörfler, axeld@pinc-software.de. All rights reserved. + * Distributed under the terms of the MIT License. + */ + + +#include "AttributeListView.h" + +#include + + +const struct type_map kTypeMap[] = { + {"String", B_STRING_TYPE}, + {"Boolean", B_BOOL_TYPE}, + {"Integer 8 bit", B_INT8_TYPE}, + {"Integer 16 bit", B_INT16_TYPE}, + {"Integer 32 bit", B_INT32_TYPE}, + {"Integer 64 bit", B_INT64_TYPE}, + {"Float", B_FLOAT_TYPE}, + {"Double", B_DOUBLE_TYPE}, + {"Time", B_TIME_TYPE}, + {NULL, 0} +}; + + +static void +name_for_type(BString& string, type_code type) +{ + for (int32 i = 0; kTypeMap[i].name != NULL; i++) { + if (kTypeMap[i].type == type) { + string = kTypeMap[i].name; + return; + } + } + + char buffer[32]; + buffer[0] = '\''; + buffer[1] = 0xff & (type >> 24); + buffer[2] = 0xff & (type >> 16); + buffer[3] = 0xff & (type >> 8); + buffer[4] = 0xff & (type); + buffer[5] = '\''; + buffer[6] = 0; + for (int16 i = 0;i < 4;i++) { + if (buffer[i] < ' ') + buffer[i] = '.'; + } + + snprintf(buffer + 6, sizeof(buffer), " (0x%lx)", type); + string = buffer; +} + + +AttributeItem * +create_attribute_item(BMessage& attributes, int32 index) +{ + const char* publicName; + if (attributes.FindString("attr:public_name", index, &publicName) != B_OK) + return NULL; + + const char* name; + if (attributes.FindString("attr:name", index, &name) != B_OK) + name = "-"; + + type_code type; + if (attributes.FindInt32("attr:type", index, (int32 *)&type) != B_OK) + type = B_STRING_TYPE; + + const char* displayAs; + if (attributes.FindString("attr:display_as", index, &displayAs) != B_OK) + displayAs = NULL; + + bool editable; + if (attributes.FindBool("attr:editable", index, &editable) != B_OK) + editable = false; + bool visible; + if (attributes.FindBool("attr:viewable", index, &visible) != B_OK) + visible = false; + + int32 alignment; + if (attributes.FindInt32("attr:alignment", index, &alignment) != B_OK) + alignment = B_ALIGN_LEFT; + + int32 width; + if (attributes.FindInt32("attr:width", index, &width) != B_OK) + width = 50; + + return new AttributeItem(name, publicName, type, displayAs, alignment, + width, visible, editable); +} + + +// #pragma mark - + + +AttributeItem::AttributeItem(const char* name, const char* publicName, + type_code type, const char* displayAs, int32 alignment, + int32 width, bool visible, bool editable) + : BStringItem(publicName), + fName(name), + fType(type), + fDisplayAs(displayAs), + fAlignment(alignment), + fWidth(width), + fVisible(visible), + fEditable(editable) +{ +} + + +AttributeItem::AttributeItem() + : BStringItem(""), + fType(B_STRING_TYPE), + fAlignment(B_ALIGN_LEFT), + fWidth(60), + fVisible(true), + fEditable(false) +{ +} + + +AttributeItem::AttributeItem(const AttributeItem& other) + : BStringItem(other.PublicName()) +{ + *this = other; +} + + +AttributeItem::~AttributeItem() +{ +} + + +void +AttributeItem::DrawItem(BView* owner, BRect frame, bool drawEverything) +{ + BStringItem::DrawItem(owner, frame, drawEverything); + + rgb_color highColor = owner->HighColor(); + rgb_color lowColor = owner->LowColor(); + + if (IsSelected()) + owner->SetLowColor(tint_color(lowColor, B_DARKEN_2_TINT)); + + rgb_color black = {0, 0, 0, 255}; + + if (!IsEnabled()) + owner->SetHighColor(tint_color(black, B_LIGHTEN_2_TINT)); + else + owner->SetHighColor(black); + + owner->MovePenTo(frame.left + frame.Width() / 2.0f + 5.0f, owner->PenLocation().y); + + BString type; + name_for_type(type, fType); + owner->DrawString(type.String()); + + owner->SetHighColor(tint_color(owner->ViewColor(), B_DARKEN_1_TINT)); + + float middle = frame.left + frame.Width() / 2.0f; + owner->StrokeLine(BPoint(middle, 0.0f), BPoint(middle, frame.bottom)); + + owner->SetHighColor(highColor); + owner->SetLowColor(lowColor); +} + + +AttributeItem& +AttributeItem::operator=(const AttributeItem& other) +{ + SetText(other.PublicName()); + fName = other.Name(); + fType = other.Type(); + fDisplayAs = other.DisplayAs(); + fAlignment = other.Alignment(); + fWidth = other.Width(); + fVisible = other.Visible(); + fEditable = other.Editable(); + + return *this; +} + + +bool +AttributeItem::operator==(const AttributeItem& other) const +{ + return !strcmp(Name(), other.Name()) + && !strcmp(PublicName(), other.PublicName()) + && !strcmp(DisplayAs(), other.DisplayAs()) + && Type() == other.Type() + && Alignment() == other.Alignment() + && Width() == other.Width() + && Visible() == other.Visible() + && Editable() == other.Editable(); +} + + +bool +AttributeItem::operator!=(const AttributeItem& other) const +{ + return !(*this == other); +} + + +// #pragma mark - + + +AttributeListView::AttributeListView(BRect frame, const char* name, + uint32 resizingMode) + : BListView(frame, name, B_SINGLE_SELECTION_LIST, resizingMode, + B_WILL_DRAW | B_NAVIGABLE | B_FULL_UPDATE_ON_RESIZE) +{ +} + + +AttributeListView::~AttributeListView() +{ + _DeleteItems(); +} + + +void +AttributeListView::_DeleteItems() +{ + for (int32 i = CountItems(); i-- > 0;) { + delete ItemAt(i); + } + MakeEmpty(); +} + + +void +AttributeListView::SetTo(BMimeType* type) +{ + _DeleteItems(); + + // fill it again + + if (type == NULL) + return; + + BMessage attributes; + if (type->GetAttrInfo(&attributes) != B_OK) + return; + + AttributeItem* item; + int32 i = 0; + while ((item = create_attribute_item(attributes, i++)) != NULL) { + AddItem(item); + } +} + + +void +AttributeListView::Draw(BRect updateRect) +{ + BListView::Draw(updateRect); + + SetHighColor(tint_color(ViewColor(), B_DARKEN_1_TINT)); + + float middle = Bounds().Width() / 2.0f; + StrokeLine(BPoint(middle, 0.0f), BPoint(middle, Bounds().bottom)); +} + diff --git a/src/preferences/filetypes/AttributeListView.h b/src/preferences/filetypes/AttributeListView.h new file mode 100644 index 0000000000..76c80e3cdf --- /dev/null +++ b/src/preferences/filetypes/AttributeListView.h @@ -0,0 +1,73 @@ +/* + * Copyright 2006, Axel Dörfler, axeld@pinc-software.de. All rights reserved. + * Distributed under the terms of the MIT License. + */ +#ifndef ATTRIBUTE_LIST_VIEW_H +#define ATTRIBUTE_LIST_VIEW_H + + +#include +#include +#include + + +class AttributeItem : public BStringItem { + public: + AttributeItem(const char* name, const char* publicName, type_code type, + const char* displayAs, int32 alignment, int32 width, bool visible, + bool editable); + AttributeItem(); + AttributeItem(const AttributeItem& other); + virtual ~AttributeItem(); + + virtual void DrawItem(BView* owner, BRect itemRect, + bool drawEverything = false); + + const char* Name() const { return fName.String(); } + const char* PublicName() const { return Text(); } + + type_code Type() const { return fType; } + const char* DisplayAs() const { return fDisplayAs.String(); } + int32 Alignment() const { return fAlignment; } + int32 Width() const { return fWidth; } + bool Visible() const { return fVisible; } + bool Editable() const { return fEditable; } + + AttributeItem& operator=(const AttributeItem& other); + + bool operator==(const AttributeItem& other) const; + bool operator!=(const AttributeItem& other) const; + + private: + BString fName; + type_code fType; + BString fDisplayAs; + int32 fAlignment; + int32 fWidth; + bool fVisible; + bool fEditable; +}; + +class AttributeListView : public BListView { + public: + AttributeListView(BRect frame, const char* name, uint32 resizingMode); + virtual ~AttributeListView(); + + void SetTo(BMimeType* type); + + virtual void Draw(BRect updateRect); + + private: + void _DeleteItems(); +}; + +struct type_map { + const char* name; + type_code type; +}; + +extern const struct type_map kTypeMap[]; + +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 new file mode 100644 index 0000000000..17f136c5b4 --- /dev/null +++ b/src/preferences/filetypes/AttributeWindow.cpp @@ -0,0 +1,392 @@ +/* + * Copyright 2006, Axel Dörfler, axeld@pinc-software.de. All rights reserved. + * Distributed under the terms of the MIT License. + */ + + +#include "AttributeWindow.h" +#include "FileTypesWindow.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include + + +const uint32 kMsgAttributeUpdated = 'atup'; +const uint32 kMsgTypeChosen = 'typc'; +const uint32 kMsgVisibilityChanged = 'vsch'; +const uint32 kMsgAlignmentChosen = 'alnc'; +const uint32 kMsgAccept = 'acpt'; + + +static int +compare_attributes(const void* _a, const void* _b) +{ + AttributeItem* a = *(AttributeItem **)_a; + AttributeItem* b = *(AttributeItem **)_b; + + int compare = strcasecmp(a->PublicName(), b->PublicName()); + if (compare != 0) + return compare; + + return strcmp(a->Name(), b->Name()); +} + + +// #pragma mark - + + +AttributeWindow::AttributeWindow(FileTypesWindow* target, BMimeType& mimeType, + AttributeItem* item) + : BWindow(BRect(100, 100, 350, 200), "Attribute", B_MODAL_WINDOW_LOOK, + B_MODAL_SUBSET_WINDOW_FEEL, B_NOT_ZOOMABLE | B_NOT_V_RESIZABLE + | B_ASYNCHRONOUS_CONTROLS), + fTarget(target), + fMimeType(mimeType.Type()) +{ + if (item != NULL) + fAttribute = *item; + + BRect rect = Bounds(); + BView* topView = new BView(rect, NULL, B_FOLLOW_ALL, B_WILL_DRAW); + topView->SetViewColor(ui_color(B_PANEL_BACKGROUND_COLOR)); + AddChild(topView); + + rect.InsetBy(8.0f, 8.0f); + fPublicNameControl = new BTextControl(rect, "public", "Attribute Name:", + fAttribute.PublicName(), NULL, B_FOLLOW_LEFT_RIGHT); + fPublicNameControl->SetModificationMessage(new BMessage(kMsgAttributeUpdated)); + + float labelWidth = fPublicNameControl->StringWidth(fPublicNameControl->Label()) + 2.0f; + fPublicNameControl->SetDivider(labelWidth); + fPublicNameControl->SetAlignment(B_ALIGN_RIGHT, B_ALIGN_LEFT); + + float width, height; + fPublicNameControl->GetPreferredSize(&width, &height); + fPublicNameControl->ResizeTo(rect.Width(), height); + topView->AddChild(fPublicNameControl); + + rect = fPublicNameControl->Frame(); + rect.OffsetBy(0.0f, rect.Height() + 5.0f); + fAttributeControl = new BTextControl(rect, "internal", "Internal Name:", + fAttribute.Name(), NULL, B_FOLLOW_LEFT_RIGHT); + fAttributeControl->SetModificationMessage(new BMessage(kMsgAttributeUpdated)); + fAttributeControl->SetDivider(labelWidth); + fAttributeControl->SetAlignment(B_ALIGN_RIGHT, B_ALIGN_LEFT); + + // filter out invalid characters that can't be part of an attribute + BTextView* textView = fAttributeControl->TextView(); + const char* disallowedCharacters = "/"; + for (int32 i = 0; disallowedCharacters[i]; i++) { + textView->DisallowChar(disallowedCharacters[i]); + } + + topView->AddChild(fAttributeControl); + + fTypeMenu = new BPopUpMenu("type"); + BMenuItem* item; + for (int32 i = 0; kTypeMap[i].name != NULL; i++) { + BMessage* message = new BMessage(kMsgTypeChosen); + message->AddInt32("type", kTypeMap[i].type); + + item = new BMenuItem(kTypeMap[i].name, message); + fTypeMenu->AddItem(item); + + if (kTypeMap[i].type == fAttribute.Type()) + item->SetMarked(true); + } + + rect.OffsetBy(0.0f, rect.Height() + 4.0f); + BMenuField* menuField = new BMenuField(rect, "types", + "Type:", fTypeMenu); + menuField->SetDivider(labelWidth); + menuField->SetAlignment(B_ALIGN_RIGHT); + menuField->GetPreferredSize(&width, &height); + menuField->ResizeTo(rect.Width(), height); + topView->AddChild(menuField); + + rect.OffsetBy(0.0f, rect.Height() + 4.0f); + rect.bottom = rect.top + fAttributeControl->Bounds().Height() * 5.0f + 22.0f; + BBox* box = new BBox(rect, "", B_FOLLOW_LEFT_RIGHT); + topView->AddChild(box); + + fVisibleCheckBox = new BCheckBox(rect, "visible", "Visible", + new BMessage(kMsgVisibilityChanged)); + fVisibleCheckBox->SetValue(fAttribute.Visible()); + fVisibleCheckBox->ResizeToPreferred(); + box->SetLabel(fVisibleCheckBox); + + labelWidth -= 8.0f; + + BMenu* menu = new BPopUpMenu("display as"); + // TODO! + menu->AddItem(item = new BMenuItem("Default", NULL)); + item->SetMarked(true); + + rect.OffsetTo(8.0f, fVisibleCheckBox->Bounds().Height()); + rect.right -= 18.0f; + fDisplayAsMenuField = new BMenuField(rect, "display as", + "Display As:", menu); + fDisplayAsMenuField->SetDivider(labelWidth); + fDisplayAsMenuField->SetAlignment(B_ALIGN_RIGHT); + fDisplayAsMenuField->ResizeTo(rect.Width(), height); + box->AddChild(fDisplayAsMenuField); + + fEditableCheckBox = new BCheckBox(rect, "editable", "Editable", + new BMessage(kMsgAttributeUpdated), B_FOLLOW_RIGHT); + fEditableCheckBox->SetValue(fAttribute.Editable()); + fEditableCheckBox->ResizeToPreferred(); + fEditableCheckBox->MoveTo(rect.right - fEditableCheckBox->Bounds().Width(), + rect.top + (fDisplayAsMenuField->Bounds().Height() + - fEditableCheckBox->Bounds().Height()) / 2.0f); + box->AddChild(fEditableCheckBox); + + 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); + fSpecialControl->SetModificationMessage(new BMessage(kMsgAttributeUpdated)); + fSpecialControl->SetDivider(labelWidth); + fSpecialControl->SetAlignment(B_ALIGN_RIGHT, B_ALIGN_LEFT); + fSpecialControl->SetEnabled(false); + box->AddChild(fSpecialControl); + + char text[64]; + snprintf(text, sizeof(text), "%ld", fAttribute.Width()); + rect.OffsetBy(0.0f, fSpecialControl->Bounds().Height() + 4.0f); + fWidthControl = new BTextControl(rect, "width", "Width:", + text, NULL, B_FOLLOW_LEFT_RIGHT); + fWidthControl->SetModificationMessage(new BMessage(kMsgAttributeUpdated)); + fWidthControl->SetDivider(labelWidth); + fWidthControl->SetAlignment(B_ALIGN_RIGHT, B_ALIGN_LEFT); + + // filter out invalid characters that can't be part of a width + textView = fWidthControl->TextView(); + for (int32 i = 0; i < 256; i++) { + if (!isdigit(i)) + textView->DisallowChar(i); + } + textView->SetMaxBytes(4); + + box->AddChild(fWidthControl); + + const struct alignment_map { + int32 alignment; + const char* name; + } kAlignmentMap[] = { + {B_ALIGN_LEFT, "Left"}, + {B_ALIGN_RIGHT, "Right"}, + {B_ALIGN_CENTER, "Center"}, + {0, NULL} + }; + + menu = new BPopUpMenu("alignment"); + for (int32 i = 0; kAlignmentMap[i].name != NULL; i++) { + BMessage* message = new BMessage(kMsgAlignmentChosen); + message->AddInt32("alignment", kAlignmentMap[i].alignment); + + item = new BMenuItem(kAlignmentMap[i].name, message); + menu->AddItem(item); + + if (kAlignmentMap[i].alignment == fAttribute.Alignment()) + item->SetMarked(true); + } + + rect.OffsetBy(0.0f, menuField->Bounds().Height() + 1.0f); + fAlignmentMenuField = new BMenuField(rect, "alignment", + "Alignment:", menu); + fAlignmentMenuField->SetDivider(labelWidth); + fAlignmentMenuField->SetAlignment(B_ALIGN_RIGHT); + fAlignmentMenuField->ResizeTo(rect.Width(), height); + box->AddChild(fAlignmentMenuField); + + fAcceptButton = new BButton(rect, "add", item ? "Done" : "Add", + new BMessage(kMsgAccept), B_FOLLOW_RIGHT | B_FOLLOW_BOTTOM); + fAcceptButton->ResizeToPreferred(); + fAcceptButton->MoveTo(Bounds().Width() - 8.0f - fAcceptButton->Bounds().Width(), + Bounds().Height() - 8.0f - fAcceptButton->Bounds().Height()); + fAcceptButton->SetEnabled(false); + topView->AddChild(fAcceptButton); + + BButton* button = new BButton(rect, "cancel", "Cancel", + new BMessage(B_QUIT_REQUESTED), B_FOLLOW_RIGHT | B_FOLLOW_BOTTOM); + button->ResizeToPreferred(); + button->MoveTo(fAcceptButton->Frame().left - 10.0f - button->Bounds().Width(), + fAcceptButton->Frame().top); + topView->AddChild(button); + + ResizeTo(labelWidth * 4.0f + 24.0f, box->Frame().bottom + + button->Bounds().Height() + 20.0f); + SetSizeLimits(fEditableCheckBox->Bounds().Width() + button->Bounds().Width() + + fAcceptButton->Bounds().Width() + labelWidth + 24.0f, + 32767.0f, Frame().Height(), Frame().Height()); + + fAcceptButton->MakeDefault(true); + fPublicNameControl->MakeFocus(true); + + target->PlaceSubWindow(this); + AddToSubset(target); +} + + +AttributeWindow::~AttributeWindow() +{ +} + + +void +AttributeWindow::_CheckAcceptable() +{ + bool enabled = fAttributeControl->Text() != NULL + && fAttributeControl->Text()[0] != '\0' + && fPublicNameControl->Text() != NULL + && fPublicNameControl->Text()[0] != '\0'; + + if (enabled) { + // check for equality + AttributeItem* item = _NewItemFromCurrent(); + enabled = fAttribute != *item; + delete item; + } + + // Update button + + if (fAcceptButton->IsEnabled() != enabled) + fAcceptButton->SetEnabled(enabled); +} + + +AttributeItem* +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; + } + + int32 alignment = B_ALIGN_LEFT; + item = fAlignmentMenuField->Menu()->FindMarked(); + if (item != NULL && item->Message() != NULL) { + int32 value; + if (item->Message()->FindInt32("alignment", &value) == B_OK) + alignment = value; + } + + int32 width = atoi(fWidthControl->Text()); + if (width < 0) + width = 0; + + char displayAs[512]; + displayAs[0] = '\0'; + //strlcpy(displayAs, fSpecialControl->Text(), sizeof(displayAs)); + + return new AttributeItem(newAttribute, + fPublicNameControl->Text(), type, displayAs, alignment, + width, fVisibleCheckBox->Value() == B_CONTROL_ON, + fEditableCheckBox->Value() == B_CONTROL_ON); +} + + +void +AttributeWindow::MessageReceived(BMessage* message) +{ + switch (message->what) { + case kMsgAttributeUpdated: + case kMsgAlignmentChosen: + case kMsgTypeChosen: + _CheckAcceptable(); + 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); + + _CheckAcceptable(); + break; + } + + case kMsgAccept: + { + BMessage attributes; + status_t status = fMimeType.GetAttrInfo(&attributes); + if (status == B_OK) { + // replace the entry, and remove any equivalent entries + BList list; + + const char* newAttribute = fAttributeControl->Text(); + list.AddItem(_NewItemFromCurrent()); + + const char* attribute; + for (int32 i = 0; attributes.FindString("attr:name", i, + &attribute) == B_OK; i++) { + if (!strcmp(fAttribute.Name(), attribute) + || !strcmp(newAttribute, attribute)) { + // remove this item + continue; + } + + AttributeItem* item = create_attribute_item(attributes, i); + if (item != NULL) + list.AddItem(item); + } + + list.SortItems(compare_attributes); + + // Copy them to a new message (their memory is still part of the + // original BMessage) + BMessage newAttributes; + for (int32 i = 0; i < list.CountItems(); i++) { + AttributeItem* item = (AttributeItem*)list.ItemAt(i); + + newAttributes.AddString("attr:name", item->Name()); + newAttributes.AddString("attr:public_name", item->PublicName()); + newAttributes.AddInt32("attr:type", (int32)item->Type()); + newAttributes.AddString("attr:display_as", item->DisplayAs()); + newAttributes.AddInt32("attr:alignment", item->Alignment()); + newAttributes.AddInt32("attr:width", item->Width()); + newAttributes.AddBool("attr:viewable", item->Visible()); + newAttributes.AddBool("attr:editable", item->Editable()); + + delete item; + } + + status = fMimeType.SetAttrInfo(&newAttributes); + } + + if (status != B_OK) + error_alert("Could not change attributes", status); + + PostMessage(B_QUIT_REQUESTED); + break; + } + } +} + + +bool +AttributeWindow::QuitRequested() +{ + return true; +} diff --git a/src/preferences/filetypes/AttributeWindow.h b/src/preferences/filetypes/AttributeWindow.h new file mode 100644 index 0000000000..025baee714 --- /dev/null +++ b/src/preferences/filetypes/AttributeWindow.h @@ -0,0 +1,52 @@ +/* + * Copyright 2006, Axel Dörfler, axeld@pinc-software.de. All rights reserved. + * Distributed under the terms of the MIT License. + */ +#ifndef ATTRIBUTE_WINDOW_H +#define ATTRIBUTE_WINDOW_H + + +#include "AttributeListView.h" + +#include +#include +#include +#include + +class BButton; +class BMenu; +class BTextControl; + +class FileTypesWindow; + + +class AttributeWindow : public BWindow { + public: + AttributeWindow(FileTypesWindow* target, BMimeType& type, + AttributeItem* item); + virtual ~AttributeWindow(); + + virtual void MessageReceived(BMessage* message); + virtual bool QuitRequested(); + + private: + void _CheckAcceptable(); + AttributeItem* _NewItemFromCurrent(); + + private: + BMessenger fTarget; + BMimeType fMimeType; + AttributeItem fAttribute; + BTextControl* fPublicNameControl; + BTextControl* fAttributeControl; + BMenu* fTypeMenu; + BMenuField* fDisplayAsMenuField; + BMenuField* fAlignmentMenuField; + BCheckBox* fVisibleCheckBox; + BCheckBox* fEditableCheckBox; + BTextControl* fSpecialControl; + BTextControl* fWidthControl; + BButton* fAcceptButton; +}; + +#endif // ATTRIBUTE_WINDOW_H diff --git a/src/preferences/filetypes/ExtensionWindow.cpp b/src/preferences/filetypes/ExtensionWindow.cpp index 39010900b5..a90e3386c8 100644 --- a/src/preferences/filetypes/ExtensionWindow.cpp +++ b/src/preferences/filetypes/ExtensionWindow.cpp @@ -41,7 +41,7 @@ compare_extensions(const void* _a, const void* _b) ExtensionWindow::ExtensionWindow(FileTypesWindow* target, BMimeType& type, - const char* extension) + const char* extension) : BWindow(BRect(100, 100, 350, 200), "Extension", B_MODAL_WINDOW_LOOK, B_MODAL_SUBSET_WINDOW_FEEL, B_NOT_ZOOMABLE | B_NOT_V_RESIZABLE | B_ASYNCHRONOUS_CONTROLS), @@ -177,10 +177,3 @@ ExtensionWindow::MessageReceived(BMessage* message) } } - -bool -ExtensionWindow::QuitRequested() -{ - fTarget.SendMessage(kMsgNewTypeWindowClosed); - return true; -} diff --git a/src/preferences/filetypes/ExtensionWindow.h b/src/preferences/filetypes/ExtensionWindow.h index 0f03c0b121..af3df0723a 100644 --- a/src/preferences/filetypes/ExtensionWindow.h +++ b/src/preferences/filetypes/ExtensionWindow.h @@ -19,11 +19,11 @@ class FileTypesWindow; class ExtensionWindow : public BWindow { public: - ExtensionWindow(FileTypesWindow* target, BMimeType& type, const char* extension); + ExtensionWindow(FileTypesWindow* target, BMimeType& type, + const char* extension); virtual ~ExtensionWindow(); virtual void MessageReceived(BMessage* message); - virtual bool QuitRequested(); private: BMessenger fTarget; diff --git a/src/preferences/filetypes/FileTypesWindow.cpp b/src/preferences/filetypes/FileTypesWindow.cpp index 4a1196dd35..d98aff3e54 100644 --- a/src/preferences/filetypes/FileTypesWindow.cpp +++ b/src/preferences/filetypes/FileTypesWindow.cpp @@ -4,6 +4,8 @@ */ +#include "AttributeListView.h" +#include "AttributeWindow.h" #include "ExtensionWindow.h" #include "FileTypes.h" #include "FileTypesWindow.h" @@ -56,22 +58,6 @@ const uint32 kMsgDescriptionEntered = 'dsce'; const uint32 kMsgToggleIcons = 'tgic'; -const struct type_map { - const char* name; - type_code type; -} kTypeMap[] = { - {"String", B_STRING_TYPE}, - {"Boolean", B_BOOL_TYPE}, - {"Integer 8 bit", B_INT8_TYPE}, - {"Integer 16 bit", B_INT16_TYPE}, - {"Integer 32 bit", B_INT32_TYPE}, - {"Integer 64 bit", B_INT64_TYPE}, - {"Float", B_FLOAT_TYPE}, - {"Double", B_DOUBLE_TYPE}, - {"Time", B_TIME_TYPE}, - {NULL, 0} -}; - class IconView : public BControl { public: IconView(BRect frame, const char* name, BMessage* message); @@ -93,38 +79,6 @@ class IconView : public BControl { icon_source fIconSource; }; -class AttributeListView : public BListView { - public: - AttributeListView(BRect frame, const char* name, uint32 resizingMode); - virtual ~AttributeListView(); - - void SetTo(BMimeType* type); - - virtual void Draw(BRect updateRect); - - private: - void _DeleteItems(); -}; - -class AttributeItem : public BStringItem { - public: - AttributeItem(const char* name, const char* publicName, type_code type, - int32 alignment, int32 width, bool visible, bool editable); - virtual ~AttributeItem(); - - virtual void DrawItem(BView* owner, BRect itemRect, - bool drawEverything = false); - - private: - BString fName; - BString fPublicName; - type_code fType; - int32 fAlignment; - int32 fWidth; - bool fVisible; - bool fEditable; -}; - // #pragma mark - @@ -153,34 +107,6 @@ is_application_in_message(BMessage& applications, const char* app) } -static void -name_for_type(BString& string, type_code type) -{ - for (int32 i = 0; kTypeMap[i].name != NULL; i++) { - if (kTypeMap[i].type == type) { - string = kTypeMap[i].name; - return; - } - } - - char buffer[32]; - buffer[0] = '\''; - buffer[1] = 0xff & (type >> 24); - buffer[2] = 0xff & (type >> 16); - buffer[3] = 0xff & (type >> 8); - buffer[4] = 0xff & (type); - buffer[5] = '\''; - buffer[6] = 0; - for (int16 i = 0;i < 4;i++) { - if (buffer[i] < ' ') - buffer[i] = '.'; - } - - snprintf(buffer + 6, sizeof(buffer), " (0x%lx)", type); - string = buffer; -} - - void error_alert(const char* message, status_t status, alert_type type) { @@ -312,152 +238,6 @@ IconView::GetPreferredSize(float* _width, float* _height) // #pragma mark - -AttributeItem::AttributeItem(const char* name, const char* publicName, - type_code type, int32 alignment, int32 width, bool visible, - bool editable) - : BStringItem(publicName), - fName(name), - fType(type), - fAlignment(alignment), - fWidth(width), - fVisible(visible), - fEditable(editable) -{ -} - - -AttributeItem::~AttributeItem() -{ -} - - -void -AttributeItem::DrawItem(BView* owner, BRect frame, bool drawEverything) -{ - BStringItem::DrawItem(owner, frame, drawEverything); - - rgb_color highColor = owner->HighColor(); - rgb_color lowColor = owner->LowColor(); - - if (IsSelected()) - owner->SetLowColor(tint_color(lowColor, B_DARKEN_2_TINT)); - - rgb_color black = {0, 0, 0, 255}; - - if (!IsEnabled()) - owner->SetHighColor(tint_color(black, B_LIGHTEN_2_TINT)); - else - owner->SetHighColor(black); - - owner->MovePenTo(frame.left + frame.Width() / 2.0f + 5.0f, owner->PenLocation().y); - - BString type; - name_for_type(type, fType); - owner->DrawString(type.String()); - - owner->SetHighColor(tint_color(owner->ViewColor(), B_DARKEN_1_TINT)); - - float middle = frame.left + frame.Width() / 2.0f; - owner->StrokeLine(BPoint(middle, 0.0f), BPoint(middle, frame.bottom)); - - owner->SetHighColor(highColor); - owner->SetLowColor(lowColor); -} - - -// #pragma mark - - - -AttributeListView::AttributeListView(BRect frame, const char* name, - uint32 resizingMode) - : BListView(frame, name, B_SINGLE_SELECTION_LIST, resizingMode, - B_WILL_DRAW | B_NAVIGABLE | B_FULL_UPDATE_ON_RESIZE) -{ -} - - -AttributeListView::~AttributeListView() -{ - _DeleteItems(); -} - - -void -AttributeListView::_DeleteItems() -{ - for (int32 i = CountItems(); i-- > 0;) { - delete ItemAt(i); - } - MakeEmpty(); -} - - -void -AttributeListView::SetTo(BMimeType* type) -{ - _DeleteItems(); - - // fill it again - - if (type == NULL) - return; - - BMessage attributes; - if (type->GetAttrInfo(&attributes) != B_OK) - return; - - const char* publicName; - int32 i = 0; - while (attributes.FindString("attr:public_name", i, &publicName) == B_OK) { - const char* name; - if (attributes.FindString("attr:name", i, &name) != B_OK) - name = "-"; - - type_code type; - if (attributes.FindInt32("attr:type", i, (int32 *)&type) != B_OK) - type = B_STRING_TYPE; - - bool editable; - if (attributes.FindBool("attr:editable", i, &editable) != B_OK) - editable = false; - bool visible; - if (attributes.FindBool("attr:viewable", i, &visible) != B_OK) - visible = false; - bool extra; - if (attributes.FindBool("attr:extra", i, &extra) != B_OK) - extra = false; - - int32 alignment; - if (attributes.FindInt32("attr:alignment", i, &alignment) != B_OK) - alignment = B_ALIGN_LEFT; - - int32 width; - if (attributes.FindInt32("attr:width", i, &width) != B_OK) - width = 50; - - AddItem(new AttributeItem(name, publicName, type, alignment, width, - visible, editable)); - - i++; - } -} - - -void -AttributeListView::Draw(BRect updateRect) -{ - BListView::Draw(updateRect); - - SetHighColor(tint_color(ViewColor(), B_DARKEN_1_TINT)); - - float middle = Bounds().Width() / 2.0f; - StrokeLine(BPoint(middle, 0.0f), BPoint(middle, Bounds().bottom)); -} - - -// #pragma mark - - - FileTypesWindow::FileTypesWindow(BRect frame) : BWindow(frame, "FileTypes", B_TITLED_WINDOW, B_NOT_ZOOMABLE | B_ASYNCHRONOUS_CONTROLS), @@ -1282,12 +1062,32 @@ FileTypesWindow::MessageReceived(BMessage* message) } case kMsgAttributeInvoked: - puts("attr"); + { + if (fCurrentType.Type() == NULL) + break; + + int32 index; + if (message->FindInt32("index", &index) == B_OK) { + AttributeItem* item = (AttributeItem*)fAttributeListView->ItemAt(index); + if (item == NULL) + break; + + BWindow* window = new AttributeWindow(this, fCurrentType, + item); + window->Show(); + } break; + } case kMsgAddAttribute: - puts("add attr"); + { + if (fCurrentType.Type() == NULL) + break; + + BWindow* window = new AttributeWindow(this, fCurrentType, NULL); + window->Show(); break; + } case kMsgRemoveAttribute: { diff --git a/src/preferences/filetypes/Jamfile b/src/preferences/filetypes/Jamfile index bbd62dedc4..b941956677 100644 --- a/src/preferences/filetypes/Jamfile +++ b/src/preferences/filetypes/Jamfile @@ -9,8 +9,10 @@ Preference FileTypes : FileTypes.cpp FileTypesWindow.cpp ApplicationTypesWindow.cpp + AttributeListView.cpp MimeTypeListView.cpp NewFileTypeWindow.cpp + AttributeWindow.cpp ExtensionWindow.cpp StringView.cpp : be tracker diff --git a/src/preferences/filetypes/StringView.cpp b/src/preferences/filetypes/StringView.cpp index dbd9478374..d41d6c9702 100644 --- a/src/preferences/filetypes/StringView.cpp +++ b/src/preferences/filetypes/StringView.cpp @@ -6,8 +6,6 @@ #include "StringView.h" -//#include - StringView::StringView(BRect frame, const char* name, const char* label, const char* text, uint32 resizeMask, uint32 flags) @@ -84,7 +82,13 @@ StringView::Draw(BRect updateRect) float y = ceilf(fontHeight.ascent) + 1.0f; float x; - SetHighColor(IsEnabled() ? ui_color(B_CONTROL_TEXT_COLOR) +#if defined(HAIKU_TARGET_PLATFORM_BEOS) || defined(HAIKU_TARGET_PLATFORM_BONE) + rgb_color textColor = {0, 0, 0, 255}; +#else + rgb_color textColor = ui_color(B_CONTROL_TEXT_COLOR); +#endif + + SetHighColor(IsEnabled() ? textColor : tint_color(ui_color(B_PANEL_BACKGROUND_COLOR), B_DISABLED_LABEL_TINT)); if (Label()) {