HaikuDepot: Implemented filtering by search terms

This commit is contained in:
Stephan Aßmus 2013-08-10 21:30:37 +02:00
parent 3a6ccc8579
commit 09d44cec8d
5 changed files with 113 additions and 10 deletions

View File

@ -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;

View File

@ -1,5 +1,5 @@
/*
* Copyright 2009-2012, Stephan Aßmus <superstippi@gmx.de>
* Copyright 2009-2013, Stephan Aßmus <superstippi@gmx.de>
* All rights reserved. Distributed under the terms of the MIT License.
*/
#ifndef LIST_H

View File

@ -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;

View File

@ -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<BString, false> 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);
}

View File

@ -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;
};