diff --git a/src/apps/haikudepot/HaikuDepotConstants.h b/src/apps/haikudepot/HaikuDepotConstants.h index c0c535735a..5ccb3d85dc 100644 --- a/src/apps/haikudepot/HaikuDepotConstants.h +++ b/src/apps/haikudepot/HaikuDepotConstants.h @@ -9,7 +9,6 @@ enum { MSG_PACKAGE_ACTION_DONE = 'mpad', MSG_BULK_LOAD_DONE = 'mmwd', MSG_MAIN_WINDOW_CLOSED = 'mwcl', - MSG_PACKAGE_SELECTED = 'pkgs', MSG_PACKAGE_WORKER_BUSY = 'pkwb', MSG_PACKAGE_WORKER_IDLE = 'pkwi', MSG_CLIENT_TOO_OLD = 'oldc', diff --git a/src/apps/haikudepot/model/Model.cpp b/src/apps/haikudepot/model/Model.cpp index 3a520742c6..9cc54fa950 100644 --- a/src/apps/haikudepot/model/Model.cpp +++ b/src/apps/haikudepot/model/Model.cpp @@ -130,6 +130,48 @@ Model::~Model() } +/*! Returns the currently selected package. If there is no selected package then + this will return an empty reference. +*/ +PackageInfoRef +Model::SelectedPackage() const +{ + BAutolock locker(&fLock); + if (fSelectedPackageName.IsEmpty()) + return PackageInfoRef(); + return PackageForName(fSelectedPackageName); +} + + +/*! Sets the currently selected package. The package can be unset in which case + there will be no selected package. If the selected package changes then a + notification will be sent to the listeners. +*/ +void +Model::SetSelectedPackage(const PackageInfoRef& package) +{ + BAutolock locker(&fLock); + if (package.IsSet() && package->Name() != fSelectedPackageName) { + fSelectedPackageName = package->Name(); + _NotifySelectedPackageChanged(); + } else if (!fSelectedPackageName.IsEmpty()) { + fSelectedPackageName = ""; + _NotifySelectedPackageChanged(); + } +} + + +void +Model::ClearSelectedPackage() +{ + BAutolock locker(&fLock); + if (!fSelectedPackageName.IsEmpty()) { + fSelectedPackageName = ""; + _NotifySelectedPackageChanged(); + } +} + + const std::vector Model::Languages() const { @@ -584,6 +626,20 @@ Model::SetCredentials(const UserCredentials& credentials) // #pragma mark - listener notification methods +/*! Assumes that the class is locked. + */ +void +Model::_NotifySelectedPackageChanged() +{ + std::vector::const_iterator it; + for (it = fListeners.begin(); it != fListeners.end(); it++) { + const ModelListenerRef& listener = *it; + if (listener.IsSet()) + listener->SelectedPackageChanged(); + } +} + + /*! Assumes that the class is locked. */ void diff --git a/src/apps/haikudepot/model/Model.h b/src/apps/haikudepot/model/Model.h index d435eb4e95..b78e534158 100644 --- a/src/apps/haikudepot/model/Model.h +++ b/src/apps/haikudepot/model/Model.h @@ -39,6 +39,7 @@ class ModelListener : public BReferenceable { public: virtual ~ModelListener(); + virtual void SelectedPackageChanged() = 0; virtual void AuthorizationChanged() = 0; virtual void CategoryListChanged() = 0; virtual void ScreenshotCached(const ScreenshotCoordinate& coordinate) = 0; @@ -92,6 +93,10 @@ public: void Clear(); + PackageInfoRef SelectedPackage() const; + void SetSelectedPackage(const PackageInfoRef& package); + void ClearSelectedPackage(); + void AddListener(const ModelListenerRef& listener); void AddPackageListener(const PackageInfoListenerRef& packageListener); @@ -173,6 +178,7 @@ private: const BMessage &responsePayload, const char *sourceDescription) const; + void _NotifySelectedPackageChanged(); void _NotifyPackageFilterChanged(); void _NotifyIconsChanged(); void _NotifyAuthorizationChanged(); @@ -183,6 +189,8 @@ private: private: mutable BLocker fLock; + BString fSelectedPackageName; + LanguageRef fPreferredLanguage; std::map diff --git a/src/apps/haikudepot/ui/FeaturedPackagesView.cpp b/src/apps/haikudepot/ui/FeaturedPackagesView.cpp index 1d658cde16..f8aebf4135 100644 --- a/src/apps/haikudepot/ui/FeaturedPackagesView.cpp +++ b/src/apps/haikudepot/ui/FeaturedPackagesView.cpp @@ -290,19 +290,10 @@ public: } - /*! This method will send a message to the Window so that it can signal - back to this and other views that a package has been selected. This - method won't actually change the state of this view directly. - */ - void _MessageSelectIndex(int32 index) const { - if (index != -1) { - BMessage message(MSG_PACKAGE_SELECTED); - BString packageName = fPackages[index]->Name(); - message.AddString(shared_message_keys::kKeyPackageName, packageName); - Window()->PostMessage(&message); - } + if (index != -1) + fModel.SetSelectedPackage(fPackages[index]); } diff --git a/src/apps/haikudepot/ui/MainWindow.cpp b/src/apps/haikudepot/ui/MainWindow.cpp index 022b24719b..c9d36ced2c 100644 --- a/src/apps/haikudepot/ui/MainWindow.cpp +++ b/src/apps/haikudepot/ui/MainWindow.cpp @@ -82,6 +82,7 @@ enum { MSG_WORK_STATUS_CLEAR = 'wscl', MSG_INCREMENT_VIEW_COUNTER = 'icrv', MSG_SCREENSHOT_CACHED = 'ssca', + MSG_SELECTED_PACKAGE_CHANGED = 'spch', MSG_CHANGE_PACKAGE_LIST_VIEW_MODE = 'cplm', MSG_SHOW_DESKTOP_PACKAGES = 'sodk', @@ -175,6 +176,12 @@ public: fMessenger.SendMessage(MSG_ICONS_CHANGED); } + virtual void SelectedPackageChanged() + { + if (fMessenger.IsValid()) + fMessenger.SendMessage(MSG_SELECTED_PACKAGE_CHANGED); + } + private: BMessenger fMessenger; }; @@ -505,6 +512,10 @@ MainWindow::MessageReceived(BMessage* message) _UpdateAuthorization(); break; + case MSG_SELECTED_PACKAGE_CHANGED: + _HandleSelectedPackageChanged(); + break; + case MSG_ICONS_CHANGED: _HandleIconsChanged(); break; @@ -584,25 +595,6 @@ MainWindow::MessageReceived(BMessage* message) _HandleIncrementViewCounter(message); break; - case MSG_PACKAGE_SELECTED: - { - BString name; - if (message->FindString(shared_message_keys::kKeyPackageName, &name) == B_OK) { - PackageInfoRef package; - package = fModel.PackageForName(name); - - if (!package.IsSet() || name != package->Name()) { - debugger("unable to find the named package"); - } else { - _AdoptPackage(package); - _SetupDelayedIncrementViewCounter(package); - } - } else { - _ClearPackage(); - } - break; - } - case MSG_CATEGORY_SELECTED: { BString code; @@ -808,6 +800,23 @@ MainWindow::StoreSettings(BMessage& settings) } +/*! Informs the window that the selected package has changed. This gives the + window the opportunity to update the UI accordingly. +*/ +void +MainWindow::_HandleSelectedPackageChanged() +{ + PackageInfoRef package = fModel.SelectedPackage(); + + if (package.IsSet()) { + _AdoptPackage(package); + _SetupDelayedIncrementViewCounter(package); + } else { + _ClearPackage(); + } +} + + /*! This method is invoked in the situation that a package changes in the model. The events are processed into a `BMessage` which is then posted to the diff --git a/src/apps/haikudepot/ui/MainWindow.h b/src/apps/haikudepot/ui/MainWindow.h index f3430f8047..881a688c3d 100644 --- a/src/apps/haikudepot/ui/MainWindow.h +++ b/src/apps/haikudepot/ui/MainWindow.h @@ -131,6 +131,8 @@ private: void _HandleProcessCoordinatorChanged( ProcessCoordinatorState& coordinatorState); + void _HandleSelectedPackageChanged(); + void _HandlePackagesChanged(const BMessage* message); void _HandlePackagesChanged(const PackageChangeEvents& events); diff --git a/src/apps/haikudepot/ui/PackageListView.cpp b/src/apps/haikudepot/ui/PackageListView.cpp index fe14d5c51c..9c37ebd4de 100644 --- a/src/apps/haikudepot/ui/PackageListView.cpp +++ b/src/apps/haikudepot/ui/PackageListView.cpp @@ -1219,13 +1219,10 @@ PackageListView::SelectionChanged() if (fIgnoreSelectionChanged) return; - BMessage message(MSG_PACKAGE_SELECTED); - PackageRow* selected = dynamic_cast(CurrentSelection()); - if (selected != NULL) - message.AddString(shared_message_keys::kKeyPackageName, selected->Package()->Name()); - Window()->PostMessage(&message); + if (selected != NULL) + fModel->SetSelectedPackage(selected->Package()); }