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 <[email protected]>
This commit is contained in:
@@ -173,6 +173,7 @@ local applicationSources =
|
|||||||
AppUtils.cpp
|
AppUtils.cpp
|
||||||
DataIOUtils.cpp
|
DataIOUtils.cpp
|
||||||
LanguageMenuUtils.cpp
|
LanguageMenuUtils.cpp
|
||||||
|
LocaleUtils.cpp
|
||||||
RepositoryUrlUtils.cpp
|
RepositoryUrlUtils.cpp
|
||||||
StorageUtils.cpp
|
StorageUtils.cpp
|
||||||
ToFileUrlProtocolListener.cpp
|
ToFileUrlProtocolListener.cpp
|
||||||
|
|||||||
@@ -10,25 +10,23 @@
|
|||||||
|
|
||||||
#include "HaikuDepotConstants.h"
|
#include "HaikuDepotConstants.h"
|
||||||
#include "Logger.h"
|
#include "Logger.h"
|
||||||
|
#include "LocaleUtils.h"
|
||||||
|
|
||||||
|
|
||||||
static int32
|
static int32
|
||||||
LanguagesCompareFn(const LanguageRef& l1, const LanguageRef& l2)
|
LanguagesCompareFn(const LanguageRef& l1, const LanguageRef& l2)
|
||||||
{
|
{
|
||||||
const BLocale* locale = BLocaleRoster::Default()->GetDefaultLocale();
|
BCollator* collator = LocaleUtils::GetSharedCollator();
|
||||||
BCollator collator;
|
|
||||||
|
|
||||||
if (B_OK != locale->GetCollator(&collator)) {
|
|
||||||
debugger("unable to get the locale's collator");
|
|
||||||
}
|
|
||||||
|
|
||||||
BString name1;
|
BString name1;
|
||||||
BString name2;
|
BString name2;
|
||||||
|
int32 result = 0;
|
||||||
|
|
||||||
if (l1->GetName(name1) == B_OK && l2->GetName(name2) == B_OK)
|
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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -14,15 +14,18 @@
|
|||||||
|
|
||||||
#include <Autolock.h>
|
#include <Autolock.h>
|
||||||
#include <Catalog.h>
|
#include <Catalog.h>
|
||||||
|
#include <Collator.h>
|
||||||
#include <Directory.h>
|
#include <Directory.h>
|
||||||
#include <Entry.h>
|
#include <Entry.h>
|
||||||
#include <File.h>
|
#include <File.h>
|
||||||
#include <KeyStore.h>
|
#include <KeyStore.h>
|
||||||
|
#include <Locale.h>
|
||||||
#include <LocaleRoster.h>
|
#include <LocaleRoster.h>
|
||||||
#include <Message.h>
|
#include <Message.h>
|
||||||
#include <Path.h>
|
#include <Path.h>
|
||||||
|
|
||||||
#include "Logger.h"
|
#include "Logger.h"
|
||||||
|
#include "LocaleUtils.h"
|
||||||
#include "StorageUtils.h"
|
#include "StorageUtils.h"
|
||||||
#include "RepositoryUrlUtils.h"
|
#include "RepositoryUrlUtils.h"
|
||||||
|
|
||||||
@@ -103,7 +106,7 @@ public:
|
|||||||
const CategoryRef& category = categories.ItemAtFast(i);
|
const CategoryRef& category = categories.ItemAtFast(i);
|
||||||
if (category.Get() == NULL)
|
if (category.Get() == NULL)
|
||||||
continue;
|
continue;
|
||||||
if (category->Name() == fCategory)
|
if (category->Code() == fCategory)
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
@@ -311,44 +314,22 @@ is_develop_package(const PackageInfoRef& package)
|
|||||||
// #pragma mark - Model
|
// #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()
|
Model::Model()
|
||||||
:
|
:
|
||||||
fDepots(),
|
fDepots(),
|
||||||
|
fCategories(&PackageCategoryCompareFn, NULL),
|
||||||
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),
|
|
||||||
|
|
||||||
fCategoryFilter(PackageFilterRef(new AnyFilter(), true)),
|
fCategoryFilter(PackageFilterRef(new AnyFilter(), true)),
|
||||||
fDepotFilter(""),
|
fDepotFilter(""),
|
||||||
fSearchTermsFilter(PackageFilterRef(new AnyFilter(), true)),
|
fSearchTermsFilter(PackageFilterRef(new AnyFilter(), true)),
|
||||||
@@ -360,23 +341,6 @@ Model::Model()
|
|||||||
fShowDevelopPackages(false)
|
fShowDevelopPackages(false)
|
||||||
{
|
{
|
||||||
_UpdateIsFeaturedFilter();
|
_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
|
/*! This method will find the stored 'DepotInfo' that correlates to the
|
||||||
supplied 'url' and will invoke the mapper function in order to get a
|
supplied 'url' and will invoke the mapper function in order to get a
|
||||||
replacement for the 'DepotInfo'. The 'url' is a unique identifier
|
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);
|
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);
|
||||||
|
}
|
||||||
|
|||||||
@@ -37,6 +37,7 @@ public:
|
|||||||
virtual ~ModelListener();
|
virtual ~ModelListener();
|
||||||
|
|
||||||
virtual void AuthorizationChanged() = 0;
|
virtual void AuthorizationChanged() = 0;
|
||||||
|
virtual void CategoryListChanged() = 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
@@ -86,30 +87,7 @@ public:
|
|||||||
|
|
||||||
void Clear();
|
void Clear();
|
||||||
|
|
||||||
// Access to global categories
|
void AddCategories(const CategoryList& 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; }
|
|
||||||
|
|
||||||
const CategoryList& Categories() const
|
const CategoryList& Categories() const
|
||||||
{ return fCategories; }
|
{ return fCategories; }
|
||||||
|
|
||||||
@@ -176,6 +154,7 @@ public:
|
|||||||
void LogDepotsWithNoWebAppRepositoryCode() const;
|
void LogDepotsWithNoWebAppRepositoryCode() const;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
void _AddCategory(const CategoryRef& category);
|
||||||
status_t _LocalDataPath(const BString leaf,
|
status_t _LocalDataPath(const BString leaf,
|
||||||
BPath& path) const;
|
BPath& path) const;
|
||||||
|
|
||||||
@@ -207,25 +186,13 @@ private:
|
|||||||
bool ignoreAge, time_t maxAge) const;
|
bool ignoreAge, time_t maxAge) const;
|
||||||
|
|
||||||
void _NotifyAuthorizationChanged();
|
void _NotifyAuthorizationChanged();
|
||||||
|
void _NotifyCategoryListChanged();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
BLocker fLock;
|
BLocker fLock;
|
||||||
|
|
||||||
DepotList fDepots;
|
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;
|
CategoryList fCategories;
|
||||||
|
|
||||||
PackageList fInstalledPackages;
|
PackageList fInstalledPackages;
|
||||||
|
|||||||
@@ -371,19 +371,16 @@ PublisherInfo::operator!=(const PublisherInfo& other) const
|
|||||||
PackageCategory::PackageCategory()
|
PackageCategory::PackageCategory()
|
||||||
:
|
:
|
||||||
BReferenceable(),
|
BReferenceable(),
|
||||||
fIcon(),
|
fCode(),
|
||||||
fLabel(),
|
|
||||||
fName()
|
fName()
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
PackageCategory::PackageCategory(const BitmapRef& icon, const BString& label,
|
PackageCategory::PackageCategory(const BString& code, const BString& name)
|
||||||
const BString& name)
|
|
||||||
:
|
:
|
||||||
BReferenceable(),
|
BReferenceable(),
|
||||||
fIcon(icon),
|
fCode(code),
|
||||||
fLabel(label),
|
|
||||||
fName(name)
|
fName(name)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
@@ -392,8 +389,7 @@ PackageCategory::PackageCategory(const BitmapRef& icon, const BString& label,
|
|||||||
PackageCategory::PackageCategory(const PackageCategory& other)
|
PackageCategory::PackageCategory(const PackageCategory& other)
|
||||||
:
|
:
|
||||||
BReferenceable(),
|
BReferenceable(),
|
||||||
fIcon(other.fIcon),
|
fCode(other.fCode),
|
||||||
fLabel(other.fLabel),
|
|
||||||
fName(other.fName)
|
fName(other.fName)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
@@ -402,8 +398,7 @@ PackageCategory::PackageCategory(const PackageCategory& other)
|
|||||||
PackageCategory&
|
PackageCategory&
|
||||||
PackageCategory::operator=(const PackageCategory& other)
|
PackageCategory::operator=(const PackageCategory& other)
|
||||||
{
|
{
|
||||||
fIcon = other.fIcon;
|
fCode = other.fCode;
|
||||||
fLabel = other.fLabel;
|
|
||||||
fName = other.fName;
|
fName = other.fName;
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
@@ -412,9 +407,7 @@ PackageCategory::operator=(const PackageCategory& other)
|
|||||||
bool
|
bool
|
||||||
PackageCategory::operator==(const PackageCategory& other) const
|
PackageCategory::operator==(const PackageCategory& other) const
|
||||||
{
|
{
|
||||||
return fIcon == other.fIcon
|
return fCode == other.fCode && fName == other.fName;
|
||||||
&& fLabel == other.fLabel
|
|
||||||
&& fName == other.fName;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -192,8 +192,7 @@ private:
|
|||||||
class PackageCategory : public BReferenceable {
|
class PackageCategory : public BReferenceable {
|
||||||
public:
|
public:
|
||||||
PackageCategory();
|
PackageCategory();
|
||||||
PackageCategory(const BitmapRef& icon,
|
PackageCategory(const BString& code,
|
||||||
const BString& label,
|
|
||||||
const BString& name);
|
const BString& name);
|
||||||
PackageCategory(const PackageCategory& other);
|
PackageCategory(const PackageCategory& other);
|
||||||
|
|
||||||
@@ -201,15 +200,12 @@ public:
|
|||||||
bool operator==(const PackageCategory& other) const;
|
bool operator==(const PackageCategory& other) const;
|
||||||
bool operator!=(const PackageCategory& other) const;
|
bool operator!=(const PackageCategory& other) const;
|
||||||
|
|
||||||
const BitmapRef& Icon() const
|
const BString& Code() const
|
||||||
{ return fIcon; }
|
{ return fCode; }
|
||||||
const BString& Label() const
|
|
||||||
{ return fLabel; }
|
|
||||||
const BString& Name() const
|
const BString& Name() const
|
||||||
{ return fName; }
|
{ return fName; }
|
||||||
private:
|
private:
|
||||||
BitmapRef fIcon;
|
BString fCode;
|
||||||
BString fLabel;
|
|
||||||
BString fName;
|
BString fName;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -86,8 +86,8 @@ PackageFillingPkgListener::~PackageFillingPkgListener()
|
|||||||
// TODO; performance could be improved by not needing the linear search
|
// TODO; performance could be improved by not needing the linear search
|
||||||
|
|
||||||
inline int32
|
inline int32
|
||||||
PackageFillingPkgListener::IndexOfCategoryByName(
|
PackageFillingPkgListener::IndexOfCategoryByCode(
|
||||||
const BString& name) const
|
const BString& code) const
|
||||||
{
|
{
|
||||||
int32 i;
|
int32 i;
|
||||||
int32 categoryCount = fCategories.CountItems();
|
int32 categoryCount = fCategories.CountItems();
|
||||||
@@ -95,7 +95,7 @@ PackageFillingPkgListener::IndexOfCategoryByName(
|
|||||||
for (i = 0; i < categoryCount; i++) {
|
for (i = 0; i < categoryCount; i++) {
|
||||||
const CategoryRef categoryRef = fCategories.ItemAtFast(i);
|
const CategoryRef categoryRef = fCategories.ItemAtFast(i);
|
||||||
|
|
||||||
if (categoryRef->Name() == name)
|
if (categoryRef->Code() == code)
|
||||||
return i;
|
return i;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -140,7 +140,7 @@ PackageFillingPkgListener::ConsumePackage(const PackageInfoRef& package,
|
|||||||
|
|
||||||
for (i = 0; i < countPkgCategories; i++) {
|
for (i = 0; i < countPkgCategories; i++) {
|
||||||
BString* categoryCode = pkg->PkgCategoriesItemAt(i)->Code();
|
BString* categoryCode = pkg->PkgCategoriesItemAt(i)->Code();
|
||||||
int categoryIndex = IndexOfCategoryByName(*(categoryCode));
|
int categoryIndex = IndexOfCategoryByCode(*(categoryCode));
|
||||||
|
|
||||||
if (categoryIndex == -1) {
|
if (categoryIndex == -1) {
|
||||||
printf("unable to find the category for [%s]\n",
|
printf("unable to find the category for [%s]\n",
|
||||||
|
|||||||
@@ -107,8 +107,12 @@ ServerReferenceDataUpdateProcess::ProcessLocalData()
|
|||||||
status_t
|
status_t
|
||||||
ServerReferenceDataUpdateProcess::_ProcessData(DumpExportReference* data)
|
ServerReferenceDataUpdateProcess::_ProcessData(DumpExportReference* data)
|
||||||
{
|
{
|
||||||
// more to come here later...
|
status_t result = B_OK;
|
||||||
return _ProcessNaturalLanguages(data);
|
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++) {
|
for (int32 i = 0; i < data->CountNaturalLanguages(); i++) {
|
||||||
DumpExportReferenceNaturalLanguage* naturalLanguage =
|
DumpExportReferenceNaturalLanguage* naturalLanguage =
|
||||||
data->NaturalLanguagesItemAt(i);
|
data->NaturalLanguagesItemAt(i);
|
||||||
result.Add(LanguageRef(new Language(
|
result.Add(LanguageRef(
|
||||||
*(naturalLanguage->Code()),
|
new Language(
|
||||||
*(naturalLanguage->Name()),
|
*(naturalLanguage->Code()),
|
||||||
naturalLanguage->IsPopular())));
|
*(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
|
status_t
|
||||||
ServerReferenceDataUpdateProcess::GetStandardMetaDataPath(BPath& path) const
|
ServerReferenceDataUpdateProcess::GetStandardMetaDataPath(BPath& path) const
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -46,6 +46,8 @@ private:
|
|||||||
status_t _ProcessData(DumpExportReference* data);
|
status_t _ProcessData(DumpExportReference* data);
|
||||||
status_t _ProcessNaturalLanguages(
|
status_t _ProcessNaturalLanguages(
|
||||||
DumpExportReference* data);
|
DumpExportReference* data);
|
||||||
|
status_t _ProcessPkgCategories(
|
||||||
|
DumpExportReference* data);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
Model* fModel;
|
Model* fModel;
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright 2013, Stephan Aßmus <superstippi@gmx.de>.
|
* Copyright 2013, Stephan Aßmus <superstippi@gmx.de>.
|
||||||
|
* Copyright 2019, Andrew Lindesay <apl@lindesay.co.nz>.
|
||||||
* All rights reserved. Distributed under the terms of the MIT License.
|
* All rights reserved. Distributed under the terms of the MIT License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
@@ -8,6 +9,7 @@
|
|||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
|
|
||||||
|
#include <AutoLocker.h>
|
||||||
#include <Catalog.h>
|
#include <Catalog.h>
|
||||||
#include <CheckBox.h>
|
#include <CheckBox.h>
|
||||||
#include <LayoutBuilder.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++) {
|
for (int i = 0; i < categories.CountItems(); i++) {
|
||||||
const CategoryRef& category = categories.ItemAtFast(i);
|
const CategoryRef& category = categories.ItemAtFast(i);
|
||||||
BMessage* message = new BMessage(MSG_CATEGORY_SELECTED);
|
BMessage* message = new BMessage(MSG_CATEGORY_SELECTED);
|
||||||
message->AddString("name", category->Name());
|
message->AddString("code", category->Code());
|
||||||
BMenuItem* item = new BMenuItem(category->Label(), message);
|
BMenuItem* item = new BMenuItem(category->Name(), message);
|
||||||
menu->AddItem(item);
|
menu->AddItem(item);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -88,7 +90,6 @@ FilterView::AttachedToWindow()
|
|||||||
{
|
{
|
||||||
fShowField->Menu()->SetTargetForItems(Window());
|
fShowField->Menu()->SetTargetForItems(Window());
|
||||||
fSearchTermsText->SetTarget(this);
|
fSearchTermsText->SetTarget(this);
|
||||||
|
|
||||||
fSearchTermsText->MakeFocus();
|
fSearchTermsText->MakeFocus();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -113,7 +114,7 @@ FilterView::MessageReceived(BMessage* message)
|
|||||||
|
|
||||||
|
|
||||||
void
|
void
|
||||||
FilterView::AdoptModel(const Model& model)
|
FilterView::AdoptModel(Model& model)
|
||||||
{
|
{
|
||||||
// Adopt categories
|
// Adopt categories
|
||||||
BMenu* showMenu = fShowField->Menu();
|
BMenu* showMenu = fShowField->Menu();
|
||||||
@@ -122,25 +123,47 @@ FilterView::AdoptModel(const Model& model)
|
|||||||
showMenu->AddItem(new BMenuItem(B_TRANSLATE("All categories"),
|
showMenu->AddItem(new BMenuItem(B_TRANSLATE("All categories"),
|
||||||
new BMessage(MSG_CATEGORY_SELECTED)));
|
new BMessage(MSG_CATEGORY_SELECTED)));
|
||||||
|
|
||||||
showMenu->AddItem(new BSeparatorItem());
|
AutoLocker<BLocker> locker(model.Lock());
|
||||||
|
CategoryList categories = model.Categories();
|
||||||
|
|
||||||
add_categories_to_menu(model.Categories(), showMenu);
|
if (!categories.IsEmpty()) {
|
||||||
|
showMenu->AddItem(new BSeparatorItem());
|
||||||
bool foundSelectedCategory = false;
|
add_categories_to_menu(categories, showMenu);
|
||||||
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) {
|
|
||||||
item->SetMarked(true);
|
|
||||||
foundSelectedCategory = true;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
if (!foundSelectedCategory)
|
|
||||||
|
showMenu->SetEnabled(!categories.IsEmpty());
|
||||||
|
|
||||||
|
if (!_SelectCategoryCode(showMenu, model.Category()))
|
||||||
showMenu->ItemAt(0)->SetMarked(true);
|
showMenu->ItemAt(0)->SetMarked(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*! 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);
|
||||||
|
return 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;
|
||||||
|
}
|
||||||
@@ -1,5 +1,6 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright 2013, Stephan Aßmus <superstippi@gmx.de>.
|
* Copyright 2013, Stephan Aßmus <superstippi@gmx.de>.
|
||||||
|
* Copyright 2019, Andrew Lindesay <apl@lindesay.co.nz>.
|
||||||
* All rights reserved. Distributed under the terms of the MIT License.
|
* All rights reserved. Distributed under the terms of the MIT License.
|
||||||
*/
|
*/
|
||||||
#ifndef FILTER_VIEW_H
|
#ifndef FILTER_VIEW_H
|
||||||
@@ -9,7 +10,9 @@
|
|||||||
|
|
||||||
|
|
||||||
class BCheckBox;
|
class BCheckBox;
|
||||||
|
class BMenu;
|
||||||
class BMenuField;
|
class BMenuField;
|
||||||
|
class BMenuItem;
|
||||||
class BTextControl;
|
class BTextControl;
|
||||||
class Model;
|
class Model;
|
||||||
|
|
||||||
@@ -29,7 +32,13 @@ public:
|
|||||||
virtual void AttachedToWindow();
|
virtual void AttachedToWindow();
|
||||||
virtual void MessageReceived(BMessage* message);
|
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:
|
private:
|
||||||
BMenuField* fShowField;
|
BMenuField* fShowField;
|
||||||
|
|||||||
@@ -3,7 +3,7 @@
|
|||||||
* Copyright 2013-2014, Stephan Aßmus <superstippi@gmx.de>.
|
* Copyright 2013-2014, Stephan Aßmus <superstippi@gmx.de>.
|
||||||
* Copyright 2013, Rene Gollent, rene@gollent.com.
|
* Copyright 2013, Rene Gollent, rene@gollent.com.
|
||||||
* Copyright 2013, Ingo Weinhold, ingo_weinhold@gmx.de.
|
* Copyright 2013, Ingo Weinhold, ingo_weinhold@gmx.de.
|
||||||
* Copyright 2016-2018, Andrew Lindesay <apl@lindesay.co.nz>.
|
* Copyright 2016-2019, Andrew Lindesay <apl@lindesay.co.nz>.
|
||||||
* Copyright 2017, Julian Harnath <julian.harnath@rwth-aachen.de>.
|
* Copyright 2017, Julian Harnath <julian.harnath@rwth-aachen.de>.
|
||||||
* All rights reserved. Distributed under the terms of the MIT License.
|
* All rights reserved. Distributed under the terms of the MIT License.
|
||||||
*/
|
*/
|
||||||
@@ -63,6 +63,7 @@ enum {
|
|||||||
MSG_LOG_IN = 'lgin',
|
MSG_LOG_IN = 'lgin',
|
||||||
MSG_LOG_OUT = 'lgot',
|
MSG_LOG_OUT = 'lgot',
|
||||||
MSG_AUTHORIZATION_CHANGED = 'athc',
|
MSG_AUTHORIZATION_CHANGED = 'athc',
|
||||||
|
MSG_CATEGORIES_LIST_CHANGED = 'clic',
|
||||||
MSG_PACKAGE_CHANGED = 'pchd',
|
MSG_PACKAGE_CHANGED = 'pchd',
|
||||||
MSG_WORK_STATUS_CHANGE = 'wsch',
|
MSG_WORK_STATUS_CHANGE = 'wsch',
|
||||||
MSG_WORK_STATUS_CLEAR = 'wscl',
|
MSG_WORK_STATUS_CLEAR = 'wscl',
|
||||||
@@ -95,9 +96,9 @@ struct RefreshWorkerParameters {
|
|||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
class MessageModelListener : public ModelListener {
|
class MainWindowModelListener : public ModelListener {
|
||||||
public:
|
public:
|
||||||
MessageModelListener(const BMessenger& messenger)
|
MainWindowModelListener(const BMessenger& messenger)
|
||||||
:
|
:
|
||||||
fMessenger(messenger)
|
fMessenger(messenger)
|
||||||
{
|
{
|
||||||
@@ -109,6 +110,12 @@ public:
|
|||||||
fMessenger.SendMessage(MSG_AUTHORIZATION_CHANGED);
|
fMessenger.SendMessage(MSG_AUTHORIZATION_CHANGED);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
virtual void CategoryListChanged()
|
||||||
|
{
|
||||||
|
if (fMessenger.IsValid())
|
||||||
|
fMessenger.SendMessage(MSG_CATEGORIES_LIST_CHANGED);
|
||||||
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
BMessenger fMessenger;
|
BMessenger fMessenger;
|
||||||
};
|
};
|
||||||
@@ -123,7 +130,7 @@ MainWindow::MainWindow(const BMessage& settings)
|
|||||||
fUserMenu(NULL),
|
fUserMenu(NULL),
|
||||||
fLogInItem(NULL),
|
fLogInItem(NULL),
|
||||||
fLogOutItem(NULL),
|
fLogOutItem(NULL),
|
||||||
fModelListener(new MessageModelListener(BMessenger(this)), true),
|
fModelListener(new MainWindowModelListener(BMessenger(this)), true),
|
||||||
fBulkLoadProcessCoordinator(NULL),
|
fBulkLoadProcessCoordinator(NULL),
|
||||||
fSinglePackageMode(false)
|
fSinglePackageMode(false)
|
||||||
{
|
{
|
||||||
@@ -221,7 +228,7 @@ MainWindow::MainWindow(const BMessage& settings, const PackageInfoRef& package)
|
|||||||
fUserMenu(NULL),
|
fUserMenu(NULL),
|
||||||
fLogInItem(NULL),
|
fLogInItem(NULL),
|
||||||
fLogOutItem(NULL),
|
fLogOutItem(NULL),
|
||||||
fModelListener(new MessageModelListener(BMessenger(this)), true),
|
fModelListener(new MainWindowModelListener(BMessenger(this)), true),
|
||||||
fBulkLoadProcessCoordinator(NULL),
|
fBulkLoadProcessCoordinator(NULL),
|
||||||
fSinglePackageMode(true)
|
fSinglePackageMode(true)
|
||||||
{
|
{
|
||||||
@@ -331,6 +338,10 @@ MainWindow::MessageReceived(BMessage* message)
|
|||||||
_UpdateAuthorization();
|
_UpdateAuthorization();
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case MSG_CATEGORIES_LIST_CHANGED:
|
||||||
|
fFilterView->AdoptModel(fModel);
|
||||||
|
break;
|
||||||
|
|
||||||
case MSG_SHOW_FEATURED_PACKAGES:
|
case MSG_SHOW_FEATURED_PACKAGES:
|
||||||
// check to see if we aren't already on the current tab
|
// check to see if we aren't already on the current tab
|
||||||
if (fListTabs->Selection() ==
|
if (fListTabs->Selection() ==
|
||||||
@@ -421,12 +432,12 @@ MainWindow::MessageReceived(BMessage* message)
|
|||||||
|
|
||||||
case MSG_CATEGORY_SELECTED:
|
case MSG_CATEGORY_SELECTED:
|
||||||
{
|
{
|
||||||
BString name;
|
BString code;
|
||||||
if (message->FindString("name", &name) != B_OK)
|
if (message->FindString("code", &code) != B_OK)
|
||||||
name = "";
|
code = "";
|
||||||
{
|
{
|
||||||
BAutolock locker(fModel.Lock());
|
BAutolock locker(fModel.Lock());
|
||||||
fModel.SetCategory(name);
|
fModel.SetCategory(code);
|
||||||
}
|
}
|
||||||
_AdoptModel();
|
_AdoptModel();
|
||||||
break;
|
break;
|
||||||
|
|||||||
@@ -0,0 +1,36 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2019, Andrew Lindesay <apl@lindesay.co.nz>.
|
||||||
|
* 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);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,25 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2019, Andrew Lindesay <apl@lindesay.co.nz>.
|
||||||
|
* 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
|
||||||
Reference in New Issue
Block a user