xref: /haiku/src/servers/package/ResultWindow.cpp (revision 325c28a8ae5feb43bb597881267219ee341824fe)
16c883121SIngo Weinhold /*
26c883121SIngo Weinhold  * Copyright 2013, Ingo Weinhold, ingo_weinhold@gmx.de.
36c883121SIngo Weinhold  * Distributed under the terms of the MIT License.
46c883121SIngo Weinhold  */
56c883121SIngo Weinhold 
66c883121SIngo Weinhold 
76c883121SIngo Weinhold #include "ResultWindow.h"
86c883121SIngo Weinhold 
96c883121SIngo Weinhold #include <Button.h>
10cf0ba058SHumdinger #include <Catalog.h>
116c883121SIngo Weinhold #include <GroupView.h>
126c883121SIngo Weinhold #include <LayoutBuilder.h>
136c883121SIngo Weinhold #include <ScrollView.h>
146c883121SIngo Weinhold #include <StringView.h>
156c883121SIngo Weinhold #include <package/solver/SolverPackage.h>
166c883121SIngo Weinhold #include <package/solver/SolverRepository.h>
176c883121SIngo Weinhold 
186c883121SIngo Weinhold #include <AutoDeleter.h>
196c883121SIngo Weinhold #include <AutoLocker.h>
206c883121SIngo Weinhold #include <ViewPort.h>
216c883121SIngo Weinhold 
226c883121SIngo Weinhold 
23cf0ba058SHumdinger #undef B_TRANSLATION_CONTEXT
24cf0ba058SHumdinger #define B_TRANSLATION_CONTEXT "PackageResult"
25cf0ba058SHumdinger 
266c883121SIngo Weinhold using namespace BPackageKit;
276c883121SIngo Weinhold 
286c883121SIngo Weinhold 
296c883121SIngo Weinhold static const uint32 kApplyMessage = 'rtry';
306c883121SIngo Weinhold 
316c883121SIngo Weinhold 
ResultWindow()326c883121SIngo Weinhold ResultWindow::ResultWindow()
336c883121SIngo Weinhold 	:
34cf0ba058SHumdinger 	BWindow(BRect(0, 0, 400, 300), B_TRANSLATE_COMMENT("Package changes",
35cf0ba058SHumdinger 			"Window title"), B_TITLED_WINDOW_LOOK,
366c883121SIngo Weinhold 		B_NORMAL_WINDOW_FEEL,
376c883121SIngo Weinhold 		B_ASYNCHRONOUS_CONTROLS | B_NOT_MINIMIZABLE | B_AUTO_UPDATE_SIZE_LIMITS,
386c883121SIngo Weinhold 		B_ALL_WORKSPACES),
396c883121SIngo Weinhold 	fDoneSemaphore(-1),
406c883121SIngo Weinhold 	fClientWaiting(false),
416c883121SIngo Weinhold 	fAccepted(false),
426c883121SIngo Weinhold 	fContainerView(NULL),
436c883121SIngo Weinhold 	fCancelButton(NULL),
446c883121SIngo Weinhold 	fApplyButton(NULL)
456c883121SIngo Weinhold 
466c883121SIngo Weinhold {
476c883121SIngo Weinhold 	fDoneSemaphore = create_sem(0, "package changes");
486c883121SIngo Weinhold 	if (fDoneSemaphore < 0)
496c883121SIngo Weinhold 		throw std::bad_alloc();
506c883121SIngo Weinhold 
516c883121SIngo Weinhold 	BStringView* topTextView = NULL;
526c883121SIngo Weinhold 	BViewPort* viewPort = NULL;
536c883121SIngo Weinhold 
546c883121SIngo Weinhold 	BLayoutBuilder::Group<>(this, B_VERTICAL, B_USE_DEFAULT_SPACING)
556c883121SIngo Weinhold 		.SetInsets(B_USE_SMALL_INSETS)
56cf0ba058SHumdinger 		.Add(topTextView = new BStringView(NULL, B_TRANSLATE(
57cf0ba058SHumdinger 				"The following additional package changes have to be made:")))
586c883121SIngo Weinhold 		.Add(new BScrollView(NULL, viewPort = new BViewPort(), 0, false, true))
596c883121SIngo Weinhold 		.AddGroup(B_HORIZONTAL)
60cf0ba058SHumdinger 			.Add(fCancelButton = new BButton(B_TRANSLATE("Cancel"),
61cf0ba058SHumdinger 				new BMessage(B_CANCEL)))
626c883121SIngo Weinhold 			.AddGlue()
63cf0ba058SHumdinger 			.Add(fApplyButton = new BButton(B_TRANSLATE("Apply changes"),
646c883121SIngo Weinhold 				new BMessage(kApplyMessage)))
656c883121SIngo Weinhold 		.End();
666c883121SIngo Weinhold 
676c883121SIngo Weinhold 	topTextView->SetExplicitMaxSize(BSize(B_SIZE_UNLIMITED, B_SIZE_UNSET));
686c883121SIngo Weinhold 
696c883121SIngo Weinhold 	viewPort->SetChildView(fContainerView = new BGroupView(B_VERTICAL, 0));
706c883121SIngo Weinhold 
716c883121SIngo Weinhold 	// set small scroll step (large step will be set by the view port)
726c883121SIngo Weinhold 	font_height fontHeight;
736c883121SIngo Weinhold 	topTextView->GetFontHeight(&fontHeight);
746c883121SIngo Weinhold 	float smallStep = ceilf(fontHeight.ascent + fontHeight.descent);
756c883121SIngo Weinhold 	viewPort->ScrollBar(B_VERTICAL)->SetSteps(smallStep, smallStep);
766c883121SIngo Weinhold }
776c883121SIngo Weinhold 
786c883121SIngo Weinhold 
~ResultWindow()796c883121SIngo Weinhold ResultWindow::~ResultWindow()
806c883121SIngo Weinhold {
816c883121SIngo Weinhold 	if (fDoneSemaphore >= 0)
826c883121SIngo Weinhold 		delete_sem(fDoneSemaphore);
836c883121SIngo Weinhold }
846c883121SIngo Weinhold 
856c883121SIngo Weinhold 
866c883121SIngo Weinhold bool
AddLocationChanges(const char * location,const PackageList & packagesToInstall,const PackageSet & packagesAlreadyAdded,const PackageList & packagesToUninstall,const PackageSet & packagesAlreadyRemoved)876c883121SIngo Weinhold ResultWindow::AddLocationChanges(const char* location,
886c883121SIngo Weinhold 	const PackageList& packagesToInstall,
896c883121SIngo Weinhold 	const PackageSet& packagesAlreadyAdded,
906c883121SIngo Weinhold 	const PackageList& packagesToUninstall,
916c883121SIngo Weinhold 	const PackageSet& packagesAlreadyRemoved)
926c883121SIngo Weinhold {
936c883121SIngo Weinhold 	BGroupView* locationGroup = new BGroupView(B_VERTICAL);
946c883121SIngo Weinhold 	ObjectDeleter<BGroupView> locationGroupDeleter(locationGroup);
956c883121SIngo Weinhold 
966c883121SIngo Weinhold 	locationGroup->GroupLayout()->SetInsets(B_USE_SMALL_INSETS);
976c883121SIngo Weinhold 
985d7e699aSJessica Hamilton 	float backgroundTint = B_NO_TINT;
996c883121SIngo Weinhold 	if ((fContainerView->CountChildren() & 1) != 0)
1005d7e699aSJessica Hamilton 		backgroundTint = 1.04;
101*325c28a8SJohn Scipione 
102*325c28a8SJohn Scipione 	locationGroup->SetViewUIColor(B_DOCUMENT_BACKGROUND_COLOR, backgroundTint);
103*325c28a8SJohn Scipione 	locationGroup->SetHighUIColor(B_DOCUMENT_TEXT_COLOR);
1046c883121SIngo Weinhold 
1056cb94b77SJohn Scipione 	BStringView* locationView = new BStringView(NULL, BString().SetToFormat("in %s:", location));
1066c883121SIngo Weinhold 	locationGroup->AddChild(locationView);
1076c883121SIngo Weinhold 	locationView->SetExplicitMaxSize(BSize(B_SIZE_UNLIMITED, B_SIZE_UNSET));
1085d7e699aSJessica Hamilton 	locationView->AdoptParentColors();
109*325c28a8SJohn Scipione 
1106c883121SIngo Weinhold 	BFont locationFont;
1116c883121SIngo Weinhold 	locationView->GetFont(&locationFont);
1126c883121SIngo Weinhold 	locationFont.SetFace(B_BOLD_FACE);
1136c883121SIngo Weinhold 	locationView->SetFont(&locationFont);
1146c883121SIngo Weinhold 
1156c883121SIngo Weinhold 	BGroupLayout* packagesGroup = new BGroupLayout(B_VERTICAL);
1166c883121SIngo Weinhold 	locationGroup->GroupLayout()->AddItem(packagesGroup);
1176c883121SIngo Weinhold 	packagesGroup->SetInsets(20, 0, 0, 0);
1186c883121SIngo Weinhold 
1196c883121SIngo Weinhold 	bool packagesAdded = _AddPackages(packagesGroup, packagesToInstall,
1206c883121SIngo Weinhold 		packagesAlreadyAdded, true);
1216c883121SIngo Weinhold 	packagesAdded |= _AddPackages(packagesGroup, packagesToUninstall,
1226c883121SIngo Weinhold 		packagesAlreadyRemoved, false);
1236c883121SIngo Weinhold 
1246c883121SIngo Weinhold 	if (!packagesAdded)
1256c883121SIngo Weinhold 		return false;
1266c883121SIngo Weinhold 
1276c883121SIngo Weinhold 	fContainerView->AddChild(locationGroup);
1286c883121SIngo Weinhold 	locationGroupDeleter.Detach();
1296c883121SIngo Weinhold 
1306c883121SIngo Weinhold 	return true;
1316c883121SIngo Weinhold }
1326c883121SIngo Weinhold 
1336c883121SIngo Weinhold 
1346c883121SIngo Weinhold bool
Go()1356c883121SIngo Weinhold ResultWindow::Go()
1366c883121SIngo Weinhold {
1376c883121SIngo Weinhold 	AutoLocker<ResultWindow> locker(this);
1386c883121SIngo Weinhold 
1396c883121SIngo Weinhold 	CenterOnScreen();
1406c883121SIngo Weinhold 	Show();
1416c883121SIngo Weinhold 
1426c883121SIngo Weinhold 	fAccepted = false;
1436c883121SIngo Weinhold 	fClientWaiting = true;
1446c883121SIngo Weinhold 
1456c883121SIngo Weinhold 	locker.Unlock();
1466c883121SIngo Weinhold 
1476c883121SIngo Weinhold 	while (acquire_sem(fDoneSemaphore) == B_INTERRUPTED) {
1486c883121SIngo Weinhold 	}
1496c883121SIngo Weinhold 
1506c883121SIngo Weinhold 	locker.Lock();
1516c883121SIngo Weinhold 	bool result = false;
1526c883121SIngo Weinhold 	if (locker.IsLocked()) {
1536c883121SIngo Weinhold 		result = fAccepted;
1546c883121SIngo Weinhold 		Quit();
1556c883121SIngo Weinhold 		locker.Detach();
1566c883121SIngo Weinhold 	} else
1576c883121SIngo Weinhold 		PostMessage(B_QUIT_REQUESTED);
1586c883121SIngo Weinhold 
1596c883121SIngo Weinhold 	return result;
1606c883121SIngo Weinhold }
1616c883121SIngo Weinhold 
1626c883121SIngo Weinhold 
1636c883121SIngo Weinhold bool
QuitRequested()1646c883121SIngo Weinhold ResultWindow::QuitRequested()
1656c883121SIngo Weinhold {
1666c883121SIngo Weinhold 	if (fClientWaiting) {
1676c883121SIngo Weinhold 		Hide();
1686c883121SIngo Weinhold 		fClientWaiting = false;
1696c883121SIngo Weinhold 		release_sem(fDoneSemaphore);
1706c883121SIngo Weinhold 		return false;
1716c883121SIngo Weinhold 	}
1726c883121SIngo Weinhold 
1736c883121SIngo Weinhold 	return true;
1746c883121SIngo Weinhold }
1756c883121SIngo Weinhold 
1766c883121SIngo Weinhold 
1776c883121SIngo Weinhold void
MessageReceived(BMessage * message)1786c883121SIngo Weinhold ResultWindow::MessageReceived(BMessage* message)
1796c883121SIngo Weinhold {
1806c883121SIngo Weinhold 	switch (message->what) {
1816c883121SIngo Weinhold 		case B_CANCEL:
1826c883121SIngo Weinhold 		case kApplyMessage:
1836c883121SIngo Weinhold 			Hide();
1846c883121SIngo Weinhold 			fAccepted = message->what == kApplyMessage;
1856c883121SIngo Weinhold 			fClientWaiting = false;
1866c883121SIngo Weinhold 			release_sem(fDoneSemaphore);
1876c883121SIngo Weinhold 			break;
1886c883121SIngo Weinhold 		default:
1896c883121SIngo Weinhold 			BWindow::MessageReceived(message);
1906c883121SIngo Weinhold 			break;
1916c883121SIngo Weinhold 	}
1926c883121SIngo Weinhold }
1936c883121SIngo Weinhold 
1946c883121SIngo Weinhold 
1956c883121SIngo Weinhold bool
_AddPackages(BGroupLayout * packagesGroup,const PackageList & packages,const PackageSet & ignorePackages,bool install)1966c883121SIngo Weinhold ResultWindow::_AddPackages(BGroupLayout* packagesGroup,
1976c883121SIngo Weinhold 	const PackageList& packages, const PackageSet& ignorePackages, bool install)
1986c883121SIngo Weinhold {
1996c883121SIngo Weinhold 	bool packagesAdded = false;
2006c883121SIngo Weinhold 
2016c883121SIngo Weinhold 	for (int32 i = 0; BSolverPackage* package = packages.ItemAt(i);
2026c883121SIngo Weinhold 		i++) {
2036c883121SIngo Weinhold 		if (ignorePackages.find(package) != ignorePackages.end())
2046c883121SIngo Weinhold 			continue;
2056c883121SIngo Weinhold 
2066c883121SIngo Weinhold 		BString text;
2076c883121SIngo Weinhold 		if (install) {
208cf0ba058SHumdinger 			text.SetToFormat(B_TRANSLATE_COMMENT("install package %s from "
209cf0ba058SHumdinger 					"repository %s\n", "Don't change '%s' variables"),
2106c883121SIngo Weinhold 				package->Info().FileName().String(),
2116c883121SIngo Weinhold 				package->Repository()->Name().String());
2126c883121SIngo Weinhold 		} else {
213cf0ba058SHumdinger 			text.SetToFormat(B_TRANSLATE_COMMENT("uninstall package %s\n",
214cf0ba058SHumdinger 					"Don't change '%s' variable"),
2156c883121SIngo Weinhold 				package->VersionedName().String());
2166c883121SIngo Weinhold 		}
2176c883121SIngo Weinhold 
2186c883121SIngo Weinhold 		BStringView* packageView = new BStringView(NULL, text);
2196c883121SIngo Weinhold 		packagesGroup->AddView(packageView);
2206c883121SIngo Weinhold 		packageView->SetExplicitMaxSize(BSize(B_SIZE_UNLIMITED, B_SIZE_UNSET));
2215d7e699aSJessica Hamilton 		packageView->AdoptParentColors();
2226c883121SIngo Weinhold 
2236c883121SIngo Weinhold 		packagesAdded = true;
2246c883121SIngo Weinhold 	}
2256c883121SIngo Weinhold 
2266c883121SIngo Weinhold 	return packagesAdded;
2276c883121SIngo Weinhold }
228