From 42479955aef6ef698eb5b554449262f10d10ed8d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Stephan=20A=C3=9Fmus?= Date: Sat, 10 Aug 2013 19:08:44 +0200 Subject: [PATCH] HaikuDepot: Implemented filtering by category --- src/apps/haiku-depot/FilterView.cpp | 25 ++++++++++++------- src/apps/haiku-depot/FilterView.h | 7 ++++++ src/apps/haiku-depot/MainWindow.cpp | 13 +++++++++- src/apps/haiku-depot/Model.cpp | 36 ++++++++++++++++++++++++++++ src/apps/haiku-depot/Model.h | 7 +++++- src/apps/haiku-depot/PackageInfo.cpp | 12 +++++----- src/apps/haiku-depot/PackageInfo.h | 10 ++++---- 7 files changed, 88 insertions(+), 22 deletions(-) diff --git a/src/apps/haiku-depot/FilterView.cpp b/src/apps/haiku-depot/FilterView.cpp index 41a35c67a9..df090f9790 100644 --- a/src/apps/haiku-depot/FilterView.cpp +++ b/src/apps/haiku-depot/FilterView.cpp @@ -23,20 +23,14 @@ #define B_TRANSLATION_CONTEXT "FilterView" -enum { - MSG_CATEGORY_SELECTED = 'ctsl', - MSG_REPOSITORY_SELECTED = 'rpsl', - MSG_SEARCH_TERMS_MODIFIED = 'stmd', -}; - - FilterView::FilterView(const Model& model) : BGroupView("filter view") { // Contruct category popup BPopUpMenu* categoryMenu = new BPopUpMenu(B_TRANSLATE("Show")); - categoryMenu->AddItem(new BMenuItem(B_TRANSLATE("All packages"), NULL)); + categoryMenu->AddItem(new BMenuItem(B_TRANSLATE("All packages"), + new BMessage(MSG_CATEGORY_SELECTED))); categoryMenu->AddItem(new BSeparatorItem()); const CategoryList& categories = model.Categories(); @@ -68,8 +62,21 @@ FilterView::FilterView(const Model& model) // Construct repository popup BPopUpMenu* repositoryMenu = new BPopUpMenu(B_TRANSLATE("Depot")); - repositoryMenu->AddItem(new BMenuItem(B_TRANSLATE("All depots"), NULL)); + repositoryMenu->AddItem(new BMenuItem(B_TRANSLATE("All depots"), + new BMessage(MSG_DEPOT_SELECTED))); repositoryMenu->ItemAt(0)->SetMarked(true); + + repositoryMenu->AddItem(new BSeparatorItem()); + + const DepotList& depots = model.Depots(); + for (int i = 0; i < depots.CountItems(); i++) { + const DepotInfo& depot = depots.ItemAtFast(i); + BMessage* message = new BMessage(MSG_DEPOT_SELECTED); + message->AddString("name", depot.Name()); + BMenuItem* item = new BMenuItem(depot.Name(), message); + repositoryMenu->AddItem(item); + } + fRepositoryField = new BMenuField("repository", B_TRANSLATE("Depot:"), repositoryMenu); diff --git a/src/apps/haiku-depot/FilterView.h b/src/apps/haiku-depot/FilterView.h index abfdc9f6da..8231854d89 100644 --- a/src/apps/haiku-depot/FilterView.h +++ b/src/apps/haiku-depot/FilterView.h @@ -13,6 +13,13 @@ class BTextControl; class Model; +enum { + MSG_CATEGORY_SELECTED = 'ctsl', + MSG_DEPOT_SELECTED = 'dpsl', + MSG_SEARCH_TERMS_MODIFIED = 'stmd', +}; + + class FilterView : public BGroupView { public: FilterView(const Model& model); diff --git a/src/apps/haiku-depot/MainWindow.cpp b/src/apps/haiku-depot/MainWindow.cpp index f8990d0479..40cbfd43e7 100644 --- a/src/apps/haiku-depot/MainWindow.cpp +++ b/src/apps/haiku-depot/MainWindow.cpp @@ -33,6 +33,8 @@ MainWindow::MainWindow(BRect frame) B_DOCUMENT_WINDOW_LOOK, B_NORMAL_WINDOW_FEEL, B_ASYNCHRONOUS_CONTROLS | B_AUTO_UPDATE_SIZE_LIMITS) { + _InitDummyModel(); + BMenuBar* menuBar = new BMenuBar(B_TRANSLATE("Main Menu")); _BuildMenu(menuBar); @@ -59,7 +61,6 @@ MainWindow::MainWindow(BRect frame) fSplitView->SetCollapsible(0, false); fSplitView->SetCollapsible(1, false); - _InitDummyModel(); _AdoptModel(); } @@ -100,6 +101,16 @@ MainWindow::MessageReceived(BMessage* message) break; } + case MSG_CATEGORY_SELECTED: + { + BString name; + if (message->FindString("name", &name) != B_OK) + name = ""; + fModel.SetCategory(name); + _AdoptModel(); + break; + } + default: BWindow::MessageReceived(message); break; diff --git a/src/apps/haiku-depot/Model.cpp b/src/apps/haiku-depot/Model.cpp index 2313c7da36..a2f89359f2 100644 --- a/src/apps/haiku-depot/Model.cpp +++ b/src/apps/haiku-depot/Model.cpp @@ -60,6 +60,32 @@ private: }; +class CategoryFilter : public PackageFilter { +public: + CategoryFilter(const BString& category) + : + fCategory(category) + { + } + + virtual bool AcceptsPackage(const PackageInfo& package) const + { + const CategoryList& categories = package.Categories(); + for (int i = categories.CountItems() - 1; i >= 0; i--) { + const CategoryRef& category = categories.ItemAtFast(i); + if (category.Get() == NULL) + continue; + if (category->Name() == fCategory) + return true; + } + return false; + } + +private: + BString fCategory; +}; + + // #pragma mark - Model @@ -137,3 +163,13 @@ Model::AddDepot(const DepotInfo& depot) return fDepots.Add(depot); } + +void +Model::SetCategory(const BString& category) +{ + if (category.Length() == 0) + fCategoryFilter.SetTo(new AnyFilter(), true); + else + fCategoryFilter.SetTo(new CategoryFilter(category), true); +} + diff --git a/src/apps/haiku-depot/Model.h b/src/apps/haiku-depot/Model.h index 84cf35f63c..cdc0128e17 100644 --- a/src/apps/haiku-depot/Model.h +++ b/src/apps/haiku-depot/Model.h @@ -28,6 +28,8 @@ public: PackageInfoList CreatePackageList() const; bool AddDepot(const DepotInfo& depot); + const DepotList& Depots() const + { return fDepots; } // Access to global categories const CategoryRef& CategoryAudio() const @@ -48,10 +50,13 @@ public: const CategoryList& Categories() const { return fCategories; } + // Configure PackageFilters + void SetCategory(const BString& category); + private: BString fSearchTerms; - DepotInfoList fDepots; + DepotList fDepots; CategoryRef fCategoryAudio; CategoryRef fCategoryVideo; diff --git a/src/apps/haiku-depot/PackageInfo.cpp b/src/apps/haiku-depot/PackageInfo.cpp index e338a9d78c..7f1fdde597 100644 --- a/src/apps/haiku-depot/PackageInfo.cpp +++ b/src/apps/haiku-depot/PackageInfo.cpp @@ -584,15 +584,15 @@ PackageInfo::AddScreenshot(const BitmapRef& screenshot) DepotInfo::DepotInfo() : - fTitle(), + fName(), fPackages() { } -DepotInfo::DepotInfo(const BString& title) +DepotInfo::DepotInfo(const BString& name) : - fTitle(title), + fName(name), fPackages() { } @@ -600,7 +600,7 @@ DepotInfo::DepotInfo(const BString& title) DepotInfo::DepotInfo(const DepotInfo& other) : - fTitle(other.fTitle), + fName(other.fName), fPackages(other.fPackages) { } @@ -609,7 +609,7 @@ DepotInfo::DepotInfo(const DepotInfo& other) DepotInfo& DepotInfo::operator=(const DepotInfo& other) { - fTitle = other.fTitle; + fName = other.fName; fPackages = other.fPackages; return *this; } @@ -618,7 +618,7 @@ DepotInfo::operator=(const DepotInfo& other) bool DepotInfo::operator==(const DepotInfo& other) const { - return fTitle == other.fTitle + return fName == other.fName && fPackages == other.fPackages; } diff --git a/src/apps/haiku-depot/PackageInfo.h b/src/apps/haiku-depot/PackageInfo.h index 019fd1f078..db9f1b7abd 100644 --- a/src/apps/haiku-depot/PackageInfo.h +++ b/src/apps/haiku-depot/PackageInfo.h @@ -238,15 +238,15 @@ typedef List PackageInfoList; class DepotInfo { public: DepotInfo(); - DepotInfo(const BString& title); + DepotInfo(const BString& name); DepotInfo(const DepotInfo& other); DepotInfo& operator=(const DepotInfo& other); bool operator==(const DepotInfo& other) const; bool operator!=(const DepotInfo& other) const; - const BString& Title() const - { return fTitle; } + const BString& Name() const + { return fName; } const PackageInfoList& PackageList() const { return fPackages; } @@ -254,12 +254,12 @@ public: bool AddPackage(const PackageInfo& package); private: - BString fTitle; + BString fName; PackageInfoList fPackages; }; -typedef List DepotInfoList; +typedef List DepotList; #endif // PACKAGE_INFO_H