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:
@@ -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) {
|
||||
|
||||
@@ -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();
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user