diff --git a/src/preferences/datatranslations/DataTranslations.cpp b/src/preferences/datatranslations/DataTranslations.cpp index 3e47daefe8..553ec22832 100644 --- a/src/preferences/datatranslations/DataTranslations.cpp +++ b/src/preferences/datatranslations/DataTranslations.cpp @@ -15,9 +15,15 @@ #include #include +#include +#include #include #include +#include +#include +#include + const char* kApplicationSignature = "application/x-vnd.haiku-translations"; @@ -64,112 +70,36 @@ DataTranslationsApplication::AboutRequested() void -DataTranslationsApplication::InstallDone() +DataTranslationsApplication::_InstallError(const char* name, status_t status) { - (new BAlert("", - "You have to quit and restart running applications\n" - "for the installed Translators to be available for them.", - "OK"))->Go(); + BString text; + text << "Could not install " << name << ":\n" << strerror(status); + (new BAlert("DataTranslations - Error", text.String(), "Stop"))->Go(); +} + + +/*! + Installs the given entry in the target directory either by moving + or copying the entry. +*/ +status_t +DataTranslationsApplication::_Install(BDirectory& target, BEntry& entry) +{ + // Find out wether we need to copy it + status_t status = entry.MoveTo(&target, NULL, true); + + if (status == B_OK) + return B_OK; + + // we need to copy the file + + // TODO! + return B_ERROR; } void -DataTranslationsApplication::RefsReceived(BMessage *message) -{ - uint32 type; - int32 count; - entry_ref ref; - BPath path; - BString newfile; - - char e_name[B_FILE_NAME_LENGTH]; - - message->GetInfo("refs", &type, &count); - if (type != B_REF_TYPE) - return; - - if (message->FindRef("refs", &ref) == B_OK) { - BEntry entry(&ref, true); - entry.GetName(e_name); - - if (entry.IsFile() && entry.GetPath(&path) == B_OK) { - BTranslatorRoster *roster = BTranslatorRoster::Default(); - if (roster->AddTranslators(path.Path()) == B_OK) { - BDirectory dirt("/boot/home/config/add-ons/Translators/"); - newfile.SetTo("/boot/home/config/add-ons/Translators/"); - newfile << e_name; // Newfile with full path. - - // Find out wether we need to copy it - string.SetTo(""); - string << "The item '" << e_name << "' is now copied into the right place.\nWhat do you want to do with the original?"; - BAlert *keep = new BAlert("keep", string.String() , "Remove", "Keep"); - keep->SetShortcut(1, B_ESCAPE); - if (keep->Go() == 0) - moveit = true; - - if (moveit) { - // Just a quick move - if (dirt.Contains(newfile.String())) { - string.SetTo(""); - string << "An item named '" << e_name <<"' already is in the \nTranslators folder"; - BAlert *myAlert = new BAlert("title", string.String() , "Overwrite", "Stop"); - myAlert->SetShortcut(1, B_ESCAPE); - - if (myAlert->Go() != 0) - return; - // File exists, we are still here. Kill it. - BEntry dele; - dirt.FindEntry(e_name, &dele); - dele.Remove(); - } - entry.MoveTo(&dirt); // Move it. - InstallDone(); // Installation done - return; - } - - if (dirt.Contains(newfile.String())) { - // File exists, What are we supposed to do now (Overwrite/_Stopp_?) - string.SetTo(""); - string << "An item named '" << e_name <<"' already is in the \nTranslators folder"; - BAlert *myAlert = new BAlert("title", string.String() , "Overwrite", "Stop"); - myAlert->SetShortcut(1, B_ESCAPE); - - if (myAlert->Go() != 0) - return; - } - - string.SetTo(path.Path()); // Fullpath+Filename - - BString command; -#ifdef __HAIKU__ - command = "cp "; -#else - command = "copyattr -d -r "; -#endif - command << string.String() << " " << newfile.String(); // Prepare Copy - - system(command.String()); // Execute copy command - - string.SetTo(""); - string << "Filename: " << e_name << "\nPath: " << path.Path() ; - - // The new Translator has been installed by now. - // And done we are - InstallDone(); - } else { - // Not a Translator - NoTranslatorError(e_name); - } - } else { - // Not even a file... - NoTranslatorError(e_name); - } - } -} - - -void -DataTranslationsApplication::NoTranslatorError(const char* name) +DataTranslationsApplication::_NoTranslatorError(const char* name) { BString text; text.SetTo("The item '"); @@ -178,6 +108,71 @@ DataTranslationsApplication::NoTranslatorError(const char* name) } +void +DataTranslationsApplication::RefsReceived(BMessage* message) +{ + BTranslatorRoster* roster = BTranslatorRoster::Default(); + + BPath path; + status_t status = find_directory(B_USER_ADDONS_DIRECTORY, &path, true); + if (status != B_OK) { + _InstallError("translator", status); + return; + } + + BDirectory target; + status = target.SetTo(path.Path()); + if (status == B_OK) { + if (!target.Contains("Translators")) + status = target.CreateDirectory("Translators", &target); + else + status = target.SetTo(&target, "Translators"); + } + if (status != B_OK) { + _InstallError("translator", status); + return; + } + + entry_ref ref; + int32 i = 0; + while (message->FindRef("refs", i++, &ref) == B_OK) { + if (!roster->IsTranslator(&ref)) + _NoTranslatorError(ref.name); + + BEntry entry(&ref, true); + status = entry.InitCheck(); + if (status != B_OK) { + _InstallError(ref.name, status); + continue; + } + + if (target.Contains(ref.name)) { + BString string; + string << "An item named '" << ref.name + << "' already exists in the Translators folder"; + + BAlert* alert = new BAlert("DataTranslations - Note", string.String(), + "Overwrite", "Stop"); + alert->SetShortcut(1, B_ESCAPE); + if (alert->Go() != 0) + continue; + + // the original file will be replaced + } + + // find out wether we need to copy it or not + + status = _Install(target, entry); + if (status == B_OK) { + (new BAlert("DataTranslations - Note", + "The new translator has been installed successfully", + "OK"))->Go(NULL); + } else + _InstallError(ref.name, status); + } +} + + // #pragma mark - diff --git a/src/preferences/datatranslations/DataTranslations.h b/src/preferences/datatranslations/DataTranslations.h index 2a0e7d58af..8c3f36da26 100644 --- a/src/preferences/datatranslations/DataTranslations.h +++ b/src/preferences/datatranslations/DataTranslations.h @@ -15,10 +15,6 @@ #include "DataTranslationsSettings.h" #include -#include -#include - -#include class DataTranslationsApplication : public BApplication { @@ -33,13 +29,11 @@ class DataTranslationsApplication : public BApplication { void SetWindowCorner(BPoint corner); private: - void InstallDone(); - void NoTranslatorError(const char* name); + void _InstallError(const char* name, status_t status); + status_t _Install(BDirectory& target, BEntry& entry); + void _NoTranslatorError(const char* name); DataTranslationsSettings* fSettings; - - bool overwrite, moveit; - BString string; }; #endif // DATA_TRANSLATIONS_H diff --git a/src/preferences/datatranslations/DataTranslationsMessages.h b/src/preferences/datatranslations/DataTranslationsMessages.h deleted file mode 100644 index 5f39d8571f..0000000000 --- a/src/preferences/datatranslations/DataTranslationsMessages.h +++ /dev/null @@ -1,21 +0,0 @@ -/* - * Copyright 2003-2006, Haiku, Inc. - * Distributed under the terms of the MIT license. - * - * Authors: - * Unknown? - * Michael Wilber - */ -#ifndef DATA_TRANSLATIONS_MESSAGES_H -#define DATA_TRANSLATIONS_MESSAGES_H - - -#include - - -#define BUTTON_MSG 'PRES' - -const uint32 SEL_CHANGE = 'SEch'; -const uint32 ERROR_DETECTED = 'ERor'; - -#endif // DATA_TRANSLATIONS_MESSAGES_H diff --git a/src/preferences/datatranslations/DataTranslationsSettings.cpp b/src/preferences/datatranslations/DataTranslationsSettings.cpp index d92173e4a5..4e900370c5 100644 --- a/src/preferences/datatranslations/DataTranslationsSettings.cpp +++ b/src/preferences/datatranslations/DataTranslationsSettings.cpp @@ -1,67 +1,63 @@ /* - * DataTranslationsSettings.cpp - * DataTranslations Oliver Siebenmarck + * Copyright 2002-2006, Haiku, Inc. + * Distributed under the terms of the MIT license. * + * Authors: + * Oliver Siebenmarck + * Axel Dörfler */ - + + +#include "DataTranslationsSettings.h" + #include -#include #include #include #include -#include +#include + #include -#include "DataTranslationsSettings.h" -#include "DataTranslationsMessages.h" - -const char DataTranslationsSettings::kDataTranslationsSettingsFile[] = "Translation Settings"; DataTranslationsSettings::DataTranslationsSettings() { BPath path; - - if (find_directory(B_USER_SETTINGS_DIRECTORY,&path) == B_OK) { - path.Append(kDataTranslationsSettingsFile); - BFile file(path.Path(), B_READ_ONLY); - if (file.InitCheck() == B_OK) { - // Now read in the data - file.Seek(-8,SEEK_END); // Skip over the first 497 bytes to just the window - // position. - if (file.Read(&fCorner, sizeof(BPoint)) != sizeof(BPoint)) { - fCorner.x=50; - fCorner.y=50; - }; - } - else { - fCorner.x=50; - fCorner.y=50; - } + if (find_directory(B_USER_SETTINGS_DIRECTORY, &path) != B_OK) + return; + + fCorner = BPoint(50, 50); + + path.Append("system/DataTranslations settings"); + BFile file(path.Path(), B_READ_ONLY); + BMessage settings; + + if (file.InitCheck() == B_OK + && settings.Unflatten(&file) == B_OK) { + BPoint corner; + if (settings.FindPoint("window corner", &corner) == B_OK) + fCorner = corner; } - else - be_app->PostMessage(ERROR_DETECTED); } + DataTranslationsSettings::~DataTranslationsSettings() { BPath path; - - if (find_directory(B_USER_SETTINGS_DIRECTORY,&path) < B_OK) + if (find_directory(B_USER_SETTINGS_DIRECTORY, &path) < B_OK) return; - path.Append(kDataTranslationsSettingsFile); + BMessage settings; + settings.AddPoint("window corner", fCorner); - BFile file(path.Path(), B_WRITE_ONLY | B_CREATE_FILE); - if (file.InitCheck() == B_OK) { - file.Seek(-8,SEEK_END); // Skip over the first 497 bytes to just the window - // position. - PRINT_OBJECT(fCorner); - file.Write(&fCorner, sizeof(BPoint)); - } + path.Append("system/DataTranslations settings"); + BFile file(path.Path(), B_WRITE_ONLY | B_CREATE_FILE | B_ERASE_FILE); + if (file.InitCheck() == B_OK) + settings.Flatten(&file); } + void DataTranslationsSettings::SetWindowCorner(BPoint corner) { - fCorner=corner; + fCorner = corner; } diff --git a/src/preferences/datatranslations/DataTranslationsSettings.h b/src/preferences/datatranslations/DataTranslationsSettings.h index 97ca4af177..4a486e9f0f 100644 --- a/src/preferences/datatranslations/DataTranslationsSettings.h +++ b/src/preferences/datatranslations/DataTranslationsSettings.h @@ -1,17 +1,27 @@ -#ifndef DATA_TRANSLATIONS_SETTINGS_H_ -#define DATA_TRANSLATIONS_SETTINGS_H_ +/* + * Copyright 2002-2006, Haiku, Inc. + * Distributed under the terms of the MIT license. + * + * Authors: + * Oliver Siebenmarck + */ +#ifndef DATA_TRANSLATIONS_SETTINGS_H +#define DATA_TRANSLATIONS_SETTINGS_H -class DataTranslationsSettings{ -public : - DataTranslationsSettings(); - ~DataTranslationsSettings(); - - BPoint WindowCorner() const { return fCorner; } - void SetWindowCorner(BPoint corner); - -private: - static const char kDataTranslationsSettingsFile[]; - BPoint fCorner; + +#include + + +class DataTranslationsSettings { + public: + DataTranslationsSettings(); + ~DataTranslationsSettings(); + + BPoint WindowCorner() const { return fCorner; } + void SetWindowCorner(BPoint corner); + + private: + BPoint fCorner; }; -#endif +#endif // DATA_TRANSLATIONS_SETTINGS_H diff --git a/src/preferences/datatranslations/DataTranslationsWindow.cpp b/src/preferences/datatranslations/DataTranslationsWindow.cpp index c897e7b34a..cdea1578bf 100644 --- a/src/preferences/datatranslations/DataTranslationsWindow.cpp +++ b/src/preferences/datatranslations/DataTranslationsWindow.cpp @@ -10,8 +10,6 @@ #include "DataTranslations.h" -#include "DataTranslationsMessages.h" -#include "DataTranslationsSettings.h" #include "DataTranslationsWindow.h" #include "IconView.h" #include "TranslatorListView.h" @@ -35,6 +33,10 @@ #define DTW_BOTTOM 300 +const uint32 kMsgTranslatorInfo = 'trin'; +const uint32 kMsgSelectedTranslator = 'trsl'; + + DataTranslationsWindow::DataTranslationsWindow() : BWindow(BRect(0, 0, DTW_RIGHT, DTW_BOTTOM), "DataTranslations", B_TITLED_WINDOW, B_NOT_ZOOMABLE | B_NOT_RESIZABLE) @@ -61,12 +63,18 @@ DataTranslationsWindow::DataTranslationsWindow() MoveTo(x, y); _SetupViews(); + + BTranslatorRoster *roster = BTranslatorRoster::Default(); + roster->StartWatching(this); + Show(); } DataTranslationsWindow::~DataTranslationsWindow() { + BTranslatorRoster *roster = BTranslatorRoster::Default(); + roster->StopWatching(this); } @@ -87,7 +95,7 @@ DataTranslationsWindow::_PopulateListView() int32 version; const char *name, *info; roster->GetTranslatorInfo(translators[i], &name, &info, &version); - fTranslatorListView->AddItem(new BStringItem(name)); + fTranslatorListView->AddItem(new TranslatorItem(translators[i], name)); } delete[] translators; @@ -96,33 +104,26 @@ DataTranslationsWindow::_PopulateListView() status_t -DataTranslationsWindow::_GetTranslatorInfo(int32 id, const char *&tranName, - const char *&tranInfo, int32 &tranVersion, BPath &tranPath) +DataTranslationsWindow::_GetTranslatorInfo(int32 id, const char*& name, + const char*& info, int32& version, BPath& path) { // Returns information about the translator with the given id if (id < 0) return B_BAD_VALUE; - int32 numTranslators = 0; - translator_id tid = 0, *translators = NULL; BTranslatorRoster *roster = BTranslatorRoster::Default(); - roster->GetAllTranslators(&translators, &numTranslators); - tid = ((id < numTranslators) ? translators[id] : 0); - delete[] translators; + if (roster->GetTranslatorInfo(id, &name, &info, &version) != B_OK) + return B_ERROR; - if (id >= numTranslators) - return B_BAD_VALUE; - - // Getting the first three Infos: Name, Info & Version - roster->GetTranslatorInfo(tid, &tranName, &tranInfo, &tranVersion); - // Get the translator's path - entry_ref tranRef; - roster->GetRefFor(tid, &tranRef); - BEntry tmpEntry(&tranRef); - tranPath.SetTo(&tmpEntry); - + entry_ref ref; + if (roster->GetRefFor(id, &ref) == B_OK) { + BEntry entry(&ref); + path.SetTo(&entry); + } else + path.Unset(); + return B_OK; } @@ -135,23 +136,16 @@ DataTranslationsWindow::_ShowConfigView(int32 id) if (id < 0) return B_BAD_VALUE; - int32 numTranslators = 0; - translator_id tid = 0, *translators = NULL; BTranslatorRoster *roster = BTranslatorRoster::Default(); - roster->GetAllTranslators(&translators, &numTranslators); - tid = ((id < numTranslators) ? translators[id] : 0); - delete[] translators; - if (id >= numTranslators) - return B_BAD_VALUE; - // fConfigView is NULL the first time this function // is called, prevent a segment fault if (fConfigView) fRightBox->RemoveChild(fConfigView); + BMessage emptyMsg; BRect rect(0, 0, 200, 233); - status_t ret = roster->MakeConfigurationView(tid, &emptyMsg, &fConfigView, &rect); + status_t ret = roster->MakeConfigurationView(id, &emptyMsg, &fConfigView, &rect); if (ret != B_OK) { fRightBox->RemoveChild(fConfigView); return ret; @@ -174,9 +168,7 @@ DataTranslationsWindow::_ShowConfigView(int32 id) fConfigView->SetViewColor(ui_color(B_PANEL_BACKGROUND_COLOR)); // force config views to all have the same color fRightBox->AddChild(fConfigView); - - UpdateIfNeeded(); - + return B_OK; } @@ -196,7 +188,7 @@ DataTranslationsWindow::_SetupViews() // Add the translators list view fTranslatorListView = new TranslatorListView(BRect(10, 10, 120, Bounds().Height() - 10), "TransList", B_SINGLE_SELECTION_LIST); - fTranslatorListView->SetSelectionMessage(new BMessage(SEL_CHANGE)); + fTranslatorListView->SetSelectionMessage(new BMessage(kMsgSelectedTranslator)); BScrollView *scrollView = new BScrollView("scroll_trans", fTranslatorListView, B_FOLLOW_LEFT | B_FOLLOW_TOP_BOTTOM, B_WILL_DRAW | B_FRAME_EVENTS, @@ -219,7 +211,7 @@ DataTranslationsWindow::_SetupViews() // Add the translator info button BRect infoRect(0, 0, 80, 20); BButton *button = new BButton(infoRect, "STD", "Info...", - new BMessage(BUTTON_MSG), B_FOLLOW_BOTTOM | B_FOLLOW_RIGHT, + new BMessage(kMsgTranslatorInfo), B_FOLLOW_BOTTOM | B_FOLLOW_RIGHT, B_WILL_DRAW | B_FRAME_EVENTS | B_NAVIGABLE); button->ResizeToPreferred(); button->MoveTo(fRightBox->Bounds().Width() - button->Bounds().Width() - 10.0f, @@ -262,13 +254,13 @@ DataTranslationsWindow::_ShowInfoAlert(int32 id) _GetTranslatorInfo(id, name, info, version, path); BString message; - message << "Name:\t" << name << "\nVersion:\t"; + message << "Name: " << name << "\nVersion: "; // Convert the version number into a readable format message << (int)B_TRANSLATION_MAJOR_VERSION(version) << '.' << (int)B_TRANSLATION_MINOR_VERSION(version) << '.' << (int)B_TRANSLATION_REVISION_VERSION(version); - message << "\nInfo:\t\t" << info << + message << "\nInfo: " << info << "\n\nPath:\n" << path.Path() << "\n"; BAlert *alert = new BAlert("info", message.String(), "OK"); @@ -294,7 +286,7 @@ void DataTranslationsWindow::MessageReceived(BMessage *message) { switch (message->what) { - case BUTTON_MSG: + case kMsgTranslatorInfo: { int32 selected = fTranslatorListView->CurrentSelection(0); if (selected < 0) { @@ -309,11 +301,13 @@ DataTranslationsWindow::MessageReceived(BMessage *message) break; } - _ShowInfoAlert(selected); + TranslatorItem* item = dynamic_cast(fTranslatorListView->ItemAt(selected)); + if (item != NULL) + _ShowInfoAlert(item->ID()); break; } - case SEL_CHANGE: + case kMsgSelectedTranslator: { // Update the icon and translator info panel // to match the new selection @@ -327,18 +321,57 @@ DataTranslationsWindow::MessageReceived(BMessage *message) break; } - _ShowConfigView(selected); + TranslatorItem* item = dynamic_cast(fTranslatorListView->ItemAt(selected)); + if (item == NULL) + break; + + _ShowConfigView(item->ID()); const char* name = NULL; const char* info = NULL; int32 version = 0; BPath path; - _GetTranslatorInfo(selected, name, info, version, path); + _GetTranslatorInfo(item->ID(), name, info, version, path); fTranslatorNameView->SetText(path.Leaf()); fIconView->SetIcon(path); break; } + case B_TRANSLATOR_ADDED: + { + int32 index = 0, id; + while (message->FindInt32("translator_id", index++, &id) == B_OK) { + const char* name; + const char* info; + int32 version; + BPath path; + if (_GetTranslatorInfo(id, name, info, version, path) == B_OK) + fTranslatorListView->AddItem(new TranslatorItem(id, name)); + } + + fTranslatorListView->SortItems(); + break; + } + + case B_TRANSLATOR_REMOVED: + { + int32 index = 0, id; + while (message->FindInt32("translator_id", index++, &id) == B_OK) { + for (int32 i = 0; i < fTranslatorListView->CountItems(); i++) { + TranslatorItem* item = dynamic_cast(fTranslatorListView->ItemAt(i)); + if (item == NULL) + continue; + + if (item->ID() == (translator_id)id) { + fTranslatorListView->RemoveItem(i); + delete item; + break; + } + } + } + break; + } + default: BWindow::MessageReceived(message); break; diff --git a/src/preferences/datatranslations/DataTranslationsWindow.h b/src/preferences/datatranslations/DataTranslationsWindow.h index 48aa8a6920..3df6532b09 100644 --- a/src/preferences/datatranslations/DataTranslationsWindow.h +++ b/src/preferences/datatranslations/DataTranslationsWindow.h @@ -11,7 +11,6 @@ #define DATA_TRANSLATIONS_WINDOW_H -//#include "DataTranslationsSettings.h" #include "IconView.h" #include diff --git a/src/preferences/datatranslations/TranslatorListView.cpp b/src/preferences/datatranslations/TranslatorListView.cpp index 5be3cae054..13706acfbe 100644 --- a/src/preferences/datatranslations/TranslatorListView.cpp +++ b/src/preferences/datatranslations/TranslatorListView.cpp @@ -14,6 +14,33 @@ #include +static int +compare_items(const void* a, const void* b) +{ + const BStringItem* stringA = *(const BStringItem**)a; + const BStringItem* stringB = *(const BStringItem**)b; + + return strcmp(stringA->Text(), stringB->Text()); +} + + +// #pragma mark - + + +TranslatorItem::TranslatorItem(translator_id id, const char* name) + : BStringItem(name), + fID(id) +{ +} + + +TranslatorItem::~TranslatorItem() +{ +} + + +// #pragma mark - + TranslatorListView::TranslatorListView(BRect rect, const char *name, list_view_type type) @@ -66,3 +93,10 @@ TranslatorListView::MouseMoved(BPoint point, uint32 transit, const BMessage *dra Invalidate(); } + +void +TranslatorListView::SortItems() +{ + BListView::SortItems(&compare_items); +} + diff --git a/src/preferences/datatranslations/TranslatorListView.h b/src/preferences/datatranslations/TranslatorListView.h index 50cf8db9c1..709381b811 100644 --- a/src/preferences/datatranslations/TranslatorListView.h +++ b/src/preferences/datatranslations/TranslatorListView.h @@ -12,8 +12,20 @@ #include +#include +class TranslatorItem : public BStringItem { + public: + TranslatorItem(translator_id id, const char* name); + virtual ~TranslatorItem(); + + translator_id ID() const { return fID; } + + private: + translator_id fID; +}; + class TranslatorListView : public BListView { public: TranslatorListView(BRect rect, const char *name, @@ -22,6 +34,8 @@ class TranslatorListView : public BListView { virtual void MessageReceived(BMessage *message); virtual void MouseMoved(BPoint point, uint32 transit, const BMessage *msg); + + void SortItems(); }; #endif // TRANSLATOR_LIST_VIEW_H