HaikuDepot: Remove Custom List

Further removal of the use of custom list class.

Relates To #15534

Change-Id: I1d84b562b334e5e52ed4772bad3a6aea7b715562
Reviewed-on: https://review.haiku-os.org/c/haiku/+/3657
Reviewed-by: Adrien Destugues <pulkomandy@gmail.com>
This commit is contained in:
Andrew Lindesay 2021-01-07 22:00:25 +13:00
parent 0fbba5d721
commit 9984ca59f6
11 changed files with 328 additions and 233 deletions

View File

@ -1,7 +1,7 @@
/*
* Copyright 2013-2014, Stephan Aßmus <superstippi@gmx.de>.
* Copyright 2014, Axel Dörfler <axeld@pinc-software.de>.
* Copyright 2016-2020, Andrew Lindesay <apl@lindesay.co.nz>.
* Copyright 2016-2021, Andrew Lindesay <apl@lindesay.co.nz>.
* All rights reserved. Distributed under the terms of the MIT License.
*/
@ -167,38 +167,6 @@ private:
};
class NotContainedInFilter : public PackageFilter {
public:
NotContainedInFilter(const PackageList* packageList, ...)
{
va_list args;
va_start(args, packageList);
while (true) {
const PackageList* packageList = va_arg(args, const PackageList*);
if (packageList == NULL)
break;
fPackageLists.Add(packageList);
}
va_end(args);
}
virtual bool AcceptsPackage(const PackageInfoRef& package) const
{
if (package.Get() == NULL)
return false;
for (int32 i = 0; i < fPackageLists.CountItems(); i++) {
if (fPackageLists.ItemAtFast(i)->Contains(package))
return false;
}
return true;
}
private:
List<const PackageList*, true> fPackageLists;
};
class StateFilter : public PackageFilter {
public:
StateFilter(PackageState state)
@ -348,10 +316,10 @@ Model::InitPackageIconRepository()
}
bool
void
Model::AddListener(const ModelListenerRef& listener)
{
return fListeners.Add(listener);
fListeners.push_back(listener);
}
@ -725,9 +693,10 @@ Model::PopulatePackage(const PackageInfoRef& package, uint32 flags)
item.FindDouble("createTimestamp", &createTimestamp);
// Add the rating to the PackageInfo
UserRating userRating = UserRating(UserInfo(user), rating,
UserRatingRef userRating(new UserRating(
UserInfo(user), rating,
comment, languageCode, versionString,
(uint64) createTimestamp);
(uint64) createTimestamp), true);
package->AddUserRating(userRating);
HDDEBUG("rating [%s] retrieved from server", code.String());
}
@ -741,14 +710,16 @@ Model::PopulatePackage(const PackageInfoRef& package, uint32 flags)
}
if ((flags & POPULATE_SCREEN_SHOTS) != 0) {
ScreenshotInfoList screenshotInfos;
std::vector<ScreenshotInfoRef> screenshotInfos;
{
BAutolock locker(&fLock);
screenshotInfos = package->ScreenshotInfos();
for (int32 i = 0; i < package->CountScreenshotInfos(); i++)
screenshotInfos.push_back(package->ScreenshotInfoAtIndex(i));
package->ClearScreenshots();
}
for (int i = 0; i < screenshotInfos.CountItems(); i++) {
const ScreenshotInfo& info = screenshotInfos.ItemAtFast(i);
std::vector<ScreenshotInfoRef>::iterator it;
for (it = screenshotInfos.begin(); it != screenshotInfos.end(); it++) {
const ScreenshotInfoRef& info = *it;
_PopulatePackageScreenshot(package, info, 320, false);
}
}
@ -942,7 +913,7 @@ Model::DumpExportPkgDataPath(BPath& path,
void
Model::_PopulatePackageScreenshot(const PackageInfoRef& package,
const ScreenshotInfo& info, int32 scaledWidth, bool fromCacheOnly)
const ScreenshotInfoRef& info, int32 scaledWidth, bool fromCacheOnly)
{
// See if there is a cached screenshot
BFile screenshotFile;
@ -957,7 +928,7 @@ Model::_PopulatePackageScreenshot(const PackageInfoRef& package,
}
bool fileExists = false;
BString screenshotName(info.Code());
BString screenshotName(info->Code());
screenshotName << "@" << scaledWidth;
screenshotName << ".png";
time_t modifiedTime;
@ -989,9 +960,9 @@ Model::_PopulatePackageScreenshot(const PackageInfoRef& package,
// Retrieve screenshot from web-app
BMallocIO buffer;
int32 scaledHeight = scaledWidth * info.Height() / info.Width();
int32 scaledHeight = scaledWidth * info->Height() / info->Width();
status_t status = fWebAppInterface.RetrieveScreenshot(info.Code(),
status_t status = fWebAppInterface.RetrieveScreenshot(info->Code(),
scaledWidth, scaledHeight, &buffer);
if (status == B_OK) {
BitmapRef bitmapRef(new(std::nothrow)SharedBitmap(buffer), true);
@ -1004,7 +975,7 @@ Model::_PopulatePackageScreenshot(const PackageInfoRef& package,
}
} else {
HDERROR("Failed to retrieve screenshot for code '%s' "
"at %" B_PRIi32 "x%" B_PRIi32 ".", info.Code().String(),
"at %" B_PRIi32 "x%" B_PRIi32 ".", info->Code().String(),
scaledWidth, scaledHeight);
}
}
@ -1016,8 +987,9 @@ Model::_PopulatePackageScreenshot(const PackageInfoRef& package,
void
Model::_NotifyAuthorizationChanged()
{
for (int32 i = fListeners.CountItems() - 1; i >= 0; i--) {
const ModelListenerRef& listener = fListeners.ItemAtFast(i);
std::vector<ModelListenerRef>::const_iterator it;
for (it = fListeners.begin(); it != fListeners.end(); it++) {
const ModelListenerRef& listener = *it;
if (listener.Get() != NULL)
listener->AuthorizationChanged();
}
@ -1027,8 +999,9 @@ Model::_NotifyAuthorizationChanged()
void
Model::_NotifyCategoryListChanged()
{
for (int32 i = fListeners.CountItems() - 1; i >= 0; i--) {
const ModelListenerRef& listener = fListeners.ItemAtFast(i);
std::vector<ModelListenerRef>::const_iterator it;
for (it = fListeners.begin(); it != fListeners.end(); it++) {
const ModelListenerRef& listener = *it;
if (listener.Get() != NULL)
listener->CategoryListChanged();
}

View File

@ -1,6 +1,6 @@
/*
* Copyright 2013-2014, Stephan Aßmus <superstippi@gmx.de>.
* Copyright 2016-2020, Andrew Lindesay <apl@lindesay.co.nz>.
* Copyright 2016-2021, Andrew Lindesay <apl@lindesay.co.nz>.
* All rights reserved. Distributed under the terms of the MIT License.
*/
#ifndef MODEL_H
@ -58,7 +58,6 @@ public:
typedef BReference<ModelListener> ModelListenerRef;
typedef List<ModelListenerRef, false> ModelListenerList;
class Model {
@ -74,7 +73,7 @@ public:
BLocker* Lock()
{ return &fLock; }
bool AddListener(const ModelListenerRef& listener);
void AddListener(const ModelListenerRef& listener);
PackageInfoRef PackageForName(const BString& name);
bool MatchesFilter(
@ -176,7 +175,7 @@ private:
void _PopulatePackageScreenshot(
const PackageInfoRef& package,
const ScreenshotInfo& info,
const ScreenshotInfoRef& info,
int32 scaledWidth, bool fromCacheOnly);
void _NotifyAuthorizationChanged();
@ -215,7 +214,8 @@ private:
fPackageIconRepository;
WebAppInterface fWebAppInterface;
ModelListenerList fListeners;
std::vector<ModelListenerRef>
fListeners;
};

View File

@ -1,7 +1,7 @@
/*
* Copyright 2013-2014, Stephan Aßmus <superstippi@gmx.de>.
* Copyright 2013, Rene Gollent <rene@gollent.com>.
* Copyright 2016-2020, Andrew Lindesay <apl@lindesay.co.nz>.
* Copyright 2016-2021, Andrew Lindesay <apl@lindesay.co.nz>.
* All rights reserved. Distributed under the terms of the MIT License.
*/
@ -792,22 +792,32 @@ PackageInfo::IsLocalFile() const
void
PackageInfo::ClearUserRatings()
{
if (!fUserRatings.IsEmpty()) {
fUserRatings.Clear();
if (!fUserRatings.empty()) {
fUserRatings.clear();
_NotifyListeners(PKG_CHANGED_RATINGS);
}
}
bool
PackageInfo::AddUserRating(const UserRating& rating)
int32
PackageInfo::CountUserRatings() const
{
if (!fUserRatings.Add(rating))
return false;
return fUserRatings.size();
}
UserRatingRef
PackageInfo::UserRatingAtIndex(int32 index) const
{
return fUserRatings[index];
}
void
PackageInfo::AddUserRating(const UserRatingRef& rating)
{
fUserRatings.push_back(rating);
_NotifyListeners(PKG_CHANGED_RATINGS);
return true;
}
@ -826,11 +836,11 @@ PackageInfo::SetRatingSummary(const RatingSummary& summary)
RatingSummary
PackageInfo::CalculateRatingSummary() const
{
if (fUserRatings.CountItems() == 0)
if (fUserRatings.empty())
return fCachedRatingSummary;
RatingSummary summary;
summary.ratingCount = fUserRatings.CountItems();
summary.ratingCount = fUserRatings.size();
summary.averageRating = 0.0f;
int starRatingCount = sizeof(summary.ratingCountByStar) / sizeof(int);
for (int i = 0; i < starRatingCount; i++)
@ -843,7 +853,7 @@ PackageInfo::CalculateRatingSummary() const
int ratingsSpecified = summary.ratingCount;
for (int i = 0; i < summary.ratingCount; i++) {
float rating = fUserRatings.ItemAtFast(i).Rating();
float rating = fUserRatings[i]->Rating();
if (rating < 0.0f)
rating = -1.0f;
@ -897,14 +907,28 @@ PackageInfo::IsProminent() const
void
PackageInfo::ClearScreenshotInfos()
{
fScreenshotInfos.Clear();
fScreenshotInfos.clear();
}
bool
PackageInfo::AddScreenshotInfo(const ScreenshotInfo& info)
int32
PackageInfo::CountScreenshotInfos() const
{
return fScreenshotInfos.Add(info);
return fScreenshotInfos.size();
}
ScreenshotInfoRef
PackageInfo::ScreenshotInfoAtIndex(int32 index) const
{
return fScreenshotInfos[index];
}
void
PackageInfo::AddScreenshotInfo(const ScreenshotInfoRef& info)
{
fScreenshotInfos.push_back(info);
}
@ -977,14 +1001,15 @@ PackageInfo::SetDepotName(const BString& depotName)
bool
PackageInfo::AddListener(const PackageInfoListenerRef& listener)
{
return fListeners.Add(listener);
fListeners.push_back(listener);
return true;
}
void
PackageInfo::RemoveListener(const PackageInfoListenerRef& listener)
{
fListeners.Remove(listener);
std::remove(fListeners.begin(), fListeners.end(), listener);
}
@ -1026,21 +1051,23 @@ PackageInfo::_NotifyListeners(uint32 changes)
void
PackageInfo::_NotifyListenersImmediate(uint32 changes)
{
int count = fListeners.CountItems();
int count = fListeners.size();
if (count == 0)
return;
// Clone list to avoid listeners detaching themselves in notifications
// to screw up the list while iterating it.
PackageListenerList listeners(fListeners);
std::vector<PackageInfoListenerRef> listeners(fListeners);
// Check if it worked:
if (listeners.CountItems() != count)
if (listeners.size() != count)
return;
PackageInfoEvent event(PackageInfoRef(this), changes);
for (int i = 0; i < count; i++) {
const PackageInfoListenerRef& listener = listeners.ItemAtFast(i);
std::vector<PackageInfoListenerRef>::iterator it;
for (it = listeners.begin(); it != listeners.end(); it++) {
const PackageInfoListenerRef listener = *it;
if (listener.Get() != NULL)
listener->PackageChanged(event);
}

View File

@ -1,6 +1,6 @@
/*
* Copyright 2013-2014, Stephan Aßmus <superstippi@gmx.de>.
* Copyright 2016-2020, Andrew Lindesay <apl@lindesay.co.nz>.
* Copyright 2016-2021, Andrew Lindesay <apl@lindesay.co.nz>.
* All rights reserved. Distributed under the terms of the MIT License.
*/
#ifndef PACKAGE_INFO_H
@ -64,7 +64,7 @@ private:
};
class UserRating {
class UserRating : public BReferenceable {
public:
UserRating();
UserRating(const UserInfo& userInfo,
@ -102,7 +102,7 @@ private:
};
typedef List<UserRating, false> UserRatingList;
typedef BReference<UserRating> UserRatingRef;
class RatingSummary {
@ -183,7 +183,7 @@ extern bool IsPackageCategoryBefore(const CategoryRef& c1,
const CategoryRef& c2);
class ScreenshotInfo {
class ScreenshotInfo : public BReferenceable {
public:
ScreenshotInfo();
ScreenshotInfo(const BString& code,
@ -211,10 +211,9 @@ private:
};
typedef List<ScreenshotInfo, false, 2> ScreenshotInfoList;
typedef BReference<ScreenshotInfo> ScreenshotInfoRef;
typedef List<PackageInfoListenerRef, false, 2> PackageListenerList;
typedef std::set<int32> PackageInstallationLocationSet;
@ -309,9 +308,9 @@ public:
CategoryRef CategoryAtIndex(int32 index) const;
void ClearUserRatings();
bool AddUserRating(const UserRating& rating);
const UserRatingList& UserRatings() const
{ return fUserRatings; }
void AddUserRating(const UserRatingRef& rating);
int32 CountUserRatings() const;
UserRatingRef UserRatingAtIndex(int32 index) const;
void SetRatingSummary(const RatingSummary& summary);
RatingSummary CalculateRatingSummary() const;
@ -323,9 +322,10 @@ public:
bool IsProminent() const;
void ClearScreenshotInfos();
bool AddScreenshotInfo(const ScreenshotInfo& info);
const ScreenshotInfoList& ScreenshotInfos() const
{ return fScreenshotInfos; }
void AddScreenshotInfo(
const ScreenshotInfoRef& info);
int32 CountScreenshotInfos() const;
ScreenshotInfoRef ScreenshotInfoAtIndex(int32 index) const;
void ClearScreenshots();
bool AddScreenshot(const BitmapRef& screenshot);
@ -366,17 +366,20 @@ private:
BString fChangelog;
std::vector<CategoryRef>
fCategories;
UserRatingList fUserRatings;
std::vector<UserRatingRef>
fUserRatings;
RatingSummary fCachedRatingSummary;
int64 fProminence;
ScreenshotInfoList fScreenshotInfos;
std::vector<ScreenshotInfoRef>
fScreenshotInfos;
std::vector<BitmapRef>
fScreenshots;
PackageState fState;
PackageInstallationLocationSet
fInstallationLocations;
float fDownloadProgress;
PackageListenerList fListeners;
std::vector<PackageInfoListenerRef>
fListeners;
int32 fFlags;
bool fSystemDependency;
BString fArchitecture;

View File

@ -331,22 +331,23 @@ private:
// #pragma mark - OpenPackageAction
struct DeskbarLink {
class DeskbarLink {
public:
DeskbarLink()
{
}
DeskbarLink(const BString& path, const BString& link)
:
path(path),
link(link)
fPath(path),
fLink(link)
{
}
DeskbarLink(const DeskbarLink& other)
:
path(other.path),
link(other.link)
fPath(other.fPath),
fLink(other.fLink)
{
}
@ -354,14 +355,24 @@ struct DeskbarLink {
{
if (this == &other)
return *this;
path = other.path;
link = other.link;
fPath = other.Path();
fLink = other.Link();
return *this;
}
const BString Path() const
{
return fPath;
}
const BString Link() const
{
return fLink;
}
bool operator==(const DeskbarLink& other)
{
return path == other.path && link == other.link;
return fPath == other.fPath && fLink == other.fLink;
}
bool operator!=(const DeskbarLink& other)
@ -369,17 +380,18 @@ struct DeskbarLink {
return !(*this == other);
}
BString path;
BString link;
private:
BString fPath;
BString fLink;
};
typedef List<DeskbarLink, false> DeskbarLinkList;
typedef BReference<DeskbarLink> DeskbarLinkRef;
class DeskbarLinkFinder : public BPackageContentHandler {
public:
DeskbarLinkFinder(DeskbarLinkList& foundLinks)
DeskbarLinkFinder(std::vector<DeskbarLink>& foundLinks)
:
fDeskbarLinks(foundLinks)
{
@ -392,7 +404,7 @@ public:
&& entry->SymlinkPath() != NULL) {
HDINFO("found deskbar entry: %s -> %s",
path.String(), entry->SymlinkPath());
fDeskbarLinks.Add(DeskbarLink(path, entry->SymlinkPath()));
fDeskbarLinks.push_back(DeskbarLink(path, entry->SymlinkPath()));
}
return B_OK;
}
@ -431,7 +443,7 @@ public:
}
private:
DeskbarLinkList& fDeskbarLinks;
std::vector<DeskbarLink> fDeskbarLinks;
};
@ -444,7 +456,7 @@ public:
fDeskbarLink(link),
fLabel(B_TRANSLATE("Open %DeskbarLink%"))
{
BString target = fDeskbarLink.link;
BString target = fDeskbarLink.Link();
int32 lastPathSeparator = target.FindLast('/');
if (lastPathSeparator > 0 && lastPathSeparator + 1 < target.Length())
target.Remove(0, lastPathSeparator + 1);
@ -461,8 +473,8 @@ public:
{
status_t status;
BPath path;
if (fDeskbarLink.link.FindFirst('/') == 0) {
status = path.SetTo(fDeskbarLink.link);
if (fDeskbarLink.Link().FindFirst('/') == 0) {
status = path.SetTo(fDeskbarLink.Link());
HDINFO("trying to launch (absolute link): %s", path.Path());
} else {
int32 location = InstallLocation();
@ -478,11 +490,11 @@ public:
return B_ERROR;
}
status = path.Append(fDeskbarLink.path);
status = path.Append(fDeskbarLink.Path());
if (status == B_OK)
status = path.GetParent(&path);
if (status == B_OK) {
status = path.Append(fDeskbarLink.link, true);
status = path.Append(fDeskbarLink.Link(), true);
HDINFO("trying to launch: %s", path.Path());
}
}
@ -498,7 +510,7 @@ public:
}
static bool FindAppToLaunch(const PackageInfoRef& package,
DeskbarLinkList& foundLinks)
std::vector<DeskbarLink>& foundLinks)
{
if (package.Get() == NULL)
return false;
@ -545,7 +557,7 @@ public:
return false;
}
return foundLinks.CountItems() > 0;
return !foundLinks.empty();
}
private:
@ -585,36 +597,50 @@ PackageManager::GetPackageState(const PackageInfo& package)
}
PackageActionList
PackageManager::GetPackageActions(PackageInfoRef package, Model* model)
void
PackageManager::GetPackageActions(PackageInfoRef package, Model* model,
Collector<PackageActionRef>& actionList)
{
PackageActionList actionList;
if (package->IsSystemPackage() || package->IsSystemDependency())
return actionList;
return;
int32 state = package->State();
if (state == ACTIVATED || state == INSTALLED) {
actionList.Add(PackageActionRef(new UninstallPackageAction(
package, model), true));
// Add OpenPackageActions for each deskbar link found in the
// package
DeskbarLinkList foundLinks;
if (OpenPackageAction::FindAppToLaunch(package, foundLinks)
&& foundLinks.CountItems() < 4) {
for (int32 i = 0; i < foundLinks.CountItems(); i++) {
const DeskbarLink& link = foundLinks.ItemAtFast(i);
actionList.Add(PackageActionRef(new OpenPackageAction(
package, model, link), true));
}
}
} else if (state == NONE || state == UNINSTALLED) {
actionList.Add(PackageActionRef(new InstallPackageAction(package,
model), true));
switch (package->State()) {
case ACTIVATED:
case INSTALLED:
_GatherPackageActionsForActivatedOrInstalled(
package, model, actionList);
break;
case NONE:
case UNINSTALLED:
actionList.Add(PackageActionRef(
new InstallPackageAction(package, model), true));
break;
default:
break;
}
// TODO: activation status
}
return actionList;
void
PackageManager::_GatherPackageActionsForActivatedOrInstalled(
PackageInfoRef package, Model* model,
Collector<PackageActionRef>& actionList)
{
actionList.Add(PackageActionRef(new UninstallPackageAction(
package, model), true));
// Add OpenPackageActions for each deskbar link found in the
// package
std::vector<DeskbarLink> foundLinks;
if (OpenPackageAction::FindAppToLaunch(package, foundLinks)
&& foundLinks.size() < 4) {
std::vector<DeskbarLink>::const_iterator it;
for (it = foundLinks.begin(); it != foundLinks.end(); it++) {
const DeskbarLink& aLink = *it;
actionList.Add(PackageActionRef(new OpenPackageAction(
package, model, aLink), true));
}
}
}

View File

@ -14,6 +14,7 @@
#include <package/DaemonClient.h>
#include <package/manager/PackageManager.h>
#include "Collector.h"
#include "DecisionProvider.h"
#include "JobStateListener.h"
#include "PackageAction.h"
@ -72,8 +73,9 @@ public:
virtual ~PackageManager();
virtual PackageState GetPackageState(const PackageInfo& package);
virtual PackageActionList GetPackageActions(PackageInfoRef package,
Model* model);
virtual void GetPackageActions(PackageInfoRef package,
Model* model,
Collector<PackageActionRef>& actionList);
void SetCurrentActionPackage(
PackageInfoRef package,
@ -120,6 +122,9 @@ private:
InstalledRepository& repository);
private:
void _GatherPackageActionsForActivatedOrInstalled(
PackageInfoRef package, Model* model,
Collector<PackageActionRef>& actionList);
bool _AddResults(
BPackageManager::InstalledRepository&
repository,

View File

@ -143,12 +143,12 @@ PackageFillingPkgListener::ConsumePackage(const PackageInfoRef& package,
for (i = 0; i < countPkgScreenshots; i++) {
DumpExportPkgScreenshot* screenshot = pkg->PkgScreenshotsItemAt(i);
package->AddScreenshotInfo(ScreenshotInfo(
package->AddScreenshotInfo(ScreenshotInfoRef(new ScreenshotInfo(
*(screenshot->Code()),
static_cast<int32>(screenshot->Width()),
static_cast<int32>(screenshot->Height()),
static_cast<int32>(screenshot->Length())
));
), true));
}
HDDEBUG("did populate data for [%s] (%s)", pkg->Name()->String(),

View File

@ -525,50 +525,20 @@ public:
// TODO: if the given package is either a system package
// or a system dependency, show a message indicating that status
// so the user knows why no actions are presented
PackageActionList actions = manager.GetPackageActions(
std::vector<PackageActionRef> actions;
VectorCollector<PackageActionRef> actionsCollector(actions);
manager.GetPackageActions(
const_cast<PackageInfo*>(&package),
fPackageActionHandler->GetModel());
bool clearNeeded = fStatusBar != NULL;
if (!clearNeeded) {
if (actions.CountItems() != fPackageActions.CountItems())
clearNeeded = true;
else {
for (int32 i = 0; i < actions.CountItems(); i++) {
if (actions.ItemAtFast(i)->Type()
!= fPackageActions.ItemAtFast(i)->Type()) {
clearNeeded = true;
break;
}
}
}
}
fPackageActionHandler->GetModel(), actionsCollector);
bool clearNeeded = _IsClearNeededToAdoptActions(actions);
fPackageActions = actions;
if (!clearNeeded && fButtons.CountItems() == actions.CountItems()) {
int32 index = 0;
for (int32 i = fPackageActions.CountItems() - 1; i >= 0; i--) {
const PackageActionRef& action = fPackageActions.ItemAtFast(i);
BButton* button = (BButton*)fButtons.ItemAtFast(index++);
button->SetLabel(action->Label());
}
return;
}
Clear();
// Add Buttons in reverse action order
for (int32 i = fPackageActions.CountItems() - 1; i >= 0; i--) {
const PackageActionRef& action = fPackageActions.ItemAtFast(i);
BMessage* message = new BMessage(MSG_PACKAGE_ACTION);
message->AddInt32("index", i);
BButton* button = new BButton(action->Label(), message);
fLayout->AddView(button);
button->SetTarget(this);
fButtons.AddItem(button);
if (clearNeeded) {
Clear();
_CreateAllNewButtonsForAdoptActions();
} else {
_UpdateExistingButtonsForAdoptActions();
}
}
@ -615,13 +585,56 @@ public:
}
private:
bool _IsClearNeededToAdoptActions(std::vector<PackageActionRef> actions)
{
if (fStatusBar != NULL)
return true;
if (actions.size() != fPackageActions.size())
return true;
if (fButtons.CountItems() != actions.size())
return true;
for (int i = 0; (i < actions.size()); i++) {
if (actions[i]->Type() != fPackageActions[i]->Type())
return true;
}
return false;
}
void _UpdateExistingButtonsForAdoptActions()
{
// note that by this point, the actions will have been set to the
// member variable.
int32 index = 0;
for (int32 i = fPackageActions.size() - 1; i >= 0; i--) {
const PackageActionRef& action = fPackageActions[i];
BButton* button = (BButton*)fButtons.ItemAtFast(index++);
button->SetLabel(action->Label());
}
}
void _CreateAllNewButtonsForAdoptActions()
{
for (int32 i = fPackageActions.size() - 1; i >= 0; i--) {
const PackageActionRef& action = fPackageActions[i];
BMessage* message = new BMessage(MSG_PACKAGE_ACTION);
message->AddInt32("index", i);
BButton* button = new BButton(action->Label(), message);
fLayout->AddView(button);
button->SetTarget(this);
fButtons.AddItem(button);
}
}
void _RunPackageAction(BMessage* message)
{
int32 index;
if (message->FindInt32("index", &index) != B_OK)
return;
const PackageActionRef& action = fPackageActions.ItemAt(index);
const PackageActionRef& action = fPackageActions[index];
if (action.Get() == NULL)
return;
@ -670,8 +683,10 @@ private:
private:
BGroupLayout* fLayout;
PackageActionList fPackageActions;
PackageActionHandler* fPackageActionHandler;
std::vector<PackageActionRef>
fPackageActions;
PackageActionHandler*
fPackageActionHandler;
BList fButtons;
BStringView* fStatusLabel;
@ -889,7 +904,7 @@ private:
class RatingItemView : public BGroupView {
public:
RatingItemView(const UserRating& rating)
RatingItemView(const UserRatingRef rating)
:
BGroupView(B_HORIZONTAL, 0.0f)
{
@ -900,7 +915,7 @@ public:
{
BStringView* userNicknameView = new BStringView("user-nickname",
rating.User().NickName());
rating->User().NickName());
userNicknameView->SetFont(be_bold_font);
verticalGroup->AddView(userNicknameView);
}
@ -909,23 +924,23 @@ public:
new BGroupLayout(B_HORIZONTAL, B_USE_DEFAULT_SPACING);
verticalGroup->AddItem(ratingGroup);
if (rating.Rating() >= 0) {
if (rating->Rating() >= 0) {
RatingView* ratingView = new RatingView("package rating view");
ratingView->SetRating(rating.Rating());
ratingView->SetRating(rating->Rating());
ratingGroup->AddView(ratingView);
}
{
BString createTimestampPresentation =
LocaleUtils::TimestampToDateTimeString(
rating.CreateTimestamp());
rating->CreateTimestamp());
BString ratingContextDescription(
B_TRANSLATE("%hd.timestamp% (version %hd.version%)"));
ratingContextDescription.ReplaceAll("%hd.timestamp%",
createTimestampPresentation);
ratingContextDescription.ReplaceAll("%hd.version%",
rating.PackageVersion());
rating->PackageVersion());
BStringView* ratingContextView = new BStringView("rating-context",
ratingContextDescription);
@ -936,12 +951,12 @@ public:
ratingGroup->AddItem(BSpaceLayoutItem::CreateGlue());
if (rating.Comment() > 0) {
if (rating->Comment() > 0) {
TextView* textView = new TextView("rating-text");
ParagraphStyle paragraphStyle(textView->ParagraphStyle());
paragraphStyle.SetJustify(true);
textView->SetParagraphStyle(paragraphStyle);
textView->SetText(rating.Comment());
textView->SetText(rating->Comment());
verticalGroup->AddItem(BSpaceLayoutItem::CreateVerticalStrut(8.0f));
verticalGroup->AddView(textView);
verticalGroup->AddItem(BSpaceLayoutItem::CreateVerticalStrut(8.0f));
@ -1078,9 +1093,7 @@ public:
// TODO: Re-use rating summary already used for TitleView...
fRatingSummaryView->SetToSummary(package.CalculateRatingSummary());
const UserRatingList& userRatings = package.UserRatings();
int count = userRatings.CountItems();
int count = package.CountUserRatings();
if (count == 0) {
BStringView* noRatingsView = new BStringView("no ratings",
B_TRANSLATE("No user ratings available."));
@ -1094,9 +1107,8 @@ public:
return;
}
// TODO: Sort by age or usefullness rating
for (int i = count - 1; i >= 0; i--) {
const UserRating& rating = userRatings.ItemAtFast(i);
UserRatingRef rating = package.UserRatingAtIndex(i);
// was previously filtering comments just for the current
// user's language, but as there are not so many comments at
// the moment, just show all of them for now.

View File

@ -1,7 +1,7 @@
/*
* Copyright 2014, Stephan Aßmus <superstippi@gmx.de>.
* Copyright 2017, Julian Harnath <julian.harnath@rwth-aachen.de>.
* Copyright 2020, Andrew Lindesay <apl@lindesay.co.nz>.
* Copyright 2020-2021, Andrew Lindesay <apl@lindesay.co.nz>.
* All rights reserved. Distributed under the terms of the MIT License.
*/
@ -254,6 +254,8 @@ ScreenshotWindow::_DownloadThreadEntry(void* data)
void
ScreenshotWindow::_DownloadThread()
{
ScreenshotInfoRef info;
if (!Lock()) {
HDERROR("failed to lock screenshot window");
return;
@ -261,23 +263,24 @@ ScreenshotWindow::_DownloadThread()
fScreenshotView->UnsetBitmap();
ScreenshotInfoList screenshotInfos;
if (fPackage.Get() != NULL)
screenshotInfos = fPackage->ScreenshotInfos();
if (fPackage.Get() == NULL)
HDINFO("package not set");
else {
if (fPackage->CountScreenshotInfos() == 0)
HDINFO("package has no screenshots");
else {
int32 index = atomic_get(&fCurrentScreenshotIndex);
info = fPackage->ScreenshotInfoAtIndex(index);
}
}
Unlock();
if (screenshotInfos.CountItems() == 0) {
HDINFO("package has no screenshots");
if (info.Get() == NULL) {
HDINFO("screenshot not set");
return;
}
// Obtain the correct code for the screenshot to display
// TODO: Once navigation buttons are added, we could use the
// ScreenshotInfo at the "current" index.
const ScreenshotInfo& info = screenshotInfos.ItemAtFast(
atomic_get(&fCurrentScreenshotIndex));
BMallocIO buffer;
WebAppInterface interface;
@ -288,8 +291,8 @@ ScreenshotWindow::_DownloadThread()
kProgressIndicatorDelay, 1);
// Retrieve screenshot from web-app
status_t status = interface.RetrieveScreenshot(info.Code(),
info.Width(), info.Height(), &buffer);
status_t status = interface.RetrieveScreenshot(info->Code(),
info->Width(), info->Height(), &buffer);
delayedMessenger.SetCount(0);
messenger.SendMessage(MSG_DOWNLOAD_STOP);
@ -305,28 +308,35 @@ ScreenshotWindow::_DownloadThread()
}
BSize
ScreenshotWindow::_MaxWidthAndHeightOfAllScreenshots()
{
BSize size(0, 0);
// Find out dimensions of the largest screenshot of this package
if (fPackage.Get() != NULL) {
int count = fPackage->CountScreenshotInfos();
for(int32 i = 0; i < count; i++) {
const ScreenshotInfoRef& info = fPackage->ScreenshotInfoAtIndex(i);
if (info.Get() != NULL) {
float w = (float) info->Width();
float h = (float) info->Height();
if (w > size.Width())
size.SetWidth(w);
if (h > size.Height())
size.SetHeight(h);
}
}
}
return size;
}
void
ScreenshotWindow::_ResizeToFitAndCenter()
{
// Find out dimensions of the largest screenshot of this package
ScreenshotInfoList screenshotInfos;
if (fPackage.Get() != NULL)
screenshotInfos = fPackage->ScreenshotInfos();
int32 largestScreenshotWidth = 0;
int32 largestScreenshotHeight = 0;
const uint32 numScreenshots = fPackage->ScreenshotInfos().CountItems();
for (uint32 i = 0; i < numScreenshots; i++) {
const ScreenshotInfo& info = screenshotInfos.ItemAtFast(i);
if (info.Width() > largestScreenshotWidth)
largestScreenshotWidth = info.Width();
if (info.Height() > largestScreenshotHeight)
largestScreenshotHeight = info.Height();
}
fScreenshotView->SetExplicitMinSize(
BSize(largestScreenshotWidth, largestScreenshotHeight));
fScreenshotView->SetExplicitMinSize(_MaxWidthAndHeightOfAllScreenshots());
Layout(false);
// TODO: Limit window size to screen size (with a little margin),
@ -343,7 +353,7 @@ ScreenshotWindow::_ResizeToFitAndCenter()
void
ScreenshotWindow::_UpdateToolBar()
{
const int32 numScreenshots = fPackage->ScreenshotInfos().CountItems();
const int32 numScreenshots = fPackage->CountScreenshotInfos();
const int32 currentIndex = atomic_get(&fCurrentScreenshotIndex);
fToolBar->SetActionEnabled(MSG_PREVIOUS_SCREENSHOT,

View File

@ -1,5 +1,6 @@
/*
* Copyright 2014, Stephan Aßmus <superstippi@gmx.de>.
* Copyright 2021, Andrew Lindesay <apl@lindesay.co.nz>.
* All rights reserved. Distributed under the terms of the MIT License.
*/
#ifndef SCREENSHOT_WINDOW_H
@ -51,6 +52,7 @@ private:
static int32 _DownloadThreadEntry(void* data);
void _DownloadThread();
BSize _MaxWidthAndHeightOfAllScreenshots();
void _ResizeToFitAndCenter();
void _UpdateToolBar();

View File

@ -0,0 +1,37 @@
/*
* Copyright 2021, Andrew Lindesay <apl@lindesay.co.nz>
* All rights reserved. Distributed under the terms of the MIT License.
*/
#ifndef COLLECTOR_H
#define COLLECTOR_H
#include <vector>
template <typename T>
class Collector {
public:
virtual void Add(T value) = 0;
};
template <typename T>
class VectorCollector : public Collector<T> {
public:
VectorCollector(std::vector<T>& target)
:
fTarget(target)
{
}
virtual void Add(T value) {
fTarget.push_back(value);
}
private:
std::vector<T>& fTarget;
};
#endif // COLLECTOR_H