HaikuDepot: Miscellanous improvements to package state tracking.

- MainWindow now listens for package installation state changes so
  it can keep Model's package location lists in sync.
- PackageListView now updates its status column on package state changes.
- PackageInfoView now updates the available action list when package
  installation state changes.
- PackageManager populates the expected user-specified install/uninstall
  package sets for ProblemWindow so that one can properly filter those out.

There still remain some issues with the installed locations for ResultWindow
not being entirely correct though, which causes issues for package
uninstallation.
This commit is contained in:
Rene Gollent
2013-09-21 14:27:12 -04:00
parent fdcd014b1d
commit e550d7b8c5
6 changed files with 193 additions and 66 deletions
+28 -1
View File
@@ -43,7 +43,8 @@
enum {
MSG_MODEL_WORKER_DONE = 'mmwd',
MSG_REFRESH_DEPOTS = 'mrdp'
MSG_REFRESH_DEPOTS = 'mrdp',
MSG_PACKAGE_STATE_CHANGED = 'mpsc'
};
@@ -197,6 +198,16 @@ MainWindow::MessageReceived(BMessage* message)
searchTerms = "";
fModel.SetSearchTerms(searchTerms);
_AdoptModel();
break;
}
case MSG_PACKAGE_STATE_CHANGED:
{
PackageInfo* info;
if (message->FindPointer("package", (void **)&info) == B_OK) {
PackageInfoRef ref(info, true);
fModel.SetPackageState(ref, ref->State());
}
}
default:
@@ -206,6 +217,20 @@ MainWindow::MessageReceived(BMessage* message)
}
void
MainWindow::PackageChanged(const PackageInfoEvent& event)
{
if ((event.Changes() & PKG_CHANGED_STATE) != 0) {
PackageInfoRef ref(event.Package());
BMessage message(MSG_PACKAGE_STATE_CHANGED);
message.AddPointer("package", ref.Get());
ref.Detach();
// reference needs to be released by MessageReceived();
PostMessage(&message);
}
}
void
MainWindow::_BuildMenu(BMenuBar* menuBar)
{
@@ -367,6 +392,8 @@ MainWindow::_RefreshPackageList()
foundPackages[repoPackageInfo.Name()] = modelInfo;
}
modelInfo->AddListener(this);
BSolverRepository* repository = package->Repository();
if (dynamic_cast<BPackageManager::RemoteRepository*>(repository)
!= NULL) {
+8 -1
View File
@@ -1,5 +1,6 @@
/*
* Copyright 2013, Stephan Aßmus <[email protected]>.
* Copyright 2013, Rene Gollent <[email protected]>.
* All rights reserved. Distributed under the terms of the MIT License.
*/
#ifndef MAIN_WINDOW_H
@@ -8,6 +9,7 @@
#include <Window.h>
#include "Model.h"
#include "PackageInfoListener.h"
#include "PackageManager.h"
@@ -22,7 +24,7 @@ enum {
};
class MainWindow : public BWindow {
class MainWindow : public BWindow, private PackageInfoListener {
public:
MainWindow(BRect frame);
virtual ~MainWindow();
@@ -31,6 +33,11 @@ public:
virtual bool QuitRequested();
virtual void MessageReceived(BMessage* message);
private:
// PackageInfoListener
virtual void PackageChanged(
const PackageInfoEvent& event);
private:
void _BuildMenu(BMenuBar* menuBar);
void _AdoptModel();
+7 -3
View File
@@ -521,7 +521,7 @@ public:
if (result != B_OK) {
fprintf(stderr, "Failed to schedule action: "
"%s '%s'\n", action->Label(),
action->Package().Title().String());
action->Package()->Title().String());
}
}
}
@@ -538,7 +538,8 @@ public:
{
Clear();
fPackageActions = fPackageManager->GetPackageActions(package);
fPackageActions = fPackageManager->GetPackageActions(
const_cast<PackageInfo*>(&package));
// Add Buttons in reverse action order
for (int32 i = fPackageActions.CountItems() - 1; i >= 0; i--) {
@@ -1280,8 +1281,11 @@ PackageInfoView::MessageReceived(BMessage* message)
fTitleView->SetPackage(package);
}
if ((changes & PKG_CHANGED_RATINGS) != 0) {
if ((changes & PKG_CHANGED_RATINGS) != 0)
fPagesView->SetPackage(package);
if ((changes & PKG_CHANGED_STATE) != 0) {
fPackageActionView->SetPackage(package);
}
break;
+18 -10
View File
@@ -112,6 +112,7 @@ public:
const PackageInfoRef& Package() const
{ return fPackage; }
void UpdateState();
void UpdateRating();
private:
@@ -139,9 +140,6 @@ public:
virtual void PackageChanged(const PackageInfoEvent& event)
{
if ((event.Changes() & PKG_CHANGED_RATINGS) == 0)
return;
BMessenger messenger(fView);
if (!messenger.IsValid())
return;
@@ -489,6 +487,17 @@ PackageRow::~PackageRow()
}
void
PackageRow::UpdateState()
{
if (fPackage.Get() == NULL)
return;
BStringField* field = (BStringField*)GetField(kStatusColumn);
field->SetString(package_state_to_string(fPackage->State()));
}
void
PackageRow::UpdateRating()
{
@@ -634,15 +643,14 @@ PackageListView::MessageReceived(BMessage* message)
break;
}
if ((changes & PKG_CHANGED_RATINGS) == 0)
break;
BAutolock _(fModelLock);
PackageRow* row = _FindRow(title);
if (row != NULL)
row->UpdateRating();
if (row != NULL) {
if ((changes & PKG_CHANGED_RATINGS) != 0)
row->UpdateRating();
if ((changes & PKG_CHANGED_STATE) != 0)
row->UpdateState();
}
break;
}
+110 -47
View File
@@ -24,6 +24,7 @@
#include "AutoDeleter.h"
#include "AutoLocker.h"
#include "PackageInfo.h"
#include "ProblemWindow.h"
#include "ResultWindow.h"
@@ -44,7 +45,7 @@ using BPackageKit::BSolverRepository;
// #pragma mark - PackageAction
PackageAction::PackageAction(const PackageInfo& package,
PackageAction::PackageAction(PackageInfoRef package,
PackageManager* manager)
:
fPackageManager(manager),
@@ -63,7 +64,7 @@ PackageAction::~PackageAction()
class InstallPackageAction : public PackageAction {
public:
InstallPackageAction(const PackageInfo& package, PackageManager* manager)
InstallPackageAction(PackageInfoRef package, PackageManager* manager)
:
PackageAction(package, manager)
{
@@ -76,7 +77,9 @@ public:
virtual status_t Perform()
{
const char* packageName = Package().Title().String();
PackageInfoRef ref(Package());
fPackageManager->SetCurrentActionPackage(ref, true);
const char* packageName = ref->Title().String();
try {
fPackageManager->Install(&packageName, 1);
} catch (BFatalErrorException ex) {
@@ -84,11 +87,17 @@ public:
"%s: %s (%s)\n", packageName, ex.Message().String(),
ex.Details().String());
return ex.Error();
} catch (BAbortedByUserException ex) {
return B_OK;
} catch (BNothingToDoException ex) {
} catch (BException ex) {
fprintf(stderr, "Exception occurred while installing package "
"%s: %s\n", packageName, ex.Message().String());
return B_ERROR;;
}
ref->SetState(ACTIVATED);
return B_OK;
}
};
@@ -99,7 +108,7 @@ public:
class UninstallPackageAction : public PackageAction {
public:
UninstallPackageAction(const PackageInfo& package, PackageManager* manager)
UninstallPackageAction(PackageInfoRef package, PackageManager* manager)
:
PackageAction(package, manager)
{
@@ -112,7 +121,9 @@ public:
virtual status_t Perform()
{
const char* packageName = Package().Title().String();
PackageInfoRef ref(Package());
fPackageManager->SetCurrentActionPackage(ref, false);
const char* packageName = ref->Title().String();
try {
fPackageManager->Uninstall(&packageName, 1);
} catch (BFatalErrorException ex) {
@@ -120,11 +131,15 @@ public:
"%s: %s (%s)\n", packageName, ex.Message().String(),
ex.Details().String());
return ex.Error();
} catch (BException ex) {
} catch (BAbortedByUserException ex) {
} catch (BNothingToDoException ex) {
fprintf(stderr, "Exception occurred while uninstalling package "
"%s: %s\n", packageName, ex.Message().String());
return B_ERROR;
}
ref->SetState(NONE);
return B_OK;
}
};
@@ -141,7 +156,9 @@ PackageManager::PackageManager(BPackageInstallationLocation location)
fJobStateListener(),
fContext(fDecisionProvider, fJobStateListener),
fClientInstallationInterface(),
fProblemWindow(NULL)
fProblemWindow(NULL),
fCurrentInstallPackage(NULL),
fCurrentUninstallPackage(NULL)
{
fInstallationInterface = &fClientInstallationInterface;
fRequestHandler = this;
@@ -178,47 +195,40 @@ PackageManager::GetPackageState(const PackageInfo& package)
PackageActionList
PackageManager::GetPackageActions(const PackageInfo& package)
PackageManager::GetPackageActions(PackageInfoRef package)
{
PackageActionList actionList;
BObjectList<BSolverPackage> packages;
status_t result = Solver()->FindPackages(package.Title(),
BSolver::B_FIND_IN_NAME, packages);
if (result == B_OK) {
bool installed = false;
bool systemPackage = false;
for (int32 i = 0; i < packages.CountItems(); i++) {
const BSolverPackage* solverPackage = packages.ItemAt(i);
if (solverPackage->Name() != package.Title())
continue;
bool installed = false;
bool systemPackage = false;
BSolverPackage* solverPackage = _GetSolverPackage(package);
if (solverPackage == NULL)
return actionList;
const BSolverRepository* repository = solverPackage->Repository();
if (repository == static_cast<const BSolverRepository*>(
SystemRepository())) {
installed = true;
systemPackage = true;
} else if (repository == static_cast<const BSolverRepository*>(
CommonRepository())) {
installed = true;
} else if (repository == static_cast<const BSolverRepository*>(
HomeRepository())) {
installed = true;
}
}
if (installed) {
if (!systemPackage) {
actionList.Add(PackageActionRef(new UninstallPackageAction(
package, this), true));
}
} else {
actionList.Add(PackageActionRef(new InstallPackageAction(package,
this), true));
}
// TODO: activation status
const BSolverRepository* repository = solverPackage->Repository();
if (repository == static_cast<const BSolverRepository*>(
SystemRepository())) {
installed = true;
systemPackage = true;
} else if (repository == static_cast<const BSolverRepository*>(
CommonRepository())) {
installed = true;
} else if (repository == static_cast<const BSolverRepository*>(
HomeRepository())) {
installed = true;
}
if (installed) {
if (!systemPackage) {
actionList.Add(PackageActionRef(new UninstallPackageAction(
package, this), true));
}
} else {
actionList.Add(PackageActionRef(new InstallPackageAction(package,
this), true));
}
// TODO: activation status
return actionList;
}
@@ -237,6 +247,27 @@ PackageManager::SchedulePackageActions(PackageActionList& list)
}
void
PackageManager::SetCurrentActionPackage(PackageInfoRef package, bool install)
{
BSolverPackage* solverPackage = _GetSolverPackage(package);
if (solverPackage == NULL)
ClearCurrentActionPackage();
else {
fCurrentInstallPackage = install ? solverPackage : NULL;
fCurrentUninstallPackage = install ? NULL : solverPackage;
}
}
void
PackageManager::ClearCurrentActionPackage()
{
fCurrentInstallPackage = NULL;
fCurrentUninstallPackage = NULL;
}
status_t
PackageManager::RefreshRepository(const BRepositoryConfig& repoConfig)
{
@@ -286,8 +317,15 @@ PackageManager::HandleProblems()
if (fProblemWindow == NULL)
fProblemWindow = new ProblemWindow;
ProblemWindow::SolverPackageSet dummy;
if (!fProblemWindow->Go(fSolver,dummy, dummy))
ProblemWindow::SolverPackageSet installPackages;
ProblemWindow::SolverPackageSet uninstallPackages;
if (fCurrentInstallPackage != NULL)
installPackages.insert(fCurrentInstallPackage);
if (fCurrentUninstallPackage != NULL)
uninstallPackages.insert(fCurrentInstallPackage);
if (!fProblemWindow->Go(fSolver,installPackages, uninstallPackages))
throw BAbortedByUserException();
}
@@ -364,6 +402,7 @@ PackageManager::_PackageActionWorker(void* arg)
}
ref->Perform();
manager->ClearCurrentActionPackage();
}
return 0;
@@ -377,10 +416,34 @@ PackageManager::_AddResults(InstalledRepository& repository,
if (!repository.HasChanges())
return false;
ProblemWindow::SolverPackageSet dummy;
ProblemWindow::SolverPackageSet installPackages;
ProblemWindow::SolverPackageSet uninstallPackages;
if (fCurrentInstallPackage != NULL)
installPackages.insert(fCurrentInstallPackage);
if (fCurrentUninstallPackage != NULL)
uninstallPackages.insert(fCurrentInstallPackage);
return window->AddLocationChanges(repository.Name(),
repository.PackagesToActivate(), dummy,
repository.PackagesToDeactivate(), dummy);
repository.PackagesToActivate(), installPackages,
repository.PackagesToDeactivate(), uninstallPackages);
}
BSolverPackage*
PackageManager::_GetSolverPackage(PackageInfoRef package)
{
BObjectList<BSolverPackage> packages;
status_t result = Solver()->FindPackages(package->Title(),
BSolver::B_FIND_IN_NAME, packages);
if (result == B_OK) {
for (int32 i = 0; i < packages.CountItems(); i++) {
BSolverPackage* solverPackage = packages.ItemAt(i);
if (solverPackage->Name() != package->Title())
continue;
return solverPackage;
}
}
return NULL;
}
+22 -4
View File
@@ -18,6 +18,11 @@
#include "PackageInfo.h"
namespace BPackageKit {
class BSolverPackage;
}
class PackageManager;
class ProblemWindow;
class ResultWindow;
@@ -25,7 +30,7 @@ class ResultWindow;
class PackageAction : public BReferenceable {
public:
PackageAction(const PackageInfo& package,
PackageAction(PackageInfoRef package,
PackageManager* manager);
virtual ~PackageAction();
@@ -36,14 +41,14 @@ public:
// Package Kit supports this stuff already.
virtual status_t Perform() = 0;
const PackageInfo& Package() const
PackageInfoRef Package() const
{ return fPackage; }
protected:
PackageManager* fPackageManager;
private:
PackageInfo fPackage;
PackageInfoRef fPackage;
};
@@ -66,11 +71,17 @@ public:
virtual ~PackageManager();
virtual PackageState GetPackageState(const PackageInfo& package);
virtual PackageActionList GetPackageActions(const PackageInfo& package);
virtual PackageActionList GetPackageActions(PackageInfoRef package);
status_t SchedulePackageActions(
PackageActionList& list);
void SetCurrentActionPackage(
PackageInfoRef package,
bool install);
void ClearCurrentActionPackage();
private:
// RequestHandler
virtual status_t RefreshRepository(
@@ -101,6 +112,9 @@ private:
repository,
ResultWindow* window);
BPackageKit::BSolverPackage*
_GetSolverPackage(PackageInfoRef package);
private:
DecisionProvider fDecisionProvider;
JobStateListener fJobStateListener;
@@ -113,6 +127,10 @@ private:
BLocker fPendingActionsLock;
sem_id fPendingActionsSem;
ProblemWindow* fProblemWindow;
BPackageKit::BSolverPackage*
fCurrentInstallPackage;
BPackageKit::BSolverPackage*
fCurrentUninstallPackage;
};
#endif // PACKAGE_MANAGER_H