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:
@@ -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.
|
||||
*/
|
||||
|
||||
@@ -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));
|
||||
|
||||
@@ -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.
|
||||
*/
|
||||
#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
|
||||
|
||||
@@ -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.
|
||||
*/
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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();
|
||||
|
||||
|
||||
@@ -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."
|
||||
};
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user