mirror of
https://review.haiku-os.org/haiku
synced 2024-11-23 07:18:40 +01:00
HaikuDepot: Model package classification
This moves the categories, prominence and native desktop (new) flag into a separate model. Change-Id: I4c45004a3a38cc08bb610184f8d7ef786f0d1a08 Reviewed-on: https://review.haiku-os.org/c/haiku/+/8474 Tested-by: Commit checker robot <no-reply+buildbot@haiku-os.org> Reviewed-by: Jérôme Duval <jerome.duval@gmail.com>
This commit is contained in:
parent
f13cec8031
commit
8cc3ed34bc
@ -177,6 +177,7 @@ local applicationSources =
|
||||
DepotInfo.cpp
|
||||
Language.cpp
|
||||
PackageCategory.cpp
|
||||
PackageClassificationInfo.cpp
|
||||
PackageFilter.cpp
|
||||
PackageFilterModel.cpp
|
||||
PackageInfo.cpp
|
||||
|
@ -19,12 +19,12 @@ enum {
|
||||
PKG_CHANGED_STATE = 1 << 5,
|
||||
PKG_CHANGED_ICON = 1 << 6,
|
||||
PKG_CHANGED_CHANGELOG = 1 << 7,
|
||||
PKG_CHANGED_CATEGORIES = 1 << 8,
|
||||
PKG_CHANGED_PROMINENCE = 1 << 9,
|
||||
PKG_CHANGED_SIZE = 1 << 10,
|
||||
PKG_CHANGED_DEPOT = 1 << 11,
|
||||
PKG_CHANGED_VERSION = 1 << 12,
|
||||
PKG_CHANGED_VERSION_CREATE_TIMESTAMP = 1 << 13
|
||||
PKG_CHANGED_CLASSIFICATION = 1 << 8,
|
||||
// ^ This covers categories, prominence and is native desktop
|
||||
PKG_CHANGED_SIZE = 1 << 9,
|
||||
PKG_CHANGED_DEPOT = 1 << 10,
|
||||
PKG_CHANGED_VERSION = 1 << 11,
|
||||
PKG_CHANGED_VERSION_CREATE_TIMESTAMP = 1 << 12
|
||||
// ...
|
||||
};
|
||||
|
||||
|
@ -199,8 +199,12 @@ DepotInfo::HasAnyProminentPackages() const
|
||||
std::vector<PackageInfoRef>::const_iterator it;
|
||||
for (it = fPackages.begin(); it != fPackages.end(); it++) {
|
||||
const PackageInfoRef& package = *it;
|
||||
if (package->IsProminent())
|
||||
return true;
|
||||
const PackageClassificationInfoRef& classification = package->PackageClassificationInfo();
|
||||
|
||||
if (classification.IsSet()) {
|
||||
if (classification->IsProminent())
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
133
src/apps/haikudepot/packagemodel/PackageClassificationInfo.cpp
Normal file
133
src/apps/haikudepot/packagemodel/PackageClassificationInfo.cpp
Normal file
@ -0,0 +1,133 @@
|
||||
/*
|
||||
* Copyright 2024, Andrew Lindesay <apl@lindesay.co.nz>.
|
||||
* All rights reserved. Distributed under the terms of the MIT License.
|
||||
*/
|
||||
|
||||
|
||||
#include "PackageClassificationInfo.h"
|
||||
|
||||
#include <algorithm>
|
||||
|
||||
#include "HaikuDepotConstants.h"
|
||||
|
||||
|
||||
PackageClassificationInfo::PackageClassificationInfo()
|
||||
:
|
||||
fCategories(),
|
||||
fProminence(-1L),
|
||||
fIsNativeDesktop(false)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
PackageClassificationInfo::PackageClassificationInfo(const PackageClassificationInfo& other)
|
||||
:
|
||||
fCategories(other.fCategories),
|
||||
fProminence(other.Prominence()),
|
||||
fIsNativeDesktop(other.IsNativeDesktop())
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
int32
|
||||
PackageClassificationInfo::CountCategories() const
|
||||
{
|
||||
return fCategories.size();
|
||||
}
|
||||
|
||||
|
||||
CategoryRef
|
||||
PackageClassificationInfo::CategoryAtIndex(int32 index) const
|
||||
{
|
||||
return fCategories[index];
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
PackageClassificationInfo::ClearCategories()
|
||||
{
|
||||
if (!fCategories.empty())
|
||||
fCategories.clear();
|
||||
}
|
||||
|
||||
|
||||
bool
|
||||
PackageClassificationInfo::AddCategory(const CategoryRef& category)
|
||||
{
|
||||
std::vector<CategoryRef>::const_iterator itInsertionPt = std::lower_bound(fCategories.begin(),
|
||||
fCategories.end(), category, &IsPackageCategoryBefore);
|
||||
|
||||
if (itInsertionPt == fCategories.end()) {
|
||||
fCategories.push_back(category);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
bool
|
||||
PackageClassificationInfo::HasCategoryByCode(const BString& code) const
|
||||
{
|
||||
for (int32 i = CountCategories() - 1; i >= 0; i--) {
|
||||
if (CategoryAtIndex(i)->Code() == code)
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
PackageClassificationInfo::SetProminence(uint32 prominence)
|
||||
{
|
||||
fProminence = prominence;
|
||||
}
|
||||
|
||||
|
||||
bool
|
||||
PackageClassificationInfo::IsProminent() const
|
||||
{
|
||||
return HasProminence() && Prominence() <= PROMINANCE_ORDERING_PROMINENT_MAX;
|
||||
}
|
||||
|
||||
|
||||
bool
|
||||
PackageClassificationInfo::IsNativeDesktop() const
|
||||
{
|
||||
return fIsNativeDesktop;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
PackageClassificationInfo::SetIsNativeDesktop(bool value)
|
||||
{
|
||||
fIsNativeDesktop = value;
|
||||
}
|
||||
|
||||
|
||||
bool
|
||||
PackageClassificationInfo::operator==(const PackageClassificationInfo& other) const
|
||||
{
|
||||
if (fIsNativeDesktop != other.IsNativeDesktop())
|
||||
return false;
|
||||
|
||||
if (fProminence != other.Prominence())
|
||||
return false;
|
||||
|
||||
if (CountCategories() != other.CountCategories())
|
||||
return false;
|
||||
|
||||
for (int32 i = CountCategories() - 1; i >= 0; i--) {
|
||||
if (other.CategoryAtIndex(i) != CategoryAtIndex(i))
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
bool
|
||||
PackageClassificationInfo::operator!=(const PackageClassificationInfo& other) const
|
||||
{
|
||||
return !(*this == other);
|
||||
}
|
52
src/apps/haikudepot/packagemodel/PackageClassificationInfo.h
Normal file
52
src/apps/haikudepot/packagemodel/PackageClassificationInfo.h
Normal file
@ -0,0 +1,52 @@
|
||||
/*
|
||||
* Copyright 2024, Andrew Lindesay <apl@lindesay.co.nz>.
|
||||
* All rights reserved. Distributed under the terms of the MIT License.
|
||||
*/
|
||||
#ifndef PACKAGE_CLASSIFICATION_INFO_H
|
||||
#define PACKAGE_CLASSIFICATION_INFO_H
|
||||
|
||||
|
||||
#include <vector>
|
||||
|
||||
#include <Referenceable.h>
|
||||
|
||||
#include "PackageCategory.h"
|
||||
|
||||
|
||||
class PackageClassificationInfo : public BReferenceable
|
||||
{
|
||||
public:
|
||||
PackageClassificationInfo();
|
||||
PackageClassificationInfo(const PackageClassificationInfo& other);
|
||||
|
||||
bool operator==(const PackageClassificationInfo& other) const;
|
||||
bool operator!=(const PackageClassificationInfo& other) const;
|
||||
|
||||
void SetProminence(uint32 prominence);
|
||||
uint32 Prominence() const
|
||||
{ return fProminence; }
|
||||
bool HasProminence() const
|
||||
{ return fProminence != 0; }
|
||||
bool IsProminent() const;
|
||||
|
||||
void ClearCategories();
|
||||
bool AddCategory(const CategoryRef& category);
|
||||
int32 CountCategories() const;
|
||||
CategoryRef CategoryAtIndex(int32 index) const;
|
||||
bool HasCategoryByCode(const BString& code) const;
|
||||
|
||||
bool IsNativeDesktop() const;
|
||||
void SetIsNativeDesktop(bool value);
|
||||
|
||||
private:
|
||||
std::vector<CategoryRef>
|
||||
fCategories;
|
||||
uint32 fProminence;
|
||||
bool fIsNativeDesktop;
|
||||
};
|
||||
|
||||
|
||||
typedef BReference<PackageClassificationInfo> PackageClassificationInfoRef;
|
||||
|
||||
|
||||
#endif // PACKAGE_CLASSIFICATION_INFO_H
|
@ -72,9 +72,9 @@ private:
|
||||
|
||||
class CategoryFilter : public PackageFilter {
|
||||
public:
|
||||
CategoryFilter(const BString& category)
|
||||
CategoryFilter(const BString& categoryCode)
|
||||
:
|
||||
fCategory(category)
|
||||
fCategoryCode(categoryCode)
|
||||
{
|
||||
}
|
||||
|
||||
@ -83,23 +83,21 @@ public:
|
||||
if (!package.IsSet())
|
||||
return false;
|
||||
|
||||
for (int i = package->CountCategories() - 1; i >= 0; i--) {
|
||||
const CategoryRef& category = package->CategoryAtIndex(i);
|
||||
if (!category.IsSet())
|
||||
continue;
|
||||
if (category->Code() == fCategory)
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
PackageClassificationInfoRef classificationInfo = package->PackageClassificationInfo();
|
||||
|
||||
if (!classificationInfo.IsSet())
|
||||
return false;
|
||||
|
||||
return classificationInfo->HasCategoryByCode(CategoryCode());
|
||||
}
|
||||
|
||||
const BString& Category() const
|
||||
const BString& CategoryCode() const
|
||||
{
|
||||
return fCategory;
|
||||
return fCategoryCode;
|
||||
}
|
||||
|
||||
private:
|
||||
BString fCategory;
|
||||
BString fCategoryCode;
|
||||
};
|
||||
|
||||
|
||||
|
@ -30,7 +30,7 @@ PackageInfo::PackageInfo()
|
||||
fFullDescription(),
|
||||
fHasChangelog(false),
|
||||
fChangelog(),
|
||||
fProminence(0),
|
||||
fPackageClassificationInfo(),
|
||||
fScreenshotInfos(),
|
||||
fUserRatingInfo(),
|
||||
fState(NONE),
|
||||
@ -60,7 +60,7 @@ PackageInfo::PackageInfo(const BPackageInfo& info)
|
||||
fFullDescription(info.Description()),
|
||||
fHasChangelog(false),
|
||||
fChangelog(),
|
||||
fProminence(0),
|
||||
fPackageClassificationInfo(),
|
||||
fScreenshotInfos(),
|
||||
fUserRatingInfo(),
|
||||
fState(NONE),
|
||||
@ -111,8 +111,7 @@ PackageInfo::PackageInfo(const BString& name, const BPackageVersion& version,
|
||||
fFullDescription(fullDescription),
|
||||
fHasChangelog(false),
|
||||
fChangelog(),
|
||||
fCategories(),
|
||||
fProminence(0),
|
||||
fPackageClassificationInfo(),
|
||||
fScreenshotInfos(),
|
||||
fUserRatingInfo(),
|
||||
fState(NONE),
|
||||
@ -142,8 +141,7 @@ PackageInfo::PackageInfo(const PackageInfo& other)
|
||||
fFullDescription(other.fFullDescription),
|
||||
fHasChangelog(other.fHasChangelog),
|
||||
fChangelog(other.fChangelog),
|
||||
fCategories(other.fCategories),
|
||||
fProminence(other.fProminence),
|
||||
fPackageClassificationInfo(other.fPackageClassificationInfo),
|
||||
fScreenshotInfos(other.fScreenshotInfos),
|
||||
fUserRatingInfo(other.fUserRatingInfo),
|
||||
fState(other.fState),
|
||||
@ -175,8 +173,7 @@ PackageInfo::operator=(const PackageInfo& other)
|
||||
fFullDescription = other.fFullDescription;
|
||||
fHasChangelog = other.fHasChangelog;
|
||||
fChangelog = other.fChangelog;
|
||||
fCategories = other.fCategories;
|
||||
fProminence = other.fProminence;
|
||||
fPackageClassificationInfo = other.fPackageClassificationInfo;
|
||||
fScreenshotInfos = other.fScreenshotInfos;
|
||||
fUserRatingInfo = other.fUserRatingInfo;
|
||||
fState = other.fState;
|
||||
@ -207,8 +204,7 @@ PackageInfo::operator==(const PackageInfo& other) const
|
||||
&& fFullDescription == other.fFullDescription
|
||||
&& fHasChangelog == other.fHasChangelog
|
||||
&& fChangelog == other.fChangelog
|
||||
&& fCategories == other.fCategories
|
||||
&& fProminence == other.fProminence
|
||||
&& fPackageClassificationInfo == other.fPackageClassificationInfo
|
||||
&& fScreenshotInfos == other.fScreenshotInfos
|
||||
&& fUserRatingInfo == fUserRatingInfo
|
||||
&& fState == other.fState
|
||||
@ -291,49 +287,16 @@ PackageInfo::IsSystemPackage() const
|
||||
}
|
||||
|
||||
|
||||
int32
|
||||
PackageInfo::CountCategories() const
|
||||
{
|
||||
return fCategories.size();
|
||||
}
|
||||
|
||||
|
||||
CategoryRef
|
||||
PackageInfo::CategoryAtIndex(int32 index) const
|
||||
{
|
||||
return fCategories[index];
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
PackageInfo::ClearCategories()
|
||||
PackageInfo::SetPackageClassificationInfo(PackageClassificationInfoRef value)
|
||||
{
|
||||
if (!fCategories.empty()) {
|
||||
fCategories.clear();
|
||||
_NotifyListeners(PKG_CHANGED_CATEGORIES);
|
||||
if (value != fPackageClassificationInfo) {
|
||||
fPackageClassificationInfo = value;
|
||||
_NotifyListeners(PKG_CHANGED_CLASSIFICATION);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
bool
|
||||
PackageInfo::AddCategory(const CategoryRef& category)
|
||||
{
|
||||
std::vector<CategoryRef>::const_iterator itInsertionPt
|
||||
= std::lower_bound(
|
||||
fCategories.begin(),
|
||||
fCategories.end(),
|
||||
category,
|
||||
&IsPackageCategoryBefore);
|
||||
|
||||
if (itInsertionPt == fCategories.end()) {
|
||||
fCategories.push_back(category);
|
||||
_NotifyListeners(PKG_CHANGED_CATEGORIES);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
PackageInfo::SetSystemDependency(bool isDependency)
|
||||
{
|
||||
@ -409,22 +372,8 @@ PackageInfo::SetUserRatingInfo(UserRatingInfoRef value)
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
PackageInfo::SetProminence(int64 prominence)
|
||||
{
|
||||
if (fProminence != prominence) {
|
||||
fProminence = prominence;
|
||||
_NotifyListeners(PKG_CHANGED_PROMINENCE);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
bool
|
||||
PackageInfo::IsProminent() const
|
||||
{
|
||||
return HasProminence() && Prominence() <= PROMINANCE_ORDERING_PROMINENT_MAX;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
PackageInfo::ClearScreenshotInfos()
|
||||
|
@ -15,7 +15,7 @@
|
||||
|
||||
#include "Language.h"
|
||||
#include "List.h"
|
||||
#include "PackageCategory.h"
|
||||
#include "PackageClassificationInfo.h"
|
||||
#include "PackageInfoListener.h"
|
||||
#include "PublisherInfo.h"
|
||||
#include "ScreenshotInfo.h"
|
||||
@ -115,21 +115,15 @@ public:
|
||||
const BString& FileName() const
|
||||
{ return fFileName; }
|
||||
|
||||
void ClearCategories();
|
||||
bool AddCategory(const CategoryRef& category);
|
||||
int32 CountCategories() const;
|
||||
CategoryRef CategoryAtIndex(int32 index) const;
|
||||
void SetPackageClassificationInfo(
|
||||
PackageClassificationInfoRef value);
|
||||
PackageClassificationInfoRef
|
||||
PackageClassificationInfo() const
|
||||
{ return fPackageClassificationInfo; }
|
||||
|
||||
UserRatingInfoRef UserRatingInfo();
|
||||
void SetUserRatingInfo(UserRatingInfoRef userRatingInfo);
|
||||
|
||||
void SetProminence(int64 prominence);
|
||||
int64 Prominence() const
|
||||
{ return fProminence; }
|
||||
bool HasProminence() const
|
||||
{ return fProminence != 0; }
|
||||
bool IsProminent() const;
|
||||
|
||||
void ClearScreenshotInfos();
|
||||
void AddScreenshotInfo(
|
||||
const ScreenshotInfoRef& info);
|
||||
@ -174,9 +168,8 @@ private:
|
||||
BString fFullDescription;
|
||||
bool fHasChangelog;
|
||||
BString fChangelog;
|
||||
std::vector<CategoryRef>
|
||||
fCategories;
|
||||
int64 fProminence;
|
||||
PackageClassificationInfoRef
|
||||
fPackageClassificationInfo;
|
||||
std::vector<ScreenshotInfoRef>
|
||||
fScreenshotInfos;
|
||||
UserRatingInfoRef fUserRatingInfo;
|
||||
|
@ -109,6 +109,9 @@ UserRatingInfo::operator==(const UserRatingInfo& other) const
|
||||
if (UserRatingsPopulated() != other.UserRatingsPopulated())
|
||||
return false;
|
||||
|
||||
if (CountUserRatings() != other.CountUserRatings())
|
||||
return false;
|
||||
|
||||
for (int32 i = CountUserRatings() - 1; i >= 0; i--) {
|
||||
if (other.UserRatingAtIndex(i) != UserRatingAtIndex(i))
|
||||
return false;
|
||||
|
@ -93,6 +93,8 @@ PackageFillingPkgListener::ConsumePackage(const PackageInfoRef& package,
|
||||
|
||||
package->StartCollatingChanges();
|
||||
|
||||
PackageClassificationInfoRef packageClassificationInfo(new PackageClassificationInfo(), true);
|
||||
|
||||
if (0 != pkg->CountPkgVersions()) {
|
||||
|
||||
// this makes the assumption that the only version will be the
|
||||
@ -126,7 +128,7 @@ PackageFillingPkgListener::ConsumePackage(const PackageInfoRef& package,
|
||||
HDERROR("unable to find the category for [%s]",
|
||||
categoryCode->String());
|
||||
} else
|
||||
package->AddCategory(category);
|
||||
packageClassificationInfo->AddCategory(category);
|
||||
}
|
||||
|
||||
if (!pkg->DerivedRatingIsNull()) {
|
||||
@ -142,7 +144,10 @@ PackageFillingPkgListener::ConsumePackage(const PackageInfoRef& package,
|
||||
package->SetHasChangelog(pkg->HasChangelog());
|
||||
|
||||
if (!pkg->ProminenceOrderingIsNull())
|
||||
package->SetProminence(pkg->ProminenceOrdering());
|
||||
packageClassificationInfo->SetProminence(static_cast<uint32>(pkg->ProminenceOrdering()));
|
||||
|
||||
if (!pkg->IsNativeDesktopIsNull())
|
||||
packageClassificationInfo->SetIsNativeDesktop(pkg->IsNativeDesktop());
|
||||
|
||||
int32 countPkgScreenshots = pkg->CountPkgScreenshots();
|
||||
|
||||
@ -161,6 +166,8 @@ PackageFillingPkgListener::ConsumePackage(const PackageInfoRef& package,
|
||||
|
||||
fCount++;
|
||||
|
||||
package->SetPackageClassificationInfo(packageClassificationInfo);
|
||||
|
||||
package->EndCollatingChanges();
|
||||
|
||||
return !fStoppable->WasStopped();
|
||||
|
@ -415,16 +415,31 @@ public:
|
||||
packageB.
|
||||
*/
|
||||
|
||||
static bool _IsPackageBefore(const PackageInfoRef& packageA,
|
||||
const PackageInfoRef& packageB)
|
||||
static bool _IsPackageBefore(const PackageInfoRef& packageA, const PackageInfoRef& packageB)
|
||||
{
|
||||
if (!packageA.IsSet() || !packageB.IsSet())
|
||||
HDFATAL("unexpected NULL reference in a referencable");
|
||||
int c = _CmpProminences(packageA->Prominence(), packageB->Prominence());
|
||||
|
||||
uint32 prominenceA = 0;
|
||||
uint32 prominenceB = 0;
|
||||
|
||||
PackageClassificationInfoRef classificationInfoA = packageA->PackageClassificationInfo();
|
||||
PackageClassificationInfoRef classificationInfoB = packageB->PackageClassificationInfo();
|
||||
|
||||
if (classificationInfoA.IsSet())
|
||||
prominenceA = classificationInfoA->Prominence();
|
||||
|
||||
if (classificationInfoB.IsSet())
|
||||
prominenceB = classificationInfoB->Prominence();
|
||||
|
||||
int c = static_cast<int>(prominenceA) - static_cast<int>(prominenceB);
|
||||
|
||||
if (c == 0)
|
||||
c = packageA->Title().ICompare(packageB->Title());
|
||||
|
||||
if (c == 0)
|
||||
c = packageA->Name().Compare(packageB->Name());
|
||||
|
||||
return c < 0;
|
||||
}
|
||||
|
||||
|
@ -720,7 +720,7 @@ MainWindow::Consume(ProcessCoordinator *item)
|
||||
void
|
||||
MainWindow::PackageChanged(const PackageInfoEvent& event)
|
||||
{
|
||||
uint32 watchedChanges = PKG_CHANGED_STATE | PKG_CHANGED_PROMINENCE;
|
||||
uint32 watchedChanges = PKG_CHANGED_STATE | PKG_CHANGED_CLASSIFICATION;
|
||||
if ((event.Changes() & watchedChanges) != 0) {
|
||||
PackageInfoRef ref(event.Package());
|
||||
BMessage message(MSG_PACKAGE_CHANGED);
|
||||
@ -988,8 +988,13 @@ MainWindow::_AddRemovePackageFromLists(const PackageInfoRef& package)
|
||||
}
|
||||
|
||||
if (matches) {
|
||||
if (package->IsProminent())
|
||||
fFeaturedPackagesView->AddPackage(package);
|
||||
PackageClassificationInfoRef classification = package->PackageClassificationInfo();
|
||||
|
||||
if (classification.IsSet()) {
|
||||
if (classification->IsProminent())
|
||||
fFeaturedPackagesView->AddPackage(package);
|
||||
}
|
||||
|
||||
fPackageListView->AddPackage(package);
|
||||
} else {
|
||||
fFeaturedPackagesView->RemovePackage(package);
|
||||
|
Loading…
Reference in New Issue
Block a user