diff --git a/src/apps/haiku-depot/FilterView.cpp b/src/apps/haiku-depot/FilterView.cpp index 5f0e9541af..8ce97637f3 100644 --- a/src/apps/haiku-depot/FilterView.cpp +++ b/src/apps/haiku-depot/FilterView.cpp @@ -112,8 +112,8 @@ FilterView::~FilterView() void FilterView::AttachedToWindow() { - fShowField->Menu()->SetTargetForItems(this); - fRepositoryField->Menu()->SetTargetForItems(this); + fShowField->Menu()->SetTargetForItems(Window()); + fRepositoryField->Menu()->SetTargetForItems(Window()); fSearchTermsText->SetTarget(this); } @@ -122,6 +122,14 @@ void FilterView::MessageReceived(BMessage* message) { switch (message->what) { + case MSG_SEARCH_TERMS_MODIFIED: + { + BMessage searchTerms(MSG_SEARCH_TERMS_MODIFIED); + searchTerms.AddString("search terms", fSearchTermsText->Text()); + Window()->PostMessage(&searchTerms); + break; + } + default: BGroupView::MessageReceived(message); break; diff --git a/src/apps/haiku-depot/List.h b/src/apps/haiku-depot/List.h index d60bfaf0e4..77752f7477 100644 --- a/src/apps/haiku-depot/List.h +++ b/src/apps/haiku-depot/List.h @@ -1,5 +1,5 @@ /* - * Copyright 2009-2012, Stephan Aßmus + * Copyright 2009-2013, Stephan Aßmus * All rights reserved. Distributed under the terms of the MIT License. */ #ifndef LIST_H diff --git a/src/apps/haiku-depot/MainWindow.cpp b/src/apps/haiku-depot/MainWindow.cpp index 22ab1281b5..5f6968e64c 100644 --- a/src/apps/haiku-depot/MainWindow.cpp +++ b/src/apps/haiku-depot/MainWindow.cpp @@ -111,6 +111,26 @@ MainWindow::MessageReceived(BMessage* message) break; } + case MSG_DEPOT_SELECTED: + { + BString name; + if (message->FindString("name", &name) != B_OK) + name = ""; + fModel.SetDepot(name); + _AdoptModel(); + break; + } + + case MSG_SEARCH_TERMS_MODIFIED: + { + // TODO: Do this with a delay! + BString searchTerms; + if (message->FindString("search terms", &searchTerms) != B_OK) + searchTerms = ""; + fModel.SetSearchTerms(searchTerms); + _AdoptModel(); + } + default: BWindow::MessageReceived(message); break; diff --git a/src/apps/haiku-depot/Model.cpp b/src/apps/haiku-depot/Model.cpp index d6bd927ba0..ef2f2b9ec6 100644 --- a/src/apps/haiku-depot/Model.cpp +++ b/src/apps/haiku-depot/Model.cpp @@ -126,12 +126,59 @@ private: }; +class SearchTermsFilter : public PackageFilter { +public: + SearchTermsFilter(const BString& searchTerms) + { + // Separate the string into terms at spaces + int32 index = 0; + while (index < searchTerms.Length()) { + int32 nextSpace = searchTerms.FindFirst(" ", index); + if (nextSpace < 0) + nextSpace = searchTerms.Length(); + if (nextSpace > index) { + BString term; + searchTerms.CopyInto(term, index, nextSpace - index); + term.ToLower(); + fSearchTerms.Add(term); + } + index = nextSpace + 1; + } + } + + virtual bool AcceptsPackage(const PackageInfo& package) const + { + // Every search term must be found in one of the package texts + for (int32 i = fSearchTerms.CountItems() - 1; i >= 0; i--) { + const BString& term = fSearchTerms.ItemAtFast(i); + if (!_TextContains(package.Title(), term) + && !_TextContains(package.Publisher().Name(), term) + && !_TextContains(package.ShortDescription(), term) + /*&& !_TextContains(package.FullDescription(), term)*/) { + return false; + } + } + return true; + } + +private: + bool _TextContains(BString text, const BString& string) const + { + text.ToLower(); + int32 index = text.FindFirst(string); + return index >= 0; + } + +private: + List fSearchTerms; +}; + + // #pragma mark - Model Model::Model() : - fSearchTerms(), fDepots(), fCategoryAudio(new PackageCategory( @@ -157,7 +204,7 @@ Model::Model() B_TRANSLATE("Games"), "games"), true), fCategoryFilter(PackageFilterRef(new AnyFilter(), true)), - fDepotFilter(PackageFilterRef(new AnyFilter(), true)), + fDepotFilter(""), fSearchTermsFilter(PackageFilterRef(new AnyFilter(), true)) { // Don't forget to add new categories to this list: @@ -208,12 +255,16 @@ Model::CreatePackageList() const PackageList resultList; for (int32 i = 0; i < fDepots.CountItems(); i++) { - const PackageList& packages = fDepots.ItemAtFast(i).Packages(); + const DepotInfo& depot = fDepots.ItemAtFast(i); + + if (fDepotFilter.Length() > 0 && fDepotFilter != depot.Name()) + continue; + + const PackageList& packages = depot.Packages(); for (int32 j = 0; j < packages.CountItems(); j++) { const PackageInfo& package = packages.ItemAtFast(j); if (fCategoryFilter->AcceptsPackage(package) - && fDepotFilter->AcceptsPackage(package) && fSearchTermsFilter->AcceptsPackage(package)) { resultList.Add(package); } @@ -263,6 +314,9 @@ Model::SetPackageState(const PackageInfo& package, PackageState state) } +// #pragma mark - filters + + void Model::SetCategory(const BString& category) { @@ -287,3 +341,24 @@ Model::SetCategory(const BString& category) fCategoryFilter.SetTo(filter, true); } + +void +Model::SetDepot(const BString& depot) +{ + fDepotFilter = depot; +} + + +void +Model::SetSearchTerms(const BString& searchTerms) +{ + PackageFilter* filter; + + if (searchTerms.Length() == 0) + filter = new AnyFilter(); + else + filter = new SearchTermsFilter(searchTerms); + + fSearchTermsFilter.SetTo(filter, true); +} + diff --git a/src/apps/haiku-depot/Model.h b/src/apps/haiku-depot/Model.h index ebb3621f36..87ff560d3e 100644 --- a/src/apps/haiku-depot/Model.h +++ b/src/apps/haiku-depot/Model.h @@ -60,10 +60,10 @@ public: // Configure PackageFilters void SetCategory(const BString& category); + void SetDepot(const BString& depot); + void SetSearchTerms(const BString& searchTerms); private: - BString fSearchTerms; - DepotList fDepots; CategoryRef fCategoryAudio; @@ -86,7 +86,7 @@ private: PackageList fUpdateablePackages; PackageFilterRef fCategoryFilter; - PackageFilterRef fDepotFilter; + BString fDepotFilter; PackageFilterRef fSearchTermsFilter; };