From 4abd2b711028005315bbe67dafd1fce46bea8117 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Stephan=20A=C3=9Fmus?= Date: Sat, 10 Aug 2013 18:39:02 +0200 Subject: [PATCH] HaikuDepot: Beginnings of supporting filters... ... to reduce the package list. No filters can be defined via the UI, but a DepotFilter is already implemented, although its performance will probably need to improve. --- src/apps/haiku-depot/FilterView.cpp | 24 +++++++---- src/apps/haiku-depot/FilterView.h | 3 +- src/apps/haiku-depot/MainWindow.cpp | 2 +- src/apps/haiku-depot/Model.cpp | 66 ++++++++++++++++++++++++++++- src/apps/haiku-depot/Model.h | 18 ++++++++ 5 files changed, 101 insertions(+), 12 deletions(-) diff --git a/src/apps/haiku-depot/FilterView.cpp b/src/apps/haiku-depot/FilterView.cpp index 5a7f6c8732..41a35c67a9 100644 --- a/src/apps/haiku-depot/FilterView.cpp +++ b/src/apps/haiku-depot/FilterView.cpp @@ -16,6 +16,8 @@ #include #include +#include "Model.h" + #undef B_TRANSLATION_CONTEXT #define B_TRANSLATION_CONTEXT "FilterView" @@ -28,7 +30,7 @@ enum { }; -FilterView::FilterView() +FilterView::FilterView(const Model& model) : BGroupView("filter view") { @@ -36,21 +38,27 @@ FilterView::FilterView() BPopUpMenu* categoryMenu = new BPopUpMenu(B_TRANSLATE("Show")); categoryMenu->AddItem(new BMenuItem(B_TRANSLATE("All packages"), NULL)); categoryMenu->AddItem(new BSeparatorItem()); - categoryMenu->AddItem(new BMenuItem(B_TRANSLATE("Audio"), NULL)); - categoryMenu->AddItem(new BMenuItem(B_TRANSLATE("Games"), NULL)); - categoryMenu->AddItem(new BMenuItem(B_TRANSLATE("Graphics"), NULL)); - categoryMenu->AddItem(new BMenuItem(B_TRANSLATE("Development"), NULL)); - categoryMenu->AddItem(new BMenuItem(B_TRANSLATE("Miscellaneous"), NULL)); - categoryMenu->AddItem(new BMenuItem(B_TRANSLATE("Shell"), NULL)); - categoryMenu->AddItem(new BMenuItem(B_TRANSLATE("Video"), NULL)); + + const CategoryList& categories = model.Categories(); + for (int i = 0; i < categories.CountItems(); i++) { + const CategoryRef& category = categories.ItemAtFast(i); + BMessage* message = new BMessage(MSG_CATEGORY_SELECTED); + message->AddString("name", category->Name()); + BMenuItem* item = new BMenuItem(category->Label(), message); + categoryMenu->AddItem(item); + } + categoryMenu->AddItem(new BSeparatorItem()); + categoryMenu->AddItem(new BMenuItem(B_TRANSLATE("Installed packages"), NULL)); categoryMenu->AddItem(new BMenuItem(B_TRANSLATE("Uninstalled packages"), NULL)); categoryMenu->AddItem(new BMenuItem(B_TRANSLATE("User selected packages"), NULL)); + categoryMenu->AddItem(new BSeparatorItem()); + categoryMenu->AddItem(new BMenuItem(B_TRANSLATE("Downloading"), NULL)); categoryMenu->AddItem(new BMenuItem(B_TRANSLATE("Update available"), NULL)); categoryMenu->ItemAt(0)->SetMarked(true); diff --git a/src/apps/haiku-depot/FilterView.h b/src/apps/haiku-depot/FilterView.h index 8877e3cb22..abfdc9f6da 100644 --- a/src/apps/haiku-depot/FilterView.h +++ b/src/apps/haiku-depot/FilterView.h @@ -10,11 +10,12 @@ class BMenuField; class BTextControl; +class Model; class FilterView : public BGroupView { public: - FilterView(); + FilterView(const Model& model); virtual ~FilterView(); virtual void AttachedToWindow(); diff --git a/src/apps/haiku-depot/MainWindow.cpp b/src/apps/haiku-depot/MainWindow.cpp index 563694c8f8..f8990d0479 100644 --- a/src/apps/haiku-depot/MainWindow.cpp +++ b/src/apps/haiku-depot/MainWindow.cpp @@ -36,7 +36,7 @@ MainWindow::MainWindow(BRect frame) BMenuBar* menuBar = new BMenuBar(B_TRANSLATE("Main Menu")); _BuildMenu(menuBar); - fFilterView = new FilterView(); + fFilterView = new FilterView(fModel); fPackageListView = new PackageListView(); fPackageInfoView = new PackageInfoView(&fPackageManager); diff --git a/src/apps/haiku-depot/Model.cpp b/src/apps/haiku-depot/Model.cpp index 195e8dcb0d..2313c7da36 100644 --- a/src/apps/haiku-depot/Model.cpp +++ b/src/apps/haiku-depot/Model.cpp @@ -14,6 +14,55 @@ #define B_TRANSLATION_CONTEXT "Model" +// #pragma mark - PackageFilters + + +PackageFilter::~PackageFilter() +{ +} + + +class AnyFilter : public PackageFilter { +public: + virtual bool AcceptsPackage(const PackageInfo& package) const + { + return true; + } +}; + + +class DepotFilter : public PackageFilter { +public: + DepotFilter(const DepotInfo& depot) + : + fDepot(depot) + { + } + + virtual bool AcceptsPackage(const PackageInfo& package) const + { + // TODO: Maybe a PackageInfo ought to know the Depot it came from? + // But right now the same package could theoretically be provided + // from different depots and the filter would work correctly. + // Also the PackageList could actually contain references to packages + // instead of the packages as objects. The equal operator is quite + // expensive as is. + const PackageInfoList& packageList = fDepot.PackageList(); + for (int i = packageList.CountItems() - 1; i >= 0; i--) { + if (packageList.ItemAtFast(i) == package) + return true; + } + return false; + } + +private: + DepotInfo fDepot; +}; + + +// #pragma mark - Model + + Model::Model() : fSearchTerms(), @@ -36,7 +85,14 @@ Model::Model() B_TRANSLATE("Development"), "development"), true), fCategoryCommandLine(new PackageCategory( BitmapRef(), - B_TRANSLATE("Command line"), "command-line"), true) + B_TRANSLATE("Command line"), "command-line"), true), + fCategoryGames(new PackageCategory( + BitmapRef(), + B_TRANSLATE("Games"), "games"), true), + + fCategoryFilter(PackageFilterRef(new AnyFilter(), true)), + fDepotFilter(PackageFilterRef(new AnyFilter(), true)), + fSearchTermsFilter(PackageFilterRef(new AnyFilter(), true)) { // Don't forget to add new categories to this list: fCategories.Add(fCategoryAudio); @@ -45,6 +101,7 @@ Model::Model() fCategories.Add(fCategoryProductivity); fCategories.Add(fCategoryDevelopment); fCategories.Add(fCategoryCommandLine); + fCategories.Add(fCategoryGames); } @@ -61,7 +118,12 @@ Model::CreatePackageList() const = fDepots.ItemAtFast(i).PackageList(); for (int32 j = 0; j < packageList.CountItems(); j++) { - resultList.Add(packageList.ItemAtFast(j)); + const PackageInfo& package = packageList.ItemAtFast(j); + if (fCategoryFilter->AcceptsPackage(package) + && fDepotFilter->AcceptsPackage(package) + && fSearchTermsFilter->AcceptsPackage(package)) { + resultList.Add(package); + } } } diff --git a/src/apps/haiku-depot/Model.h b/src/apps/haiku-depot/Model.h index dc311799df..84cf35f63c 100644 --- a/src/apps/haiku-depot/Model.h +++ b/src/apps/haiku-depot/Model.h @@ -9,6 +9,17 @@ #include "PackageInfo.h" +class PackageFilter : public BReferenceable { +public: + virtual ~PackageFilter(); + + virtual bool AcceptsPackage( + const PackageInfo& package) const = 0; +}; + +typedef BReference PackageFilterRef; + + class Model { public: Model(); @@ -31,6 +42,8 @@ public: { return fCategoryDevelopment; } const CategoryRef& CategoryCommandLine() const { return fCategoryCommandLine; } + const CategoryRef& CategoryGames() const + { return fCategoryGames; } const CategoryList& Categories() const { return fCategories; } @@ -46,9 +59,14 @@ private: CategoryRef fCategoryProductivity; CategoryRef fCategoryDevelopment; CategoryRef fCategoryCommandLine; + CategoryRef fCategoryGames; // TODO: More categories CategoryList fCategories; + + PackageFilterRef fCategoryFilter; + PackageFilterRef fDepotFilter; + PackageFilterRef fSearchTermsFilter; };