package daemon: Replace changes alert by a window

This commit is contained in:
Ingo Weinhold
2013-09-11 15:06:44 +02:00
parent f2cba19f53
commit 6c88312170
5 changed files with 296 additions and 58 deletions
+1
View File
@@ -12,6 +12,7 @@ Server package_daemon
PackageDaemon.cpp
PackageManager.cpp
ProblemWindow.cpp
ResultWindow.cpp
Root.cpp
Volume.cpp
:
+15 -56
View File
@@ -6,7 +6,6 @@
#include "PackageManager.h"
#include <Alert.h>
#include <Notification.h>
#include <package/DownloadFileRequest.h>
#include <package/RefreshRepositoryRequest.h>
@@ -15,11 +14,13 @@
#include <package/solver/SolverProblem.h>
#include <package/solver/SolverProblemSolution.h>
#include <AutoDeleter.h>
#include <package/manager/Exceptions.h>
#include <package/manager/RepositoryBuilder.h>
#include <Server.h>
#include "ProblemWindow.h"
#include "ResultWindow.h"
#include "Root.h"
#include "Volume.h"
@@ -290,29 +291,27 @@ void
PackageManager::ConfirmChanges(bool fromMostSpecific)
{
// Check whether there are any changes other than those made by the user.
BString alertText(
"The following additional package changes have to be made:");
_InitGui();
ResultWindow* window = new ResultWindow;
ObjectDeleter<ResultWindow> windowDeleter(window);
bool hasOtherChanges = false;
int32 count = fInstalledRepositories.CountItems();
if (fromMostSpecific) {
for (int32 i = count - 1; i >= 0; i--)
hasOtherChanges
|= _GetResultText(*fInstalledRepositories.ItemAt(i), alertText);
|= _AddResults(*fInstalledRepositories.ItemAt(i), window);
} else {
for (int32 i = 0; i < count; i++)
hasOtherChanges
|= _GetResultText(*fInstalledRepositories.ItemAt(i), alertText);
|= _AddResults(*fInstalledRepositories.ItemAt(i), window);
}
if (!hasOtherChanges)
return;
// show an alert
_InitGui();
BAlert* alert = new BAlert("Package changes", alertText,
"Cancel", "Apply changes");
alert->SetShortcut(0, B_ESCAPE);
if (alert->Go() == 0)
// show the window
if (windowDeleter.Detach()->Go() == 0)
throw BAbortedByUserException();
}
@@ -381,55 +380,15 @@ PackageManager::JobAborted(BJob* job)
bool
PackageManager::_GetResultText(InstalledRepository& repository,
BString& _text)
PackageManager::_AddResults(InstalledRepository& repository,
ResultWindow* window)
{
if (!repository.HasChanges())
return false;
bool hasOtherChanges = false;
bool isTargetLocation
= repository.Location() == fVolume->Location();
BString text = BString().SetToFormat("\n in %s:",
repository.Name().String());
PackageList& packagesToActivate = repository.PackagesToActivate();
PackageList& packagesToDeactivate = repository.PackagesToDeactivate();
for (int32 i = 0; BSolverPackage* package = packagesToActivate.ItemAt(i);
i++) {
if (isTargetLocation
&& fPackagesAddedByUser.find(package)
!= fPackagesAddedByUser.end()) {
continue;
}
text << BString().SetToFormat(
"\n install package %s from repository %s\n",
package->Info().FileName().String(),
package->Repository()->Name().String());
hasOtherChanges = true;
}
for (int32 i = 0; BSolverPackage* package = packagesToDeactivate.ItemAt(i);
i++) {
if (isTargetLocation
&& fPackagesRemovedByUser.find(package)
!= fPackagesRemovedByUser.end()) {
continue;
}
text << BString().SetToFormat(
"\n uninstall package %s\n", package->VersionedName().String());
hasOtherChanges = true;
}
if (!hasOtherChanges)
return false;
_text << text;
return true;
return window->AddLocationChanges(repository.Name(),
repository.PackagesToActivate(), fPackagesAddedByUser,
repository.PackagesToDeactivate(), fPackagesRemovedByUser);
}
+3 -2
View File
@@ -30,6 +30,7 @@ using BPackageKit::BManager::BPrivate::BPackageManager;
class Package;
class ProblemWindow;
class ResultWindow;
class Root;
class Volume;
@@ -95,8 +96,8 @@ private:
typedef std::map<Package*, BSolverPackage*> SolverPackageMap;
private:
bool _GetResultText(InstalledRepository& repository,
BString& _text);
bool _AddResults(InstalledRepository& repository,
ResultWindow* window);
BSolverPackage* _SolverPackageFor(Package* package) const;
+215
View File
@@ -0,0 +1,215 @@
/*
* Copyright 2013, Ingo Weinhold, [email protected].
* Distributed under the terms of the MIT License.
*/
#include "ResultWindow.h"
#include <Button.h>
#include <GroupView.h>
#include <LayoutBuilder.h>
#include <ScrollView.h>
#include <StringView.h>
#include <package/solver/SolverPackage.h>
#include <package/solver/SolverRepository.h>
#include <AutoDeleter.h>
#include <AutoLocker.h>
#include <ViewPort.h>
using namespace BPackageKit;
static const uint32 kApplyMessage = 'rtry';
ResultWindow::ResultWindow()
:
BWindow(BRect(0, 0, 400, 300), "Package changes", B_TITLED_WINDOW_LOOK,
B_NORMAL_WINDOW_FEEL,
B_ASYNCHRONOUS_CONTROLS | B_NOT_MINIMIZABLE | B_AUTO_UPDATE_SIZE_LIMITS,
B_ALL_WORKSPACES),
fDoneSemaphore(-1),
fClientWaiting(false),
fAccepted(false),
fContainerView(NULL),
fCancelButton(NULL),
fApplyButton(NULL)
{
fDoneSemaphore = create_sem(0, "package changes");
if (fDoneSemaphore < 0)
throw std::bad_alloc();
BStringView* topTextView = NULL;
BViewPort* viewPort = NULL;
BLayoutBuilder::Group<>(this, B_VERTICAL, B_USE_DEFAULT_SPACING)
.SetInsets(B_USE_SMALL_INSETS)
.Add(topTextView = new BStringView(NULL,
"The following additional package changes have to be made:"))
.Add(new BScrollView(NULL, viewPort = new BViewPort(), 0, false, true))
.AddGroup(B_HORIZONTAL)
.Add(fCancelButton = new BButton("Cancel", new BMessage(B_CANCEL)))
.AddGlue()
.Add(fApplyButton = new BButton("Apply changes",
new BMessage(kApplyMessage)))
.End();
topTextView->SetExplicitMaxSize(BSize(B_SIZE_UNLIMITED, B_SIZE_UNSET));
viewPort->SetChildView(fContainerView = new BGroupView(B_VERTICAL, 0));
// set small scroll step (large step will be set by the view port)
font_height fontHeight;
topTextView->GetFontHeight(&fontHeight);
float smallStep = ceilf(fontHeight.ascent + fontHeight.descent);
viewPort->ScrollBar(B_VERTICAL)->SetSteps(smallStep, smallStep);
}
ResultWindow::~ResultWindow()
{
if (fDoneSemaphore >= 0)
delete_sem(fDoneSemaphore);
}
bool
ResultWindow::AddLocationChanges(const char* location,
const PackageList& packagesToInstall,
const PackageSet& packagesAlreadyAdded,
const PackageList& packagesToUninstall,
const PackageSet& packagesAlreadyRemoved)
{
BGroupView* locationGroup = new BGroupView(B_VERTICAL);
ObjectDeleter<BGroupView> locationGroupDeleter(locationGroup);
locationGroup->GroupLayout()->SetInsets(B_USE_SMALL_INSETS);
rgb_color background = ui_color(B_LIST_BACKGROUND_COLOR);
if ((fContainerView->CountChildren() & 1) != 0)
background = tint_color(background, 1.04);
locationGroup->SetViewColor(background);
BStringView* locationView = new BStringView(NULL,
BString().SetToFormat("in %s:", location));
locationGroup->AddChild(locationView);
locationView->SetExplicitMaxSize(BSize(B_SIZE_UNLIMITED, B_SIZE_UNSET));
BFont locationFont;
locationView->GetFont(&locationFont);
locationFont.SetFace(B_BOLD_FACE);
locationView->SetFont(&locationFont);
BGroupLayout* packagesGroup = new BGroupLayout(B_VERTICAL);
locationGroup->GroupLayout()->AddItem(packagesGroup);
packagesGroup->SetInsets(20, 0, 0, 0);
bool packagesAdded = _AddPackages(packagesGroup, packagesToInstall,
packagesAlreadyAdded, true);
packagesAdded |= _AddPackages(packagesGroup, packagesToUninstall,
packagesAlreadyRemoved, false);
if (!packagesAdded)
return false;
fContainerView->AddChild(locationGroup);
locationGroupDeleter.Detach();
return true;
}
bool
ResultWindow::Go()
{
AutoLocker<ResultWindow> locker(this);
CenterOnScreen();
Show();
fAccepted = false;
fClientWaiting = true;
locker.Unlock();
while (acquire_sem(fDoneSemaphore) == B_INTERRUPTED) {
}
locker.Lock();
bool result = false;
if (locker.IsLocked()) {
result = fAccepted;
Quit();
locker.Detach();
} else
PostMessage(B_QUIT_REQUESTED);
return result;
}
bool
ResultWindow::QuitRequested()
{
if (fClientWaiting) {
Hide();
fClientWaiting = false;
release_sem(fDoneSemaphore);
return false;
}
return true;
}
void
ResultWindow::MessageReceived(BMessage* message)
{
switch (message->what) {
case B_CANCEL:
case kApplyMessage:
Hide();
fAccepted = message->what == kApplyMessage;
fClientWaiting = false;
release_sem(fDoneSemaphore);
break;
default:
BWindow::MessageReceived(message);
break;
}
}
bool
ResultWindow::_AddPackages(BGroupLayout* packagesGroup,
const PackageList& packages, const PackageSet& ignorePackages, bool install)
{
bool packagesAdded = false;
for (int32 i = 0; BSolverPackage* package = packages.ItemAt(i);
i++) {
if (ignorePackages.find(package) != ignorePackages.end())
continue;
BString text;
if (install) {
text.SetToFormat("install package %s from repository %s\n",
package->Info().FileName().String(),
package->Repository()->Name().String());
} else {
text.SetToFormat("uninstall package %s\n",
package->VersionedName().String());
}
BStringView* packageView = new BStringView(NULL, text);
packagesGroup->AddView(packageView);
packageView->SetExplicitMaxSize(BSize(B_SIZE_UNLIMITED, B_SIZE_UNSET));
packagesAdded = true;
}
return packagesAdded;
}
+62
View File
@@ -0,0 +1,62 @@
/*
* Copyright 2013, Ingo Weinhold, [email protected].
* Distributed under the terms of the MIT License.
*/
#ifndef RESULT_WINDOW_H
#define RESULT_WINDOW_H
#include <map>
#include <set>
#include <ObjectList.h>
#include <Window.h>
namespace BPackageKit {
class BSolverPackage;
}
using BPackageKit::BSolverPackage;
class BButton;
class BGroupLayout;
class BGroupView;
class ResultWindow : public BWindow {
public:
typedef std::set<BSolverPackage*> PackageSet;
typedef BObjectList<BSolverPackage> PackageList;
public:
ResultWindow();
virtual ~ResultWindow();
bool AddLocationChanges(const char* location,
const PackageList& packagesToInstall,
const PackageSet& packagesAlreadyAdded,
const PackageList& packagesToUninstall,
const PackageSet& packagesAlreadyRemoved);
bool Go();
virtual bool QuitRequested();
virtual void MessageReceived(BMessage* message);
private:
bool _AddPackages(BGroupLayout* packagesGroup,
const PackageList& packages,
const PackageSet& ignorePackages,
bool install);
private:
sem_id fDoneSemaphore;
bool fClientWaiting;
bool fAccepted;
BGroupView* fContainerView;
BButton* fCancelButton;
BButton* fApplyButton;
};
#endif // RESULT_WINDOW_H