From a051f66681931057536717d0f5b56773a2a4963e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Axel=20D=C3=B6rfler?= Date: Tue, 7 Mar 2006 02:26:31 +0000 Subject: [PATCH] * Changed the way file panels are created, there is now only a single message the FileType application understands. * The FileTypeWindow now has support for setting the type via "Same As...", also by dropping a file over the window. * The preferred application of a file can now also be specified via "Select...", and "Same As...". * Moved FileTypesWindow::_AdoptPreferredApplication() to PreferredAppMenu.cpp; FileTypeWindow is now using it as well. * Shuffled some functions around a bit. git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@16619 a95241bf-73f2-0310-859d-f6bbb57e9c96 --- src/preferences/filetypes/AttributeWindow.cpp | 1 + src/preferences/filetypes/ExtensionWindow.cpp | 1 + src/preferences/filetypes/FileTypeWindow.cpp | 88 +++++++++++- src/preferences/filetypes/FileTypeWindow.h | 2 + src/preferences/filetypes/FileTypes.cpp | 63 ++++---- src/preferences/filetypes/FileTypes.h | 8 +- src/preferences/filetypes/FileTypesWindow.cpp | 136 +++--------------- src/preferences/filetypes/FileTypesWindow.h | 7 - src/preferences/filetypes/IconView.cpp | 3 +- .../filetypes/NewFileTypeWindow.cpp | 1 + .../filetypes/PreferredAppMenu.cpp | 114 +++++++++++++++ src/preferences/filetypes/PreferredAppMenu.h | 4 + 12 files changed, 270 insertions(+), 158 deletions(-) diff --git a/src/preferences/filetypes/AttributeWindow.cpp b/src/preferences/filetypes/AttributeWindow.cpp index 0e74fed3a7..9538841324 100644 --- a/src/preferences/filetypes/AttributeWindow.cpp +++ b/src/preferences/filetypes/AttributeWindow.cpp @@ -5,6 +5,7 @@ #include "AttributeWindow.h" +#include "FileTypes.h" #include "FileTypesWindow.h" #include diff --git a/src/preferences/filetypes/ExtensionWindow.cpp b/src/preferences/filetypes/ExtensionWindow.cpp index 536ad0c7bb..0e2ba1d9aa 100644 --- a/src/preferences/filetypes/ExtensionWindow.cpp +++ b/src/preferences/filetypes/ExtensionWindow.cpp @@ -5,6 +5,7 @@ #include "ExtensionWindow.h" +#include "FileTypes.h" #include "FileTypesWindow.h" #include diff --git a/src/preferences/filetypes/FileTypeWindow.cpp b/src/preferences/filetypes/FileTypeWindow.cpp index 30ca74e186..8c6103a601 100644 --- a/src/preferences/filetypes/FileTypeWindow.cpp +++ b/src/preferences/filetypes/FileTypeWindow.cpp @@ -26,10 +26,13 @@ const uint32 kMsgTypeEntered = 'type'; const uint32 kMsgSelectType = 'sltp'; const uint32 kMsgSameTypeAs = 'stpa'; +const uint32 kMsgSameTypeAsOpened = 'stpO'; const uint32 kMsgPreferredAppChosen = 'papc'; const uint32 kMsgSelectPreferredApp = 'slpa'; const uint32 kMsgSamePreferredAppAs = 'spaa'; +const uint32 kMsgPreferredAppOpened = 'paOp'; +const uint32 kMsgSamePreferredAppAsOpened = 'spaO'; FileTypeWindow::FileTypeWindow(BPoint position, const BMessage& refs) @@ -78,7 +81,7 @@ FileTypeWindow::FileTypeWindow(BPoint position, const BMessage& refs) rect.OffsetBy(fSelectTypeButton->Bounds().Width() + 8.0f, 0.0f); fSameTypeAsButton = new BButton(rect, "same type as", "Same As" B_UTF8_ELLIPSIS, - new BMessage(kMsgSamePreferredAppAs), B_FOLLOW_LEFT | B_FOLLOW_TOP); + new BMessage(kMsgSameTypeAs), B_FOLLOW_LEFT | B_FOLLOW_TOP); fSameTypeAsButton->ResizeToPreferred(); box->AddChild(fSameTypeAsButton); @@ -263,6 +266,39 @@ FileTypeWindow::_SetTo(const BMessage& refs) } +void +FileTypeWindow::_AdoptType(BMessage* message) +{ + entry_ref ref; + if (message == NULL || message->FindRef("refs", &ref) != B_OK) + return; + + BNode node(&ref); + status_t status = node.InitCheck(); + + char type[B_MIME_TYPE_LENGTH]; + + if (status == B_OK) { + // get type from file + BNodeInfo nodeInfo(&node); + status = nodeInfo.InitCheck(); + if (status == B_OK) { + if (nodeInfo.GetType(type) != B_OK) + type[0] = '\0'; + } + } + + if (status != B_OK) { + error_alert("Could not open file", status); + return; + } + + fCommonType = type; + fTypeControl->SetText(type); + _AdoptType(); +} + + void FileTypeWindow::_AdoptType() { @@ -278,6 +314,17 @@ FileTypeWindow::_AdoptType() } +void +FileTypeWindow::_AdoptPreferredApp(BMessage* message, bool sameAs) +{ + if (retrieve_preferred_app(message, sameAs, fCommonType.String(), + fCommonPreferredApp) == B_OK) { + _AdoptPreferredApp(); + _UpdatePreferredApps(); + } +} + + void FileTypeWindow::_AdoptPreferredApp() { @@ -318,6 +365,21 @@ FileTypeWindow::MessageReceived(BMessage* message) _AdoptType(); break; + case kMsgSameTypeAs: + { + BMessage panel(kMsgOpenFilePanel); + panel.AddString("title", "Select Same Type As"); + panel.AddInt32("message", kMsgSameTypeAsOpened); + panel.AddMessenger("target", this); + + be_app_messenger.SendMessage(&panel); + break; + } + case B_SIMPLE_DATA: + case kMsgSameTypeAsOpened: + _AdoptType(message); + break; + // Preferred Application group case kMsgPreferredAppChosen: @@ -332,21 +394,33 @@ FileTypeWindow::MessageReceived(BMessage* message) break; } -#if 0 case kMsgSelectPreferredApp: - be_app->PostMessage(kMsgOpenSelectPanel); + { + BMessage panel(kMsgOpenFilePanel); + panel.AddString("title", "Select Preferred Application"); + panel.AddInt32("message", kMsgPreferredAppOpened); + panel.AddMessenger("target", this); + + be_app_messenger.SendMessage(&panel); break; + } case kMsgPreferredAppOpened: - _AdoptPreferredApplication(message, false); + _AdoptPreferredApp(message, false); break; case kMsgSamePreferredAppAs: - be_app->PostMessage(kMsgOpenSameAsPanel); + { + BMessage panel(kMsgOpenFilePanel); + panel.AddString("title", "Select Same Preferred Application As"); + panel.AddInt32("message", kMsgSamePreferredAppAsOpened); + panel.AddMessenger("target", this); + + be_app_messenger.SendMessage(&panel); break; + } case kMsgSamePreferredAppAsOpened: - _AdoptPreferredApplication(message, true); + _AdoptPreferredApp(message, true); break; -#endif case B_META_MIME_CHANGED: const char* type; diff --git a/src/preferences/filetypes/FileTypeWindow.h b/src/preferences/filetypes/FileTypeWindow.h index 186dece4e8..b41e3f6006 100644 --- a/src/preferences/filetypes/FileTypeWindow.h +++ b/src/preferences/filetypes/FileTypeWindow.h @@ -31,7 +31,9 @@ class FileTypeWindow : public BWindow { private: BString _Title(const BMessage& refs); void _SetTo(const BMessage& refs); + void _AdoptType(BMessage* message); void _AdoptType(); + void _AdoptPreferredApp(BMessage* message, bool sameAs); void _AdoptPreferredApp(); void _UpdatePreferredApps(); diff --git a/src/preferences/filetypes/FileTypes.cpp b/src/preferences/filetypes/FileTypes.cpp index 872ff3b2e3..f6fffefdc8 100644 --- a/src/preferences/filetypes/FileTypes.cpp +++ b/src/preferences/filetypes/FileTypes.cpp @@ -43,6 +43,7 @@ class FileTypes : public BApplication { void _WindowClosed(); BFilePanel *fFilePanel; + BMessenger fFilePanelTarget; BWindow *fTypesWindow; BWindow *fApplicationTypesWindow; uint32 fWindowCount; @@ -233,37 +234,34 @@ FileTypes::MessageReceived(BMessage *message) case kMsgOpenFilePanel: + { // the open file panel sends us a message when it's done - fFilePanel->Window()->SetTitle("FileTypes: Open File"); - fFilePanel->SetMessage(new BMessage(B_REFS_RECEIVED)); + const char* subTitle; + if (message->FindString("title", &subTitle) != B_OK) + subTitle = "Open File"; + + int32 what; + if (message->FindInt32("message", &what) != B_OK) + what = B_REFS_RECEIVED; + + BMessenger target; + if (message->FindMessenger("target", &target) != B_OK) + target = be_app_messenger; + + BString title = "FileTypes"; + if (subTitle != NULL && subTitle[0]) { + title.Append(": "); + title.Append(subTitle); + } + + fFilePanel->SetMessage(new BMessage(what)); + fFilePanel->Window()->SetTitle(title.String()); + fFilePanel->SetTarget(target); if (!fFilePanel->IsShowing()) fFilePanel->Show(); break; - - case kMsgOpenSelectPanel: - fFilePanel->Window()->SetTitle("FileTypes: Select Preferred Application"); - fFilePanel->SetMessage(new BMessage(kMsgPreferredAppOpened)); - - if (!fFilePanel->IsShowing()) - fFilePanel->Show(); - break; - case kMsgPreferredAppOpened: - if (fTypesWindow != NULL) - fTypesWindow->PostMessage(message); - break; - - case kMsgOpenSameAsPanel: - fFilePanel->Window()->SetTitle("FileTypes: Select Same Preferred Application As"); - fFilePanel->SetMessage(new BMessage(kMsgSamePreferredAppAsOpened)); - - if (!fFilePanel->IsShowing()) - fFilePanel->Show(); - break; - case kMsgSamePreferredAppAsOpened: - if (fTypesWindow != NULL) - fTypesWindow->PostMessage(message); - break; + } case B_CANCEL: if (fWindowCount == 0) @@ -311,6 +309,19 @@ FileTypes::QuitRequested() // #pragma mark - +void +error_alert(const char* message, status_t status, alert_type type) +{ + char warning[512]; + if (status != B_OK) + snprintf(warning, sizeof(warning), "%s:\n\t%s\n", message, strerror(status)); + + (new BAlert("FileTypes Request", + status == B_OK ? message : warning, + "Ok", NULL, NULL, B_WIDTH_AS_USUAL, type))->Go(); +} + + int main(int argc, char **argv) { diff --git a/src/preferences/filetypes/FileTypes.h b/src/preferences/filetypes/FileTypes.h index bfec2fbf9a..d0d3949db9 100644 --- a/src/preferences/filetypes/FileTypes.h +++ b/src/preferences/filetypes/FileTypes.h @@ -6,14 +6,12 @@ #define FILE_TYPES_H -#include +#include extern const char* kSignature; static const uint32 kMsgOpenFilePanel = 'opFp'; -static const uint32 kMsgOpenSelectPanel = 'opSp'; -static const uint32 kMsgOpenSameAsPanel = 'opAp'; static const uint32 kMsgOpenTypesWindow = 'opTw'; static const uint32 kMsgTypesWindowClosed = 'clTw'; @@ -24,4 +22,8 @@ static const uint32 kMsgApplicationTypesWindowClosed = 'clAw'; static const uint32 kMsgTypeWindowClosed = 'cltw'; static const uint32 kMsgWindowClosed = 'WiCl'; + +extern void error_alert(const char* message, status_t status = B_OK, + alert_type type = B_WARNING_ALERT); + #endif // FILE_TYPES_H diff --git a/src/preferences/filetypes/FileTypesWindow.cpp b/src/preferences/filetypes/FileTypesWindow.cpp index 0a9e2597f0..4e300b7b85 100644 --- a/src/preferences/filetypes/FileTypesWindow.cpp +++ b/src/preferences/filetypes/FileTypesWindow.cpp @@ -54,6 +54,9 @@ const uint32 kMsgPreferredAppChosen = 'papc'; const uint32 kMsgSelectPreferredApp = 'slpa'; const uint32 kMsgSamePreferredAppAs = 'spaa'; +const uint32 kMsgPreferredAppOpened = 'paOp'; +const uint32 kMsgSamePreferredAppAsOpened = 'spaO'; + const uint32 kMsgTypeEntered = 'type'; const uint32 kMsgDescriptionEntered = 'dsce'; @@ -84,36 +87,6 @@ class TypeIconView : public BControl { // #pragma mark - -static bool -is_application_in_message(BMessage& applications, const char* app) -{ - const char* signature; - int32 i = 0; - while (applications.FindString("applications", i++, &signature) == B_OK) { - if (!strcasecmp(signature, app)) - return true; - } - - return false; -} - - -void -error_alert(const char* message, status_t status, alert_type type) -{ - char warning[512]; - if (status != B_OK) - snprintf(warning, sizeof(warning), "%s:\n\t%s\n", message, strerror(status)); - - (new BAlert("FileTypes Request", - status == B_OK ? message : warning, - "Ok", NULL, NULL, B_WIDTH_AS_USUAL, type))->Go(); -} - - -// #pragma mark - - - TypeIconView::TypeIconView(BRect frame, const char* name, BMessage* message) : BControl(frame, name, NULL, message, B_FOLLOW_LEFT | B_FOLLOW_TOP, B_WILL_DRAW), @@ -541,90 +514,11 @@ FileTypesWindow::_AdoptPreferredApplication(BMessage* message, bool sameAs) if (fCurrentType.Type() == NULL) return; - entry_ref ref; - if (message->FindRef("refs", &ref) != B_OK) + BString preferred; + if (retrieve_preferred_app(message, sameAs, fCurrentType.Type(), preferred) != B_OK) return; - BFile file(&ref, B_READ_ONLY); - status_t status = file.InitCheck(); - - char preferred[B_MIME_TYPE_LENGTH]; - - if (status == B_OK) { - if (sameAs) { - // get preferred app from file - BNodeInfo nodeInfo(&file); - status = nodeInfo.InitCheck(); - if (status == B_OK) { - if (nodeInfo.GetPreferredApp(preferred) != B_OK) - preferred[0] = '\0'; - - if (!preferred[0]) { - // get MIME type from file - char type[B_MIME_TYPE_LENGTH]; - if (nodeInfo.GetType(type) == B_OK) { - BMimeType mimeType(type); - mimeType.GetPreferredApp(preferred); - } - } - } - } else { - // get application signature - BAppFileInfo appInfo(&file); - status = appInfo.InitCheck(); - - if (status == B_OK && appInfo.GetSignature(preferred) != B_OK) - preferred[0] = '\0'; - } - } - - if (status != B_OK) { - error_alert("File could not be opened", status, B_STOP_ALERT); - return; - } - - if (!preferred[0]) { - error_alert(sameAs ? "Could not retrieve preferred application of this file." - : "Could not retrieve application signature."); - return; - } - - // Check if the application chosen supports this type - - bool found = false; - - BMessage applications; - if (fCurrentType.GetSupportingApps(&applications) == B_OK - && is_application_in_message(applications, preferred)) - found = true; - - applications.MakeEmpty(); - - if (!found && fCurrentType.GetWildcardApps(&applications) == B_OK - && is_application_in_message(applications, preferred)) - found = true; - - if (!found) { - // warn user - BMimeType appType(preferred); - char description[B_MIME_TYPE_LENGTH]; - if (appType.GetShortDescription(description) != B_OK) - description[0] = '\0'; - - char warning[512]; - snprintf(warning, sizeof(warning), "The application \"%s\" does not " - "support this file type.\n" - "Are you sure you want to set it anyway?", - description[0] ? description : preferred); - - BAlert* alert = new BAlert("FileTypes Request", warning, - "Set Preferred Application", "Cancel", NULL, B_WIDTH_AS_USUAL, - B_WARNING_ALERT); - if (alert->Go() == 1) - return; - } - - status = fCurrentType.SetPreferredApp(preferred); + status_t status = fCurrentType.SetPreferredApp(preferred.String()); if (status != B_OK) error_alert("Could not set preferred application", status); } @@ -893,15 +787,29 @@ FileTypesWindow::MessageReceived(BMessage* message) } case kMsgSelectPreferredApp: - be_app->PostMessage(kMsgOpenSelectPanel); + { + BMessage panel(kMsgOpenFilePanel); + panel.AddString("title", "Select Preferred Application"); + panel.AddInt32("message", kMsgPreferredAppOpened); + panel.AddMessenger("target", this); + + be_app_messenger.SendMessage(&panel); break; + } case kMsgPreferredAppOpened: _AdoptPreferredApplication(message, false); break; case kMsgSamePreferredAppAs: - be_app->PostMessage(kMsgOpenSameAsPanel); + { + BMessage panel(kMsgOpenFilePanel); + panel.AddString("title", "Select Same Preferred Application As"); + panel.AddInt32("message", kMsgSamePreferredAppAsOpened); + panel.AddMessenger("target", this); + + be_app_messenger.SendMessage(&panel); break; + } case kMsgSamePreferredAppAsOpened: _AdoptPreferredApplication(message, true); break; diff --git a/src/preferences/filetypes/FileTypesWindow.h b/src/preferences/filetypes/FileTypesWindow.h index 1004ebc3f8..188cfa599a 100644 --- a/src/preferences/filetypes/FileTypesWindow.h +++ b/src/preferences/filetypes/FileTypesWindow.h @@ -67,14 +67,7 @@ class FileTypesWindow : public BWindow { BWindow* fNewTypeWindow; }; -static const uint32 kMsgPreferredAppOpened = 'paOp'; -static const uint32 kMsgSamePreferredAppAsOpened = 'spaO'; - static const uint32 kMsgSelectNewType = 'slnt'; static const uint32 kMsgNewTypeWindowClosed = 'ntwc'; - -extern void error_alert(const char* message, status_t status = B_OK, - alert_type type = B_WARNING_ALERT); - #endif // FILE_TYPES_WINDOW_H diff --git a/src/preferences/filetypes/IconView.cpp b/src/preferences/filetypes/IconView.cpp index 8163e95cde..3d0444b195 100644 --- a/src/preferences/filetypes/IconView.cpp +++ b/src/preferences/filetypes/IconView.cpp @@ -66,7 +66,8 @@ IconView::MouseDown(BPoint where) BPopUpMenu* menu = new BPopUpMenu("context"); menu->SetFont(be_plain_font); BMenuItem* item; - menu->AddItem(item = new BMenuItem("Edit Icon" B_UTF8_ELLIPSIS, NULL)); + menu->AddItem(item = new BMenuItem(fIcon != NULL + ? "Edit Icon" B_UTF8_ELLIPSIS : "Add Icon" B_UTF8_ELLIPSIS, NULL)); item->SetEnabled(false); menu->AddItem(item = new BMenuItem("Remove Icon", NULL)); item->SetEnabled(false); diff --git a/src/preferences/filetypes/NewFileTypeWindow.cpp b/src/preferences/filetypes/NewFileTypeWindow.cpp index a6216b1d49..884f565b0a 100644 --- a/src/preferences/filetypes/NewFileTypeWindow.cpp +++ b/src/preferences/filetypes/NewFileTypeWindow.cpp @@ -4,6 +4,7 @@ */ +#include "FileTypes.h" #include "FileTypesWindow.h" #include "NewFileTypeWindow.h" diff --git a/src/preferences/filetypes/PreferredAppMenu.cpp b/src/preferences/filetypes/PreferredAppMenu.cpp index f8273dc011..a25d8ecac6 100644 --- a/src/preferences/filetypes/PreferredAppMenu.cpp +++ b/src/preferences/filetypes/PreferredAppMenu.cpp @@ -4,11 +4,15 @@ */ +#include "FileTypes.h" #include "PreferredAppMenu.h" +#include +#include #include #include #include +#include #include #include @@ -24,6 +28,20 @@ compare_menu_items(const void* _a, const void* _b) } +static bool +is_application_in_message(BMessage& applications, const char* app) +{ + const char* signature; + int32 i = 0; + while (applications.FindString("applications", i++, &signature) == B_OK) { + if (!strcasecmp(signature, app)) + return true; + } + + return false; +} + + static void add_signature(BMenuItem* item, const char* signature) { @@ -54,6 +72,9 @@ create_application_item(const char* signature, uint32 what) } +// #pragma mark - Public functions + + void update_preferred_app_menu(BMenu* menu, BMimeType* type, uint32 what, const char* preferredFrom) @@ -175,3 +196,96 @@ update_preferred_app_menu(BMenu* menu, BMimeType* type, uint32 what, } } + +status_t +retrieve_preferred_app(BMessage* message, bool sameAs, const char* forType, + BString& preferredApp) +{ + entry_ref ref; + if (message == NULL || message->FindRef("refs", &ref) != B_OK) + return B_BAD_VALUE; + + BFile file(&ref, B_READ_ONLY); + status_t status = file.InitCheck(); + + char preferred[B_MIME_TYPE_LENGTH]; + + if (status == B_OK) { + if (sameAs) { + // get preferred app from file + BNodeInfo nodeInfo(&file); + status = nodeInfo.InitCheck(); + if (status == B_OK) { + if (nodeInfo.GetPreferredApp(preferred) != B_OK) + preferred[0] = '\0'; + + if (!preferred[0]) { + // get MIME type from file + char type[B_MIME_TYPE_LENGTH]; + if (nodeInfo.GetType(type) == B_OK) { + BMimeType mimeType(type); + mimeType.GetPreferredApp(preferred); + } + } + } + } else { + // get application signature + BAppFileInfo appInfo(&file); + status = appInfo.InitCheck(); + + if (status == B_OK && appInfo.GetSignature(preferred) != B_OK) + preferred[0] = '\0'; + } + } + + if (status != B_OK) { + error_alert("File could not be opened", status, B_STOP_ALERT); + return status; + } + + if (!preferred[0]) { + error_alert(sameAs ? "Could not retrieve preferred application of this file." + : "Could not retrieve application signature."); + return B_ERROR; + } + + // Check if the application chosen supports this type + + BMimeType mimeType(forType); + bool found = false; + + BMessage applications; + if (mimeType.GetSupportingApps(&applications) == B_OK + && is_application_in_message(applications, preferred)) + found = true; + + applications.MakeEmpty(); + + if (!found && mimeType.GetWildcardApps(&applications) == B_OK + && is_application_in_message(applications, preferred)) + found = true; + + if (!found) { + // warn user + BMimeType appType(preferred); + char description[B_MIME_TYPE_LENGTH]; + if (appType.GetShortDescription(description) != B_OK) + description[0] = '\0'; + + char warning[512]; + snprintf(warning, sizeof(warning), "The application \"%s\" does not " + "support this file type.\n" + "Are you sure you want to set it anyway?", + description[0] ? description : preferred); + + BAlert* alert = new BAlert("FileTypes Request", warning, + "Set Preferred Application", "Cancel", NULL, B_WIDTH_AS_USUAL, + B_WARNING_ALERT); + if (alert->Go() == 1) + return B_ERROR; + } + + preferredApp = preferred; + return B_OK; +} + diff --git a/src/preferences/filetypes/PreferredAppMenu.h b/src/preferences/filetypes/PreferredAppMenu.h index 6eeb33bfef..93b76157b0 100644 --- a/src/preferences/filetypes/PreferredAppMenu.h +++ b/src/preferences/filetypes/PreferredAppMenu.h @@ -9,9 +9,13 @@ #include class BMenu; +class BMessage; class BMimeType; +class BString; void update_preferred_app_menu(BMenu* menu, BMimeType* type, uint32 what, const char* preferredFrom = NULL); +status_t retrieve_preferred_app(BMessage* message, bool sameAs, const char* forType, + BString& preferredApp); #endif // PREFERRED_APP_MENU_H