1 /*
2 * Copyright 2013, Ingo Weinhold, ingo_weinhold@gmx.de.
3 * Distributed under the terms of the MIT License.
4 */
5
6
7 #include "ResultWindow.h"
8
9 #include <Button.h>
10 #include <Catalog.h>
11 #include <GroupView.h>
12 #include <LayoutBuilder.h>
13 #include <ScrollView.h>
14 #include <StringView.h>
15 #include <package/solver/SolverPackage.h>
16 #include <package/solver/SolverRepository.h>
17
18 #include <AutoDeleter.h>
19 #include <AutoLocker.h>
20 #include <ViewPort.h>
21
22
23 #undef B_TRANSLATION_CONTEXT
24 #define B_TRANSLATION_CONTEXT "PackageResult"
25
26 using namespace BPackageKit;
27
28
29 static const uint32 kApplyMessage = 'rtry';
30
31
ResultWindow()32 ResultWindow::ResultWindow()
33 :
34 BWindow(BRect(0, 0, 400, 300), B_TRANSLATE_COMMENT("Package changes",
35 "Window title"), B_TITLED_WINDOW_LOOK,
36 B_NORMAL_WINDOW_FEEL,
37 B_ASYNCHRONOUS_CONTROLS | B_NOT_MINIMIZABLE | B_AUTO_UPDATE_SIZE_LIMITS,
38 B_ALL_WORKSPACES),
39 fDoneSemaphore(-1),
40 fClientWaiting(false),
41 fAccepted(false),
42 fContainerView(NULL),
43 fCancelButton(NULL),
44 fApplyButton(NULL)
45
46 {
47 fDoneSemaphore = create_sem(0, "package changes");
48 if (fDoneSemaphore < 0)
49 throw std::bad_alloc();
50
51 BStringView* topTextView = NULL;
52 BViewPort* viewPort = NULL;
53
54 BLayoutBuilder::Group<>(this, B_VERTICAL, B_USE_DEFAULT_SPACING)
55 .SetInsets(B_USE_SMALL_INSETS)
56 .Add(topTextView = new BStringView(NULL, B_TRANSLATE(
57 "The following additional package changes have to be made:")))
58 .Add(new BScrollView(NULL, viewPort = new BViewPort(), 0, false, true))
59 .AddGroup(B_HORIZONTAL)
60 .Add(fCancelButton = new BButton(B_TRANSLATE("Cancel"),
61 new BMessage(B_CANCEL)))
62 .AddGlue()
63 .Add(fApplyButton = new BButton(B_TRANSLATE("Apply changes"),
64 new BMessage(kApplyMessage)))
65 .End();
66
67 topTextView->SetExplicitMaxSize(BSize(B_SIZE_UNLIMITED, B_SIZE_UNSET));
68
69 viewPort->SetChildView(fContainerView = new BGroupView(B_VERTICAL, 0));
70
71 // set small scroll step (large step will be set by the view port)
72 font_height fontHeight;
73 topTextView->GetFontHeight(&fontHeight);
74 float smallStep = ceilf(fontHeight.ascent + fontHeight.descent);
75 viewPort->ScrollBar(B_VERTICAL)->SetSteps(smallStep, smallStep);
76 }
77
78
~ResultWindow()79 ResultWindow::~ResultWindow()
80 {
81 if (fDoneSemaphore >= 0)
82 delete_sem(fDoneSemaphore);
83 }
84
85
86 bool
AddLocationChanges(const char * location,const PackageList & packagesToInstall,const PackageSet & packagesAlreadyAdded,const PackageList & packagesToUninstall,const PackageSet & packagesAlreadyRemoved)87 ResultWindow::AddLocationChanges(const char* location,
88 const PackageList& packagesToInstall,
89 const PackageSet& packagesAlreadyAdded,
90 const PackageList& packagesToUninstall,
91 const PackageSet& packagesAlreadyRemoved)
92 {
93 BGroupView* locationGroup = new BGroupView(B_VERTICAL);
94 ObjectDeleter<BGroupView> locationGroupDeleter(locationGroup);
95
96 locationGroup->GroupLayout()->SetInsets(B_USE_SMALL_INSETS);
97
98 float backgroundTint = B_NO_TINT;
99 if ((fContainerView->CountChildren() & 1) != 0)
100 backgroundTint = 1.04;
101
102 locationGroup->SetViewUIColor(B_DOCUMENT_BACKGROUND_COLOR, backgroundTint);
103 locationGroup->SetHighUIColor(B_DOCUMENT_TEXT_COLOR);
104
105 BStringView* locationView = new BStringView(NULL, BString().SetToFormat("in %s:", location));
106 locationGroup->AddChild(locationView);
107 locationView->SetExplicitMaxSize(BSize(B_SIZE_UNLIMITED, B_SIZE_UNSET));
108 locationView->AdoptParentColors();
109
110 BFont locationFont;
111 locationView->GetFont(&locationFont);
112 locationFont.SetFace(B_BOLD_FACE);
113 locationView->SetFont(&locationFont);
114
115 BGroupLayout* packagesGroup = new BGroupLayout(B_VERTICAL);
116 locationGroup->GroupLayout()->AddItem(packagesGroup);
117 packagesGroup->SetInsets(20, 0, 0, 0);
118
119 bool packagesAdded = _AddPackages(packagesGroup, packagesToInstall,
120 packagesAlreadyAdded, true);
121 packagesAdded |= _AddPackages(packagesGroup, packagesToUninstall,
122 packagesAlreadyRemoved, false);
123
124 if (!packagesAdded)
125 return false;
126
127 fContainerView->AddChild(locationGroup);
128 locationGroupDeleter.Detach();
129
130 return true;
131 }
132
133
134 bool
Go()135 ResultWindow::Go()
136 {
137 AutoLocker<ResultWindow> locker(this);
138
139 CenterOnScreen();
140 Show();
141
142 fAccepted = false;
143 fClientWaiting = true;
144
145 locker.Unlock();
146
147 while (acquire_sem(fDoneSemaphore) == B_INTERRUPTED) {
148 }
149
150 locker.Lock();
151 bool result = false;
152 if (locker.IsLocked()) {
153 result = fAccepted;
154 Quit();
155 locker.Detach();
156 } else
157 PostMessage(B_QUIT_REQUESTED);
158
159 return result;
160 }
161
162
163 bool
QuitRequested()164 ResultWindow::QuitRequested()
165 {
166 if (fClientWaiting) {
167 Hide();
168 fClientWaiting = false;
169 release_sem(fDoneSemaphore);
170 return false;
171 }
172
173 return true;
174 }
175
176
177 void
MessageReceived(BMessage * message)178 ResultWindow::MessageReceived(BMessage* message)
179 {
180 switch (message->what) {
181 case B_CANCEL:
182 case kApplyMessage:
183 Hide();
184 fAccepted = message->what == kApplyMessage;
185 fClientWaiting = false;
186 release_sem(fDoneSemaphore);
187 break;
188 default:
189 BWindow::MessageReceived(message);
190 break;
191 }
192 }
193
194
195 bool
_AddPackages(BGroupLayout * packagesGroup,const PackageList & packages,const PackageSet & ignorePackages,bool install)196 ResultWindow::_AddPackages(BGroupLayout* packagesGroup,
197 const PackageList& packages, const PackageSet& ignorePackages, bool install)
198 {
199 bool packagesAdded = false;
200
201 for (int32 i = 0; BSolverPackage* package = packages.ItemAt(i);
202 i++) {
203 if (ignorePackages.find(package) != ignorePackages.end())
204 continue;
205
206 BString text;
207 if (install) {
208 text.SetToFormat(B_TRANSLATE_COMMENT("install package %s from "
209 "repository %s\n", "Don't change '%s' variables"),
210 package->Info().FileName().String(),
211 package->Repository()->Name().String());
212 } else {
213 text.SetToFormat(B_TRANSLATE_COMMENT("uninstall package %s\n",
214 "Don't change '%s' variable"),
215 package->VersionedName().String());
216 }
217
218 BStringView* packageView = new BStringView(NULL, text);
219 packagesGroup->AddView(packageView);
220 packageView->SetExplicitMaxSize(BSize(B_SIZE_UNLIMITED, B_SIZE_UNSET));
221 packageView->AdoptParentColors();
222
223 packagesAdded = true;
224 }
225
226 return packagesAdded;
227 }
228