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
This commit is contained in:
Axel Dörfler
2007-04-20 17:05:56 +00:00
parent ef502a7eb3
commit 89fe2e175e
5 changed files with 175 additions and 25 deletions
@@ -1,5 +1,5 @@
/* /*
* Copyright 2006, Axel Dörfler, [email protected]. All rights reserved. * Copyright 2006-2007, Axel Dörfler, [email protected]. All rights reserved.
* Distributed under the terms of the MIT License. * Distributed under the terms of the MIT License.
*/ */
@@ -22,13 +22,43 @@ const struct type_map kTypeMap[] = {
{NULL, 0} {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 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++) { for (int32 i = 0; kTypeMap[i].name != NULL; i++) {
if (kTypeMap[i].type == type) { if (kTypeMap[i].type == type) {
string = kTypeMap[i].name; string = kTypeMap[i].name;
add_display_as(string, displayAs);
return; 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); owner->MovePenTo(frame.left + frame.Width() / 2.0f + 5.0f, owner->PenLocation().y);
BString type; BString type;
name_for_type(type, fType); name_for_type(type, fType, fDisplayAs.String());
owner->DrawString(type.String()); owner->DrawString(type.String());
owner->SetHighColor(tint_color(owner->ViewColor(), B_DARKEN_1_TINT)); owner->SetHighColor(tint_color(owner->ViewColor(), B_DARKEN_1_TINT));
@@ -1,5 +1,5 @@
/* /*
* Copyright 2006, Axel Dörfler, [email protected]. All rights reserved. * Copyright 2006-2007, Axel Dörfler, [email protected]. All rights reserved.
* Distributed under the terms of the MIT License. * Distributed under the terms of the MIT License.
*/ */
#ifndef ATTRIBUTE_LIST_VIEW_H #ifndef ATTRIBUTE_LIST_VIEW_H
@@ -68,6 +68,14 @@ struct type_map {
extern const struct type_map kTypeMap[]; 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); AttributeItem *create_attribute_item(BMessage& attributes, int32 index);
#endif // ATTRIBUTE_LIST_VIEW_H #endif // ATTRIBUTE_LIST_VIEW_H
+128 -19
View File
@@ -1,5 +1,5 @@
/* /*
* Copyright 2006, Axel Dörfler, [email protected]. All rights reserved. * Copyright 2006-2007, Axel Dörfler, [email protected]. All rights reserved.
* Distributed under the terms of the MIT License. * Distributed under the terms of the MIT License.
*/ */
@@ -26,6 +26,7 @@
const uint32 kMsgAttributeUpdated = 'atup'; const uint32 kMsgAttributeUpdated = 'atup';
const uint32 kMsgTypeChosen = 'typc'; const uint32 kMsgTypeChosen = 'typc';
const uint32 kMsgDisplayAsChosen = 'dach';
const uint32 kMsgVisibilityChanged = 'vsch'; const uint32 kMsgVisibilityChanged = 'vsch';
const uint32 kMsgAlignmentChosen = 'alnc'; const uint32 kMsgAlignmentChosen = 'alnc';
const uint32 kMsgAccept = 'acpt'; 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 - // #pragma mark -
@@ -96,7 +131,7 @@ AttributeWindow::AttributeWindow(FileTypesWindow* target, BMimeType& mimeType,
topView->AddChild(fAttributeControl); topView->AddChild(fAttributeControl);
fTypeMenu = new BPopUpMenu("type"); fTypeMenu = new BPopUpMenu("type");
BMenuItem* item; BMenuItem* item = NULL;
for (int32 i = 0; kTypeMap[i].name != NULL; i++) { for (int32 i = 0; kTypeMap[i].name != NULL; i++) {
BMessage* message = new BMessage(kMsgTypeChosen); BMessage* message = new BMessage(kMsgTypeChosen);
message->AddInt32("type", kTypeMap[i].type); message->AddInt32("type", kTypeMap[i].type);
@@ -131,9 +166,21 @@ AttributeWindow::AttributeWindow(FileTypesWindow* target, BMimeType& mimeType,
labelWidth -= 8.0f; labelWidth -= 8.0f;
BMenu* menu = new BPopUpMenu("display as"); BMenu* menu = new BPopUpMenu("display as");
// TODO! for (int32 i = 0; kDisplayAsMap[i].name != NULL; i++) {
menu->AddItem(item = new BMenuItem("Default", NULL)); BMessage* message = new BMessage(kMsgDisplayAsChosen);
item->SetMarked(true); 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.OffsetTo(8.0f, fVisibleCheckBox->Bounds().Height());
rect.right -= 18.0f; rect.right -= 18.0f;
@@ -156,7 +203,8 @@ AttributeWindow::AttributeWindow(FileTypesWindow* target, BMimeType& mimeType,
rect.OffsetBy(0.0f, menuField->Bounds().Height() + 4.0f); rect.OffsetBy(0.0f, menuField->Bounds().Height() + 4.0f);
rect.bottom = rect.top + fPublicNameControl->Bounds().Height(); rect.bottom = rect.top + fPublicNameControl->Bounds().Height();
fSpecialControl = new BTextControl(rect, "special", "Special:", 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->SetModificationMessage(new BMessage(kMsgAttributeUpdated));
fSpecialControl->SetDivider(labelWidth); fSpecialControl->SetDivider(labelWidth);
fSpecialControl->SetAlignment(B_ALIGN_RIGHT, B_ALIGN_LEFT); 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 void
AttributeWindow::_CheckAcceptable() AttributeWindow::_CheckAcceptable()
{ {
@@ -275,16 +375,10 @@ AttributeWindow::_NewItemFromCurrent()
{ {
const char* newAttribute = fAttributeControl->Text(); const char* newAttribute = fAttributeControl->Text();
type_code type = B_STRING_TYPE; type_code type = _CurrentType();
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; int32 alignment = B_ALIGN_LEFT;
item = fAlignmentMenuField->Menu()->FindMarked(); BMenuItem* item = fAlignmentMenuField->Menu()->FindMarked();
if (item != NULL && item->Message() != NULL) { if (item != NULL && item->Message() != NULL) {
int32 value; int32 value;
if (item->Message()->FindInt32("alignment", &value) == B_OK) if (item->Message()->FindInt32("alignment", &value) == B_OK)
@@ -295,12 +389,22 @@ AttributeWindow::_NewItemFromCurrent()
if (width < 0) if (width < 0)
width = 0; width = 0;
char displayAs[512]; BString displayAs;
displayAs[0] = '\0'; item = fDisplayAsMenuField->Menu()->FindMarked();
//strlcpy(displayAs, fSpecialControl->Text(), sizeof(displayAs)); 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, return new AttributeItem(newAttribute,
fPublicNameControl->Text(), type, displayAs, alignment, fPublicNameControl->Text(), type, displayAs.String(), alignment,
width, fVisibleCheckBox->Value() == B_CONTROL_ON, width, fVisibleCheckBox->Value() == B_CONTROL_ON,
fEditableCheckBox->Value() == B_CONTROL_ON); fEditableCheckBox->Value() == B_CONTROL_ON);
} }
@@ -313,19 +417,24 @@ AttributeWindow::MessageReceived(BMessage* message)
case kMsgAttributeUpdated: case kMsgAttributeUpdated:
case kMsgAlignmentChosen: case kMsgAlignmentChosen:
case kMsgTypeChosen: case kMsgTypeChosen:
_CheckDisplayAs();
_CheckAcceptable(); _CheckAcceptable();
break; break;
case kMsgDisplayAsChosen:
fSpecialControl->SetEnabled(!_DefaultDisplayAs()->IsMarked());
break;
case kMsgVisibilityChanged: case kMsgVisibilityChanged:
{ {
bool enabled = fVisibleCheckBox->Value() != B_CONTROL_OFF; bool enabled = fVisibleCheckBox->Value() != B_CONTROL_OFF;
fDisplayAsMenuField->SetEnabled(enabled); fDisplayAsMenuField->SetEnabled(enabled);
//fSpecialControl->SetEnabled(enabled);
fWidthControl->SetEnabled(enabled); fWidthControl->SetEnabled(enabled);
fAlignmentMenuField->SetEnabled(enabled); fAlignmentMenuField->SetEnabled(enabled);
fEditableCheckBox->SetEnabled(enabled); fEditableCheckBox->SetEnabled(enabled);
_CheckDisplayAs();
_CheckAcceptable(); _CheckAcceptable();
break; break;
} }
+4 -1
View File
@@ -1,5 +1,5 @@
/* /*
* Copyright 2006, Axel Dörfler, [email protected]. All rights reserved. * Copyright 2006-2007, Axel Dörfler, [email protected]. All rights reserved.
* Distributed under the terms of the MIT License. * Distributed under the terms of the MIT License.
*/ */
#ifndef ATTRIBUTE_WINDOW_H #ifndef ATTRIBUTE_WINDOW_H
@@ -32,6 +32,9 @@ class AttributeWindow : public BWindow {
virtual bool QuitRequested(); virtual bool QuitRequested();
private: private:
type_code _CurrentType() const;
BMenuItem* _DefaultDisplayAs() const;
void _CheckDisplayAs();
void _CheckAcceptable(); void _CheckAcceptable();
AttributeItem* _NewItemFromCurrent(); AttributeItem* _NewItemFromCurrent();
+1 -1
View File
@@ -23,7 +23,7 @@ resource app_version {
internal = 1, internal = 1,
short_info = "FileTypes", short_info = "FileTypes",
long_info = "FileTypes ©2006 Haiku Inc." long_info = "FileTypes ©2006-2007 Haiku Inc."
}; };