hrev53164 adds 1 changeset to branch 'master'
old head: f259502c907963f01803a757d60ed55258fe6e4c
new head: 89b16bb4d245c3a6e55e0d8f3502324e6f31bcb4
overview:
https://git.haiku-os.org/haiku/log/?qt=range&q=89b16bb4d245+%5Ef259502c9079
----------------------------------------------------------------------------
89b16bb4d245: HaikuDepot: Categories from Server
The list of categories for packages is currently
hard-coded into the HaikuDepot desktop
application. This change will change that so that
the list is obtained from the HaikuDepot Server
system and is always up to date with the server's
list of categories.
Change-Id: I757732f4d771e1599d6ad9c85cd65905640de928
Reviewed-on: https://review.haiku-os.org/c/1478
Reviewed-by: Adrien Destugues <pulkomandy@xxxxxxxxx>
[ Andrew Lindesay <apl@xxxxxxxxxxxxxx> ]
----------------------------------------------------------------------------
Revision: hrev53164
Commit: 89b16bb4d245c3a6e55e0d8f3502324e6f31bcb4
URL: https://git.haiku-os.org/haiku/commit/?id=89b16bb4d245
Author: Andrew Lindesay <apl@xxxxxxxxxxxxxx>
Date: Thu May 23 05:10:33 2019 UTC
----------------------------------------------------------------------------
14 files changed, 257 insertions(+), 159 deletions(-)
src/apps/haikudepot/Jamfile | 1 +
src/apps/haikudepot/model/LanguageModel.cpp | 16 ++-
src/apps/haikudepot/model/Model.cpp | 107 ++++++++++---------
src/apps/haikudepot/model/Model.h | 41 +------
src/apps/haikudepot/model/PackageInfo.cpp | 19 ++--
src/apps/haikudepot/model/PackageInfo.h | 12 +--
.../server/ServerPkgDataUpdateProcess.cpp | 8 +-
.../server/ServerReferenceDataUpdateProcess.cpp | 48 +++++++--
.../server/ServerReferenceDataUpdateProcess.h | 2 +
src/apps/haikudepot/ui/FilterView.cpp | 61 +++++++----
src/apps/haikudepot/ui/FilterView.h | 11 +-
src/apps/haikudepot/ui/MainWindow.cpp | 29 +++--
src/apps/haikudepot/util/LocaleUtils.cpp | 36 +++++++
src/apps/haikudepot/util/LocaleUtils.h | 25 +++++
----------------------------------------------------------------------------
diff --git a/src/apps/haikudepot/Jamfile b/src/apps/haikudepot/Jamfile
index 8e69fdfa76..70328c207d 100644
--- a/src/apps/haikudepot/Jamfile
+++ b/src/apps/haikudepot/Jamfile
@@ -173,6 +173,7 @@ local applicationSources =
AppUtils.cpp
DataIOUtils.cpp
LanguageMenuUtils.cpp
+ LocaleUtils.cpp
RepositoryUrlUtils.cpp
StorageUtils.cpp
ToFileUrlProtocolListener.cpp
diff --git a/src/apps/haikudepot/model/LanguageModel.cpp
b/src/apps/haikudepot/model/LanguageModel.cpp
index 8c602bdc49..c74cea639a 100644
--- a/src/apps/haikudepot/model/LanguageModel.cpp
+++ b/src/apps/haikudepot/model/LanguageModel.cpp
@@ -10,25 +10,23 @@
#include "HaikuDepotConstants.h"
#include "Logger.h"
+#include "LocaleUtils.h"
static int32
LanguagesCompareFn(const LanguageRef& l1, const LanguageRef& l2)
{
- const BLocale* locale = BLocaleRoster::Default()->GetDefaultLocale();
- BCollator collator;
-
- if (B_OK != locale->GetCollator(&collator)) {
- debugger("unable to get the locale's collator");
- }
-
+ BCollator* collator = LocaleUtils::GetSharedCollator();
BString name1;
BString name2;
+ int32 result = 0;
if (l1->GetName(name1) == B_OK && l2->GetName(name2) == B_OK)
- return collator.Compare(name1.String(), name2.String());
+ result = collator->Compare(name1.String(), name2.String());
+ if (0 == result)
+ result = strcmp(l1->Code(), l2->Code());
- return collator.Compare(l1->Code(), l2->Code());
+ return result;
}
diff --git a/src/apps/haikudepot/model/Model.cpp
b/src/apps/haikudepot/model/Model.cpp
index 7f583f6348..d9758ee0cf 100644
--- a/src/apps/haikudepot/model/Model.cpp
+++ b/src/apps/haikudepot/model/Model.cpp
@@ -14,15 +14,18 @@
#include <Autolock.h>
#include <Catalog.h>
+#include <Collator.h>
#include <Directory.h>
#include <Entry.h>
#include <File.h>
#include <KeyStore.h>
+#include <Locale.h>
#include <LocaleRoster.h>
#include <Message.h>
#include <Path.h>
#include "Logger.h"
+#include "LocaleUtils.h"
#include "StorageUtils.h"
#include "RepositoryUrlUtils.h"
@@ -103,7 +106,7 @@ public:
const CategoryRef& category = categories.ItemAtFast(i);
if (category.Get() == NULL)
continue;
- if (category->Name() == fCategory)
+ if (category->Code() == fCategory)
return true;
}
return false;
@@ -311,44 +314,22 @@ is_develop_package(const PackageInfoRef& package)
// #pragma mark - Model
+static int32
+PackageCategoryCompareFn(const CategoryRef& c1, const CategoryRef& c2)
+{
+ BCollator* collator = LocaleUtils::GetSharedCollator();
+ int32 result = collator->Compare(c1->Name().String(),
+ c2->Name().String());
+ if (result == 0)
+ result = c1->Code().Compare(c2->Code());
+ return result;
+}
+
+
Model::Model()
:
fDepots(),
-
- fCategoryAudio(new PackageCategory(
- BitmapRef(),
- B_TRANSLATE("Audio"), "audio"), true),
- fCategoryBusiness(new PackageCategory(
- BitmapRef(),
- B_TRANSLATE("Business"), "business"), true),
- fCategoryDevelopment(new PackageCategory(
- BitmapRef(),
- B_TRANSLATE("Development"), "development"), true),
- fCategoryEducation(new PackageCategory(
- BitmapRef(),
- B_TRANSLATE("Education"), "education"), true),
- fCategoryGames(new PackageCategory(
- BitmapRef(),
- B_TRANSLATE("Games"), "games"), true),
- fCategoryGraphics(new PackageCategory(
- BitmapRef(),
- B_TRANSLATE("Graphics"), "graphics"), true),
- fCategoryInternetAndNetwork(new PackageCategory(
- BitmapRef(),
- B_TRANSLATE("Internet & Network"), "internetandnetwork"), true),
- fCategoryProductivity(new PackageCategory(
- BitmapRef(),
- B_TRANSLATE("Productivity"), "productivity"), true),
- fCategoryScienceAndMathematics(new PackageCategory(
- BitmapRef(),
- B_TRANSLATE("Science & Mathematics"), "scienceandmathematics"),
true),
- fCategorySystemAndUtilities(new PackageCategory(
- BitmapRef(),
- B_TRANSLATE("System & Utilities"), "systemandutilities"), true),
- fCategoryVideo(new PackageCategory(
- BitmapRef(),
- B_TRANSLATE("Video"), "video"), true),
-
+ fCategories(&PackageCategoryCompareFn, NULL),
fCategoryFilter(PackageFilterRef(new AnyFilter(), true)),
fDepotFilter(""),
fSearchTermsFilter(PackageFilterRef(new AnyFilter(), true)),
@@ -360,23 +341,6 @@ Model::Model()
fShowDevelopPackages(false)
{
_UpdateIsFeaturedFilter();
-
- // Don't forget to add new categories to this list:
- fCategories.Add(fCategoryGames);
- fCategories.Add(fCategoryBusiness);
- fCategories.Add(fCategoryAudio);
- fCategories.Add(fCategoryVideo);
- fCategories.Add(fCategoryGraphics);
- fCategories.Add(fCategoryEducation);
- fCategories.Add(fCategoryProductivity);
- fCategories.Add(fCategorySystemAndUtilities);
- fCategories.Add(fCategoryInternetAndNetwork);
- fCategories.Add(fCategoryDevelopment);
- fCategories.Add(fCategoryScienceAndMathematics);
- // TODO: The server will eventually support an API to
- // get the defined categories and their translated names.
- // This should then be used instead of hard-coded
- // categories and translations in the app.
}
@@ -1057,6 +1021,18 @@ Model::_NotifyAuthorizationChanged()
}
+void
+Model::_NotifyCategoryListChanged()
+{
+ for (int32 i = fListeners.CountItems() - 1; i >= 0; i--) {
+ const ModelListenerRef& listener = fListeners.ItemAtFast(i);
+ if (listener.Get() != NULL)
+ listener->CategoryListChanged();
+ }
+}
+
+
+
/*! This method will find the stored 'DepotInfo' that correlates to the
supplied 'url' and will invoke the mapper function in order to get a
replacement for the 'DepotInfo'. The 'url' is a unique identifier
@@ -1117,3 +1093,28 @@ Model::_MaybeLogJsonRpcError(const BMessage
&responsePayload,
printf("[%s] --> an undefined error has occurred\n",
sourceDescription);
}
}
+
+
+void
+Model::AddCategories(const CategoryList& categories)
+{
+ int32 i;
+ for (i = 0; i < categories.CountItems(); i++)
+ _AddCategory(categories.ItemAt(i));
+ _NotifyCategoryListChanged();
+}
+
+
+void
+Model::_AddCategory(const CategoryRef& category)
+{
+ int32 i;
+ for (i = 0; i < fCategories.CountItems(); i++) {
+ if (fCategories.ItemAt(i)->Code() == category->Code()) {
+ fCategories.Replace(i, category);
+ return;
+ }
+ }
+
+ fCategories.Add(category);
+}
diff --git a/src/apps/haikudepot/model/Model.h
b/src/apps/haikudepot/model/Model.h
index 553f48614a..0e23af33bb 100644
--- a/src/apps/haikudepot/model/Model.h
+++ b/src/apps/haikudepot/model/Model.h
@@ -37,6 +37,7 @@ public:
virtual ~ModelListener();
virtual void AuthorizationChanged() = 0;
+ virtual void CategoryListChanged() = 0;
};
@@ -86,30 +87,7 @@ public:
void Clear();
- // Access to global categories
- const CategoryRef& CategoryAudio() const
- {
return fCategoryAudio; }
- const CategoryRef& CategoryBusiness() const
- {
return fCategoryBusiness; }
- const CategoryRef& CategoryDevelopment() const
- {
return fCategoryDevelopment; }
- const CategoryRef& CategoryEducation() const
- {
return fCategoryEducation; }
- const CategoryRef& CategoryInternetAndNetwork()
const
- {
return fCategoryInternetAndNetwork; }
- const CategoryRef& CategoryGames() const
- {
return fCategoryGames; }
- const CategoryRef& CategoryGraphics() const
- {
return fCategoryGraphics; }
- const CategoryRef& CategoryProductivity() const
- {
return fCategoryProductivity; }
- const CategoryRef& CategoryScienceAndMathematics()
const
- {
return fCategoryScienceAndMathematics; }
- const CategoryRef& CategorySystemAndUtilities()
const
- {
return fCategorySystemAndUtilities; }
- const CategoryRef& CategoryVideo() const
- {
return fCategoryVideo; }
-
+ void AddCategories(const
CategoryList& categories);
const CategoryList& Categories() const
{
return fCategories; }
@@ -176,6 +154,7 @@ public:
void
LogDepotsWithNoWebAppRepositoryCode() const;
private:
+ void _AddCategory(const
CategoryRef& category);
status_t _LocalDataPath(const
BString leaf,
BPath&
path) const;
@@ -207,25 +186,13 @@ private:
bool
ignoreAge, time_t maxAge) const;
void
_NotifyAuthorizationChanged();
+ void
_NotifyCategoryListChanged();
private:
BLocker fLock;
DepotList fDepots;
- CategoryRef fCategoryAudio;
- CategoryRef fCategoryBusiness;
- CategoryRef fCategoryDevelopment;
- CategoryRef fCategoryEducation;
- CategoryRef fCategoryGames;
- CategoryRef fCategoryGraphics;
- CategoryRef
fCategoryInternetAndNetwork;
- CategoryRef fCategoryProductivity;
- CategoryRef
fCategoryScienceAndMathematics;
- CategoryRef
fCategorySystemAndUtilities;
- CategoryRef fCategoryVideo;
- // TODO: Dynamic categories retrieved from web-app
-
CategoryList fCategories;
PackageList fInstalledPackages;
diff --git a/src/apps/haikudepot/model/PackageInfo.cpp
b/src/apps/haikudepot/model/PackageInfo.cpp
index e1cade50db..4006bbf27f 100644
--- a/src/apps/haikudepot/model/PackageInfo.cpp
+++ b/src/apps/haikudepot/model/PackageInfo.cpp
@@ -371,19 +371,16 @@ PublisherInfo::operator!=(const PublisherInfo& other)
const
PackageCategory::PackageCategory()
:
BReferenceable(),
- fIcon(),
- fLabel(),
+ fCode(),
fName()
{
}
-PackageCategory::PackageCategory(const BitmapRef& icon, const BString& label,
- const BString& name)
+PackageCategory::PackageCategory(const BString& code, const BString& name)
:
BReferenceable(),
- fIcon(icon),
- fLabel(label),
+ fCode(code),
fName(name)
{
}
@@ -392,8 +389,7 @@ PackageCategory::PackageCategory(const BitmapRef& icon,
const BString& label,
PackageCategory::PackageCategory(const PackageCategory& other)
:
BReferenceable(),
- fIcon(other.fIcon),
- fLabel(other.fLabel),
+ fCode(other.fCode),
fName(other.fName)
{
}
@@ -402,8 +398,7 @@ PackageCategory::PackageCategory(const PackageCategory&
other)
PackageCategory&
PackageCategory::operator=(const PackageCategory& other)
{
- fIcon = other.fIcon;
- fLabel = other.fLabel;
+ fCode = other.fCode;
fName = other.fName;
return *this;
}
@@ -412,9 +407,7 @@ PackageCategory::operator=(const PackageCategory& other)
bool
PackageCategory::operator==(const PackageCategory& other) const
{
- return fIcon == other.fIcon
- && fLabel == other.fLabel
- && fName == other.fName;
+ return fCode == other.fCode && fName == other.fName;
}
diff --git a/src/apps/haikudepot/model/PackageInfo.h
b/src/apps/haikudepot/model/PackageInfo.h
index c2c8ddb35b..09aabd5a19 100644
--- a/src/apps/haikudepot/model/PackageInfo.h
+++ b/src/apps/haikudepot/model/PackageInfo.h
@@ -192,8 +192,7 @@ private:
class PackageCategory : public BReferenceable {
public:
PackageCategory();
-
PackageCategory(const BitmapRef& icon,
- const
BString& label,
+
PackageCategory(const BString& code,
const
BString& name);
PackageCategory(const PackageCategory& other);
@@ -201,15 +200,12 @@ public:
bool operator==(const
PackageCategory& other) const;
bool operator!=(const
PackageCategory& other) const;
- const BitmapRef& Icon() const
- {
return fIcon; }
- const BString& Label() const
- {
return fLabel; }
+ const BString& Code() const
+ {
return fCode; }
const BString& Name() const
{
return fName; }
private:
- BitmapRef fIcon;
- BString fLabel;
+ BString fCode;
BString fName;
};
diff --git a/src/apps/haikudepot/server/ServerPkgDataUpdateProcess.cpp
b/src/apps/haikudepot/server/ServerPkgDataUpdateProcess.cpp
index 596a2a2a5c..10bdfe2f9b 100644
--- a/src/apps/haikudepot/server/ServerPkgDataUpdateProcess.cpp
+++ b/src/apps/haikudepot/server/ServerPkgDataUpdateProcess.cpp
@@ -86,8 +86,8 @@ PackageFillingPkgListener::~PackageFillingPkgListener()
// TODO; performance could be improved by not needing the linear search
inline int32
-PackageFillingPkgListener::IndexOfCategoryByName(
- const BString& name) const
+PackageFillingPkgListener::IndexOfCategoryByCode(
+ const BString& code) const
{
int32 i;
int32 categoryCount = fCategories.CountItems();
@@ -95,7 +95,7 @@ PackageFillingPkgListener::IndexOfCategoryByName(
for (i = 0; i < categoryCount; i++) {
const CategoryRef categoryRef = fCategories.ItemAtFast(i);
- if (categoryRef->Name() == name)
+ if (categoryRef->Code() == code)
return i;
}
@@ -140,7 +140,7 @@ PackageFillingPkgListener::ConsumePackage(const
PackageInfoRef& package,
for (i = 0; i < countPkgCategories; i++) {
BString* categoryCode = pkg->PkgCategoriesItemAt(i)->Code();
- int categoryIndex = IndexOfCategoryByName(*(categoryCode));
+ int categoryIndex = IndexOfCategoryByCode(*(categoryCode));
if (categoryIndex == -1) {
printf("unable to find the category for [%s]\n",
diff --git a/src/apps/haikudepot/server/ServerReferenceDataUpdateProcess.cpp
b/src/apps/haikudepot/server/ServerReferenceDataUpdateProcess.cpp
index 622fcfb2a5..97acc8928a 100644
--- a/src/apps/haikudepot/server/ServerReferenceDataUpdateProcess.cpp
+++ b/src/apps/haikudepot/server/ServerReferenceDataUpdateProcess.cpp
@@ -107,8 +107,12 @@ ServerReferenceDataUpdateProcess::ProcessLocalData()
status_t
ServerReferenceDataUpdateProcess::_ProcessData(DumpExportReference* data)
{
- // more to come here later...
- return _ProcessNaturalLanguages(data);
+ status_t result = B_OK;
+ if (result == B_OK)
+ result = _ProcessNaturalLanguages(data);
+ if (result == B_OK)
+ result = _ProcessPkgCategories(data);
+ return result;
}
@@ -124,10 +128,13 @@
ServerReferenceDataUpdateProcess::_ProcessNaturalLanguages(
for (int32 i = 0; i < data->CountNaturalLanguages(); i++) {
DumpExportReferenceNaturalLanguage* naturalLanguage =
data->NaturalLanguagesItemAt(i);
- result.Add(LanguageRef(new Language(
- *(naturalLanguage->Code()),
- *(naturalLanguage->Name()),
- naturalLanguage->IsPopular())));
+ result.Add(LanguageRef(
+ new Language(
+ *(naturalLanguage->Code()),
+ *(naturalLanguage->Name()),
+ naturalLanguage->IsPopular()
+ ),
+ true));
}
{
@@ -142,6 +149,35 @@ ServerReferenceDataUpdateProcess::_ProcessNaturalLanguages(
}
+status_t
+ServerReferenceDataUpdateProcess::_ProcessPkgCategories(
+ DumpExportReference* data)
+{
+ printf("[%s] will populate %" B_PRId32 " pkg categories\n",
+ Name(), data->CountPkgCategories());
+
+ CategoryList result;
+
+ for (int32 i = 0; i < data->CountPkgCategories(); i++) {
+ DumpExportReferencePkgCategory* pkgCategory =
+ data->PkgCategoriesItemAt(i);
+ result.Add(CategoryRef(
+ new PackageCategory(
+ *(pkgCategory->Code()),
+ *(pkgCategory->Name())
+ ),
+ true));
+ }
+
+ {
+ AutoLocker<BLocker> locker(fModel->Lock());
+ fModel->AddCategories(result);
+ }
+
+ return B_OK;
+}
+
+
status_t
ServerReferenceDataUpdateProcess::GetStandardMetaDataPath(BPath& path) const
{
diff --git a/src/apps/haikudepot/server/ServerReferenceDataUpdateProcess.h
b/src/apps/haikudepot/server/ServerReferenceDataUpdateProcess.h
index fe051b6efa..25ff2c1101 100644
--- a/src/apps/haikudepot/server/ServerReferenceDataUpdateProcess.h
+++ b/src/apps/haikudepot/server/ServerReferenceDataUpdateProcess.h
@@ -46,6 +46,8 @@ private:
status_t
_ProcessData(DumpExportReference* data);
status_t
_ProcessNaturalLanguages(
DumpExportReference* data);
+ status_t _ProcessPkgCategories(
+
DumpExportReference* data);
private:
Model* fModel;
diff --git a/src/apps/haikudepot/ui/FilterView.cpp
b/src/apps/haikudepot/ui/FilterView.cpp
index 807b030a84..cccf70185d 100644
--- a/src/apps/haikudepot/ui/FilterView.cpp
+++ b/src/apps/haikudepot/ui/FilterView.cpp
@@ -1,5 +1,6 @@
/*
* Copyright 2013, Stephan Aßmus <superstippi@xxxxxx>.
+ * Copyright 2019, Andrew Lindesay <apl@xxxxxxxxxxxxxx>.
* All rights reserved. Distributed under the terms of the MIT License.
*/
@@ -8,6 +9,7 @@
#include <algorithm>
#include <stdio.h>
+#include <AutoLocker.h>
#include <Catalog.h>
#include <CheckBox.h>
#include <LayoutBuilder.h>
@@ -31,8 +33,8 @@ add_categories_to_menu(const CategoryList& categories, BMenu*
menu)
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);
+ message->AddString("code", category->Code());
+ BMenuItem* item = new BMenuItem(category->Name(), message);
menu->AddItem(item);
}
}
@@ -88,7 +90,6 @@ FilterView::AttachedToWindow()
{
fShowField->Menu()->SetTargetForItems(Window());
fSearchTermsText->SetTarget(this);
-
fSearchTermsText->MakeFocus();
}
@@ -113,7 +114,7 @@ FilterView::MessageReceived(BMessage* message)
void
-FilterView::AdoptModel(const Model& model)
+FilterView::AdoptModel(Model& model)
{
// Adopt categories
BMenu* showMenu = fShowField->Menu();
@@ -122,25 +123,47 @@ FilterView::AdoptModel(const Model& model)
showMenu->AddItem(new BMenuItem(B_TRANSLATE("All categories"),
new BMessage(MSG_CATEGORY_SELECTED)));
- showMenu->AddItem(new BSeparatorItem());
+ AutoLocker<BLocker> locker(model.Lock());
+ CategoryList categories = model.Categories();
+
+ if (!categories.IsEmpty()) {
+ showMenu->AddItem(new BSeparatorItem());
+ add_categories_to_menu(categories, showMenu);
+ }
+
+ showMenu->SetEnabled(!categories.IsEmpty());
+
+ if (!_SelectCategoryCode(showMenu, model.Category()))
+ showMenu->ItemAt(0)->SetMarked(true);
+}
- add_categories_to_menu(model.Categories(), showMenu);
- bool foundSelectedCategory = false;
- for (int32 i = 0; i < showMenu->CountItems(); i++) {
- BMenuItem* item = showMenu->ItemAt(i);
- BMessage* message = item->Message();
- if (message == NULL)
- continue;
- BString category;
- if (message->FindString("name", &category) == B_OK
- && model.Category() == category) {
+/*! Tries to mark the menu item that corresponds to the supplied
+ category code. If the supplied code was found and the item marked
+ then the method will return true.
+*/
+
+/*static*/ bool
+FilterView::_SelectCategoryCode(BMenu* menu, const BString& code)
+{
+ for (int32 i = 0; i < menu->CountItems(); i++) {
+ BMenuItem* item = menu->ItemAt(i);
+ if (_MatchesCategoryCode(item, code)) {
item->SetMarked(true);
- foundSelectedCategory = true;
- break;
+ return true;
}
}
- if (!foundSelectedCategory)
- showMenu->ItemAt(0)->SetMarked(true);
+ return false;
}
+
+/*static*/ bool
+FilterView::_MatchesCategoryCode(BMenuItem* item, const BString& code)
+{
+ BMessage* message = item->Message();
+ if (message == NULL)
+ return false;
+ BString itemCode;
+ message->FindString("code", &itemCode);
+ return itemCode == code;
+}
\ No newline at end of file
diff --git a/src/apps/haikudepot/ui/FilterView.h
b/src/apps/haikudepot/ui/FilterView.h
index 6740766785..795c095a60 100644
--- a/src/apps/haikudepot/ui/FilterView.h
+++ b/src/apps/haikudepot/ui/FilterView.h
@@ -1,5 +1,6 @@
/*
* Copyright 2013, Stephan Aßmus <superstippi@xxxxxx>.
+ * Copyright 2019, Andrew Lindesay <apl@xxxxxxxxxxxxxx>.
* All rights reserved. Distributed under the terms of the MIT License.
*/
#ifndef FILTER_VIEW_H
@@ -9,7 +10,9 @@
class BCheckBox;
+class BMenu;
class BMenuField;
+class BMenuItem;
class BTextControl;
class Model;
@@ -29,7 +32,13 @@ public:
virtual void AttachedToWindow();
virtual void MessageReceived(BMessage*
message);
- void AdoptModel(const Model&
model);
+ void AdoptModel(Model&
model);
+
+private:
+ static bool _SelectCategoryCode(BMenu* menu,
+ const
BString& code);
+ static bool _MatchesCategoryCode(BMenuItem*
item,
+ const
BString& code);
private:
BMenuField* fShowField;
diff --git a/src/apps/haikudepot/ui/MainWindow.cpp
b/src/apps/haikudepot/ui/MainWindow.cpp
index fb26b69ba0..e0a32ec567 100644
--- a/src/apps/haikudepot/ui/MainWindow.cpp
+++ b/src/apps/haikudepot/ui/MainWindow.cpp
@@ -3,7 +3,7 @@
* Copyright 2013-2014, Stephan Aßmus <superstippi@xxxxxx>.
* Copyright 2013, Rene Gollent, rene@xxxxxxxxxxx.
* Copyright 2013, Ingo Weinhold, ingo_weinhold@xxxxxx.
- * Copyright 2016-2018, Andrew Lindesay <apl@xxxxxxxxxxxxxx>.
+ * Copyright 2016-2019, Andrew Lindesay <apl@xxxxxxxxxxxxxx>.
* Copyright 2017, Julian Harnath <julian.harnath@xxxxxxxxxxxxxx>.
* All rights reserved. Distributed under the terms of the MIT License.
*/
@@ -63,6 +63,7 @@ enum {
MSG_LOG_IN = 'lgin',
MSG_LOG_OUT = 'lgot',
MSG_AUTHORIZATION_CHANGED = 'athc',
+ MSG_CATEGORIES_LIST_CHANGED = 'clic',
MSG_PACKAGE_CHANGED = 'pchd',
MSG_WORK_STATUS_CHANGE = 'wsch',
MSG_WORK_STATUS_CLEAR = 'wscl',
@@ -95,9 +96,9 @@ struct RefreshWorkerParameters {
};
-class MessageModelListener : public ModelListener {
+class MainWindowModelListener : public ModelListener {
public:
- MessageModelListener(const BMessenger& messenger)
+ MainWindowModelListener(const BMessenger& messenger)
:
fMessenger(messenger)
{
@@ -109,6 +110,12 @@ public:
fMessenger.SendMessage(MSG_AUTHORIZATION_CHANGED);
}
+ virtual void CategoryListChanged()
+ {
+ if (fMessenger.IsValid())
+ fMessenger.SendMessage(MSG_CATEGORIES_LIST_CHANGED);
+ }
+
private:
BMessenger fMessenger;
};
@@ -123,7 +130,7 @@ MainWindow::MainWindow(const BMessage& settings)
fUserMenu(NULL),
fLogInItem(NULL),
fLogOutItem(NULL),
- fModelListener(new MessageModelListener(BMessenger(this)), true),
+ fModelListener(new MainWindowModelListener(BMessenger(this)), true),
fBulkLoadProcessCoordinator(NULL),
fSinglePackageMode(false)
{
@@ -221,7 +228,7 @@ MainWindow::MainWindow(const BMessage& settings, const
PackageInfoRef& package)
fUserMenu(NULL),
fLogInItem(NULL),
fLogOutItem(NULL),
- fModelListener(new MessageModelListener(BMessenger(this)), true),
+ fModelListener(new MainWindowModelListener(BMessenger(this)), true),
fBulkLoadProcessCoordinator(NULL),
fSinglePackageMode(true)
{
@@ -331,6 +338,10 @@ MainWindow::MessageReceived(BMessage* message)
_UpdateAuthorization();
break;
+ case MSG_CATEGORIES_LIST_CHANGED:
+ fFilterView->AdoptModel(fModel);
+ break;
+
case MSG_SHOW_FEATURED_PACKAGES:
// check to see if we aren't already on the current tab
if (fListTabs->Selection() ==
@@ -421,12 +432,12 @@ MainWindow::MessageReceived(BMessage* message)
case MSG_CATEGORY_SELECTED:
{
- BString name;
- if (message->FindString("name", &name) != B_OK)
- name = "";
+ BString code;
+ if (message->FindString("code", &code) != B_OK)
+ code = "";
{
BAutolock locker(fModel.Lock());
- fModel.SetCategory(name);
+ fModel.SetCategory(code);
}
_AdoptModel();
break;
diff --git a/src/apps/haikudepot/util/LocaleUtils.cpp
b/src/apps/haikudepot/util/LocaleUtils.cpp
new file mode 100644
index 0000000000..d354aa7929
--- /dev/null
+++ b/src/apps/haikudepot/util/LocaleUtils.cpp
@@ -0,0 +1,36 @@
+/*
+ * Copyright 2019, Andrew Lindesay <apl@xxxxxxxxxxxxxx>.
+ * All rights reserved. Distributed under the terms of the MIT License.
+ */
+#include "LocaleUtils.h"
+
+
+#include <Collator.h>
+#include <Locale.h>
+#include <LocaleRoster.h>
+
+
+BCollator* LocaleUtils::sSharedCollator = NULL;
+
+
+/*static*/ BCollator*
+LocaleUtils::GetSharedCollator()
+{
+ if (sSharedCollator == NULL) {
+ GetCollator(sSharedCollator);
+ }
+
+ return sSharedCollator;
+}
+
+
+/*static*/ void
+LocaleUtils::GetCollator(BCollator* collator)
+{
+ const BLocale* locale = BLocaleRoster::Default()->GetDefaultLocale();
+
+ if (B_OK != locale->GetCollator(collator)) {
+ debugger("unable to get the locale's collator");
+ exit(EXIT_FAILURE);
+ }
+}
\ No newline at end of file
diff --git a/src/apps/haikudepot/util/LocaleUtils.h
b/src/apps/haikudepot/util/LocaleUtils.h
new file mode 100644
index 0000000000..9887012239
--- /dev/null
+++ b/src/apps/haikudepot/util/LocaleUtils.h
@@ -0,0 +1,25 @@
+/*
+ * Copyright 2019, Andrew Lindesay <apl@xxxxxxxxxxxxxx>.
+ * All rights reserved. Distributed under the terms of the MIT License.
+ */
+#ifndef LOCALE_UTILS_H
+#define LOCALE_UTILS_H
+
+
+class BCollator;
+
+
+class LocaleUtils {
+
+public:
+ static BCollator* GetSharedCollator();
+
+private:
+ static void GetCollator(BCollator* collator);
+
+private:
+ static BCollator* sSharedCollator;
+};
+
+
+#endif // LOCALE_UTILS_H