package daemon: Replace changes alert by a window
This commit is contained in:
@@ -12,6 +12,7 @@ Server package_daemon
|
|||||||
PackageDaemon.cpp
|
PackageDaemon.cpp
|
||||||
PackageManager.cpp
|
PackageManager.cpp
|
||||||
ProblemWindow.cpp
|
ProblemWindow.cpp
|
||||||
|
ResultWindow.cpp
|
||||||
Root.cpp
|
Root.cpp
|
||||||
Volume.cpp
|
Volume.cpp
|
||||||
:
|
:
|
||||||
|
|||||||
@@ -6,7 +6,6 @@
|
|||||||
|
|
||||||
#include "PackageManager.h"
|
#include "PackageManager.h"
|
||||||
|
|
||||||
#include <Alert.h>
|
|
||||||
#include <Notification.h>
|
#include <Notification.h>
|
||||||
#include <package/DownloadFileRequest.h>
|
#include <package/DownloadFileRequest.h>
|
||||||
#include <package/RefreshRepositoryRequest.h>
|
#include <package/RefreshRepositoryRequest.h>
|
||||||
@@ -15,11 +14,13 @@
|
|||||||
#include <package/solver/SolverProblem.h>
|
#include <package/solver/SolverProblem.h>
|
||||||
#include <package/solver/SolverProblemSolution.h>
|
#include <package/solver/SolverProblemSolution.h>
|
||||||
|
|
||||||
|
#include <AutoDeleter.h>
|
||||||
#include <package/manager/Exceptions.h>
|
#include <package/manager/Exceptions.h>
|
||||||
#include <package/manager/RepositoryBuilder.h>
|
#include <package/manager/RepositoryBuilder.h>
|
||||||
#include <Server.h>
|
#include <Server.h>
|
||||||
|
|
||||||
#include "ProblemWindow.h"
|
#include "ProblemWindow.h"
|
||||||
|
#include "ResultWindow.h"
|
||||||
#include "Root.h"
|
#include "Root.h"
|
||||||
#include "Volume.h"
|
#include "Volume.h"
|
||||||
|
|
||||||
@@ -290,29 +291,27 @@ void
|
|||||||
PackageManager::ConfirmChanges(bool fromMostSpecific)
|
PackageManager::ConfirmChanges(bool fromMostSpecific)
|
||||||
{
|
{
|
||||||
// Check whether there are any changes other than those made by the user.
|
// Check whether there are any changes other than those made by the user.
|
||||||
BString alertText(
|
_InitGui();
|
||||||
"The following additional package changes have to be made:");
|
ResultWindow* window = new ResultWindow;
|
||||||
|
ObjectDeleter<ResultWindow> windowDeleter(window);
|
||||||
|
|
||||||
bool hasOtherChanges = false;
|
bool hasOtherChanges = false;
|
||||||
int32 count = fInstalledRepositories.CountItems();
|
int32 count = fInstalledRepositories.CountItems();
|
||||||
if (fromMostSpecific) {
|
if (fromMostSpecific) {
|
||||||
for (int32 i = count - 1; i >= 0; i--)
|
for (int32 i = count - 1; i >= 0; i--)
|
||||||
hasOtherChanges
|
hasOtherChanges
|
||||||
|= _GetResultText(*fInstalledRepositories.ItemAt(i), alertText);
|
|= _AddResults(*fInstalledRepositories.ItemAt(i), window);
|
||||||
} else {
|
} else {
|
||||||
for (int32 i = 0; i < count; i++)
|
for (int32 i = 0; i < count; i++)
|
||||||
hasOtherChanges
|
hasOtherChanges
|
||||||
|= _GetResultText(*fInstalledRepositories.ItemAt(i), alertText);
|
|= _AddResults(*fInstalledRepositories.ItemAt(i), window);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!hasOtherChanges)
|
if (!hasOtherChanges)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
// show an alert
|
// show the window
|
||||||
_InitGui();
|
if (windowDeleter.Detach()->Go() == 0)
|
||||||
BAlert* alert = new BAlert("Package changes", alertText,
|
|
||||||
"Cancel", "Apply changes");
|
|
||||||
alert->SetShortcut(0, B_ESCAPE);
|
|
||||||
if (alert->Go() == 0)
|
|
||||||
throw BAbortedByUserException();
|
throw BAbortedByUserException();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -381,55 +380,15 @@ PackageManager::JobAborted(BJob* job)
|
|||||||
|
|
||||||
|
|
||||||
bool
|
bool
|
||||||
PackageManager::_GetResultText(InstalledRepository& repository,
|
PackageManager::_AddResults(InstalledRepository& repository,
|
||||||
BString& _text)
|
ResultWindow* window)
|
||||||
{
|
{
|
||||||
if (!repository.HasChanges())
|
if (!repository.HasChanges())
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
bool hasOtherChanges = false;
|
return window->AddLocationChanges(repository.Name(),
|
||||||
bool isTargetLocation
|
repository.PackagesToActivate(), fPackagesAddedByUser,
|
||||||
= repository.Location() == fVolume->Location();
|
repository.PackagesToDeactivate(), fPackagesRemovedByUser);
|
||||||
|
|
||||||
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;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -30,6 +30,7 @@ using BPackageKit::BManager::BPrivate::BPackageManager;
|
|||||||
|
|
||||||
class Package;
|
class Package;
|
||||||
class ProblemWindow;
|
class ProblemWindow;
|
||||||
|
class ResultWindow;
|
||||||
class Root;
|
class Root;
|
||||||
class Volume;
|
class Volume;
|
||||||
|
|
||||||
@@ -95,8 +96,8 @@ private:
|
|||||||
typedef std::map<Package*, BSolverPackage*> SolverPackageMap;
|
typedef std::map<Package*, BSolverPackage*> SolverPackageMap;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
bool _GetResultText(InstalledRepository& repository,
|
bool _AddResults(InstalledRepository& repository,
|
||||||
BString& _text);
|
ResultWindow* window);
|
||||||
|
|
||||||
BSolverPackage* _SolverPackageFor(Package* package) const;
|
BSolverPackage* _SolverPackageFor(Package* package) const;
|
||||||
|
|
||||||
|
|||||||
@@ -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;
|
||||||
|
}
|
||||||
@@ -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
|
||||||
Reference in New Issue
Block a user