BPicture: Fix archive constructor.
[haiku.git] / src / apps / deskbar / PreferencesWindow.cpp
blobc3be5d630b44abcf0af7f3af1afad8435fcfbeb8
1 /*
2 * Copyright 2009-2011 Haiku, Inc.
3 * All Rights Reserved. Distributed under the terms of the MIT License.
5 * Authors:
6 * John Scipione, jscipione@gmail.com
7 * Jonas Sundström, jonas@kirilla.com
8 */
11 #include "PreferencesWindow.h"
13 #include <Box.h>
14 #include <Button.h>
15 #include <Catalog.h>
16 #include <CheckBox.h>
17 #include <ControlLook.h>
18 #include <File.h>
19 #include <FormattingConventions.h>
20 #include <GroupLayout.h>
21 #include <ListView.h>
22 #include <Locale.h>
23 #include <LayoutBuilder.h>
24 #include <OpenWithTracker.h>
25 #include <Path.h>
26 #include <RadioButton.h>
27 #include <Roster.h>
28 #include <SeparatorView.h>
29 #include <Screen.h>
30 #include <Slider.h>
31 #include <SpaceLayoutItem.h>
32 #include <Spinner.h>
33 #include <View.h>
35 #include "BarApp.h"
36 #include "DeskbarUtils.h"
37 #include "StatusView.h"
40 static const float kIndentSpacing
41 = be_control_look->DefaultItemSpacing() * 2.3;
42 static const uint32 kSettingsViewChanged = 'Svch';
43 static const char* kSettingsFileName = "prefs_window_settings";
46 #undef B_TRANSLATION_CONTEXT
47 #define B_TRANSLATION_CONTEXT "PreferencesWindow"
50 PreferencesWindow::PreferencesWindow(BRect frame)
52 BWindow(frame, B_TRANSLATE("Deskbar preferences"), B_TITLED_WINDOW,
53 B_NOT_RESIZABLE | B_AUTO_UPDATE_SIZE_LIMITS | B_NOT_ZOOMABLE)
55 // Initial settings (used by revert button)
56 memcpy(&fSettings, static_cast<TBarApp*>(be_app)->Settings(),
57 sizeof(desk_settings));
59 // Menu controls
60 fMenuRecentDocuments = new BCheckBox(B_TRANSLATE("Recent documents:"),
61 new BMessage(kUpdateRecentCounts));
62 fMenuRecentApplications = new BCheckBox(B_TRANSLATE("Recent applications:"),
63 new BMessage(kUpdateRecentCounts));
64 fMenuRecentFolders = new BCheckBox(B_TRANSLATE("Recent folders:"),
65 new BMessage(kUpdateRecentCounts));
67 fMenuRecentDocumentCount = new BSpinner("recent documents", NULL,
68 new BMessage(kUpdateRecentCounts));
69 fMenuRecentApplicationCount = new BSpinner("recent applications", NULL,
70 new BMessage(kUpdateRecentCounts));
71 fMenuRecentFolderCount = new BSpinner("recent folders", NULL,
72 new BMessage(kUpdateRecentCounts));
74 // Applications controls
75 fAppsSort = new BCheckBox(B_TRANSLATE("Sort applications by name"),
76 new BMessage(kSortRunningApps));
77 fAppsSortTrackerFirst = new BCheckBox(B_TRANSLATE("Tracker always first"),
78 new BMessage(kTrackerFirst));
79 fAppsShowExpanders = new BCheckBox(B_TRANSLATE("Show application expander"),
80 new BMessage(kSuperExpando));
81 fAppsExpandNew = new BCheckBox(B_TRANSLATE("Expand new applications"),
82 new BMessage(kExpandNewTeams));
83 fAppsHideLabels = new BCheckBox(B_TRANSLATE("Hide application names"),
84 new BMessage(kHideLabels));
85 fAppsIconSizeSlider = new BSlider("icon_size", B_TRANSLATE("Icon size"),
86 new BMessage(kResizeTeamIcons), kMinimumIconSize / kIconSizeInterval,
87 kMaximumIconSize / kIconSizeInterval, B_HORIZONTAL);
88 fAppsIconSizeSlider->SetHashMarks(B_HASH_MARKS_BOTTOM);
89 fAppsIconSizeSlider->SetHashMarkCount((kMaximumIconSize - kMinimumIconSize)
90 / kIconSizeInterval + 1);
91 fAppsIconSizeSlider->SetLimitLabels(B_TRANSLATE("Small"),
92 B_TRANSLATE("Large"));
93 fAppsIconSizeSlider->SetModificationMessage(new BMessage(kResizeTeamIcons));
95 // Window controls
96 fWindowAlwaysOnTop = new BCheckBox(B_TRANSLATE("Always on top"),
97 new BMessage(kAlwaysTop));
98 fWindowAutoRaise = new BCheckBox(B_TRANSLATE("Auto-raise"),
99 new BMessage(kAutoRaise));
100 fWindowAutoHide = new BCheckBox(B_TRANSLATE("Auto-hide"),
101 new BMessage(kAutoHide));
103 // Menu settings
104 fMenuRecentDocuments->SetValue(fSettings.recentDocsEnabled);
105 fMenuRecentDocumentCount->SetEnabled(fSettings.recentDocsEnabled);
106 fMenuRecentDocumentCount->SetRange(0, 50);
107 fMenuRecentDocumentCount->SetValue(fSettings.recentDocsCount);
109 fMenuRecentApplications->SetValue(fSettings.recentAppsEnabled);
110 fMenuRecentApplicationCount->SetEnabled(fSettings.recentAppsEnabled);
111 fMenuRecentApplicationCount->SetRange(0, 50);
112 fMenuRecentApplicationCount->SetValue(fSettings.recentAppsCount);
114 fMenuRecentFolders->SetValue(fSettings.recentFoldersEnabled);
115 fMenuRecentFolderCount->SetEnabled(fSettings.recentFoldersEnabled);
116 fMenuRecentFolderCount->SetRange(0, 50);
117 fMenuRecentFolderCount->SetValue(fSettings.recentFoldersCount);
119 // Applications settings
120 fAppsSort->SetValue(fSettings.sortRunningApps);
121 fAppsSortTrackerFirst->SetValue(fSettings.trackerAlwaysFirst);
122 fAppsShowExpanders->SetValue(fSettings.superExpando);
123 fAppsExpandNew->SetValue(fSettings.expandNewTeams);
124 fAppsHideLabels->SetValue(fSettings.hideLabels);
125 fAppsIconSizeSlider->SetValue(fSettings.iconSize
126 / kIconSizeInterval);
128 // Window settings
129 fWindowAlwaysOnTop->SetValue(fSettings.alwaysOnTop);
130 fWindowAutoRaise->SetValue(fSettings.autoRaise);
131 fWindowAutoHide->SetValue(fSettings.autoHide);
133 _EnableDisableDependentItems();
135 // Targets
136 fAppsSort->SetTarget(be_app);
137 fAppsSortTrackerFirst->SetTarget(be_app);
138 fAppsShowExpanders->SetTarget(be_app);
139 fAppsExpandNew->SetTarget(be_app);
140 fAppsHideLabels->SetTarget(be_app);
141 fAppsIconSizeSlider->SetTarget(be_app);
143 fWindowAlwaysOnTop->SetTarget(be_app);
144 fWindowAutoRaise->SetTarget(be_app);
145 fWindowAutoHide->SetTarget(be_app);
147 // Applications
148 BBox* appsSettingsBox = new BBox("applications");
149 appsSettingsBox->SetLabel(B_TRANSLATE("Applications"));
150 appsSettingsBox->AddChild(BLayoutBuilder::Group<>()
151 .AddGroup(B_VERTICAL, 0)
152 .Add(fAppsSort)
153 .Add(fAppsSortTrackerFirst)
154 .Add(fAppsShowExpanders)
155 .AddGroup(B_HORIZONTAL, 0)
156 .Add(BSpaceLayoutItem::CreateHorizontalStrut(kIndentSpacing))
157 .Add(fAppsExpandNew)
158 .End()
159 .Add(fAppsHideLabels)
160 .AddGlue()
161 .Add(BSpaceLayoutItem::CreateVerticalStrut(B_USE_SMALL_SPACING))
162 .Add(fAppsIconSizeSlider)
163 .SetInsets(B_USE_DEFAULT_SPACING, B_USE_DEFAULT_SPACING,
164 B_USE_DEFAULT_SPACING, B_USE_DEFAULT_SPACING)
165 .End()
166 .View());
168 // Menu
169 BBox* menuBox = new BBox("menu");
170 menuBox->SetLabel(B_TRANSLATE("Menu"));
171 menuBox->AddChild(BLayoutBuilder::Group<>()
172 .AddGroup(B_VERTICAL, 0)
173 .AddGroup(B_HORIZONTAL, 0)
174 .AddGroup(B_VERTICAL, 0)
175 .Add(fMenuRecentDocuments)
176 .Add(fMenuRecentFolders)
177 .Add(fMenuRecentApplications)
178 .End()
179 .AddGroup(B_VERTICAL, 0)
180 .Add(fMenuRecentDocumentCount)
181 .Add(fMenuRecentFolderCount)
182 .Add(fMenuRecentApplicationCount)
183 .End()
184 .End()
185 .Add(BSpaceLayoutItem::CreateVerticalStrut(
186 B_USE_SMALL_SPACING))
187 .Add(new BButton(B_TRANSLATE("Edit in Tracker"
188 B_UTF8_ELLIPSIS), new BMessage(kEditInTracker)))
189 .AddGlue()
190 .SetInsets(B_USE_DEFAULT_SPACING, B_USE_DEFAULT_SPACING,
191 B_USE_DEFAULT_SPACING, B_USE_DEFAULT_SPACING)
192 .End()
193 .View());
195 // Window
196 BBox* windowSettingsBox = new BBox("window");
197 windowSettingsBox->SetLabel(B_TRANSLATE("Window"));
198 windowSettingsBox->AddChild(BLayoutBuilder::Group<>()
199 .SetExplicitMaxSize(BSize(B_SIZE_UNLIMITED, B_SIZE_UNSET))
200 .AddGroup(B_VERTICAL, 0)
201 .Add(fWindowAlwaysOnTop)
202 .Add(fWindowAutoRaise)
203 .Add(fWindowAutoHide)
204 .AddGlue()
205 .SetInsets(B_USE_DEFAULT_SPACING, B_USE_DEFAULT_SPACING,
206 B_USE_DEFAULT_SPACING, B_USE_DEFAULT_SPACING)
207 .End()
208 .View());
210 // Action Buttons
211 fDefaultsButton = new BButton(B_TRANSLATE("Defaults"),
212 new BMessage(kDefaults));
213 fRevertButton = new BButton(B_TRANSLATE("Revert"),
214 new BMessage(kRevert));
216 // Layout
217 BLayoutBuilder::Group<>(this)
218 .AddGroup(B_VERTICAL, B_USE_DEFAULT_SPACING)
219 .AddGroup(B_HORIZONTAL, B_USE_DEFAULT_SPACING)
220 .Add(appsSettingsBox)
221 .AddGroup(B_VERTICAL, B_USE_SMALL_SPACING)
222 .Add(menuBox)
223 .Add(windowSettingsBox)
224 .End()
225 .End()
226 .AddGroup(B_HORIZONTAL, B_USE_DEFAULT_SPACING)
227 .Add(fDefaultsButton)
228 .Add(fRevertButton)
229 .AddGlue()
230 .End()
231 .SetInsets(B_USE_DEFAULT_SPACING)
232 .End();
234 BMessage windowSettings;
235 BPoint where;
236 if (_LoadSettings(&windowSettings) == B_OK
237 && windowSettings.FindPoint("window_position", &where) == B_OK
238 && BScreen(this).Frame().Contains(where)) {
239 MoveTo(where);
240 } else
241 CenterOnScreen();
245 PreferencesWindow::~PreferencesWindow()
247 _UpdateRecentCounts();
251 void
252 PreferencesWindow::MessageReceived(BMessage* message)
254 switch (message->what) {
255 case kEditInTracker:
256 OpenWithTracker(B_USER_DESKBAR_DIRECTORY);
257 break;
259 case kUpdatePreferences:
260 _EnableDisableDependentItems();
261 _UpdateButtons();
262 break;
264 case kUpdateRecentCounts:
265 _UpdateRecentCounts();
266 _UpdateButtons();
267 break;
269 case kStateChanged:
270 _EnableDisableDependentItems();
271 break;
273 case kRevert:
274 _UpdatePreferences(&fSettings);
275 break;
277 case kDefaults:
278 _UpdatePreferences(
279 static_cast<TBarApp*>(be_app)->DefaultSettings());
280 break;
282 default:
283 BWindow::MessageReceived(message);
284 break;
289 bool
290 PreferencesWindow::QuitRequested()
292 BMessage windowSettings;
293 windowSettings.AddPoint("window_position", Frame().LeftTop());
294 _SaveSettings(&windowSettings);
296 be_app->PostMessage(kConfigQuit);
298 return false;
302 void
303 PreferencesWindow::Show()
305 if (IsHidden())
306 SetWorkspaces(B_CURRENT_WORKSPACE);
308 _UpdateButtons();
310 BWindow::Show();
314 // #pragma mark - private methods
317 void
318 PreferencesWindow::_EnableDisableDependentItems()
320 TBarApp* barApp = static_cast<TBarApp*>(be_app);
321 if (barApp->BarView()->Vertical()
322 && barApp->BarView()->ExpandoState()) {
323 fAppsShowExpanders->SetEnabled(true);
324 fAppsExpandNew->SetEnabled(fAppsShowExpanders->Value());
325 } else {
326 fAppsShowExpanders->SetEnabled(false);
327 fAppsExpandNew->SetEnabled(false);
330 fMenuRecentDocumentCount->SetEnabled(
331 fMenuRecentDocuments->Value() != B_CONTROL_OFF);
332 fMenuRecentFolderCount->SetEnabled(
333 fMenuRecentFolders->Value() != B_CONTROL_OFF);
334 fMenuRecentApplicationCount->SetEnabled(
335 fMenuRecentApplications->Value() != B_CONTROL_OFF);
337 fWindowAutoRaise->SetEnabled(
338 fWindowAlwaysOnTop->Value() == B_CONTROL_OFF);
342 bool
343 PreferencesWindow::_IsDefaultable()
345 desk_settings* settings = static_cast<TBarApp*>(be_app)->Settings();
346 desk_settings* defaults = static_cast<TBarApp*>(be_app)->DefaultSettings();
348 return defaults->sortRunningApps != settings->sortRunningApps
349 || defaults->trackerAlwaysFirst != settings->trackerAlwaysFirst
350 || defaults->superExpando != settings->superExpando
351 || defaults->expandNewTeams != settings->expandNewTeams
352 || defaults->hideLabels != settings->hideLabels
353 || defaults->iconSize != settings->iconSize
354 || defaults->recentAppsEnabled != settings->recentAppsEnabled
355 || defaults->recentDocsEnabled != settings->recentDocsEnabled
356 || defaults->recentFoldersEnabled
357 != settings->recentFoldersEnabled
358 || defaults->recentAppsCount != settings->recentAppsCount
359 || defaults->recentDocsCount != settings->recentDocsCount
360 || defaults->recentFoldersCount != settings->recentFoldersCount
361 || defaults->alwaysOnTop != settings->alwaysOnTop
362 || defaults->autoRaise != settings->autoRaise
363 || defaults->autoHide != settings->autoHide;
367 bool
368 PreferencesWindow::_IsRevertable()
370 desk_settings* settings = static_cast<TBarApp*>(be_app)->Settings();
372 return fSettings.sortRunningApps != settings->sortRunningApps
373 || fSettings.trackerAlwaysFirst != settings->trackerAlwaysFirst
374 || fSettings.superExpando != settings->superExpando
375 || fSettings.expandNewTeams != settings->expandNewTeams
376 || fSettings.hideLabels != settings->hideLabels
377 || fSettings.iconSize != settings->iconSize
378 || fSettings.recentAppsEnabled != settings->recentAppsEnabled
379 || fSettings.recentDocsEnabled != settings->recentDocsEnabled
380 || fSettings.recentFoldersEnabled
381 != settings->recentFoldersEnabled
382 || fSettings.recentAppsCount != settings->recentAppsCount
383 || fSettings.recentDocsCount != settings->recentDocsCount
384 || fSettings.recentFoldersCount != settings->recentFoldersCount
385 || fSettings.alwaysOnTop != settings->alwaysOnTop
386 || fSettings.autoRaise != settings->autoRaise
387 || fSettings.autoHide != settings->autoHide;
391 status_t
392 PreferencesWindow::_InitSettingsFile(BFile* file, bool write)
394 BPath prefsPath;
395 status_t status = GetDeskbarSettingsDirectory(prefsPath);
396 if (status != B_OK)
397 return status;
399 status = prefsPath.Append(kSettingsFileName);
400 if (status != B_OK)
401 return status;
403 if (write) {
404 status = file->SetTo(prefsPath.Path(),
405 B_CREATE_FILE | B_ERASE_FILE | B_WRITE_ONLY);
406 } else
407 status = file->SetTo(prefsPath.Path(), B_READ_ONLY);
409 return status;
413 status_t
414 PreferencesWindow::_LoadSettings(BMessage* settings)
416 BFile prefsFile;
417 status_t status = _InitSettingsFile(&prefsFile, false);
418 if (status != B_OK)
419 return status;
421 return settings->Unflatten(&prefsFile);
425 status_t
426 PreferencesWindow::_SaveSettings(BMessage* settings)
428 BFile prefsFile;
429 status_t status = _InitSettingsFile(&prefsFile, true);
430 if (status != B_OK)
431 return status;
433 return settings->Flatten(&prefsFile);
437 void
438 PreferencesWindow::_UpdateButtons()
440 fDefaultsButton->SetEnabled(_IsDefaultable());
441 fRevertButton->SetEnabled(_IsRevertable());
445 void
446 PreferencesWindow::_UpdatePreferences(desk_settings* settings)
448 desk_settings* current = static_cast<TBarApp*>(be_app)->Settings();
449 bool updateRecentCounts = false;
451 if (current->sortRunningApps != settings->sortRunningApps) {
452 fAppsSort->SetValue(settings->sortRunningApps);
453 fAppsSort->Invoke();
455 if (current->trackerAlwaysFirst != settings->trackerAlwaysFirst) {
456 fAppsSortTrackerFirst->SetValue(settings->trackerAlwaysFirst);
457 fAppsSortTrackerFirst->Invoke();
459 if (current->superExpando != settings->superExpando) {
460 fAppsShowExpanders->SetValue(settings->superExpando);
461 fAppsShowExpanders->Invoke();
463 if (current->expandNewTeams != settings->expandNewTeams) {
464 fAppsExpandNew->SetValue(settings->expandNewTeams);
465 fAppsExpandNew->Invoke();
467 if (current->hideLabels != settings->hideLabels) {
468 fAppsHideLabels->SetValue(settings->hideLabels);
469 fAppsHideLabels->Invoke();
471 if (current->iconSize != settings->iconSize) {
472 fAppsIconSizeSlider->SetValue(settings->iconSize / kIconSizeInterval);
473 fAppsIconSizeSlider->Invoke();
475 if (current->recentDocsEnabled != settings->recentDocsEnabled) {
476 fMenuRecentDocuments->SetValue(settings->recentDocsEnabled
477 ? B_CONTROL_ON : B_CONTROL_OFF);
478 updateRecentCounts = true;
480 if (current->recentFoldersEnabled != settings->recentFoldersEnabled) {
481 fMenuRecentFolders->SetValue(settings->recentFoldersEnabled
482 ? B_CONTROL_ON : B_CONTROL_OFF);
483 updateRecentCounts = true;
485 if (current->recentAppsEnabled != settings->recentAppsEnabled) {
486 fMenuRecentApplications->SetValue(settings->recentAppsEnabled
487 ? B_CONTROL_ON : B_CONTROL_OFF);
488 updateRecentCounts = true;
490 if (current->recentDocsCount != settings->recentDocsCount) {
491 fMenuRecentDocumentCount->SetValue(settings->recentDocsCount);
492 updateRecentCounts = true;
494 if (current->recentFoldersCount != settings->recentFoldersCount) {
495 fMenuRecentFolderCount->SetValue(settings->recentFoldersCount);
496 updateRecentCounts = true;
498 if (current->recentAppsCount != settings->recentAppsCount) {
499 fMenuRecentApplicationCount->SetValue(settings->recentAppsCount);
500 updateRecentCounts = true;
502 if (current->alwaysOnTop != settings->alwaysOnTop) {
503 fWindowAlwaysOnTop->SetValue(settings->alwaysOnTop);
504 fWindowAlwaysOnTop->Invoke();
506 if (current->autoRaise != settings->autoRaise) {
507 fWindowAutoRaise->SetValue(settings->autoRaise);
508 fWindowAutoRaise->Invoke();
510 if (current->autoHide != settings->autoHide) {
511 fWindowAutoHide->SetValue(settings->autoHide);
512 fWindowAutoHide->Invoke();
515 if (updateRecentCounts)
516 _UpdateRecentCounts();
520 void
521 PreferencesWindow::_UpdateRecentCounts()
523 BMessage message(kUpdateRecentCounts);
525 message.AddInt32("documents", fMenuRecentDocumentCount->Value());
526 message.AddInt32("applications", fMenuRecentApplicationCount->Value());
527 message.AddInt32("folders", fMenuRecentFolderCount->Value());
529 message.AddBool("documentsEnabled", fMenuRecentDocuments->Value());
530 message.AddBool("applicationsEnabled", fMenuRecentApplications->Value());
531 message.AddBool("foldersEnabled", fMenuRecentFolders->Value());
533 be_app->PostMessage(&message);
535 _EnableDisableDependentItems();