104c9d578SStephan Aßmus /*
2f7c2983eSAxel Dörfler * Copyright 2015, Axel Dörfler, <axeld@pinc-software.de>.
304c9d578SStephan Aßmus * Copyright 2013-2014, Stephan Aßmus <superstippi@gmx.de>.
404c9d578SStephan Aßmus * Copyright 2013, Rene Gollent, rene@gollent.com.
504c9d578SStephan Aßmus * Copyright 2013, Ingo Weinhold, ingo_weinhold@gmx.de.
688af15cfSAndrew Lindesay * Copyright 2016-2024, Andrew Lindesay <apl@lindesay.co.nz>.
7125d42d9SJulian Harnath * Copyright 2017, Julian Harnath <julian.harnath@rwth-aachen.de>.
804c9d578SStephan Aßmus * All rights reserved. Distributed under the terms of the MIT License.
904c9d578SStephan Aßmus */
1004c9d578SStephan Aßmus #include "MainWindow.h"
1104c9d578SStephan Aßmus
1204c9d578SStephan Aßmus #include <map>
133b17d8ddSAndrew Lindesay #include <vector>
1404c9d578SStephan Aßmus
1504c9d578SStephan Aßmus #include <stdio.h>
1604c9d578SStephan Aßmus #include <Alert.h>
1704c9d578SStephan Aßmus #include <Autolock.h>
1804c9d578SStephan Aßmus #include <Application.h>
1904c9d578SStephan Aßmus #include <Button.h>
2004c9d578SStephan Aßmus #include <Catalog.h>
214b930ccaSStephan Aßmus #include <CardLayout.h>
2204c9d578SStephan Aßmus #include <LayoutBuilder.h>
2304c9d578SStephan Aßmus #include <MenuBar.h>
2404c9d578SStephan Aßmus #include <MenuItem.h>
2584674570SAndrew Lindesay #include <MessageRunner.h>
2604c9d578SStephan Aßmus #include <Messenger.h>
275bf2b6ebSBrian Hill #include <Roster.h>
28f7c2983eSAxel Dörfler #include <Screen.h>
2904c9d578SStephan Aßmus #include <ScrollView.h>
3004c9d578SStephan Aßmus #include <StringList.h>
310a9c9029SStephan Aßmus #include <StringView.h>
3204c9d578SStephan Aßmus #include <TabView.h>
3304c9d578SStephan Aßmus
343369e03dSAndrew Lindesay #include "AppUtils.h"
3504c9d578SStephan Aßmus #include "AutoDeleter.h"
3604c9d578SStephan Aßmus #include "AutoLocker.h"
3704c9d578SStephan Aßmus #include "DecisionProvider.h"
384b930ccaSStephan Aßmus #include "FeaturedPackagesView.h"
3904c9d578SStephan Aßmus #include "FilterView.h"
40d668d227SAndrew Lindesay #include "LocaleUtils.h"
41d13c3d89SAndrew Lindesay #include "Logger.h"
4204c9d578SStephan Aßmus #include "PackageInfoView.h"
4304c9d578SStephan Aßmus #include "PackageListView.h"
4404c9d578SStephan Aßmus #include "PackageManager.h"
45*c0789628SAndrew Lindesay #include "PackageUtils.h"
463369e03dSAndrew Lindesay #include "ProcessCoordinator.h"
473369e03dSAndrew Lindesay #include "ProcessCoordinatorFactory.h"
4804c9d578SStephan Aßmus #include "RatePackageWindow.h"
494b3c808eSAndrew Lindesay #include "RatingUtils.h"
50d5ef985eSStephan Aßmus #include "ScreenshotWindow.h"
51133ebab6SAndrew Lindesay #include "SettingsWindow.h"
5295c7b018SAndrew Lindesay #include "ShuttingDownWindow.h"
5310cd325cSAndrew Lindesay #include "ToLatestUserUsageConditionsWindow.h"
5404c9d578SStephan Aßmus #include "UserLoginWindow.h"
5501339a54SAndrew Lindesay #include "UserUsageConditionsWindow.h"
56125d42d9SJulian Harnath #include "WorkStatusView.h"
57d668d227SAndrew Lindesay #include "support.h"
5804c9d578SStephan Aßmus
5904c9d578SStephan Aßmus
6004c9d578SStephan Aßmus #undef B_TRANSLATION_CONTEXT
6104c9d578SStephan Aßmus #define B_TRANSLATION_CONTEXT "MainWindow"
6204c9d578SStephan Aßmus
6304c9d578SStephan Aßmus
6404c9d578SStephan Aßmus enum {
655bf2b6ebSBrian Hill MSG_REFRESH_REPOS = 'mrrp',
665bf2b6ebSBrian Hill MSG_MANAGE_REPOS = 'mmrp',
67d144f952SAugustin Cavalier MSG_SOFTWARE_UPDATER = 'mswu',
68133ebab6SAndrew Lindesay MSG_SETTINGS = 'stgs',
6904c9d578SStephan Aßmus MSG_LOG_IN = 'lgin',
708f03a0f9SStephan Aßmus MSG_AUTHORIZATION_CHANGED = 'athc',
7189b16bb4SAndrew Lindesay MSG_CATEGORIES_LIST_CHANGED = 'clic',
72da651104SStephan Aßmus MSG_PACKAGE_CHANGED = 'pchd',
73409af934SAndrew Lindesay MSG_PROCESS_COORDINATOR_CHANGED = 'pccd',
743369e03dSAndrew Lindesay MSG_WORK_STATUS_CHANGE = 'wsch',
753369e03dSAndrew Lindesay MSG_WORK_STATUS_CLEAR = 'wscl',
7684674570SAndrew Lindesay MSG_INCREMENT_VIEW_COUNTER = 'icrv',
7788af15cfSAndrew Lindesay MSG_SCREENSHOT_CACHED = 'ssca',
78fdec4227SStephan Aßmus
79ccf707d0SAndrew Lindesay MSG_CHANGE_PACKAGE_LIST_VIEW_MODE = 'cplm',
80fdec4227SStephan Aßmus MSG_SHOW_AVAILABLE_PACKAGES = 'savl',
81fdec4227SStephan Aßmus MSG_SHOW_INSTALLED_PACKAGES = 'sins',
8204c9d578SStephan Aßmus MSG_SHOW_SOURCE_PACKAGES = 'ssrc',
8304c9d578SStephan Aßmus MSG_SHOW_DEVELOP_PACKAGES = 'sdvl'
8404c9d578SStephan Aßmus };
8504c9d578SStephan Aßmus
8610cd325cSAndrew Lindesay #define KEY_ERROR_STATUS "errorStatus"
87ccf707d0SAndrew Lindesay
8884674570SAndrew Lindesay const bigtime_t kIncrementViewCounterDelayMicros = 3 * 1000 * 1000;
8984674570SAndrew Lindesay
90ccf707d0SAndrew Lindesay #define TAB_PROMINENT_PACKAGES 0
91ccf707d0SAndrew Lindesay #define TAB_ALL_PACKAGES 1
9204c9d578SStephan Aßmus
9304c9d578SStephan Aßmus using namespace BPackageKit;
9404c9d578SStephan Aßmus using namespace BPackageKit::BManager::BPrivate;
9504c9d578SStephan Aßmus
9604c9d578SStephan Aßmus
9704c9d578SStephan Aßmus typedef std::map<BString, PackageInfoRef> PackageInfoMap;
9804c9d578SStephan Aßmus
9904c9d578SStephan Aßmus
10004c9d578SStephan Aßmus struct RefreshWorkerParameters {
10104c9d578SStephan Aßmus MainWindow* window;
10204c9d578SStephan Aßmus bool forceRefresh;
10304c9d578SStephan Aßmus
RefreshWorkerParametersRefreshWorkerParameters10404c9d578SStephan Aßmus RefreshWorkerParameters(MainWindow* window, bool forceRefresh)
10504c9d578SStephan Aßmus :
10604c9d578SStephan Aßmus window(window),
10704c9d578SStephan Aßmus forceRefresh(forceRefresh)
10804c9d578SStephan Aßmus {
10904c9d578SStephan Aßmus }
11004c9d578SStephan Aßmus };
11104c9d578SStephan Aßmus
11204c9d578SStephan Aßmus
11389b16bb4SAndrew Lindesay class MainWindowModelListener : public ModelListener {
1148f03a0f9SStephan Aßmus public:
MainWindowModelListener(const BMessenger & messenger)11589b16bb4SAndrew Lindesay MainWindowModelListener(const BMessenger& messenger)
1168f03a0f9SStephan Aßmus :
1178f03a0f9SStephan Aßmus fMessenger(messenger)
1188f03a0f9SStephan Aßmus {
1198f03a0f9SStephan Aßmus }
1208f03a0f9SStephan Aßmus
AuthorizationChanged()1218f03a0f9SStephan Aßmus virtual void AuthorizationChanged()
1228f03a0f9SStephan Aßmus {
1238f03a0f9SStephan Aßmus if (fMessenger.IsValid())
1248f03a0f9SStephan Aßmus fMessenger.SendMessage(MSG_AUTHORIZATION_CHANGED);
1258f03a0f9SStephan Aßmus }
1268f03a0f9SStephan Aßmus
CategoryListChanged()12789b16bb4SAndrew Lindesay virtual void CategoryListChanged()
12889b16bb4SAndrew Lindesay {
12989b16bb4SAndrew Lindesay if (fMessenger.IsValid())
13089b16bb4SAndrew Lindesay fMessenger.SendMessage(MSG_CATEGORIES_LIST_CHANGED);
13189b16bb4SAndrew Lindesay }
13289b16bb4SAndrew Lindesay
ScreenshotCached(const ScreenshotCoordinate & coordinate)13388af15cfSAndrew Lindesay virtual void ScreenshotCached(const ScreenshotCoordinate& coordinate)
13488af15cfSAndrew Lindesay {
13588af15cfSAndrew Lindesay if (fMessenger.IsValid()) {
13688af15cfSAndrew Lindesay BMessage message(MSG_SCREENSHOT_CACHED);
13788af15cfSAndrew Lindesay if (coordinate.Archive(&message) != B_OK)
13888af15cfSAndrew Lindesay debugger("unable to serialize a screenshot coordinate");
13988af15cfSAndrew Lindesay fMessenger.SendMessage(&message);
14088af15cfSAndrew Lindesay }
14188af15cfSAndrew Lindesay }
14288af15cfSAndrew Lindesay
1438f03a0f9SStephan Aßmus private:
1448f03a0f9SStephan Aßmus BMessenger fMessenger;
1458f03a0f9SStephan Aßmus };
1468f03a0f9SStephan Aßmus
1478f03a0f9SStephan Aßmus
148409af934SAndrew Lindesay class MainWindowPackageInfoListener : public PackageInfoListener {
149409af934SAndrew Lindesay public:
MainWindowPackageInfoListener(MainWindow * mainWindow)150409af934SAndrew Lindesay MainWindowPackageInfoListener(MainWindow* mainWindow)
151409af934SAndrew Lindesay :
152409af934SAndrew Lindesay fMainWindow(mainWindow)
153409af934SAndrew Lindesay {
154409af934SAndrew Lindesay }
155409af934SAndrew Lindesay
~MainWindowPackageInfoListener()156409af934SAndrew Lindesay ~MainWindowPackageInfoListener()
157409af934SAndrew Lindesay {
158409af934SAndrew Lindesay }
159409af934SAndrew Lindesay
160409af934SAndrew Lindesay private:
161409af934SAndrew Lindesay // PackageInfoListener
PackageChanged(const PackageInfoEvent & event)162409af934SAndrew Lindesay virtual void PackageChanged(const PackageInfoEvent& event)
163409af934SAndrew Lindesay {
164409af934SAndrew Lindesay fMainWindow->PackageChanged(event);
165409af934SAndrew Lindesay }
166409af934SAndrew Lindesay
167409af934SAndrew Lindesay private:
168409af934SAndrew Lindesay MainWindow* fMainWindow;
169409af934SAndrew Lindesay };
170409af934SAndrew Lindesay
171409af934SAndrew Lindesay
MainWindow(const BMessage & settings)172f7c2983eSAxel Dörfler MainWindow::MainWindow(const BMessage& settings)
17304c9d578SStephan Aßmus :
174f7c2983eSAxel Dörfler BWindow(BRect(50, 50, 650, 550), B_TRANSLATE_SYSTEM_NAME("HaikuDepot"),
17504c9d578SStephan Aßmus B_DOCUMENT_WINDOW_LOOK, B_NORMAL_WINDOW_FEEL,
17604c9d578SStephan Aßmus B_ASYNCHRONOUS_CONTROLS | B_AUTO_UPDATE_SIZE_LIMITS),
177d5ef985eSStephan Aßmus fScreenshotWindow(NULL),
17895c7b018SAndrew Lindesay fShuttingDownWindow(NULL),
179e0a26dceSStephan Aßmus fUserMenu(NULL),
180e0a26dceSStephan Aßmus fLogInItem(NULL),
181e0a26dceSStephan Aßmus fLogOutItem(NULL),
182976cadf1SAndrew Lindesay fUsersUserUsageConditionsMenuItem(NULL),
18389b16bb4SAndrew Lindesay fModelListener(new MainWindowModelListener(BMessenger(this)), true),
18410cd325cSAndrew Lindesay fCoordinator(NULL),
18595c7b018SAndrew Lindesay fShouldCloseWhenNoProcessesToCoordinate(false),
18684674570SAndrew Lindesay fSinglePackageMode(false),
18784674570SAndrew Lindesay fIncrementViewCounterDelayedRunner(NULL)
18804c9d578SStephan Aßmus {
18910cd325cSAndrew Lindesay if ((fCoordinatorRunningSem = create_sem(1, "ProcessCoordinatorSem")) < B_OK)
19010cd325cSAndrew Lindesay debugger("unable to create the process coordinator semaphore");
19110cd325cSAndrew Lindesay
192ad2df681SAndrew Lindesay _InitPreferredLanguage();
193ad2df681SAndrew Lindesay
194409af934SAndrew Lindesay fPackageInfoListener = PackageInfoListenerRef(
195409af934SAndrew Lindesay new MainWindowPackageInfoListener(this), true);
196409af934SAndrew Lindesay
197cbadcae1SHumdinger BMenuBar* menuBar = new BMenuBar("Main Menu");
19804c9d578SStephan Aßmus _BuildMenu(menuBar);
19904c9d578SStephan Aßmus
200cbadcae1SHumdinger BMenuBar* userMenuBar = new BMenuBar("User Menu");
201e0a26dceSStephan Aßmus _BuildUserMenu(userMenuBar);
202e0a26dceSStephan Aßmus set_small_font(userMenuBar);
203e0a26dceSStephan Aßmus userMenuBar->SetExplicitMaxSize(BSize(B_SIZE_UNSET,
204e0a26dceSStephan Aßmus menuBar->MaxSize().height));
205e0a26dceSStephan Aßmus
20604c9d578SStephan Aßmus fFilterView = new FilterView();
207f0e491d3SAndrew Lindesay fFeaturedPackagesView = new FeaturedPackagesView(fModel);
208f0e491d3SAndrew Lindesay fPackageListView = new PackageListView(&fModel);
209f0e491d3SAndrew Lindesay fPackageInfoView = new PackageInfoView(&fModel, this);
21004c9d578SStephan Aßmus
21104c9d578SStephan Aßmus fSplitView = new BSplitView(B_VERTICAL, 5.0f);
21204c9d578SStephan Aßmus
213125d42d9SJulian Harnath fWorkStatusView = new WorkStatusView("work status");
214125d42d9SJulian Harnath fPackageListView->AttachWorkStatusView(fWorkStatusView);
215125d42d9SJulian Harnath
216e00a489bSAugustin Cavalier fListTabs = new TabView(BMessenger(this),
217ccf707d0SAndrew Lindesay BMessage(MSG_CHANGE_PACKAGE_LIST_VIEW_MODE), "list tabs");
218e00a489bSAugustin Cavalier fListTabs->AddTab(fFeaturedPackagesView);
219e00a489bSAugustin Cavalier fListTabs->AddTab(fPackageListView);
2204b930ccaSStephan Aßmus
22104c9d578SStephan Aßmus BLayoutBuilder::Group<>(this, B_VERTICAL, 0.0f)
222e0a26dceSStephan Aßmus .AddGroup(B_HORIZONTAL, 0.0f)
223e0a26dceSStephan Aßmus .Add(menuBar, 1.0f)
224e0a26dceSStephan Aßmus .Add(userMenuBar, 0.0f)
225e0a26dceSStephan Aßmus .End()
22604c9d578SStephan Aßmus .Add(fFilterView)
22704c9d578SStephan Aßmus .AddSplit(fSplitView)
22804c9d578SStephan Aßmus .AddGroup(B_VERTICAL)
229e00a489bSAugustin Cavalier .Add(fListTabs)
23004c9d578SStephan Aßmus .SetInsets(
23104c9d578SStephan Aßmus B_USE_DEFAULT_SPACING, 0.0f,
23204c9d578SStephan Aßmus B_USE_DEFAULT_SPACING, 0.0f)
23304c9d578SStephan Aßmus .End()
23404c9d578SStephan Aßmus .Add(fPackageInfoView)
23504c9d578SStephan Aßmus .End()
236125d42d9SJulian Harnath .Add(fWorkStatusView)
23704c9d578SStephan Aßmus ;
23804c9d578SStephan Aßmus
23904c9d578SStephan Aßmus fSplitView->SetCollapsible(0, false);
24004c9d578SStephan Aßmus fSplitView->SetCollapsible(1, false);
24104c9d578SStephan Aßmus
2428f03a0f9SStephan Aßmus fModel.AddListener(fModelListener);
2438f03a0f9SStephan Aßmus
24404c9d578SStephan Aßmus BMessage columnSettings;
24504c9d578SStephan Aßmus if (settings.FindMessage("column settings", &columnSettings) == B_OK)
24604c9d578SStephan Aßmus fPackageListView->LoadState(&columnSettings);
24704c9d578SStephan Aßmus
248ccf707d0SAndrew Lindesay _RestoreModelSettings(settings);
249133ebab6SAndrew Lindesay _MaybePromptCanShareAnonymousUserData(settings);
25004c9d578SStephan Aßmus
251ccf707d0SAndrew Lindesay if (fModel.PackageListViewMode() == PROMINENT)
252ccf707d0SAndrew Lindesay fListTabs->Select(TAB_PROMINENT_PACKAGES);
2532997e05bSStephan Aßmus else
254ccf707d0SAndrew Lindesay fListTabs->Select(TAB_ALL_PACKAGES);
2552997e05bSStephan Aßmus
256d2d4866dSAndrew Lindesay _RestoreNickname(settings);
25710cd325cSAndrew Lindesay _UpdateAuthorization();
258f7c2983eSAxel Dörfler _RestoreWindowFrame(settings);
259f7c2983eSAxel Dörfler
2608f03a0f9SStephan Aßmus // start worker threads
26104c9d578SStephan Aßmus BPackageRoster().StartWatching(this,
26204c9d578SStephan Aßmus B_WATCH_PACKAGE_INSTALLATION_LOCATIONS);
26304c9d578SStephan Aßmus
2649883929bSAndrew Lindesay _AdoptModel();
2659883929bSAndrew Lindesay _StartBulkLoad();
26604c9d578SStephan Aßmus }
26704c9d578SStephan Aßmus
26804c9d578SStephan Aßmus
26975a70554SAndrew Lindesay /*! This constructor is used when the application is loaded for the purpose of
27075a70554SAndrew Lindesay viewing an HPKG file.
27175a70554SAndrew Lindesay */
27275a70554SAndrew Lindesay
MainWindow(const BMessage & settings,PackageInfoRef & package)273afe7affbSAndrew Lindesay MainWindow::MainWindow(const BMessage& settings, PackageInfoRef& package)
2746d519fd1SStephan Aßmus :
275f7c2983eSAxel Dörfler BWindow(BRect(50, 50, 650, 350), B_TRANSLATE_SYSTEM_NAME("HaikuDepot"),
2766d519fd1SStephan Aßmus B_DOCUMENT_WINDOW_LOOK, B_NORMAL_WINDOW_FEEL,
2776d519fd1SStephan Aßmus B_ASYNCHRONOUS_CONTROLS | B_AUTO_UPDATE_SIZE_LIMITS),
2789883929bSAndrew Lindesay fFeaturedPackagesView(NULL),
2799883929bSAndrew Lindesay fPackageListView(NULL),
280d78bfd8dSJulian Harnath fWorkStatusView(NULL),
281d5ef985eSStephan Aßmus fScreenshotWindow(NULL),
28295c7b018SAndrew Lindesay fShuttingDownWindow(NULL),
283e0a26dceSStephan Aßmus fUserMenu(NULL),
284e0a26dceSStephan Aßmus fLogInItem(NULL),
2856d519fd1SStephan Aßmus fLogOutItem(NULL),
286976cadf1SAndrew Lindesay fUsersUserUsageConditionsMenuItem(NULL),
28789b16bb4SAndrew Lindesay fModelListener(new MainWindowModelListener(BMessenger(this)), true),
28810cd325cSAndrew Lindesay fCoordinator(NULL),
28995c7b018SAndrew Lindesay fShouldCloseWhenNoProcessesToCoordinate(false),
29084674570SAndrew Lindesay fSinglePackageMode(true),
29184674570SAndrew Lindesay fIncrementViewCounterDelayedRunner(NULL)
2926d519fd1SStephan Aßmus {
29375a70554SAndrew Lindesay BString title = B_TRANSLATE("HaikuDepot - %PackageName% %PackageVersion%");
29475a70554SAndrew Lindesay title.ReplaceAll("%PackageName%", package->Name());
29575a70554SAndrew Lindesay title.ReplaceAll("%PackageVersion%", package->Version().ToString());
29675a70554SAndrew Lindesay SetTitle(title);
29775a70554SAndrew Lindesay
29810cd325cSAndrew Lindesay if ((fCoordinatorRunningSem = create_sem(1, "ProcessCoordinatorSem")) < B_OK)
29910cd325cSAndrew Lindesay debugger("unable to create the process coordinator semaphore");
30010cd325cSAndrew Lindesay
301ad2df681SAndrew Lindesay _InitPreferredLanguage();
302ad2df681SAndrew Lindesay
303409af934SAndrew Lindesay fPackageInfoListener = PackageInfoListenerRef(
304409af934SAndrew Lindesay new MainWindowPackageInfoListener(this), true);
305409af934SAndrew Lindesay
3066d519fd1SStephan Aßmus fFilterView = new FilterView();
307f0e491d3SAndrew Lindesay fPackageInfoView = new PackageInfoView(&fModel, this);
30887016f8fSAndrew Lindesay fWorkStatusView = new WorkStatusView("work status");
3096d519fd1SStephan Aßmus
3106d519fd1SStephan Aßmus BLayoutBuilder::Group<>(this, B_VERTICAL)
3116d519fd1SStephan Aßmus .Add(fPackageInfoView)
31287016f8fSAndrew Lindesay .Add(fWorkStatusView)
3136d519fd1SStephan Aßmus .SetInsets(0, B_USE_WINDOW_INSETS, 0, 0)
3146d519fd1SStephan Aßmus ;
3156d519fd1SStephan Aßmus
3166d519fd1SStephan Aßmus fModel.AddListener(fModelListener);
3176d519fd1SStephan Aßmus
318afe7affbSAndrew Lindesay // add the single package into the model so that any internal
319afe7affbSAndrew Lindesay // business logic is able to find the package.
320afe7affbSAndrew Lindesay DepotInfoRef depot(new DepotInfo("single-pkg-depot"), true);
321afe7affbSAndrew Lindesay depot->AddPackage(package);
322afe7affbSAndrew Lindesay fModel.MergeOrAddDepot(depot);
323afe7affbSAndrew Lindesay
3246d519fd1SStephan Aßmus // Restore settings
325d2d4866dSAndrew Lindesay _RestoreNickname(settings);
326ccf707d0SAndrew Lindesay _UpdateAuthorization();
327f7c2983eSAxel Dörfler _RestoreWindowFrame(settings);
3286d519fd1SStephan Aßmus
3296d519fd1SStephan Aßmus fPackageInfoView->SetPackage(package);
33063975654SStephan Aßmus
331afe7affbSAndrew Lindesay // start worker threads
332afe7affbSAndrew Lindesay BPackageRoster().StartWatching(this,
333afe7affbSAndrew Lindesay B_WATCH_PACKAGE_INSTALLATION_LOCATIONS);
3346d519fd1SStephan Aßmus }
3356d519fd1SStephan Aßmus
3366d519fd1SStephan Aßmus
~MainWindow()33704c9d578SStephan Aßmus MainWindow::~MainWindow()
33804c9d578SStephan Aßmus {
33910cd325cSAndrew Lindesay _SpinUntilProcessCoordinatorComplete();
34010cd325cSAndrew Lindesay delete_sem(fCoordinatorRunningSem);
34110cd325cSAndrew Lindesay fCoordinatorRunningSem = 0;
34210cd325cSAndrew Lindesay
34304c9d578SStephan Aßmus BPackageRoster().StopWatching(this);
34404c9d578SStephan Aßmus
34595c7b018SAndrew Lindesay if (fScreenshotWindow != NULL) {
34695c7b018SAndrew Lindesay if (fScreenshotWindow->Lock())
347d5ef985eSStephan Aßmus fScreenshotWindow->Quit();
34804c9d578SStephan Aßmus }
34904c9d578SStephan Aßmus
35095c7b018SAndrew Lindesay if (fShuttingDownWindow != NULL) {
35195c7b018SAndrew Lindesay if (fShuttingDownWindow->Lock())
35295c7b018SAndrew Lindesay fShuttingDownWindow->Quit();
35395c7b018SAndrew Lindesay }
354d5562247SAugustin Cavalier
3554329a83fSAugustin Cavalier // We must clear the model early to release references.
356d5562247SAugustin Cavalier fModel.Clear();
35795c7b018SAndrew Lindesay }
35895c7b018SAndrew Lindesay
35904c9d578SStephan Aßmus
36004c9d578SStephan Aßmus bool
QuitRequested()36104c9d578SStephan Aßmus MainWindow::QuitRequested()
36204c9d578SStephan Aßmus {
36304c9d578SStephan Aßmus
36410cd325cSAndrew Lindesay _StopProcessCoordinators();
3653369e03dSAndrew Lindesay
36695c7b018SAndrew Lindesay // If there are any processes in flight we need to be careful to make
36795c7b018SAndrew Lindesay // sure that they are cleanly completed before actually quitting. By
36895c7b018SAndrew Lindesay // turning on the `fShouldCloseWhenNoProcessesToCoordinate` flag, when
36995c7b018SAndrew Lindesay // the process coordination has completed then it will detect this and
37095c7b018SAndrew Lindesay // quit again.
37195c7b018SAndrew Lindesay
37295c7b018SAndrew Lindesay {
37395c7b018SAndrew Lindesay AutoLocker<BLocker> lock(&fCoordinatorLock);
37495c7b018SAndrew Lindesay fShouldCloseWhenNoProcessesToCoordinate = true;
37595c7b018SAndrew Lindesay
376409af934SAndrew Lindesay if (fCoordinator != NULL) {
37795c7b018SAndrew Lindesay HDINFO("a coordinator is running --> will wait before quitting...");
37895c7b018SAndrew Lindesay
37995c7b018SAndrew Lindesay if (fShuttingDownWindow == NULL)
38095c7b018SAndrew Lindesay fShuttingDownWindow = new ShuttingDownWindow(this);
38195c7b018SAndrew Lindesay fShuttingDownWindow->Show();
38295c7b018SAndrew Lindesay
38395c7b018SAndrew Lindesay return false;
38495c7b018SAndrew Lindesay }
38595c7b018SAndrew Lindesay }
38695c7b018SAndrew Lindesay
38795c7b018SAndrew Lindesay BMessage settings;
38895c7b018SAndrew Lindesay StoreSettings(settings);
38995c7b018SAndrew Lindesay BMessage message(MSG_MAIN_WINDOW_CLOSED);
39095c7b018SAndrew Lindesay message.AddMessage(KEY_WINDOW_SETTINGS, &settings);
39195c7b018SAndrew Lindesay be_app->PostMessage(&message);
39295c7b018SAndrew Lindesay
39395c7b018SAndrew Lindesay if (fShuttingDownWindow != NULL) {
39495c7b018SAndrew Lindesay if (fShuttingDownWindow->Lock())
39595c7b018SAndrew Lindesay fShuttingDownWindow->Quit();
39695c7b018SAndrew Lindesay fShuttingDownWindow = NULL;
39795c7b018SAndrew Lindesay }
39895c7b018SAndrew Lindesay
39904c9d578SStephan Aßmus return true;
40004c9d578SStephan Aßmus }
40104c9d578SStephan Aßmus
40204c9d578SStephan Aßmus
40304c9d578SStephan Aßmus void
MessageReceived(BMessage * message)40404c9d578SStephan Aßmus MainWindow::MessageReceived(BMessage* message)
40504c9d578SStephan Aßmus {
40604c9d578SStephan Aßmus switch (message->what) {
4073369e03dSAndrew Lindesay case MSG_BULK_LOAD_DONE:
40810cd325cSAndrew Lindesay {
40910cd325cSAndrew Lindesay int64 errorStatus64;
41010cd325cSAndrew Lindesay if (message->FindInt64(KEY_ERROR_STATUS, &errorStatus64) == B_OK)
41110cd325cSAndrew Lindesay _BulkLoadCompleteReceived((status_t) errorStatus64);
41210cd325cSAndrew Lindesay else
413fa5c8097SAndrew Lindesay HDERROR("expected [%s] value in message", KEY_ERROR_STATUS);
41404c9d578SStephan Aßmus break;
41510cd325cSAndrew Lindesay }
41604c9d578SStephan Aßmus case B_SIMPLE_DATA:
41704c9d578SStephan Aßmus case B_REFS_RECEIVED:
41804c9d578SStephan Aßmus // TODO: ?
41904c9d578SStephan Aßmus break;
42004c9d578SStephan Aßmus
42104c9d578SStephan Aßmus case B_PACKAGE_UPDATE:
422f32d5c5cSAndrew Lindesay _HandleExternalPackageUpdateMessageReceived(message);
42304c9d578SStephan Aßmus break;
42404c9d578SStephan Aßmus
4255bf2b6ebSBrian Hill case MSG_REFRESH_REPOS:
4263369e03dSAndrew Lindesay _StartBulkLoad(true);
4273369e03dSAndrew Lindesay break;
4283369e03dSAndrew Lindesay
42910cd325cSAndrew Lindesay case MSG_WORK_STATUS_CLEAR:
43010cd325cSAndrew Lindesay _HandleWorkStatusClear();
43110cd325cSAndrew Lindesay break;
43210cd325cSAndrew Lindesay
4333369e03dSAndrew Lindesay case MSG_WORK_STATUS_CHANGE:
4343369e03dSAndrew Lindesay _HandleWorkStatusChangeMessageReceived(message);
43504c9d578SStephan Aßmus break;
43604c9d578SStephan Aßmus
4375bf2b6ebSBrian Hill case MSG_MANAGE_REPOS:
4385bf2b6ebSBrian Hill be_roster->Launch("application/x-vnd.Haiku-Repositories");
4395bf2b6ebSBrian Hill break;
4405bf2b6ebSBrian Hill
441d144f952SAugustin Cavalier case MSG_SOFTWARE_UPDATER:
442d144f952SAugustin Cavalier be_roster->Launch("application/x-vnd.haiku-softwareupdater");
443d144f952SAugustin Cavalier break;
444d144f952SAugustin Cavalier
44504c9d578SStephan Aßmus case MSG_LOG_IN:
4461bbda92dSStephan Aßmus _OpenLoginWindow(BMessage());
44704c9d578SStephan Aßmus break;
44804c9d578SStephan Aßmus
449133ebab6SAndrew Lindesay case MSG_SETTINGS:
450133ebab6SAndrew Lindesay _OpenSettingsWindow();
451133ebab6SAndrew Lindesay break;
452133ebab6SAndrew Lindesay
4538f03a0f9SStephan Aßmus case MSG_LOG_OUT:
454d2d4866dSAndrew Lindesay fModel.SetNickname("");
4558f03a0f9SStephan Aßmus break;
4568f03a0f9SStephan Aßmus
45701339a54SAndrew Lindesay case MSG_VIEW_LATEST_USER_USAGE_CONDITIONS:
458d2d4866dSAndrew Lindesay _ViewUserUsageConditions(LATEST);
459d2d4866dSAndrew Lindesay break;
460d2d4866dSAndrew Lindesay
461d2d4866dSAndrew Lindesay case MSG_VIEW_USERS_USER_USAGE_CONDITIONS:
462d2d4866dSAndrew Lindesay _ViewUserUsageConditions(USER);
46301339a54SAndrew Lindesay break;
46401339a54SAndrew Lindesay
4658f03a0f9SStephan Aßmus case MSG_AUTHORIZATION_CHANGED:
46610cd325cSAndrew Lindesay _StartUserVerify();
4678f03a0f9SStephan Aßmus _UpdateAuthorization();
4688f03a0f9SStephan Aßmus break;
4698f03a0f9SStephan Aßmus
47088af15cfSAndrew Lindesay case MSG_SCREENSHOT_CACHED:
47188af15cfSAndrew Lindesay _HandleScreenshotCached(message);
47288af15cfSAndrew Lindesay break;
47388af15cfSAndrew Lindesay
47489b16bb4SAndrew Lindesay case MSG_CATEGORIES_LIST_CHANGED:
47589b16bb4SAndrew Lindesay fFilterView->AdoptModel(fModel);
47689b16bb4SAndrew Lindesay break;
47789b16bb4SAndrew Lindesay
478ccf707d0SAndrew Lindesay case MSG_CHANGE_PACKAGE_LIST_VIEW_MODE:
479ccf707d0SAndrew Lindesay _HandleChangePackageListViewMode();
4804fade61fSStephan Aßmus break;
4814fade61fSStephan Aßmus
482fdec4227SStephan Aßmus case MSG_SHOW_AVAILABLE_PACKAGES:
483fdec4227SStephan Aßmus {
484fdec4227SStephan Aßmus BAutolock locker(fModel.Lock());
485363fc60bSAndrew Lindesay PackageFilterModel* filterModel = fModel.PackageFilter();
486363fc60bSAndrew Lindesay filterModel->SetShowAvailablePackages(!filterModel->ShowAvailablePackages());
487fdec4227SStephan Aßmus }
488fdec4227SStephan Aßmus _AdoptModel();
489fdec4227SStephan Aßmus break;
490fdec4227SStephan Aßmus
491fdec4227SStephan Aßmus case MSG_SHOW_INSTALLED_PACKAGES:
492fdec4227SStephan Aßmus {
493fdec4227SStephan Aßmus BAutolock locker(fModel.Lock());
494363fc60bSAndrew Lindesay PackageFilterModel* filterModel = fModel.PackageFilter();
495363fc60bSAndrew Lindesay filterModel->SetShowInstalledPackages(!filterModel->ShowInstalledPackages());
496fdec4227SStephan Aßmus }
497fdec4227SStephan Aßmus _AdoptModel();
498fdec4227SStephan Aßmus break;
499fdec4227SStephan Aßmus
50004c9d578SStephan Aßmus case MSG_SHOW_SOURCE_PACKAGES:
50104c9d578SStephan Aßmus {
50204c9d578SStephan Aßmus BAutolock locker(fModel.Lock());
503363fc60bSAndrew Lindesay PackageFilterModel* filterModel = fModel.PackageFilter();
504363fc60bSAndrew Lindesay filterModel->SetShowSourcePackages(!filterModel->ShowSourcePackages());
50504c9d578SStephan Aßmus }
50604c9d578SStephan Aßmus _AdoptModel();
50704c9d578SStephan Aßmus break;
50804c9d578SStephan Aßmus
50904c9d578SStephan Aßmus case MSG_SHOW_DEVELOP_PACKAGES:
51004c9d578SStephan Aßmus {
51104c9d578SStephan Aßmus BAutolock locker(fModel.Lock());
512363fc60bSAndrew Lindesay PackageFilterModel* filterModel = fModel.PackageFilter();
513363fc60bSAndrew Lindesay filterModel->SetShowDevelopPackages(!filterModel->ShowDevelopPackages());
51404c9d578SStephan Aßmus }
51504c9d578SStephan Aßmus _AdoptModel();
51604c9d578SStephan Aßmus break;
51704c9d578SStephan Aßmus
518a9edb9bfSAndrew Lindesay // this may be triggered by, for example, a user rating being added
519a9edb9bfSAndrew Lindesay // or having been altered.
520a9edb9bfSAndrew Lindesay case MSG_SERVER_DATA_CHANGED:
521a9edb9bfSAndrew Lindesay {
522a9edb9bfSAndrew Lindesay BString name;
523a9edb9bfSAndrew Lindesay if (message->FindString("name", &name) == B_OK) {
524a9edb9bfSAndrew Lindesay BAutolock locker(fModel.Lock());
525a9edb9bfSAndrew Lindesay if (fPackageInfoView->Package()->Name() == name) {
526a9edb9bfSAndrew Lindesay _PopulatePackageAsync(true);
527a9edb9bfSAndrew Lindesay } else {
528f96d1f4dSAndrew Lindesay HDDEBUG("pkg [%s] is updated on the server, but is "
529f96d1f4dSAndrew Lindesay "not selected so will not be updated.",
530fa5c8097SAndrew Lindesay name.String());
531a9edb9bfSAndrew Lindesay }
532a9edb9bfSAndrew Lindesay }
533a9edb9bfSAndrew Lindesay break;
534a9edb9bfSAndrew Lindesay }
535a9edb9bfSAndrew Lindesay
53684674570SAndrew Lindesay case MSG_INCREMENT_VIEW_COUNTER:
53784674570SAndrew Lindesay _HandleIncrementViewCounter(message);
53884674570SAndrew Lindesay break;
53984674570SAndrew Lindesay
54004c9d578SStephan Aßmus case MSG_PACKAGE_SELECTED:
54104c9d578SStephan Aßmus {
54272992391SStephan Aßmus BString name;
54372992391SStephan Aßmus if (message->FindString("name", &name) == B_OK) {
544c4199192SAndrew Lindesay PackageInfoRef package;
545c4199192SAndrew Lindesay {
54675ba9dbfSStephan Aßmus BAutolock locker(fModel.Lock());
547c4199192SAndrew Lindesay package = fModel.PackageForName(name);
548c4199192SAndrew Lindesay }
5496f07feadSAndrew Lindesay if (!package.IsSet() || name != package->Name())
550c4199192SAndrew Lindesay debugger("unable to find the named package");
551133ebab6SAndrew Lindesay else {
55204c9d578SStephan Aßmus _AdoptPackage(package);
55384674570SAndrew Lindesay _SetupDelayedIncrementViewCounter(package);
554133ebab6SAndrew Lindesay }
55504c9d578SStephan Aßmus } else {
55604c9d578SStephan Aßmus _ClearPackage();
55704c9d578SStephan Aßmus }
55804c9d578SStephan Aßmus break;
55904c9d578SStephan Aßmus }
56004c9d578SStephan Aßmus
56104c9d578SStephan Aßmus case MSG_CATEGORY_SELECTED:
56204c9d578SStephan Aßmus {
56389b16bb4SAndrew Lindesay BString code;
56489b16bb4SAndrew Lindesay if (message->FindString("code", &code) != B_OK)
56589b16bb4SAndrew Lindesay code = "";
56604c9d578SStephan Aßmus {
56704c9d578SStephan Aßmus BAutolock locker(fModel.Lock());
568363fc60bSAndrew Lindesay fModel.PackageFilter()->SetCategory(code);
56904c9d578SStephan Aßmus }
57004c9d578SStephan Aßmus _AdoptModel();
57104c9d578SStephan Aßmus break;
57204c9d578SStephan Aßmus }
57304c9d578SStephan Aßmus
57404c9d578SStephan Aßmus case MSG_DEPOT_SELECTED:
57504c9d578SStephan Aßmus {
57604c9d578SStephan Aßmus BString name;
57704c9d578SStephan Aßmus if (message->FindString("name", &name) != B_OK)
57804c9d578SStephan Aßmus name = "";
57904c9d578SStephan Aßmus {
58004c9d578SStephan Aßmus BAutolock locker(fModel.Lock());
581363fc60bSAndrew Lindesay fModel.PackageFilter()->SetDepotName(name);
58204c9d578SStephan Aßmus }
58304c9d578SStephan Aßmus _AdoptModel();
584b965ce70SHumdinger _UpdateAvailableRepositories();
58504c9d578SStephan Aßmus break;
58604c9d578SStephan Aßmus }
58704c9d578SStephan Aßmus
58804c9d578SStephan Aßmus case MSG_SEARCH_TERMS_MODIFIED:
58904c9d578SStephan Aßmus {
59004c9d578SStephan Aßmus // TODO: Do this with a delay!
59104c9d578SStephan Aßmus BString searchTerms;
59204c9d578SStephan Aßmus if (message->FindString("search terms", &searchTerms) != B_OK)
59304c9d578SStephan Aßmus searchTerms = "";
59404c9d578SStephan Aßmus {
59504c9d578SStephan Aßmus BAutolock locker(fModel.Lock());
596363fc60bSAndrew Lindesay fModel.PackageFilter()->SetSearchTerms(searchTerms);
59704c9d578SStephan Aßmus }
59804c9d578SStephan Aßmus _AdoptModel();
59904c9d578SStephan Aßmus break;
60004c9d578SStephan Aßmus }
60104c9d578SStephan Aßmus
602da651104SStephan Aßmus case MSG_PACKAGE_CHANGED:
60304c9d578SStephan Aßmus {
60404c9d578SStephan Aßmus PackageInfo* info;
60504c9d578SStephan Aßmus if (message->FindPointer("package", (void**)&info) == B_OK) {
60604c9d578SStephan Aßmus PackageInfoRef ref(info, true);
6070b69420bSAndrew Lindesay fFeaturedPackagesView->BeginAddRemove();
608c4199192SAndrew Lindesay _AddRemovePackageFromLists(ref);
6090b69420bSAndrew Lindesay fFeaturedPackagesView->EndAddRemove();
61010cd325cSAndrew Lindesay }
61104c9d578SStephan Aßmus break;
61204c9d578SStephan Aßmus }
61304c9d578SStephan Aßmus
614409af934SAndrew Lindesay case MSG_PROCESS_COORDINATOR_CHANGED:
615409af934SAndrew Lindesay {
616409af934SAndrew Lindesay ProcessCoordinatorState state(message);
617409af934SAndrew Lindesay _HandleProcessCoordinatorChanged(state);
618409af934SAndrew Lindesay break;
619409af934SAndrew Lindesay }
620409af934SAndrew Lindesay
62104c9d578SStephan Aßmus case MSG_RATE_PACKAGE:
6221bbda92dSStephan Aßmus _RatePackage();
62304c9d578SStephan Aßmus break;
62404c9d578SStephan Aßmus
625d5ef985eSStephan Aßmus case MSG_SHOW_SCREENSHOT:
626d5ef985eSStephan Aßmus _ShowScreenshot();
627d5ef985eSStephan Aßmus break;
628d5ef985eSStephan Aßmus
629125d42d9SJulian Harnath case MSG_PACKAGE_WORKER_BUSY:
630125d42d9SJulian Harnath {
631125d42d9SJulian Harnath BString reason;
632125d42d9SJulian Harnath status_t status = message->FindString("reason", &reason);
633125d42d9SJulian Harnath if (status != B_OK)
634125d42d9SJulian Harnath break;
635125d42d9SJulian Harnath fWorkStatusView->SetBusy(reason);
636125d42d9SJulian Harnath break;
637125d42d9SJulian Harnath }
638125d42d9SJulian Harnath
639125d42d9SJulian Harnath case MSG_PACKAGE_WORKER_IDLE:
640125d42d9SJulian Harnath fWorkStatusView->SetIdle();
641125d42d9SJulian Harnath break;
642125d42d9SJulian Harnath
64310cd325cSAndrew Lindesay case MSG_USER_USAGE_CONDITIONS_NOT_LATEST:
64410cd325cSAndrew Lindesay {
64510cd325cSAndrew Lindesay BMessage userDetailMsg;
64610cd325cSAndrew Lindesay if (message->FindMessage("userDetail", &userDetailMsg) != B_OK) {
64710cd325cSAndrew Lindesay debugger("expected the [userDetail] data to be carried in the "
64810cd325cSAndrew Lindesay "message.");
64910cd325cSAndrew Lindesay }
65010cd325cSAndrew Lindesay UserDetail userDetail(&userDetailMsg);
65110cd325cSAndrew Lindesay _HandleUserUsageConditionsNotLatest(userDetail);
65210cd325cSAndrew Lindesay break;
65310cd325cSAndrew Lindesay }
65410cd325cSAndrew Lindesay
65504c9d578SStephan Aßmus default:
65604c9d578SStephan Aßmus BWindow::MessageReceived(message);
65704c9d578SStephan Aßmus break;
65804c9d578SStephan Aßmus }
65904c9d578SStephan Aßmus }
66004c9d578SStephan Aßmus
66104c9d578SStephan Aßmus
662ccf707d0SAndrew Lindesay static const char*
main_window_package_list_view_mode_str(package_list_view_mode mode)663ccf707d0SAndrew Lindesay main_window_package_list_view_mode_str(package_list_view_mode mode)
664ccf707d0SAndrew Lindesay {
665ccf707d0SAndrew Lindesay if (mode == PROMINENT)
666ccf707d0SAndrew Lindesay return "PROMINENT";
667ccf707d0SAndrew Lindesay return "ALL";
668ccf707d0SAndrew Lindesay }
669ccf707d0SAndrew Lindesay
670ccf707d0SAndrew Lindesay
671ccf707d0SAndrew Lindesay static package_list_view_mode
main_window_str_to_package_list_view_mode(const BString & str)672ccf707d0SAndrew Lindesay main_window_str_to_package_list_view_mode(const BString& str)
673ccf707d0SAndrew Lindesay {
674ccf707d0SAndrew Lindesay if (str == "PROMINENT")
675ccf707d0SAndrew Lindesay return PROMINENT;
676ccf707d0SAndrew Lindesay return ALL;
677ccf707d0SAndrew Lindesay }
678ccf707d0SAndrew Lindesay
679ccf707d0SAndrew Lindesay
68004c9d578SStephan Aßmus void
StoreSettings(BMessage & settings)6814b347fccSAndrew Lindesay MainWindow::StoreSettings(BMessage& settings)
68204c9d578SStephan Aßmus {
683f7c2983eSAxel Dörfler settings.AddRect(_WindowFrameName(), Frame());
684f7c2983eSAxel Dörfler if (!fSinglePackageMode) {
68504c9d578SStephan Aßmus settings.AddRect("window frame", Frame());
68604c9d578SStephan Aßmus
68704c9d578SStephan Aßmus BMessage columnSettings;
6889883929bSAndrew Lindesay if (fPackageListView != NULL)
68904c9d578SStephan Aßmus fPackageListView->SaveState(&columnSettings);
69004c9d578SStephan Aßmus
69104c9d578SStephan Aßmus settings.AddMessage("column settings", &columnSettings);
69204c9d578SStephan Aßmus
693133ebab6SAndrew Lindesay settings.AddString(SETTING_PACKAGE_LIST_VIEW_MODE,
694ccf707d0SAndrew Lindesay main_window_package_list_view_mode_str(
695ccf707d0SAndrew Lindesay fModel.PackageListViewMode()));
696363fc60bSAndrew Lindesay
697133ebab6SAndrew Lindesay settings.AddBool(SETTING_SHOW_AVAILABLE_PACKAGES,
698363fc60bSAndrew Lindesay fModel.PackageFilter()->ShowAvailablePackages());
699133ebab6SAndrew Lindesay settings.AddBool(SETTING_SHOW_INSTALLED_PACKAGES,
700363fc60bSAndrew Lindesay fModel.PackageFilter()->ShowInstalledPackages());
701133ebab6SAndrew Lindesay settings.AddBool(SETTING_SHOW_DEVELOP_PACKAGES,
702363fc60bSAndrew Lindesay fModel.PackageFilter()->ShowDevelopPackages());
703133ebab6SAndrew Lindesay settings.AddBool(SETTING_SHOW_SOURCE_PACKAGES,
704363fc60bSAndrew Lindesay fModel.PackageFilter()->ShowSourcePackages());
705363fc60bSAndrew Lindesay
706133ebab6SAndrew Lindesay settings.AddBool(SETTING_CAN_SHARE_ANONYMOUS_USER_DATA,
707133ebab6SAndrew Lindesay fModel.CanShareAnonymousUsageData());
7086d519fd1SStephan Aßmus }
7098f03a0f9SStephan Aßmus
710d2d4866dSAndrew Lindesay settings.AddString("username", fModel.Nickname());
71104c9d578SStephan Aßmus }
71204c9d578SStephan Aßmus
71304c9d578SStephan Aßmus
71404c9d578SStephan Aßmus void
Consume(ProcessCoordinator * item)715a18f873fSAndrew Lindesay MainWindow::Consume(ProcessCoordinator *item)
716a18f873fSAndrew Lindesay {
717a18f873fSAndrew Lindesay _AddProcessCoordinator(item);
718a18f873fSAndrew Lindesay }
719a18f873fSAndrew Lindesay
720a18f873fSAndrew Lindesay
721a18f873fSAndrew Lindesay void
PackageChanged(const PackageInfoEvent & event)72204c9d578SStephan Aßmus MainWindow::PackageChanged(const PackageInfoEvent& event)
72304c9d578SStephan Aßmus {
724*c0789628SAndrew Lindesay uint32 watchedChanges = PKG_CHANGED_LOCAL_INFO | PKG_CHANGED_CLASSIFICATION;
725a9edb9bfSAndrew Lindesay if ((event.Changes() & watchedChanges) != 0) {
72604c9d578SStephan Aßmus PackageInfoRef ref(event.Package());
727da651104SStephan Aßmus BMessage message(MSG_PACKAGE_CHANGED);
72804c9d578SStephan Aßmus message.AddPointer("package", ref.Get());
72904c9d578SStephan Aßmus ref.Detach();
73004c9d578SStephan Aßmus // reference needs to be released by MessageReceived();
73104c9d578SStephan Aßmus PostMessage(&message);
73204c9d578SStephan Aßmus }
73304c9d578SStephan Aßmus }
73404c9d578SStephan Aßmus
73504c9d578SStephan Aßmus
73604c9d578SStephan Aßmus void
_BuildMenu(BMenuBar * menuBar)73704c9d578SStephan Aßmus MainWindow::_BuildMenu(BMenuBar* menuBar)
73804c9d578SStephan Aßmus {
7390b6928f1SHumdinger BMenu* menu = new BMenu(B_TRANSLATE_SYSTEM_NAME("HaikuDepot"));
7403369e03dSAndrew Lindesay fRefreshRepositoriesItem = new BMenuItem(
7413369e03dSAndrew Lindesay B_TRANSLATE("Refresh repositories"), new BMessage(MSG_REFRESH_REPOS));
7423369e03dSAndrew Lindesay menu->AddItem(fRefreshRepositoriesItem);
743d7f78130SHumdinger menu->AddItem(new BMenuItem(B_TRANSLATE("Manage repositories"
744d7f78130SHumdinger B_UTF8_ELLIPSIS), new BMessage(MSG_MANAGE_REPOS)));
745d144f952SAugustin Cavalier menu->AddItem(new BMenuItem(B_TRANSLATE("Check for updates"
746d144f952SAugustin Cavalier B_UTF8_ELLIPSIS), new BMessage(MSG_SOFTWARE_UPDATER)));
7470b6928f1SHumdinger menu->AddSeparatorItem();
7480b6928f1SHumdinger menu->AddItem(new BMenuItem(B_TRANSLATE("Settings" B_UTF8_ELLIPSIS),
749e1ae57abSJoachim Mairböck new BMessage(MSG_SETTINGS), ','));
7500b6928f1SHumdinger menu->AddItem(new BMenuItem(B_TRANSLATE("Quit"),
7510b6928f1SHumdinger new BMessage(B_QUIT_REQUESTED), 'Q'));
75204c9d578SStephan Aßmus menuBar->AddItem(menu);
75304c9d578SStephan Aßmus
754b965ce70SHumdinger fRepositoryMenu = new BMenu(B_TRANSLATE("Repositories"));
755b965ce70SHumdinger menuBar->AddItem(fRepositoryMenu);
756b965ce70SHumdinger
7574fade61fSStephan Aßmus menu = new BMenu(B_TRANSLATE("Show"));
7584fade61fSStephan Aßmus
759fdec4227SStephan Aßmus fShowAvailablePackagesItem = new BMenuItem(
7604fade61fSStephan Aßmus B_TRANSLATE("Available packages"),
761fdec4227SStephan Aßmus new BMessage(MSG_SHOW_AVAILABLE_PACKAGES));
762fdec4227SStephan Aßmus menu->AddItem(fShowAvailablePackagesItem);
763fdec4227SStephan Aßmus
764fdec4227SStephan Aßmus fShowInstalledPackagesItem = new BMenuItem(
7654fade61fSStephan Aßmus B_TRANSLATE("Installed packages"),
766fdec4227SStephan Aßmus new BMessage(MSG_SHOW_INSTALLED_PACKAGES));
767fdec4227SStephan Aßmus menu->AddItem(fShowInstalledPackagesItem);
768fdec4227SStephan Aßmus
769fdec4227SStephan Aßmus menu->AddSeparatorItem();
770fdec4227SStephan Aßmus
771fdec4227SStephan Aßmus fShowDevelopPackagesItem = new BMenuItem(
7724fade61fSStephan Aßmus B_TRANSLATE("Develop packages"),
773fdec4227SStephan Aßmus new BMessage(MSG_SHOW_DEVELOP_PACKAGES));
774fdec4227SStephan Aßmus menu->AddItem(fShowDevelopPackagesItem);
775fdec4227SStephan Aßmus
776fdec4227SStephan Aßmus fShowSourcePackagesItem = new BMenuItem(
7774fade61fSStephan Aßmus B_TRANSLATE("Source packages"),
778fdec4227SStephan Aßmus new BMessage(MSG_SHOW_SOURCE_PACKAGES));
779fdec4227SStephan Aßmus menu->AddItem(fShowSourcePackagesItem);
780fdec4227SStephan Aßmus
781fdec4227SStephan Aßmus menuBar->AddItem(menu);
78204c9d578SStephan Aßmus }
78304c9d578SStephan Aßmus
78404c9d578SStephan Aßmus
78504c9d578SStephan Aßmus void
_BuildUserMenu(BMenuBar * menuBar)786e0a26dceSStephan Aßmus MainWindow::_BuildUserMenu(BMenuBar* menuBar)
787e0a26dceSStephan Aßmus {
788e0a26dceSStephan Aßmus fUserMenu = new BMenu(B_TRANSLATE("Not logged in"));
789e0a26dceSStephan Aßmus
790e0a26dceSStephan Aßmus fLogInItem = new BMenuItem(B_TRANSLATE("Log in" B_UTF8_ELLIPSIS),
791e0a26dceSStephan Aßmus new BMessage(MSG_LOG_IN));
792e0a26dceSStephan Aßmus fUserMenu->AddItem(fLogInItem);
793e0a26dceSStephan Aßmus
794e0a26dceSStephan Aßmus fLogOutItem = new BMenuItem(B_TRANSLATE("Log out"),
795e0a26dceSStephan Aßmus new BMessage(MSG_LOG_OUT));
796e0a26dceSStephan Aßmus fUserMenu->AddItem(fLogOutItem);
797e0a26dceSStephan Aßmus
7980c82f64bSAndrew Lindesay BMenuItem *latestUserUsageConditionsMenuItem =
7991448ced0SHumdinger new BMenuItem(B_TRANSLATE("View latest usage conditions"
80001339a54SAndrew Lindesay B_UTF8_ELLIPSIS),
80101339a54SAndrew Lindesay new BMessage(MSG_VIEW_LATEST_USER_USAGE_CONDITIONS));
8020c82f64bSAndrew Lindesay fUserMenu->AddItem(latestUserUsageConditionsMenuItem);
80301339a54SAndrew Lindesay
804d2d4866dSAndrew Lindesay fUsersUserUsageConditionsMenuItem =
805d2d4866dSAndrew Lindesay new BMenuItem(B_TRANSLATE("View agreed usage conditions"
806d2d4866dSAndrew Lindesay B_UTF8_ELLIPSIS),
807d2d4866dSAndrew Lindesay new BMessage(MSG_VIEW_USERS_USER_USAGE_CONDITIONS));
808d2d4866dSAndrew Lindesay fUserMenu->AddItem(fUsersUserUsageConditionsMenuItem);
809d2d4866dSAndrew Lindesay
810e0a26dceSStephan Aßmus menuBar->AddItem(fUserMenu);
811e0a26dceSStephan Aßmus }
812e0a26dceSStephan Aßmus
813e0a26dceSStephan Aßmus
814e0a26dceSStephan Aßmus void
_RestoreNickname(const BMessage & settings)815d2d4866dSAndrew Lindesay MainWindow::_RestoreNickname(const BMessage& settings)
816f7c2983eSAxel Dörfler {
817d2d4866dSAndrew Lindesay BString nickname;
818d2d4866dSAndrew Lindesay if (settings.FindString("username", &nickname) == B_OK
819d2d4866dSAndrew Lindesay && nickname.Length() > 0) {
820d2d4866dSAndrew Lindesay fModel.SetNickname(nickname);
821f7c2983eSAxel Dörfler }
822f7c2983eSAxel Dörfler }
823f7c2983eSAxel Dörfler
824f7c2983eSAxel Dörfler
825f7c2983eSAxel Dörfler const char*
_WindowFrameName() const826f7c2983eSAxel Dörfler MainWindow::_WindowFrameName() const
827f7c2983eSAxel Dörfler {
828f7c2983eSAxel Dörfler if (fSinglePackageMode)
829f7c2983eSAxel Dörfler return "small window frame";
830f7c2983eSAxel Dörfler
831f7c2983eSAxel Dörfler return "window frame";
832f7c2983eSAxel Dörfler }
833f7c2983eSAxel Dörfler
834f7c2983eSAxel Dörfler
835f7c2983eSAxel Dörfler void
_RestoreWindowFrame(const BMessage & settings)836f7c2983eSAxel Dörfler MainWindow::_RestoreWindowFrame(const BMessage& settings)
837f7c2983eSAxel Dörfler {
838f7c2983eSAxel Dörfler BRect frame = Frame();
839f7c2983eSAxel Dörfler
840f7c2983eSAxel Dörfler BRect windowFrame;
841f7c2983eSAxel Dörfler bool fromSettings = false;
842f7c2983eSAxel Dörfler if (settings.FindRect(_WindowFrameName(), &windowFrame) == B_OK) {
843f7c2983eSAxel Dörfler frame = windowFrame;
844f7c2983eSAxel Dörfler fromSettings = true;
845f7c2983eSAxel Dörfler } else if (!fSinglePackageMode) {
846f7c2983eSAxel Dörfler // Resize to occupy a certain screen size
847f7c2983eSAxel Dörfler BRect screenFrame = BScreen(this).Frame();
848f7c2983eSAxel Dörfler float width = frame.Width();
849f7c2983eSAxel Dörfler float height = frame.Height();
850f7c2983eSAxel Dörfler if (width < screenFrame.Width() * .666f
851f7c2983eSAxel Dörfler && height < screenFrame.Height() * .666f) {
852f7c2983eSAxel Dörfler frame.bottom = frame.top + screenFrame.Height() * .666f;
853f7c2983eSAxel Dörfler frame.right = frame.left
854f7c2983eSAxel Dörfler + std::min(screenFrame.Width() * .666f, height * 7 / 5);
855f7c2983eSAxel Dörfler }
856f7c2983eSAxel Dörfler }
857f7c2983eSAxel Dörfler
858f7c2983eSAxel Dörfler MoveTo(frame.LeftTop());
859f7c2983eSAxel Dörfler ResizeTo(frame.Width(), frame.Height());
860f7c2983eSAxel Dörfler
861f7c2983eSAxel Dörfler if (fromSettings)
8628e96ec34SAxel Dörfler MoveOnScreen();
863f7c2983eSAxel Dörfler else
864f7c2983eSAxel Dörfler CenterOnScreen();
865f7c2983eSAxel Dörfler }
866f7c2983eSAxel Dörfler
867f7c2983eSAxel Dörfler
868f7c2983eSAxel Dörfler void
_RestoreModelSettings(const BMessage & settings)869ccf707d0SAndrew Lindesay MainWindow::_RestoreModelSettings(const BMessage& settings)
870ccf707d0SAndrew Lindesay {
871ccf707d0SAndrew Lindesay BString packageListViewMode;
872133ebab6SAndrew Lindesay if (settings.FindString(SETTING_PACKAGE_LIST_VIEW_MODE,
873ccf707d0SAndrew Lindesay &packageListViewMode) == B_OK) {
874ccf707d0SAndrew Lindesay fModel.SetPackageListViewMode(
875ccf707d0SAndrew Lindesay main_window_str_to_package_list_view_mode(packageListViewMode));
876ccf707d0SAndrew Lindesay }
877ccf707d0SAndrew Lindesay
878ccf707d0SAndrew Lindesay bool showOption;
879363fc60bSAndrew Lindesay
880133ebab6SAndrew Lindesay if (settings.FindBool(SETTING_SHOW_AVAILABLE_PACKAGES, &showOption) == B_OK)
881363fc60bSAndrew Lindesay fModel.PackageFilter()->SetShowAvailablePackages(showOption);
882133ebab6SAndrew Lindesay if (settings.FindBool(SETTING_SHOW_INSTALLED_PACKAGES, &showOption) == B_OK)
883363fc60bSAndrew Lindesay fModel.PackageFilter()->SetShowInstalledPackages(showOption);
884133ebab6SAndrew Lindesay if (settings.FindBool(SETTING_SHOW_DEVELOP_PACKAGES, &showOption) == B_OK)
885363fc60bSAndrew Lindesay fModel.PackageFilter()->SetShowDevelopPackages(showOption);
886133ebab6SAndrew Lindesay if (settings.FindBool(SETTING_SHOW_SOURCE_PACKAGES, &showOption) == B_OK)
887363fc60bSAndrew Lindesay fModel.PackageFilter()->SetShowSourcePackages(showOption);
888363fc60bSAndrew Lindesay
889133ebab6SAndrew Lindesay if (settings.FindBool(SETTING_CAN_SHARE_ANONYMOUS_USER_DATA,
890133ebab6SAndrew Lindesay &showOption) == B_OK) {
891133ebab6SAndrew Lindesay fModel.SetCanShareAnonymousUsageData(showOption);
892133ebab6SAndrew Lindesay }
893133ebab6SAndrew Lindesay }
894133ebab6SAndrew Lindesay
895133ebab6SAndrew Lindesay
896133ebab6SAndrew Lindesay void
_MaybePromptCanShareAnonymousUserData(const BMessage & settings)897133ebab6SAndrew Lindesay MainWindow::_MaybePromptCanShareAnonymousUserData(const BMessage& settings)
898133ebab6SAndrew Lindesay {
899133ebab6SAndrew Lindesay bool showOption;
900133ebab6SAndrew Lindesay if (settings.FindBool(SETTING_CAN_SHARE_ANONYMOUS_USER_DATA,
901133ebab6SAndrew Lindesay &showOption) == B_NAME_NOT_FOUND) {
902133ebab6SAndrew Lindesay _PromptCanShareAnonymousUserData();
903133ebab6SAndrew Lindesay }
904133ebab6SAndrew Lindesay }
905133ebab6SAndrew Lindesay
906133ebab6SAndrew Lindesay
907133ebab6SAndrew Lindesay void
_PromptCanShareAnonymousUserData()908133ebab6SAndrew Lindesay MainWindow::_PromptCanShareAnonymousUserData()
909133ebab6SAndrew Lindesay {
910133ebab6SAndrew Lindesay BAlert* alert = new(std::nothrow) BAlert(
911133ebab6SAndrew Lindesay B_TRANSLATE("Sending anonymous usage data"),
912133ebab6SAndrew Lindesay B_TRANSLATE("Would it be acceptable to send anonymous usage data to the"
913133ebab6SAndrew Lindesay " HaikuDepotServer system from this computer? You can change your"
914133ebab6SAndrew Lindesay " preference in the \"Settings\" window later."),
915133ebab6SAndrew Lindesay B_TRANSLATE("No"),
916133ebab6SAndrew Lindesay B_TRANSLATE("Yes"));
917133ebab6SAndrew Lindesay
918133ebab6SAndrew Lindesay int32 result = alert->Go();
919133ebab6SAndrew Lindesay fModel.SetCanShareAnonymousUsageData(1 == result);
920ccf707d0SAndrew Lindesay }
921ccf707d0SAndrew Lindesay
922ccf707d0SAndrew Lindesay
923ccf707d0SAndrew Lindesay void
_InitPreferredLanguage()924d668d227SAndrew Lindesay MainWindow::_InitPreferredLanguage()
925d668d227SAndrew Lindesay {
926d668d227SAndrew Lindesay LanguageRepository* repository = fModel.Languages();
927d668d227SAndrew Lindesay LanguageRef defaultLanguage = LocaleUtils::DeriveDefaultLanguage(repository);
928d668d227SAndrew Lindesay repository->AddLanguage(defaultLanguage);
929d668d227SAndrew Lindesay fModel.SetPreferredLanguage(defaultLanguage);
930d668d227SAndrew Lindesay }
931d668d227SAndrew Lindesay
932d668d227SAndrew Lindesay
933d668d227SAndrew Lindesay void
_AdoptModelControls()934c4199192SAndrew Lindesay MainWindow::_AdoptModelControls()
93504c9d578SStephan Aßmus {
9369883929bSAndrew Lindesay if (fSinglePackageMode)
9379883929bSAndrew Lindesay return;
9389883929bSAndrew Lindesay
93904c9d578SStephan Aßmus BAutolock locker(fModel.Lock());
940363fc60bSAndrew Lindesay fShowAvailablePackagesItem->SetMarked(fModel.PackageFilter()->ShowAvailablePackages());
941363fc60bSAndrew Lindesay fShowInstalledPackagesItem->SetMarked(fModel.PackageFilter()->ShowInstalledPackages());
942363fc60bSAndrew Lindesay fShowSourcePackagesItem->SetMarked(fModel.PackageFilter()->ShowSourcePackages());
943363fc60bSAndrew Lindesay fShowDevelopPackagesItem->SetMarked(fModel.PackageFilter()->ShowDevelopPackages());
944da651104SStephan Aßmus
945ccf707d0SAndrew Lindesay if (fModel.PackageListViewMode() == PROMINENT)
946ccf707d0SAndrew Lindesay fListTabs->Select(TAB_PROMINENT_PACKAGES);
9474fade61fSStephan Aßmus else
948ccf707d0SAndrew Lindesay fListTabs->Select(TAB_ALL_PACKAGES);
949b965ce70SHumdinger
950b965ce70SHumdinger fFilterView->AdoptModel(fModel);
95104c9d578SStephan Aßmus }
95204c9d578SStephan Aßmus
95304c9d578SStephan Aßmus
95404c9d578SStephan Aßmus void
_AdoptModel()955c4199192SAndrew Lindesay MainWindow::_AdoptModel()
956c4199192SAndrew Lindesay {
957fa5c8097SAndrew Lindesay HDTRACE("adopting model to main window ui");
958c4199192SAndrew Lindesay
959c4199192SAndrew Lindesay if (fSinglePackageMode)
960c4199192SAndrew Lindesay return;
961c4199192SAndrew Lindesay
96205880d13SAndrew Lindesay std::vector<DepotInfoRef> depots = _CreateSnapshotOfDepots();
96305880d13SAndrew Lindesay std::vector<DepotInfoRef>::iterator it;
9640b69420bSAndrew Lindesay
9650b69420bSAndrew Lindesay fFeaturedPackagesView->BeginAddRemove();
9660b69420bSAndrew Lindesay
96705880d13SAndrew Lindesay for (it = depots.begin(); it != depots.end(); it++) {
96805880d13SAndrew Lindesay DepotInfoRef depotInfoRef = *it;
969d75b4d61SAndrew Lindesay for (int i = 0; i < depotInfoRef->CountPackages(); i++) {
970d75b4d61SAndrew Lindesay PackageInfoRef package = depotInfoRef->PackageAtIndex(i);
971d75b4d61SAndrew Lindesay _AddRemovePackageFromLists(package);
972d75b4d61SAndrew Lindesay }
973c4199192SAndrew Lindesay }
974c4199192SAndrew Lindesay
9750b69420bSAndrew Lindesay fFeaturedPackagesView->EndAddRemove();
9760b69420bSAndrew Lindesay
977c4199192SAndrew Lindesay _AdoptModelControls();
978c4199192SAndrew Lindesay }
979c4199192SAndrew Lindesay
980c4199192SAndrew Lindesay
981c4199192SAndrew Lindesay void
_AddRemovePackageFromLists(const PackageInfoRef & package)982c4199192SAndrew Lindesay MainWindow::_AddRemovePackageFromLists(const PackageInfoRef& package)
983c4199192SAndrew Lindesay {
984c4199192SAndrew Lindesay bool matches;
985c4199192SAndrew Lindesay
986c4199192SAndrew Lindesay {
987c4199192SAndrew Lindesay AutoLocker<BLocker> modelLocker(fModel.Lock());
988363fc60bSAndrew Lindesay matches = fModel.PackageFilter()->Filter()->AcceptsPackage(package);
989c4199192SAndrew Lindesay }
990c4199192SAndrew Lindesay
991c4199192SAndrew Lindesay if (matches) {
9928cc3ed34SAndrew Lindesay PackageClassificationInfoRef classification = package->PackageClassificationInfo();
9938cc3ed34SAndrew Lindesay
9948cc3ed34SAndrew Lindesay if (classification.IsSet()) {
9958cc3ed34SAndrew Lindesay if (classification->IsProminent())
996c4199192SAndrew Lindesay fFeaturedPackagesView->AddPackage(package);
9978cc3ed34SAndrew Lindesay }
9988cc3ed34SAndrew Lindesay
999c4199192SAndrew Lindesay fPackageListView->AddPackage(package);
1000c4199192SAndrew Lindesay } else {
1001c4199192SAndrew Lindesay fFeaturedPackagesView->RemovePackage(package);
1002c4199192SAndrew Lindesay fPackageListView->RemovePackage(package);
1003c4199192SAndrew Lindesay }
1004c4199192SAndrew Lindesay }
1005c4199192SAndrew Lindesay
1006c4199192SAndrew Lindesay
1007c4199192SAndrew Lindesay void
_SetupDelayedIncrementViewCounter(const PackageInfoRef package)100884674570SAndrew Lindesay MainWindow::_SetupDelayedIncrementViewCounter(const PackageInfoRef package) {
100984674570SAndrew Lindesay if (fIncrementViewCounterDelayedRunner != NULL) {
101084674570SAndrew Lindesay fIncrementViewCounterDelayedRunner->SetCount(0);
101184674570SAndrew Lindesay delete fIncrementViewCounterDelayedRunner;
101284674570SAndrew Lindesay }
101384674570SAndrew Lindesay BMessage message(MSG_INCREMENT_VIEW_COUNTER);
101484674570SAndrew Lindesay message.SetString("name", package->Name());
101584674570SAndrew Lindesay fIncrementViewCounterDelayedRunner =
101684674570SAndrew Lindesay new BMessageRunner(BMessenger(this), &message,
101784674570SAndrew Lindesay kIncrementViewCounterDelayMicros, 1);
101884674570SAndrew Lindesay if (fIncrementViewCounterDelayedRunner->InitCheck()
101984674570SAndrew Lindesay != B_OK) {
102084674570SAndrew Lindesay HDERROR("unable to init the increment view counter");
102184674570SAndrew Lindesay }
102284674570SAndrew Lindesay }
102384674570SAndrew Lindesay
102484674570SAndrew Lindesay
102584674570SAndrew Lindesay void
_HandleIncrementViewCounter(const BMessage * message)102684674570SAndrew Lindesay MainWindow::_HandleIncrementViewCounter(const BMessage* message)
102784674570SAndrew Lindesay {
102884674570SAndrew Lindesay BString name;
102984674570SAndrew Lindesay if (message->FindString("name", &name) == B_OK) {
103084674570SAndrew Lindesay const PackageInfoRef& viewedPackage =
103184674570SAndrew Lindesay fPackageInfoView->Package();
103284674570SAndrew Lindesay if (viewedPackage.IsSet()) {
103384674570SAndrew Lindesay if (viewedPackage->Name() == name)
103484674570SAndrew Lindesay _IncrementViewCounter(viewedPackage);
103584674570SAndrew Lindesay else
103684674570SAndrew Lindesay HDINFO("incr. view counter; name mismatch");
103784674570SAndrew Lindesay } else
103884674570SAndrew Lindesay HDINFO("incr. view counter; no viewed pkg");
103984674570SAndrew Lindesay } else
104084674570SAndrew Lindesay HDERROR("incr. view counter; no name");
104184674570SAndrew Lindesay fIncrementViewCounterDelayedRunner->SetCount(0);
104284674570SAndrew Lindesay delete fIncrementViewCounterDelayedRunner;
104384674570SAndrew Lindesay fIncrementViewCounterDelayedRunner = NULL;
104484674570SAndrew Lindesay }
104584674570SAndrew Lindesay
104684674570SAndrew Lindesay
104784674570SAndrew Lindesay void
_IncrementViewCounter(const PackageInfoRef package)1048409af934SAndrew Lindesay MainWindow::_IncrementViewCounter(const PackageInfoRef package)
1049133ebab6SAndrew Lindesay {
1050133ebab6SAndrew Lindesay bool shouldIncrementViewCounter = false;
1051133ebab6SAndrew Lindesay
1052133ebab6SAndrew Lindesay {
1053133ebab6SAndrew Lindesay AutoLocker<BLocker> modelLocker(fModel.Lock());
1054133ebab6SAndrew Lindesay bool canShareAnonymousUsageData = fModel.CanShareAnonymousUsageData();
1055*c0789628SAndrew Lindesay if (canShareAnonymousUsageData && !PackageUtils::Viewed(package)) {
1056*c0789628SAndrew Lindesay PackageLocalInfoRef localInfo = PackageUtils::NewLocalInfo(package);
1057*c0789628SAndrew Lindesay localInfo->SetViewed();
1058*c0789628SAndrew Lindesay package->SetLocalInfo(localInfo);
1059133ebab6SAndrew Lindesay shouldIncrementViewCounter = true;
1060133ebab6SAndrew Lindesay }
1061133ebab6SAndrew Lindesay }
1062133ebab6SAndrew Lindesay
1063133ebab6SAndrew Lindesay if (shouldIncrementViewCounter) {
1064467ffecdSAugustin Cavalier ProcessCoordinator* incrementViewCoordinator =
1065133ebab6SAndrew Lindesay ProcessCoordinatorFactory::CreateIncrementViewCounter(
1066133ebab6SAndrew Lindesay &fModel, package);
1067467ffecdSAugustin Cavalier _AddProcessCoordinator(incrementViewCoordinator);
1068133ebab6SAndrew Lindesay }
1069133ebab6SAndrew Lindesay }
1070133ebab6SAndrew Lindesay
1071133ebab6SAndrew Lindesay
1072133ebab6SAndrew Lindesay void
_AdoptPackage(const PackageInfoRef & package)107304c9d578SStephan Aßmus MainWindow::_AdoptPackage(const PackageInfoRef& package)
107404c9d578SStephan Aßmus {
107575ba9dbfSStephan Aßmus {
107675ba9dbfSStephan Aßmus BAutolock locker(fModel.Lock());
107704c9d578SStephan Aßmus fPackageInfoView->SetPackage(package);
10781986ab9fSStephan Aßmus
1079664372abSStephan Aßmus if (fFeaturedPackagesView != NULL)
1080664372abSStephan Aßmus fFeaturedPackagesView->SelectPackage(package);
10811986ab9fSStephan Aßmus if (fPackageListView != NULL)
10821986ab9fSStephan Aßmus fPackageListView->SelectPackage(package);
108375ba9dbfSStephan Aßmus }
108404c9d578SStephan Aßmus
1085a9edb9bfSAndrew Lindesay _PopulatePackageAsync(false);
108604c9d578SStephan Aßmus }
108704c9d578SStephan Aßmus
108804c9d578SStephan Aßmus
108904c9d578SStephan Aßmus void
_ClearPackage()109004c9d578SStephan Aßmus MainWindow::_ClearPackage()
109104c9d578SStephan Aßmus {
109204c9d578SStephan Aßmus fPackageInfoView->Clear();
109304c9d578SStephan Aßmus }
109404c9d578SStephan Aßmus
109504c9d578SStephan Aßmus
109604c9d578SStephan Aßmus void
_StartBulkLoad(bool force)10973369e03dSAndrew Lindesay MainWindow::_StartBulkLoad(bool force)
109804c9d578SStephan Aßmus {
1099c4199192SAndrew Lindesay if (fFeaturedPackagesView != NULL)
1100c4199192SAndrew Lindesay fFeaturedPackagesView->Clear();
1101c4199192SAndrew Lindesay if (fPackageListView != NULL)
1102c4199192SAndrew Lindesay fPackageListView->Clear();
1103c4199192SAndrew Lindesay fPackageInfoView->Clear();
1104c4199192SAndrew Lindesay
110510cd325cSAndrew Lindesay fRefreshRepositoriesItem->SetEnabled(false);
110610cd325cSAndrew Lindesay ProcessCoordinator* bulkLoadCoordinator =
110710cd325cSAndrew Lindesay ProcessCoordinatorFactory::CreateBulkLoadCoordinator(
1108409af934SAndrew Lindesay fPackageInfoListener, &fModel, force);
110910cd325cSAndrew Lindesay _AddProcessCoordinator(bulkLoadCoordinator);
111004c9d578SStephan Aßmus }
111104c9d578SStephan Aßmus
111204c9d578SStephan Aßmus
111304c9d578SStephan Aßmus void
_BulkLoadCompleteReceived(status_t errorStatus)111410cd325cSAndrew Lindesay MainWindow::_BulkLoadCompleteReceived(status_t errorStatus)
111504c9d578SStephan Aßmus {
111610cd325cSAndrew Lindesay if (errorStatus != B_OK) {
11173369e03dSAndrew Lindesay AppUtils::NotifySimpleError(
11181448ced0SHumdinger B_TRANSLATE("Package update error"),
11193369e03dSAndrew Lindesay B_TRANSLATE("While updating package data, a problem has arisen "
11203369e03dSAndrew Lindesay "that may cause data to be outdated or missing from the "
11213369e03dSAndrew Lindesay "application's display. Additional details regarding this "
11223369e03dSAndrew Lindesay "problem may be able to be obtained from the application "
1123b21c9447SAndrew Lindesay "logs."
1124b21c9447SAndrew Lindesay ALERT_MSG_LOGS_USER_GUIDE));
112504c9d578SStephan Aßmus }
112610cd325cSAndrew Lindesay
11273369e03dSAndrew Lindesay fRefreshRepositoriesItem->SetEnabled(true);
112810cd325cSAndrew Lindesay _AdoptModel();
112910cd325cSAndrew Lindesay _UpdateAvailableRepositories();
1130ccf707d0SAndrew Lindesay
1131ccf707d0SAndrew Lindesay // if after loading everything in, it transpires that there are no
1132ccf707d0SAndrew Lindesay // featured packages then the featured packages should be disabled
1133ccf707d0SAndrew Lindesay // and the user should be switched to the "all packages" view so
1134ccf707d0SAndrew Lindesay // that they are not presented with a blank window!
1135ccf707d0SAndrew Lindesay
1136ccf707d0SAndrew Lindesay bool hasProminentPackages = fModel.HasAnyProminentPackages();
1137ccf707d0SAndrew Lindesay fListTabs->TabAt(TAB_PROMINENT_PACKAGES)->SetEnabled(hasProminentPackages);
1138ccf707d0SAndrew Lindesay if (!hasProminentPackages
1139ccf707d0SAndrew Lindesay && fListTabs->Selection() == TAB_PROMINENT_PACKAGES) {
1140ccf707d0SAndrew Lindesay fModel.SetPackageListViewMode(ALL);
1141ccf707d0SAndrew Lindesay fListTabs->Select(TAB_ALL_PACKAGES);
1142ccf707d0SAndrew Lindesay }
114304c9d578SStephan Aßmus }
114404c9d578SStephan Aßmus
114504c9d578SStephan Aßmus
11463369e03dSAndrew Lindesay void
_NotifyWorkStatusClear()114710cd325cSAndrew Lindesay MainWindow::_NotifyWorkStatusClear()
114804c9d578SStephan Aßmus {
114910cd325cSAndrew Lindesay BMessage message(MSG_WORK_STATUS_CLEAR);
115010cd325cSAndrew Lindesay this->PostMessage(&message, this);
115110cd325cSAndrew Lindesay }
115210cd325cSAndrew Lindesay
115310cd325cSAndrew Lindesay
115410cd325cSAndrew Lindesay void
_HandleWorkStatusClear()115510cd325cSAndrew Lindesay MainWindow::_HandleWorkStatusClear()
115610cd325cSAndrew Lindesay {
115710cd325cSAndrew Lindesay fWorkStatusView->SetText("");
11583369e03dSAndrew Lindesay fWorkStatusView->SetIdle();
11593369e03dSAndrew Lindesay }
116004c9d578SStephan Aßmus
116104c9d578SStephan Aßmus
11623369e03dSAndrew Lindesay /*! Sends off a message to the Window so that it can change the status view
11633369e03dSAndrew Lindesay on the front-end in the UI thread.
11643369e03dSAndrew Lindesay */
116504c9d578SStephan Aßmus
11663369e03dSAndrew Lindesay void
_NotifyWorkStatusChange(const BString & text,float progress)11673369e03dSAndrew Lindesay MainWindow::_NotifyWorkStatusChange(const BString& text, float progress)
11683369e03dSAndrew Lindesay {
11693369e03dSAndrew Lindesay BMessage message(MSG_WORK_STATUS_CHANGE);
117004c9d578SStephan Aßmus
11713369e03dSAndrew Lindesay if (!text.IsEmpty())
11723369e03dSAndrew Lindesay message.AddString(KEY_WORK_STATUS_TEXT, text);
11733369e03dSAndrew Lindesay message.AddFloat(KEY_WORK_STATUS_PROGRESS, progress);
117404c9d578SStephan Aßmus
11753369e03dSAndrew Lindesay this->PostMessage(&message, this);
11763369e03dSAndrew Lindesay }
117704c9d578SStephan Aßmus
11783369e03dSAndrew Lindesay
1179f32d5c5cSAndrew Lindesay void
_HandleExternalPackageUpdateMessageReceived(const BMessage * message)1180f32d5c5cSAndrew Lindesay MainWindow::_HandleExternalPackageUpdateMessageReceived(const BMessage* message)
1181f32d5c5cSAndrew Lindesay {
1182f32d5c5cSAndrew Lindesay BStringList addedPackageNames;
1183f32d5c5cSAndrew Lindesay BStringList removedPackageNames;
1184f32d5c5cSAndrew Lindesay
1185f32d5c5cSAndrew Lindesay if (message->FindStrings("added package names",
1186f32d5c5cSAndrew Lindesay &addedPackageNames) == B_OK) {
1187f32d5c5cSAndrew Lindesay addedPackageNames.Sort();
11880ebb9177SAndrew Lindesay AutoLocker<BLocker> locker(fModel.Lock());
11890ebb9177SAndrew Lindesay fModel.SetStateForPackagesByName(addedPackageNames, ACTIVATED);
1190f32d5c5cSAndrew Lindesay }
1191f32d5c5cSAndrew Lindesay else
1192f32d5c5cSAndrew Lindesay HDINFO("no [added package names] key in inbound message");
1193f32d5c5cSAndrew Lindesay
1194f32d5c5cSAndrew Lindesay if (message->FindStrings("removed package names",
1195f32d5c5cSAndrew Lindesay &removedPackageNames) == B_OK) {
1196f32d5c5cSAndrew Lindesay removedPackageNames.Sort();
11970ebb9177SAndrew Lindesay AutoLocker<BLocker> locker(fModel.Lock());
11980ebb9177SAndrew Lindesay fModel.SetStateForPackagesByName(addedPackageNames, UNINSTALLED);
1199f32d5c5cSAndrew Lindesay } else
1200f32d5c5cSAndrew Lindesay HDINFO("no [removed package names] key in inbound message");
1201f32d5c5cSAndrew Lindesay }
1202f32d5c5cSAndrew Lindesay
1203f32d5c5cSAndrew Lindesay
12043369e03dSAndrew Lindesay void
_HandleWorkStatusChangeMessageReceived(const BMessage * message)12053369e03dSAndrew Lindesay MainWindow::_HandleWorkStatusChangeMessageReceived(const BMessage* message)
12063369e03dSAndrew Lindesay {
12079883929bSAndrew Lindesay if (fWorkStatusView == NULL)
12089883929bSAndrew Lindesay return;
12099883929bSAndrew Lindesay
12103369e03dSAndrew Lindesay BString text;
12113369e03dSAndrew Lindesay float progress;
12123369e03dSAndrew Lindesay
12133369e03dSAndrew Lindesay if (message->FindString(KEY_WORK_STATUS_TEXT, &text) == B_OK)
12143369e03dSAndrew Lindesay fWorkStatusView->SetText(text);
12153369e03dSAndrew Lindesay
1216a18f873fSAndrew Lindesay if (message->FindFloat(KEY_WORK_STATUS_PROGRESS, &progress) == B_OK) {
1217a18f873fSAndrew Lindesay if (progress < 0.0f)
1218a18f873fSAndrew Lindesay fWorkStatusView->SetBusy();
1219a18f873fSAndrew Lindesay else
12203369e03dSAndrew Lindesay fWorkStatusView->SetProgress(progress);
1221a18f873fSAndrew Lindesay } else {
1222a18f873fSAndrew Lindesay HDERROR("work status change missing progress on update message");
1223a18f873fSAndrew Lindesay fWorkStatusView->SetProgress(0.0f);
122404c9d578SStephan Aßmus }
122504c9d578SStephan Aßmus }
122604c9d578SStephan Aßmus
122704c9d578SStephan Aßmus
12288266f4d7SAugustin Cavalier /*! Initially only superficial data is loaded from the server into the data
12298266f4d7SAugustin Cavalier model of the packages. When the package is viewed, additional data needs
12308266f4d7SAugustin Cavalier to be populated including ratings.
12318266f4d7SAugustin Cavalier
12328266f4d7SAugustin Cavalier This method will cause the package to have its data refreshed from
1233a9edb9bfSAndrew Lindesay the server application. The refresh happens in the background; this method
1234a9edb9bfSAndrew Lindesay is asynchronous.
1235a9edb9bfSAndrew Lindesay */
1236a9edb9bfSAndrew Lindesay
1237a9edb9bfSAndrew Lindesay void
_PopulatePackageAsync(bool forcePopulate)1238a9edb9bfSAndrew Lindesay MainWindow::_PopulatePackageAsync(bool forcePopulate)
1239a9edb9bfSAndrew Lindesay {
12408266f4d7SAugustin Cavalier const PackageInfoRef package = fPackageInfoView->Package();
1241a9edb9bfSAndrew Lindesay
12428266f4d7SAugustin Cavalier if (!fModel.CanPopulatePackage(package))
12438266f4d7SAugustin Cavalier return;
12448266f4d7SAugustin Cavalier
12458266f4d7SAugustin Cavalier const char* packageNameStr = package->Name().String();
12468266f4d7SAugustin Cavalier
1247c65ff9f1SAndrew Lindesay PackageLocalizedTextRef localized = package->LocalizedText();
1248c65ff9f1SAndrew Lindesay
1249c65ff9f1SAndrew Lindesay if (localized.IsSet()) {
1250c65ff9f1SAndrew Lindesay if (localized->HasChangelog() && (forcePopulate || localized->Changelog().IsEmpty())) {
12518266f4d7SAugustin Cavalier _AddProcessCoordinator(
12528266f4d7SAugustin Cavalier ProcessCoordinatorFactory::PopulatePkgChangelogCoordinator(&fModel, package));
12538266f4d7SAugustin Cavalier HDINFO("pkg [%s] will have changelog updated from server.", packageNameStr);
12548266f4d7SAugustin Cavalier } else {
12558266f4d7SAugustin Cavalier HDDEBUG("pkg [%s] not have changelog updated from server.", packageNameStr);
1256a9edb9bfSAndrew Lindesay }
1257c65ff9f1SAndrew Lindesay }
1258a9edb9bfSAndrew Lindesay
12594b3c808eSAndrew Lindesay if (forcePopulate || RatingUtils::ShouldTryPopulateUserRatings(package->UserRatingInfo())) {
12608266f4d7SAugustin Cavalier _AddProcessCoordinator(
12618266f4d7SAugustin Cavalier ProcessCoordinatorFactory::PopulatePkgUserRatingsCoordinator(&fModel, package));
12628266f4d7SAugustin Cavalier HDINFO("pkg [%s] will have user ratings updated from server.", packageNameStr);
12638266f4d7SAugustin Cavalier } else {
12648266f4d7SAugustin Cavalier HDDEBUG("pkg [%s] not have user ratings updated from server.", packageNameStr);
126504c9d578SStephan Aßmus }
126604c9d578SStephan Aßmus }
126704c9d578SStephan Aßmus
126804c9d578SStephan Aßmus
126904c9d578SStephan Aßmus void
_OpenSettingsWindow()1270133ebab6SAndrew Lindesay MainWindow::_OpenSettingsWindow()
1271133ebab6SAndrew Lindesay {
1272133ebab6SAndrew Lindesay SettingsWindow* window = new SettingsWindow(this, &fModel);
1273133ebab6SAndrew Lindesay window->Show();
1274133ebab6SAndrew Lindesay }
1275133ebab6SAndrew Lindesay
1276133ebab6SAndrew Lindesay
1277133ebab6SAndrew Lindesay void
_OpenLoginWindow(const BMessage & onSuccessMessage)12781bbda92dSStephan Aßmus MainWindow::_OpenLoginWindow(const BMessage& onSuccessMessage)
127904c9d578SStephan Aßmus {
128004c9d578SStephan Aßmus UserLoginWindow* window = new UserLoginWindow(this,
128104c9d578SStephan Aßmus BRect(0, 0, 500, 400), fModel);
12821bbda92dSStephan Aßmus
12831bbda92dSStephan Aßmus if (onSuccessMessage.what != 0)
12841bbda92dSStephan Aßmus window->SetOnSuccessMessage(BMessenger(this), onSuccessMessage);
12851bbda92dSStephan Aßmus
128604c9d578SStephan Aßmus window->Show();
128704c9d578SStephan Aßmus }
128804c9d578SStephan Aßmus
12898f03a0f9SStephan Aßmus
12908f03a0f9SStephan Aßmus void
_StartUserVerify()129110cd325cSAndrew Lindesay MainWindow::_StartUserVerify()
129210cd325cSAndrew Lindesay {
129310cd325cSAndrew Lindesay if (!fModel.Nickname().IsEmpty()) {
129410cd325cSAndrew Lindesay _AddProcessCoordinator(
129510cd325cSAndrew Lindesay ProcessCoordinatorFactory::CreateUserDetailVerifierCoordinator(
129610cd325cSAndrew Lindesay this,
129710cd325cSAndrew Lindesay // UserDetailVerifierListener
129810cd325cSAndrew Lindesay &fModel) );
129910cd325cSAndrew Lindesay }
130010cd325cSAndrew Lindesay }
130110cd325cSAndrew Lindesay
130210cd325cSAndrew Lindesay
130310cd325cSAndrew Lindesay void
_UpdateAuthorization()13048f03a0f9SStephan Aßmus MainWindow::_UpdateAuthorization()
13058f03a0f9SStephan Aßmus {
1306d2d4866dSAndrew Lindesay BString nickname(fModel.Nickname());
1307d2d4866dSAndrew Lindesay bool hasUser = !nickname.IsEmpty();
1308e0a26dceSStephan Aßmus
13096d519fd1SStephan Aßmus if (fLogOutItem != NULL)
1310e0a26dceSStephan Aßmus fLogOutItem->SetEnabled(hasUser);
1311d2d4866dSAndrew Lindesay if (fUsersUserUsageConditionsMenuItem != NULL)
1312d2d4866dSAndrew Lindesay fUsersUserUsageConditionsMenuItem->SetEnabled(hasUser);
1313e0a26dceSStephan Aßmus if (fLogInItem != NULL) {
1314e0a26dceSStephan Aßmus if (hasUser)
1315e0a26dceSStephan Aßmus fLogInItem->SetLabel(B_TRANSLATE("Switch account" B_UTF8_ELLIPSIS));
1316e0a26dceSStephan Aßmus else
1317e0a26dceSStephan Aßmus fLogInItem->SetLabel(B_TRANSLATE("Log in" B_UTF8_ELLIPSIS));
1318e0a26dceSStephan Aßmus }
1319e0a26dceSStephan Aßmus
1320e0a26dceSStephan Aßmus if (fUserMenu != NULL) {
1321e0a26dceSStephan Aßmus BString label;
1322d2d4866dSAndrew Lindesay if (hasUser) {
1323e0a26dceSStephan Aßmus label = B_TRANSLATE("Logged in as %User%");
1324d2d4866dSAndrew Lindesay label.ReplaceAll("%User%", nickname);
1325d2d4866dSAndrew Lindesay } else {
1326d2d4866dSAndrew Lindesay label = B_TRANSLATE("Not logged in");
1327e0a26dceSStephan Aßmus }
1328e0a26dceSStephan Aßmus fUserMenu->Superitem()->SetLabel(label);
1329e0a26dceSStephan Aßmus }
13308f03a0f9SStephan Aßmus }
13311bbda92dSStephan Aßmus
13321bbda92dSStephan Aßmus
13331bbda92dSStephan Aßmus void
_UpdateAvailableRepositories()1334b965ce70SHumdinger MainWindow::_UpdateAvailableRepositories()
1335b965ce70SHumdinger {
1336b965ce70SHumdinger fRepositoryMenu->RemoveItems(0, fRepositoryMenu->CountItems(), true);
1337b965ce70SHumdinger
1338b965ce70SHumdinger fRepositoryMenu->AddItem(new BMenuItem(B_TRANSLATE("All repositories"),
1339b965ce70SHumdinger new BMessage(MSG_DEPOT_SELECTED)));
1340b965ce70SHumdinger
1341b965ce70SHumdinger fRepositoryMenu->AddItem(new BSeparatorItem());
1342b965ce70SHumdinger
1343b965ce70SHumdinger bool foundSelectedDepot = false;
134405880d13SAndrew Lindesay std::vector<DepotInfoRef> depots = _CreateSnapshotOfDepots();
134505880d13SAndrew Lindesay std::vector<DepotInfoRef>::iterator it;
1346d13c3d89SAndrew Lindesay
134705880d13SAndrew Lindesay for (it = depots.begin(); it != depots.end(); it++) {
134805880d13SAndrew Lindesay DepotInfoRef depot = *it;
134905880d13SAndrew Lindesay
135005880d13SAndrew Lindesay if (depot->Name().Length() != 0) {
1351b965ce70SHumdinger BMessage* message = new BMessage(MSG_DEPOT_SELECTED);
135205880d13SAndrew Lindesay message->AddString("name", depot->Name());
135305880d13SAndrew Lindesay BMenuItem* item = new(std::nothrow) BMenuItem(depot->Name(), message);
135405880d13SAndrew Lindesay
135505880d13SAndrew Lindesay if (item == NULL)
135605880d13SAndrew Lindesay HDFATAL("memory exhaustion");
135705880d13SAndrew Lindesay
1358b965ce70SHumdinger fRepositoryMenu->AddItem(item);
1359b965ce70SHumdinger
1360363fc60bSAndrew Lindesay if (depot->Name() == fModel.PackageFilter()->DepotName()) {
1361b965ce70SHumdinger item->SetMarked(true);
1362b965ce70SHumdinger foundSelectedDepot = true;
1363b965ce70SHumdinger }
1364b965ce70SHumdinger }
1365d13c3d89SAndrew Lindesay }
1366b965ce70SHumdinger
1367b965ce70SHumdinger if (!foundSelectedDepot)
1368b965ce70SHumdinger fRepositoryMenu->ItemAt(0)->SetMarked(true);
1369b965ce70SHumdinger }
1370b965ce70SHumdinger
1371b965ce70SHumdinger
1372a9edb9bfSAndrew Lindesay bool
_SelectedPackageHasWebAppRepositoryCode()1373a9edb9bfSAndrew Lindesay MainWindow::_SelectedPackageHasWebAppRepositoryCode()
1374a9edb9bfSAndrew Lindesay {
1375a9edb9bfSAndrew Lindesay const PackageInfoRef& package = fPackageInfoView->Package();
13766ab878c0SAndrew Lindesay const BString depotName = package->DepotName();
1377a9edb9bfSAndrew Lindesay
13786ab878c0SAndrew Lindesay if (depotName.IsEmpty()) {
1379fa5c8097SAndrew Lindesay HDDEBUG("the package [%s] has no depot name", package->Name().String());
13806ab878c0SAndrew Lindesay } else {
13816ab878c0SAndrew Lindesay const DepotInfo* depot = fModel.DepotForName(depotName);
1382a9edb9bfSAndrew Lindesay
13836ab878c0SAndrew Lindesay if (depot == NULL) {
1384f96d1f4dSAndrew Lindesay HDINFO("the depot [%s] was not able to be found",
1385fa5c8097SAndrew Lindesay depotName.String());
13866ab878c0SAndrew Lindesay } else {
13876ab878c0SAndrew Lindesay BString repositoryCode = depot->WebAppRepositoryCode();
1388a9edb9bfSAndrew Lindesay
13896ab878c0SAndrew Lindesay if (repositoryCode.IsEmpty()) {
1390f96d1f4dSAndrew Lindesay HDINFO("the depot [%s] has no web app repository code",
1391fa5c8097SAndrew Lindesay depotName.String());
1392fa5c8097SAndrew Lindesay } else
13936ab878c0SAndrew Lindesay return true;
13946ab878c0SAndrew Lindesay }
13956ab878c0SAndrew Lindesay }
13966ab878c0SAndrew Lindesay
13976ab878c0SAndrew Lindesay return false;
1398a9edb9bfSAndrew Lindesay }
1399a9edb9bfSAndrew Lindesay
1400a9edb9bfSAndrew Lindesay
1401b965ce70SHumdinger void
_RatePackage()14021bbda92dSStephan Aßmus MainWindow::_RatePackage()
14031bbda92dSStephan Aßmus {
1404a9edb9bfSAndrew Lindesay if (!_SelectedPackageHasWebAppRepositoryCode()) {
1405a9edb9bfSAndrew Lindesay BAlert* alert = new(std::nothrow) BAlert(
1406cbadcae1SHumdinger B_TRANSLATE("Rating not possible"),
1407cbadcae1SHumdinger B_TRANSLATE("This package doesn't seem to be on the HaikuDepot "
1408cbadcae1SHumdinger "Server, so it's not possible to create a new rating "
1409cbadcae1SHumdinger "or edit an existing rating."),
1410a9edb9bfSAndrew Lindesay B_TRANSLATE("OK"));
1411a9edb9bfSAndrew Lindesay alert->Go();
1412a9edb9bfSAndrew Lindesay return;
1413a9edb9bfSAndrew Lindesay }
1414a9edb9bfSAndrew Lindesay
1415d2d4866dSAndrew Lindesay if (fModel.Nickname().IsEmpty()) {
14161bbda92dSStephan Aßmus BAlert* alert = new(std::nothrow) BAlert(
14171bbda92dSStephan Aßmus B_TRANSLATE("Not logged in"),
14181bbda92dSStephan Aßmus B_TRANSLATE("You need to be logged into an account before you "
14191bbda92dSStephan Aßmus "can rate packages."),
14201bbda92dSStephan Aßmus B_TRANSLATE("Cancel"),
14211bbda92dSStephan Aßmus B_TRANSLATE("Login or Create account"));
14221bbda92dSStephan Aßmus
14231bbda92dSStephan Aßmus if (alert == NULL)
14241bbda92dSStephan Aßmus return;
14251bbda92dSStephan Aßmus
14261bbda92dSStephan Aßmus int32 choice = alert->Go();
14271bbda92dSStephan Aßmus if (choice == 1)
14281bbda92dSStephan Aßmus _OpenLoginWindow(BMessage(MSG_RATE_PACKAGE));
14291bbda92dSStephan Aßmus return;
14301bbda92dSStephan Aßmus }
14311bbda92dSStephan Aßmus
14321bbda92dSStephan Aßmus // TODO: Allow only one RatePackageWindow
14331bbda92dSStephan Aßmus // TODO: Mechanism for remembering the window frame
14341bbda92dSStephan Aßmus RatePackageWindow* window = new RatePackageWindow(this,
14351bbda92dSStephan Aßmus BRect(0, 0, 500, 400), fModel);
14361bbda92dSStephan Aßmus window->SetPackage(fPackageInfoView->Package());
14371bbda92dSStephan Aßmus window->Show();
14381bbda92dSStephan Aßmus }
1439d5ef985eSStephan Aßmus
1440d5ef985eSStephan Aßmus
1441d5ef985eSStephan Aßmus void
_ShowScreenshot()1442d5ef985eSStephan Aßmus MainWindow::_ShowScreenshot()
1443d5ef985eSStephan Aßmus {
1444d5ef985eSStephan Aßmus // TODO: Mechanism for remembering the window frame
1445d5ef985eSStephan Aßmus if (fScreenshotWindow == NULL)
144688af15cfSAndrew Lindesay fScreenshotWindow = new ScreenshotWindow(this, BRect(0, 0, 500, 400), &fModel);
1447d5ef985eSStephan Aßmus
1448d5ef985eSStephan Aßmus if (fScreenshotWindow->LockWithTimeout(1000) != B_OK)
1449d5ef985eSStephan Aßmus return;
1450d5ef985eSStephan Aßmus
1451d5ef985eSStephan Aßmus fScreenshotWindow->SetPackage(fPackageInfoView->Package());
1452d5ef985eSStephan Aßmus
1453d5ef985eSStephan Aßmus if (fScreenshotWindow->IsHidden())
1454d5ef985eSStephan Aßmus fScreenshotWindow->Show();
1455d5ef985eSStephan Aßmus else
1456d5ef985eSStephan Aßmus fScreenshotWindow->Activate();
1457d5ef985eSStephan Aßmus
1458d5ef985eSStephan Aßmus fScreenshotWindow->Unlock();
1459d5ef985eSStephan Aßmus }
146001339a54SAndrew Lindesay
146101339a54SAndrew Lindesay
146201339a54SAndrew Lindesay void
_ViewUserUsageConditions(UserUsageConditionsSelectionMode mode)1463d2d4866dSAndrew Lindesay MainWindow::_ViewUserUsageConditions(
1464d2d4866dSAndrew Lindesay UserUsageConditionsSelectionMode mode)
146501339a54SAndrew Lindesay {
146601339a54SAndrew Lindesay UserUsageConditionsWindow* window = new UserUsageConditionsWindow(
1467d2d4866dSAndrew Lindesay fModel, mode);
146801339a54SAndrew Lindesay window->Show();
146901339a54SAndrew Lindesay }
147010cd325cSAndrew Lindesay
147110cd325cSAndrew Lindesay
147210cd325cSAndrew Lindesay void
UserCredentialsFailed()147310cd325cSAndrew Lindesay MainWindow::UserCredentialsFailed()
147410cd325cSAndrew Lindesay {
147510cd325cSAndrew Lindesay BString message = B_TRANSLATE("The password previously "
147610cd325cSAndrew Lindesay "supplied for the user [%Nickname%] is not currently "
147710cd325cSAndrew Lindesay "valid. The user will be logged-out of this application "
147810cd325cSAndrew Lindesay "and you should login again with your updated password.");
147910cd325cSAndrew Lindesay message.ReplaceAll("%Nickname%", fModel.Nickname());
148010cd325cSAndrew Lindesay
148110cd325cSAndrew Lindesay AppUtils::NotifySimpleError(B_TRANSLATE("Login issue"),
148210cd325cSAndrew Lindesay message);
148310cd325cSAndrew Lindesay
148410cd325cSAndrew Lindesay {
148510cd325cSAndrew Lindesay AutoLocker<BLocker> locker(fModel.Lock());
148610cd325cSAndrew Lindesay fModel.SetNickname("");
148710cd325cSAndrew Lindesay }
148810cd325cSAndrew Lindesay }
148910cd325cSAndrew Lindesay
149010cd325cSAndrew Lindesay
149110cd325cSAndrew Lindesay /*! \brief This method is invoked from the UserDetailVerifierProcess on a
149210cd325cSAndrew Lindesay background thread. For this reason it lodges a message into itself
149310cd325cSAndrew Lindesay which can then be handled on the main thread.
149410cd325cSAndrew Lindesay */
149510cd325cSAndrew Lindesay
149610cd325cSAndrew Lindesay void
UserUsageConditionsNotLatest(const UserDetail & userDetail)149710cd325cSAndrew Lindesay MainWindow::UserUsageConditionsNotLatest(const UserDetail& userDetail)
149810cd325cSAndrew Lindesay {
149910cd325cSAndrew Lindesay BMessage message(MSG_USER_USAGE_CONDITIONS_NOT_LATEST);
150010cd325cSAndrew Lindesay BMessage detailsMessage;
150110cd325cSAndrew Lindesay if (userDetail.Archive(&detailsMessage, true) != B_OK
150210cd325cSAndrew Lindesay || message.AddMessage("userDetail", &detailsMessage) != B_OK) {
1503fa5c8097SAndrew Lindesay HDERROR("unable to archive the user detail into a message");
150410cd325cSAndrew Lindesay }
150510cd325cSAndrew Lindesay else
150610cd325cSAndrew Lindesay BMessenger(this).SendMessage(&message);
150710cd325cSAndrew Lindesay }
150810cd325cSAndrew Lindesay
150910cd325cSAndrew Lindesay
151010cd325cSAndrew Lindesay void
_HandleUserUsageConditionsNotLatest(const UserDetail & userDetail)151110cd325cSAndrew Lindesay MainWindow::_HandleUserUsageConditionsNotLatest(
151210cd325cSAndrew Lindesay const UserDetail& userDetail)
151310cd325cSAndrew Lindesay {
151410cd325cSAndrew Lindesay ToLatestUserUsageConditionsWindow* window =
151510cd325cSAndrew Lindesay new ToLatestUserUsageConditionsWindow(this, fModel, userDetail);
151610cd325cSAndrew Lindesay window->Show();
151710cd325cSAndrew Lindesay }
151810cd325cSAndrew Lindesay
151910cd325cSAndrew Lindesay
152010cd325cSAndrew Lindesay void
_AddProcessCoordinator(ProcessCoordinator * item)152110cd325cSAndrew Lindesay MainWindow::_AddProcessCoordinator(ProcessCoordinator* item)
152210cd325cSAndrew Lindesay {
152310cd325cSAndrew Lindesay AutoLocker<BLocker> lock(&fCoordinatorLock);
152410cd325cSAndrew Lindesay
152595c7b018SAndrew Lindesay if (fShouldCloseWhenNoProcessesToCoordinate) {
152695c7b018SAndrew Lindesay HDINFO("system shutting down --> new process coordinator [%s] rejected",
152795c7b018SAndrew Lindesay item->Name().String());
152895c7b018SAndrew Lindesay return;
152995c7b018SAndrew Lindesay }
153095c7b018SAndrew Lindesay
1531a18f873fSAndrew Lindesay item->SetListener(this);
1532a18f873fSAndrew Lindesay
1533409af934SAndrew Lindesay if (fCoordinator == NULL) {
153410cd325cSAndrew Lindesay if (acquire_sem(fCoordinatorRunningSem) != B_OK)
153510cd325cSAndrew Lindesay debugger("unable to acquire the process coordinator sem");
1536f96d1f4dSAndrew Lindesay HDINFO("adding and starting a process coordinator [%s]",
1537fa5c8097SAndrew Lindesay item->Name().String());
1538409af934SAndrew Lindesay delete fCoordinator;
1539409af934SAndrew Lindesay fCoordinator = item;
154010cd325cSAndrew Lindesay fCoordinator->Start();
15417d7de135SAugustin Cavalier } else {
1542f96d1f4dSAndrew Lindesay HDINFO("adding process coordinator [%s] to the queue",
154310cd325cSAndrew Lindesay item->Name().String());
154410cd325cSAndrew Lindesay fCoordinatorQueue.push(item);
154510cd325cSAndrew Lindesay }
154610cd325cSAndrew Lindesay }
154710cd325cSAndrew Lindesay
154810cd325cSAndrew Lindesay
154910cd325cSAndrew Lindesay void
_SpinUntilProcessCoordinatorComplete()155010cd325cSAndrew Lindesay MainWindow::_SpinUntilProcessCoordinatorComplete()
155110cd325cSAndrew Lindesay {
155210cd325cSAndrew Lindesay while (true) {
155310cd325cSAndrew Lindesay if (acquire_sem(fCoordinatorRunningSem) != B_OK)
155410cd325cSAndrew Lindesay debugger("unable to acquire the process coordinator sem");
155510cd325cSAndrew Lindesay if (release_sem(fCoordinatorRunningSem) != B_OK)
155610cd325cSAndrew Lindesay debugger("unable to release the process coordinator sem");
155710cd325cSAndrew Lindesay {
155810cd325cSAndrew Lindesay AutoLocker<BLocker> lock(&fCoordinatorLock);
1559409af934SAndrew Lindesay if (fCoordinator == NULL)
156010cd325cSAndrew Lindesay return;
156110cd325cSAndrew Lindesay }
156210cd325cSAndrew Lindesay }
156310cd325cSAndrew Lindesay }
156410cd325cSAndrew Lindesay
156510cd325cSAndrew Lindesay
156610cd325cSAndrew Lindesay void
_StopProcessCoordinators()156710cd325cSAndrew Lindesay MainWindow::_StopProcessCoordinators()
156810cd325cSAndrew Lindesay {
156995c7b018SAndrew Lindesay HDINFO("will stop all queued process coordinators");
157010cd325cSAndrew Lindesay AutoLocker<BLocker> lock(&fCoordinatorLock);
157110cd325cSAndrew Lindesay
157210cd325cSAndrew Lindesay while (!fCoordinatorQueue.empty()) {
1573409af934SAndrew Lindesay ProcessCoordinator* processCoordinator
1574f96d1f4dSAndrew Lindesay = fCoordinatorQueue.front();
1575f96d1f4dSAndrew Lindesay HDINFO("will drop queued process coordinator [%s]",
1576fa5c8097SAndrew Lindesay processCoordinator->Name().String());
157710cd325cSAndrew Lindesay fCoordinatorQueue.pop();
1578409af934SAndrew Lindesay delete processCoordinator;
157910cd325cSAndrew Lindesay }
158010cd325cSAndrew Lindesay
1581409af934SAndrew Lindesay if (fCoordinator != NULL)
158295c7b018SAndrew Lindesay fCoordinator->RequestStop();
158310cd325cSAndrew Lindesay }
158410cd325cSAndrew Lindesay
158510cd325cSAndrew Lindesay
158610cd325cSAndrew Lindesay /*! This method is called when there is some change in the bulk load process
158710cd325cSAndrew Lindesay or other process coordinator.
158810cd325cSAndrew Lindesay A change may mean that a new process has started / stopped etc... or it
158910cd325cSAndrew Lindesay may mean that the entire coordinator has finished.
159010cd325cSAndrew Lindesay */
159110cd325cSAndrew Lindesay
159210cd325cSAndrew Lindesay void
CoordinatorChanged(ProcessCoordinatorState & coordinatorState)159310cd325cSAndrew Lindesay MainWindow::CoordinatorChanged(ProcessCoordinatorState& coordinatorState)
159410cd325cSAndrew Lindesay {
1595409af934SAndrew Lindesay BMessage message(MSG_PROCESS_COORDINATOR_CHANGED);
1596409af934SAndrew Lindesay if (coordinatorState.Archive(&message, true) != B_OK) {
1597409af934SAndrew Lindesay HDFATAL("unable to archive message when the process coordinator"
1598409af934SAndrew Lindesay " has changed");
1599409af934SAndrew Lindesay }
1600409af934SAndrew Lindesay BMessenger(this).SendMessage(&message);
1601409af934SAndrew Lindesay }
1602409af934SAndrew Lindesay
1603409af934SAndrew Lindesay
1604409af934SAndrew Lindesay void
_HandleProcessCoordinatorChanged(ProcessCoordinatorState & coordinatorState)1605409af934SAndrew Lindesay MainWindow::_HandleProcessCoordinatorChanged(ProcessCoordinatorState& coordinatorState)
1606409af934SAndrew Lindesay {
160710cd325cSAndrew Lindesay AutoLocker<BLocker> lock(&fCoordinatorLock);
160810cd325cSAndrew Lindesay
1609409af934SAndrew Lindesay if (fCoordinator->Identifier()
1610409af934SAndrew Lindesay == coordinatorState.ProcessCoordinatorIdentifier()) {
161110cd325cSAndrew Lindesay if (!coordinatorState.IsRunning()) {
161210cd325cSAndrew Lindesay if (release_sem(fCoordinatorRunningSem) != B_OK)
161310cd325cSAndrew Lindesay debugger("unable to release the process coordinator sem");
1614f96d1f4dSAndrew Lindesay HDINFO("process coordinator [%s] did complete",
1615fa5c8097SAndrew Lindesay fCoordinator->Name().String());
161610cd325cSAndrew Lindesay // complete the last one that just finished
161710cd325cSAndrew Lindesay BMessage* message = fCoordinator->Message();
161810cd325cSAndrew Lindesay
161910cd325cSAndrew Lindesay if (message != NULL) {
162010cd325cSAndrew Lindesay BMessenger messenger(this);
162110cd325cSAndrew Lindesay message->AddInt64(KEY_ERROR_STATUS,
162210cd325cSAndrew Lindesay (int64) fCoordinator->ErrorStatus());
162310cd325cSAndrew Lindesay messenger.SendMessage(message);
162410cd325cSAndrew Lindesay }
162510cd325cSAndrew Lindesay
16263538133fSAndrew Lindesay HDDEBUG("process coordinator report;\n---\n%s\n----",
16273538133fSAndrew Lindesay fCoordinator->LogReport().String());
16283538133fSAndrew Lindesay
1629409af934SAndrew Lindesay delete fCoordinator;
1630409af934SAndrew Lindesay fCoordinator = NULL;
163110cd325cSAndrew Lindesay
163210cd325cSAndrew Lindesay // now schedule the next one.
163310cd325cSAndrew Lindesay if (!fCoordinatorQueue.empty()) {
163410cd325cSAndrew Lindesay if (acquire_sem(fCoordinatorRunningSem) != B_OK)
163510cd325cSAndrew Lindesay debugger("unable to acquire the process coordinator sem");
163610cd325cSAndrew Lindesay fCoordinator = fCoordinatorQueue.front();
1637f96d1f4dSAndrew Lindesay HDINFO("starting next process coordinator [%s]",
163810cd325cSAndrew Lindesay fCoordinator->Name().String());
163910cd325cSAndrew Lindesay fCoordinatorQueue.pop();
164010cd325cSAndrew Lindesay fCoordinator->Start();
164110cd325cSAndrew Lindesay }
164210cd325cSAndrew Lindesay else {
164310cd325cSAndrew Lindesay _NotifyWorkStatusClear();
164495c7b018SAndrew Lindesay if (fShouldCloseWhenNoProcessesToCoordinate) {
164595c7b018SAndrew Lindesay HDINFO("no more processes to coord --> will quit");
164695c7b018SAndrew Lindesay BMessage message(B_QUIT_REQUESTED);
164795c7b018SAndrew Lindesay PostMessage(&message);
164895c7b018SAndrew Lindesay }
164910cd325cSAndrew Lindesay }
165010cd325cSAndrew Lindesay }
165110cd325cSAndrew Lindesay else {
165210cd325cSAndrew Lindesay _NotifyWorkStatusChange(coordinatorState.Message(),
165310cd325cSAndrew Lindesay coordinatorState.Progress());
165410cd325cSAndrew Lindesay // show the progress to the user.
165510cd325cSAndrew Lindesay }
165695c7b018SAndrew Lindesay } else {
165795c7b018SAndrew Lindesay _NotifyWorkStatusClear();
1658fa5c8097SAndrew Lindesay HDINFO("! unknown process coordinator changed");
165910cd325cSAndrew Lindesay }
166095c7b018SAndrew Lindesay }
1661ccf707d0SAndrew Lindesay
1662ccf707d0SAndrew Lindesay
1663ccf707d0SAndrew Lindesay static package_list_view_mode
main_window_tab_to_package_list_view_mode(int32 tab)1664ccf707d0SAndrew Lindesay main_window_tab_to_package_list_view_mode(int32 tab)
1665ccf707d0SAndrew Lindesay {
1666ccf707d0SAndrew Lindesay if (tab == TAB_PROMINENT_PACKAGES)
1667ccf707d0SAndrew Lindesay return PROMINENT;
1668ccf707d0SAndrew Lindesay return ALL;
1669ccf707d0SAndrew Lindesay }
1670ccf707d0SAndrew Lindesay
1671ccf707d0SAndrew Lindesay
1672ccf707d0SAndrew Lindesay void
_HandleChangePackageListViewMode()1673ccf707d0SAndrew Lindesay MainWindow::_HandleChangePackageListViewMode()
1674ccf707d0SAndrew Lindesay {
1675ccf707d0SAndrew Lindesay package_list_view_mode tabMode = main_window_tab_to_package_list_view_mode(
1676ccf707d0SAndrew Lindesay fListTabs->Selection());
1677ccf707d0SAndrew Lindesay package_list_view_mode modelMode = fModel.PackageListViewMode();
1678ccf707d0SAndrew Lindesay
1679ccf707d0SAndrew Lindesay if (tabMode != modelMode) {
1680ccf707d0SAndrew Lindesay BAutolock locker(fModel.Lock());
1681ccf707d0SAndrew Lindesay fModel.SetPackageListViewMode(tabMode);
1682ccf707d0SAndrew Lindesay }
1683ccf707d0SAndrew Lindesay }
168405880d13SAndrew Lindesay
168505880d13SAndrew Lindesay
168605880d13SAndrew Lindesay std::vector<DepotInfoRef>
_CreateSnapshotOfDepots()168705880d13SAndrew Lindesay MainWindow::_CreateSnapshotOfDepots()
168805880d13SAndrew Lindesay {
168905880d13SAndrew Lindesay std::vector<DepotInfoRef> result;
169005880d13SAndrew Lindesay BAutolock locker(fModel.Lock());
169105880d13SAndrew Lindesay int32 countDepots = fModel.CountDepots();
169205880d13SAndrew Lindesay for(int32 i = 0; i < countDepots; i++)
169305880d13SAndrew Lindesay result.push_back(fModel.DepotAtIndex(i));
169405880d13SAndrew Lindesay return result;
169505880d13SAndrew Lindesay }
169688af15cfSAndrew Lindesay
169788af15cfSAndrew Lindesay
169888af15cfSAndrew Lindesay /*! This will get invoked in the case that a screenshot has been cached
169988af15cfSAndrew Lindesay and so could now be loaded by some UI element. This method will then
170088af15cfSAndrew Lindesay signal to other UI elements that they could load a screenshot should
170188af15cfSAndrew Lindesay they have been waiting for it.
170288af15cfSAndrew Lindesay */
170388af15cfSAndrew Lindesay
170488af15cfSAndrew Lindesay void
_HandleScreenshotCached(const BMessage * message)170588af15cfSAndrew Lindesay MainWindow::_HandleScreenshotCached(const BMessage* message)
170688af15cfSAndrew Lindesay {
170788af15cfSAndrew Lindesay ScreenshotCoordinate coordinate(message);
170888af15cfSAndrew Lindesay fPackageInfoView->HandleScreenshotCached(coordinate);
170988af15cfSAndrew Lindesay }
1710