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" 453369e03dSAndrew Lindesay #include "ProcessCoordinator.h" 463369e03dSAndrew Lindesay #include "ProcessCoordinatorFactory.h" 4704c9d578SStephan Aßmus #include "RatePackageWindow.h" 484b3c808eSAndrew Lindesay #include "RatingUtils.h" 49d5ef985eSStephan Aßmus #include "ScreenshotWindow.h" 50133ebab6SAndrew Lindesay #include "SettingsWindow.h" 5195c7b018SAndrew Lindesay #include "ShuttingDownWindow.h" 5210cd325cSAndrew Lindesay #include "ToLatestUserUsageConditionsWindow.h" 5304c9d578SStephan Aßmus #include "UserLoginWindow.h" 5401339a54SAndrew Lindesay #include "UserUsageConditionsWindow.h" 55125d42d9SJulian Harnath #include "WorkStatusView.h" 56d668d227SAndrew Lindesay #include "support.h" 5704c9d578SStephan Aßmus 5804c9d578SStephan Aßmus 5904c9d578SStephan Aßmus #undef B_TRANSLATION_CONTEXT 6004c9d578SStephan Aßmus #define B_TRANSLATION_CONTEXT "MainWindow" 6104c9d578SStephan Aßmus 6204c9d578SStephan Aßmus 6304c9d578SStephan Aßmus enum { 645bf2b6ebSBrian Hill MSG_REFRESH_REPOS = 'mrrp', 655bf2b6ebSBrian Hill MSG_MANAGE_REPOS = 'mmrp', 66d144f952SAugustin Cavalier MSG_SOFTWARE_UPDATER = 'mswu', 67133ebab6SAndrew Lindesay MSG_SETTINGS = 'stgs', 6804c9d578SStephan Aßmus MSG_LOG_IN = 'lgin', 698f03a0f9SStephan Aßmus MSG_AUTHORIZATION_CHANGED = 'athc', 7089b16bb4SAndrew Lindesay MSG_CATEGORIES_LIST_CHANGED = 'clic', 71da651104SStephan Aßmus MSG_PACKAGE_CHANGED = 'pchd', 72409af934SAndrew Lindesay MSG_PROCESS_COORDINATOR_CHANGED = 'pccd', 733369e03dSAndrew Lindesay MSG_WORK_STATUS_CHANGE = 'wsch', 743369e03dSAndrew Lindesay MSG_WORK_STATUS_CLEAR = 'wscl', 7584674570SAndrew Lindesay MSG_INCREMENT_VIEW_COUNTER = 'icrv', 7688af15cfSAndrew Lindesay MSG_SCREENSHOT_CACHED = 'ssca', 77fdec4227SStephan Aßmus 78ccf707d0SAndrew Lindesay MSG_CHANGE_PACKAGE_LIST_VIEW_MODE = 'cplm', 79fdec4227SStephan Aßmus MSG_SHOW_AVAILABLE_PACKAGES = 'savl', 80fdec4227SStephan Aßmus MSG_SHOW_INSTALLED_PACKAGES = 'sins', 8104c9d578SStephan Aßmus MSG_SHOW_SOURCE_PACKAGES = 'ssrc', 8204c9d578SStephan Aßmus MSG_SHOW_DEVELOP_PACKAGES = 'sdvl' 8304c9d578SStephan Aßmus }; 8404c9d578SStephan Aßmus 8510cd325cSAndrew Lindesay #define KEY_ERROR_STATUS "errorStatus" 86ccf707d0SAndrew Lindesay 8784674570SAndrew Lindesay const bigtime_t kIncrementViewCounterDelayMicros = 3 * 1000 * 1000; 8884674570SAndrew Lindesay 89ccf707d0SAndrew Lindesay #define TAB_PROMINENT_PACKAGES 0 90ccf707d0SAndrew Lindesay #define TAB_ALL_PACKAGES 1 9104c9d578SStephan Aßmus 9204c9d578SStephan Aßmus using namespace BPackageKit; 9304c9d578SStephan Aßmus using namespace BPackageKit::BManager::BPrivate; 9404c9d578SStephan Aßmus 9504c9d578SStephan Aßmus 9604c9d578SStephan Aßmus typedef std::map<BString, PackageInfoRef> PackageInfoMap; 9704c9d578SStephan Aßmus 9804c9d578SStephan Aßmus 9904c9d578SStephan Aßmus struct RefreshWorkerParameters { 10004c9d578SStephan Aßmus MainWindow* window; 10104c9d578SStephan Aßmus bool forceRefresh; 10204c9d578SStephan Aßmus 10304c9d578SStephan Aßmus RefreshWorkerParameters(MainWindow* window, bool forceRefresh) 10404c9d578SStephan Aßmus : 10504c9d578SStephan Aßmus window(window), 10604c9d578SStephan Aßmus forceRefresh(forceRefresh) 10704c9d578SStephan Aßmus { 10804c9d578SStephan Aßmus } 10904c9d578SStephan Aßmus }; 11004c9d578SStephan Aßmus 11104c9d578SStephan Aßmus 11289b16bb4SAndrew Lindesay class MainWindowModelListener : public ModelListener { 1138f03a0f9SStephan Aßmus public: 11489b16bb4SAndrew Lindesay MainWindowModelListener(const BMessenger& messenger) 1158f03a0f9SStephan Aßmus : 1168f03a0f9SStephan Aßmus fMessenger(messenger) 1178f03a0f9SStephan Aßmus { 1188f03a0f9SStephan Aßmus } 1198f03a0f9SStephan Aßmus 1208f03a0f9SStephan Aßmus virtual void AuthorizationChanged() 1218f03a0f9SStephan Aßmus { 1228f03a0f9SStephan Aßmus if (fMessenger.IsValid()) 1238f03a0f9SStephan Aßmus fMessenger.SendMessage(MSG_AUTHORIZATION_CHANGED); 1248f03a0f9SStephan Aßmus } 1258f03a0f9SStephan Aßmus 12689b16bb4SAndrew Lindesay virtual void CategoryListChanged() 12789b16bb4SAndrew Lindesay { 12889b16bb4SAndrew Lindesay if (fMessenger.IsValid()) 12989b16bb4SAndrew Lindesay fMessenger.SendMessage(MSG_CATEGORIES_LIST_CHANGED); 13089b16bb4SAndrew Lindesay } 13189b16bb4SAndrew Lindesay 13288af15cfSAndrew Lindesay virtual void ScreenshotCached(const ScreenshotCoordinate& coordinate) 13388af15cfSAndrew Lindesay { 13488af15cfSAndrew Lindesay if (fMessenger.IsValid()) { 13588af15cfSAndrew Lindesay BMessage message(MSG_SCREENSHOT_CACHED); 13688af15cfSAndrew Lindesay if (coordinate.Archive(&message) != B_OK) 13788af15cfSAndrew Lindesay debugger("unable to serialize a screenshot coordinate"); 13888af15cfSAndrew Lindesay fMessenger.SendMessage(&message); 13988af15cfSAndrew Lindesay } 14088af15cfSAndrew Lindesay } 14188af15cfSAndrew Lindesay 1428f03a0f9SStephan Aßmus private: 1438f03a0f9SStephan Aßmus BMessenger fMessenger; 1448f03a0f9SStephan Aßmus }; 1458f03a0f9SStephan Aßmus 1468f03a0f9SStephan Aßmus 147409af934SAndrew Lindesay class MainWindowPackageInfoListener : public PackageInfoListener { 148409af934SAndrew Lindesay public: 149409af934SAndrew Lindesay MainWindowPackageInfoListener(MainWindow* mainWindow) 150409af934SAndrew Lindesay : 151409af934SAndrew Lindesay fMainWindow(mainWindow) 152409af934SAndrew Lindesay { 153409af934SAndrew Lindesay } 154409af934SAndrew Lindesay 155409af934SAndrew Lindesay ~MainWindowPackageInfoListener() 156409af934SAndrew Lindesay { 157409af934SAndrew Lindesay } 158409af934SAndrew Lindesay 159409af934SAndrew Lindesay private: 160409af934SAndrew Lindesay // PackageInfoListener 161409af934SAndrew Lindesay virtual void PackageChanged(const PackageInfoEvent& event) 162409af934SAndrew Lindesay { 163409af934SAndrew Lindesay fMainWindow->PackageChanged(event); 164409af934SAndrew Lindesay } 165409af934SAndrew Lindesay 166409af934SAndrew Lindesay private: 167409af934SAndrew Lindesay MainWindow* fMainWindow; 168409af934SAndrew Lindesay }; 169409af934SAndrew Lindesay 170409af934SAndrew Lindesay 171f7c2983eSAxel Dörfler MainWindow::MainWindow(const BMessage& settings) 17204c9d578SStephan Aßmus : 173f7c2983eSAxel Dörfler BWindow(BRect(50, 50, 650, 550), B_TRANSLATE_SYSTEM_NAME("HaikuDepot"), 17404c9d578SStephan Aßmus B_DOCUMENT_WINDOW_LOOK, B_NORMAL_WINDOW_FEEL, 17504c9d578SStephan Aßmus B_ASYNCHRONOUS_CONTROLS | B_AUTO_UPDATE_SIZE_LIMITS), 176d5ef985eSStephan Aßmus fScreenshotWindow(NULL), 17795c7b018SAndrew Lindesay fShuttingDownWindow(NULL), 178e0a26dceSStephan Aßmus fUserMenu(NULL), 179e0a26dceSStephan Aßmus fLogInItem(NULL), 180e0a26dceSStephan Aßmus fLogOutItem(NULL), 181976cadf1SAndrew Lindesay fUsersUserUsageConditionsMenuItem(NULL), 18289b16bb4SAndrew Lindesay fModelListener(new MainWindowModelListener(BMessenger(this)), true), 18310cd325cSAndrew Lindesay fCoordinator(NULL), 18495c7b018SAndrew Lindesay fShouldCloseWhenNoProcessesToCoordinate(false), 18584674570SAndrew Lindesay fSinglePackageMode(false), 18684674570SAndrew Lindesay fIncrementViewCounterDelayedRunner(NULL) 18704c9d578SStephan Aßmus { 18810cd325cSAndrew Lindesay if ((fCoordinatorRunningSem = create_sem(1, "ProcessCoordinatorSem")) < B_OK) 18910cd325cSAndrew Lindesay debugger("unable to create the process coordinator semaphore"); 19010cd325cSAndrew Lindesay 191ad2df681SAndrew Lindesay _InitPreferredLanguage(); 192ad2df681SAndrew Lindesay 193409af934SAndrew Lindesay fPackageInfoListener = PackageInfoListenerRef( 194409af934SAndrew Lindesay new MainWindowPackageInfoListener(this), true); 195409af934SAndrew Lindesay 196cbadcae1SHumdinger BMenuBar* menuBar = new BMenuBar("Main Menu"); 19704c9d578SStephan Aßmus _BuildMenu(menuBar); 19804c9d578SStephan Aßmus 199cbadcae1SHumdinger BMenuBar* userMenuBar = new BMenuBar("User Menu"); 200e0a26dceSStephan Aßmus _BuildUserMenu(userMenuBar); 201e0a26dceSStephan Aßmus set_small_font(userMenuBar); 202e0a26dceSStephan Aßmus userMenuBar->SetExplicitMaxSize(BSize(B_SIZE_UNSET, 203e0a26dceSStephan Aßmus menuBar->MaxSize().height)); 204e0a26dceSStephan Aßmus 20504c9d578SStephan Aßmus fFilterView = new FilterView(); 206f0e491d3SAndrew Lindesay fFeaturedPackagesView = new FeaturedPackagesView(fModel); 207f0e491d3SAndrew Lindesay fPackageListView = new PackageListView(&fModel); 208f0e491d3SAndrew Lindesay fPackageInfoView = new PackageInfoView(&fModel, this); 20904c9d578SStephan Aßmus 21004c9d578SStephan Aßmus fSplitView = new BSplitView(B_VERTICAL, 5.0f); 21104c9d578SStephan Aßmus 212125d42d9SJulian Harnath fWorkStatusView = new WorkStatusView("work status"); 213125d42d9SJulian Harnath fPackageListView->AttachWorkStatusView(fWorkStatusView); 214125d42d9SJulian Harnath 215e00a489bSAugustin Cavalier fListTabs = new TabView(BMessenger(this), 216ccf707d0SAndrew Lindesay BMessage(MSG_CHANGE_PACKAGE_LIST_VIEW_MODE), "list tabs"); 217e00a489bSAugustin Cavalier fListTabs->AddTab(fFeaturedPackagesView); 218e00a489bSAugustin Cavalier fListTabs->AddTab(fPackageListView); 2194b930ccaSStephan Aßmus 22004c9d578SStephan Aßmus BLayoutBuilder::Group<>(this, B_VERTICAL, 0.0f) 221e0a26dceSStephan Aßmus .AddGroup(B_HORIZONTAL, 0.0f) 222e0a26dceSStephan Aßmus .Add(menuBar, 1.0f) 223e0a26dceSStephan Aßmus .Add(userMenuBar, 0.0f) 224e0a26dceSStephan Aßmus .End() 22504c9d578SStephan Aßmus .Add(fFilterView) 22604c9d578SStephan Aßmus .AddSplit(fSplitView) 22704c9d578SStephan Aßmus .AddGroup(B_VERTICAL) 228e00a489bSAugustin Cavalier .Add(fListTabs) 22904c9d578SStephan Aßmus .SetInsets( 23004c9d578SStephan Aßmus B_USE_DEFAULT_SPACING, 0.0f, 23104c9d578SStephan Aßmus B_USE_DEFAULT_SPACING, 0.0f) 23204c9d578SStephan Aßmus .End() 23304c9d578SStephan Aßmus .Add(fPackageInfoView) 23404c9d578SStephan Aßmus .End() 235125d42d9SJulian Harnath .Add(fWorkStatusView) 23604c9d578SStephan Aßmus ; 23704c9d578SStephan Aßmus 23804c9d578SStephan Aßmus fSplitView->SetCollapsible(0, false); 23904c9d578SStephan Aßmus fSplitView->SetCollapsible(1, false); 24004c9d578SStephan Aßmus 2418f03a0f9SStephan Aßmus fModel.AddListener(fModelListener); 2428f03a0f9SStephan Aßmus 24304c9d578SStephan Aßmus BMessage columnSettings; 24404c9d578SStephan Aßmus if (settings.FindMessage("column settings", &columnSettings) == B_OK) 24504c9d578SStephan Aßmus fPackageListView->LoadState(&columnSettings); 24604c9d578SStephan Aßmus 247ccf707d0SAndrew Lindesay _RestoreModelSettings(settings); 248133ebab6SAndrew Lindesay _MaybePromptCanShareAnonymousUserData(settings); 24904c9d578SStephan Aßmus 250ccf707d0SAndrew Lindesay if (fModel.PackageListViewMode() == PROMINENT) 251ccf707d0SAndrew Lindesay fListTabs->Select(TAB_PROMINENT_PACKAGES); 2522997e05bSStephan Aßmus else 253ccf707d0SAndrew Lindesay fListTabs->Select(TAB_ALL_PACKAGES); 2542997e05bSStephan Aßmus 255d2d4866dSAndrew Lindesay _RestoreNickname(settings); 25610cd325cSAndrew Lindesay _UpdateAuthorization(); 257f7c2983eSAxel Dörfler _RestoreWindowFrame(settings); 258f7c2983eSAxel Dörfler 2598f03a0f9SStephan Aßmus // start worker threads 26004c9d578SStephan Aßmus BPackageRoster().StartWatching(this, 26104c9d578SStephan Aßmus B_WATCH_PACKAGE_INSTALLATION_LOCATIONS); 26204c9d578SStephan Aßmus 2639883929bSAndrew Lindesay _AdoptModel(); 2649883929bSAndrew Lindesay _StartBulkLoad(); 26504c9d578SStephan Aßmus } 26604c9d578SStephan Aßmus 26704c9d578SStephan Aßmus 26875a70554SAndrew Lindesay /*! This constructor is used when the application is loaded for the purpose of 26975a70554SAndrew Lindesay viewing an HPKG file. 27075a70554SAndrew Lindesay */ 27175a70554SAndrew Lindesay 272afe7affbSAndrew Lindesay MainWindow::MainWindow(const BMessage& settings, PackageInfoRef& package) 2736d519fd1SStephan Aßmus : 274f7c2983eSAxel Dörfler BWindow(BRect(50, 50, 650, 350), B_TRANSLATE_SYSTEM_NAME("HaikuDepot"), 2756d519fd1SStephan Aßmus B_DOCUMENT_WINDOW_LOOK, B_NORMAL_WINDOW_FEEL, 2766d519fd1SStephan Aßmus B_ASYNCHRONOUS_CONTROLS | B_AUTO_UPDATE_SIZE_LIMITS), 2779883929bSAndrew Lindesay fFeaturedPackagesView(NULL), 2789883929bSAndrew Lindesay fPackageListView(NULL), 279d78bfd8dSJulian Harnath fWorkStatusView(NULL), 280d5ef985eSStephan Aßmus fScreenshotWindow(NULL), 28195c7b018SAndrew Lindesay fShuttingDownWindow(NULL), 282e0a26dceSStephan Aßmus fUserMenu(NULL), 283e0a26dceSStephan Aßmus fLogInItem(NULL), 2846d519fd1SStephan Aßmus fLogOutItem(NULL), 285976cadf1SAndrew Lindesay fUsersUserUsageConditionsMenuItem(NULL), 28689b16bb4SAndrew Lindesay fModelListener(new MainWindowModelListener(BMessenger(this)), true), 28710cd325cSAndrew Lindesay fCoordinator(NULL), 28895c7b018SAndrew Lindesay fShouldCloseWhenNoProcessesToCoordinate(false), 28984674570SAndrew Lindesay fSinglePackageMode(true), 29084674570SAndrew Lindesay fIncrementViewCounterDelayedRunner(NULL) 2916d519fd1SStephan Aßmus { 29275a70554SAndrew Lindesay BString title = B_TRANSLATE("HaikuDepot - %PackageName% %PackageVersion%"); 29375a70554SAndrew Lindesay title.ReplaceAll("%PackageName%", package->Name()); 29475a70554SAndrew Lindesay title.ReplaceAll("%PackageVersion%", package->Version().ToString()); 29575a70554SAndrew Lindesay SetTitle(title); 29675a70554SAndrew Lindesay 29710cd325cSAndrew Lindesay if ((fCoordinatorRunningSem = create_sem(1, "ProcessCoordinatorSem")) < B_OK) 29810cd325cSAndrew Lindesay debugger("unable to create the process coordinator semaphore"); 29910cd325cSAndrew Lindesay 300ad2df681SAndrew Lindesay _InitPreferredLanguage(); 301ad2df681SAndrew Lindesay 302409af934SAndrew Lindesay fPackageInfoListener = PackageInfoListenerRef( 303409af934SAndrew Lindesay new MainWindowPackageInfoListener(this), true); 304409af934SAndrew Lindesay 3056d519fd1SStephan Aßmus fFilterView = new FilterView(); 306f0e491d3SAndrew Lindesay fPackageInfoView = new PackageInfoView(&fModel, this); 30787016f8fSAndrew Lindesay fWorkStatusView = new WorkStatusView("work status"); 3086d519fd1SStephan Aßmus 3096d519fd1SStephan Aßmus BLayoutBuilder::Group<>(this, B_VERTICAL) 3106d519fd1SStephan Aßmus .Add(fPackageInfoView) 31187016f8fSAndrew Lindesay .Add(fWorkStatusView) 3126d519fd1SStephan Aßmus .SetInsets(0, B_USE_WINDOW_INSETS, 0, 0) 3136d519fd1SStephan Aßmus ; 3146d519fd1SStephan Aßmus 3156d519fd1SStephan Aßmus fModel.AddListener(fModelListener); 3166d519fd1SStephan Aßmus 317afe7affbSAndrew Lindesay // add the single package into the model so that any internal 318afe7affbSAndrew Lindesay // business logic is able to find the package. 319afe7affbSAndrew Lindesay DepotInfoRef depot(new DepotInfo("single-pkg-depot"), true); 320afe7affbSAndrew Lindesay depot->AddPackage(package); 321afe7affbSAndrew Lindesay fModel.MergeOrAddDepot(depot); 322afe7affbSAndrew Lindesay 3236d519fd1SStephan Aßmus // Restore settings 324d2d4866dSAndrew Lindesay _RestoreNickname(settings); 325ccf707d0SAndrew Lindesay _UpdateAuthorization(); 326f7c2983eSAxel Dörfler _RestoreWindowFrame(settings); 3276d519fd1SStephan Aßmus 3286d519fd1SStephan Aßmus fPackageInfoView->SetPackage(package); 32963975654SStephan Aßmus 330afe7affbSAndrew Lindesay // start worker threads 331afe7affbSAndrew Lindesay BPackageRoster().StartWatching(this, 332afe7affbSAndrew Lindesay B_WATCH_PACKAGE_INSTALLATION_LOCATIONS); 3336d519fd1SStephan Aßmus } 3346d519fd1SStephan Aßmus 3356d519fd1SStephan Aßmus 33604c9d578SStephan Aßmus MainWindow::~MainWindow() 33704c9d578SStephan Aßmus { 33810cd325cSAndrew Lindesay _SpinUntilProcessCoordinatorComplete(); 33910cd325cSAndrew Lindesay delete_sem(fCoordinatorRunningSem); 34010cd325cSAndrew Lindesay fCoordinatorRunningSem = 0; 34110cd325cSAndrew Lindesay 34204c9d578SStephan Aßmus BPackageRoster().StopWatching(this); 34304c9d578SStephan Aßmus 34495c7b018SAndrew Lindesay if (fScreenshotWindow != NULL) { 34595c7b018SAndrew Lindesay if (fScreenshotWindow->Lock()) 346d5ef985eSStephan Aßmus fScreenshotWindow->Quit(); 34704c9d578SStephan Aßmus } 34804c9d578SStephan Aßmus 34995c7b018SAndrew Lindesay if (fShuttingDownWindow != NULL) { 35095c7b018SAndrew Lindesay if (fShuttingDownWindow->Lock()) 35195c7b018SAndrew Lindesay fShuttingDownWindow->Quit(); 35295c7b018SAndrew Lindesay } 353d5562247SAugustin Cavalier 3544329a83fSAugustin Cavalier // We must clear the model early to release references. 355d5562247SAugustin Cavalier fModel.Clear(); 35695c7b018SAndrew Lindesay } 35795c7b018SAndrew Lindesay 35804c9d578SStephan Aßmus 35904c9d578SStephan Aßmus bool 36004c9d578SStephan Aßmus MainWindow::QuitRequested() 36104c9d578SStephan Aßmus { 36204c9d578SStephan Aßmus 36310cd325cSAndrew Lindesay _StopProcessCoordinators(); 3643369e03dSAndrew Lindesay 36595c7b018SAndrew Lindesay // If there are any processes in flight we need to be careful to make 36695c7b018SAndrew Lindesay // sure that they are cleanly completed before actually quitting. By 36795c7b018SAndrew Lindesay // turning on the `fShouldCloseWhenNoProcessesToCoordinate` flag, when 36895c7b018SAndrew Lindesay // the process coordination has completed then it will detect this and 36995c7b018SAndrew Lindesay // quit again. 37095c7b018SAndrew Lindesay 37195c7b018SAndrew Lindesay { 37295c7b018SAndrew Lindesay AutoLocker<BLocker> lock(&fCoordinatorLock); 37395c7b018SAndrew Lindesay fShouldCloseWhenNoProcessesToCoordinate = true; 37495c7b018SAndrew Lindesay 375409af934SAndrew Lindesay if (fCoordinator != NULL) { 37695c7b018SAndrew Lindesay HDINFO("a coordinator is running --> will wait before quitting..."); 37795c7b018SAndrew Lindesay 37895c7b018SAndrew Lindesay if (fShuttingDownWindow == NULL) 37995c7b018SAndrew Lindesay fShuttingDownWindow = new ShuttingDownWindow(this); 38095c7b018SAndrew Lindesay fShuttingDownWindow->Show(); 38195c7b018SAndrew Lindesay 38295c7b018SAndrew Lindesay return false; 38395c7b018SAndrew Lindesay } 38495c7b018SAndrew Lindesay } 38595c7b018SAndrew Lindesay 38695c7b018SAndrew Lindesay BMessage settings; 38795c7b018SAndrew Lindesay StoreSettings(settings); 38895c7b018SAndrew Lindesay BMessage message(MSG_MAIN_WINDOW_CLOSED); 38995c7b018SAndrew Lindesay message.AddMessage(KEY_WINDOW_SETTINGS, &settings); 39095c7b018SAndrew Lindesay be_app->PostMessage(&message); 39195c7b018SAndrew Lindesay 39295c7b018SAndrew Lindesay if (fShuttingDownWindow != NULL) { 39395c7b018SAndrew Lindesay if (fShuttingDownWindow->Lock()) 39495c7b018SAndrew Lindesay fShuttingDownWindow->Quit(); 39595c7b018SAndrew Lindesay fShuttingDownWindow = NULL; 39695c7b018SAndrew Lindesay } 39795c7b018SAndrew Lindesay 39804c9d578SStephan Aßmus return true; 39904c9d578SStephan Aßmus } 40004c9d578SStephan Aßmus 40104c9d578SStephan Aßmus 40204c9d578SStephan Aßmus void 40304c9d578SStephan Aßmus MainWindow::MessageReceived(BMessage* message) 40404c9d578SStephan Aßmus { 40504c9d578SStephan Aßmus switch (message->what) { 4063369e03dSAndrew Lindesay case MSG_BULK_LOAD_DONE: 40710cd325cSAndrew Lindesay { 40810cd325cSAndrew Lindesay int64 errorStatus64; 40910cd325cSAndrew Lindesay if (message->FindInt64(KEY_ERROR_STATUS, &errorStatus64) == B_OK) 41010cd325cSAndrew Lindesay _BulkLoadCompleteReceived((status_t) errorStatus64); 41110cd325cSAndrew Lindesay else 412fa5c8097SAndrew Lindesay HDERROR("expected [%s] value in message", KEY_ERROR_STATUS); 41304c9d578SStephan Aßmus break; 41410cd325cSAndrew Lindesay } 41504c9d578SStephan Aßmus case B_SIMPLE_DATA: 41604c9d578SStephan Aßmus case B_REFS_RECEIVED: 41704c9d578SStephan Aßmus // TODO: ? 41804c9d578SStephan Aßmus break; 41904c9d578SStephan Aßmus 42004c9d578SStephan Aßmus case B_PACKAGE_UPDATE: 421f32d5c5cSAndrew Lindesay _HandleExternalPackageUpdateMessageReceived(message); 42204c9d578SStephan Aßmus break; 42304c9d578SStephan Aßmus 4245bf2b6ebSBrian Hill case MSG_REFRESH_REPOS: 4253369e03dSAndrew Lindesay _StartBulkLoad(true); 4263369e03dSAndrew Lindesay break; 4273369e03dSAndrew Lindesay 42810cd325cSAndrew Lindesay case MSG_WORK_STATUS_CLEAR: 42910cd325cSAndrew Lindesay _HandleWorkStatusClear(); 43010cd325cSAndrew Lindesay break; 43110cd325cSAndrew Lindesay 4323369e03dSAndrew Lindesay case MSG_WORK_STATUS_CHANGE: 4333369e03dSAndrew Lindesay _HandleWorkStatusChangeMessageReceived(message); 43404c9d578SStephan Aßmus break; 43504c9d578SStephan Aßmus 4365bf2b6ebSBrian Hill case MSG_MANAGE_REPOS: 4375bf2b6ebSBrian Hill be_roster->Launch("application/x-vnd.Haiku-Repositories"); 4385bf2b6ebSBrian Hill break; 4395bf2b6ebSBrian Hill 440d144f952SAugustin Cavalier case MSG_SOFTWARE_UPDATER: 441d144f952SAugustin Cavalier be_roster->Launch("application/x-vnd.haiku-softwareupdater"); 442d144f952SAugustin Cavalier break; 443d144f952SAugustin Cavalier 44404c9d578SStephan Aßmus case MSG_LOG_IN: 4451bbda92dSStephan Aßmus _OpenLoginWindow(BMessage()); 44604c9d578SStephan Aßmus break; 44704c9d578SStephan Aßmus 448133ebab6SAndrew Lindesay case MSG_SETTINGS: 449133ebab6SAndrew Lindesay _OpenSettingsWindow(); 450133ebab6SAndrew Lindesay break; 451133ebab6SAndrew Lindesay 4528f03a0f9SStephan Aßmus case MSG_LOG_OUT: 453d2d4866dSAndrew Lindesay fModel.SetNickname(""); 4548f03a0f9SStephan Aßmus break; 4558f03a0f9SStephan Aßmus 45601339a54SAndrew Lindesay case MSG_VIEW_LATEST_USER_USAGE_CONDITIONS: 457d2d4866dSAndrew Lindesay _ViewUserUsageConditions(LATEST); 458d2d4866dSAndrew Lindesay break; 459d2d4866dSAndrew Lindesay 460d2d4866dSAndrew Lindesay case MSG_VIEW_USERS_USER_USAGE_CONDITIONS: 461d2d4866dSAndrew Lindesay _ViewUserUsageConditions(USER); 46201339a54SAndrew Lindesay break; 46301339a54SAndrew Lindesay 4648f03a0f9SStephan Aßmus case MSG_AUTHORIZATION_CHANGED: 46510cd325cSAndrew Lindesay _StartUserVerify(); 4668f03a0f9SStephan Aßmus _UpdateAuthorization(); 4678f03a0f9SStephan Aßmus break; 4688f03a0f9SStephan Aßmus 46988af15cfSAndrew Lindesay case MSG_SCREENSHOT_CACHED: 47088af15cfSAndrew Lindesay _HandleScreenshotCached(message); 47188af15cfSAndrew Lindesay break; 47288af15cfSAndrew Lindesay 47389b16bb4SAndrew Lindesay case MSG_CATEGORIES_LIST_CHANGED: 47489b16bb4SAndrew Lindesay fFilterView->AdoptModel(fModel); 47589b16bb4SAndrew Lindesay break; 47689b16bb4SAndrew Lindesay 477ccf707d0SAndrew Lindesay case MSG_CHANGE_PACKAGE_LIST_VIEW_MODE: 478ccf707d0SAndrew Lindesay _HandleChangePackageListViewMode(); 4794fade61fSStephan Aßmus break; 4804fade61fSStephan Aßmus 481fdec4227SStephan Aßmus case MSG_SHOW_AVAILABLE_PACKAGES: 482fdec4227SStephan Aßmus { 483fdec4227SStephan Aßmus BAutolock locker(fModel.Lock()); 484363fc60bSAndrew Lindesay PackageFilterModel* filterModel = fModel.PackageFilter(); 485363fc60bSAndrew Lindesay filterModel->SetShowAvailablePackages(!filterModel->ShowAvailablePackages()); 486fdec4227SStephan Aßmus } 487fdec4227SStephan Aßmus _AdoptModel(); 488fdec4227SStephan Aßmus break; 489fdec4227SStephan Aßmus 490fdec4227SStephan Aßmus case MSG_SHOW_INSTALLED_PACKAGES: 491fdec4227SStephan Aßmus { 492fdec4227SStephan Aßmus BAutolock locker(fModel.Lock()); 493363fc60bSAndrew Lindesay PackageFilterModel* filterModel = fModel.PackageFilter(); 494363fc60bSAndrew Lindesay filterModel->SetShowInstalledPackages(!filterModel->ShowInstalledPackages()); 495fdec4227SStephan Aßmus } 496fdec4227SStephan Aßmus _AdoptModel(); 497fdec4227SStephan Aßmus break; 498fdec4227SStephan Aßmus 49904c9d578SStephan Aßmus case MSG_SHOW_SOURCE_PACKAGES: 50004c9d578SStephan Aßmus { 50104c9d578SStephan Aßmus BAutolock locker(fModel.Lock()); 502363fc60bSAndrew Lindesay PackageFilterModel* filterModel = fModel.PackageFilter(); 503363fc60bSAndrew Lindesay filterModel->SetShowSourcePackages(!filterModel->ShowSourcePackages()); 50404c9d578SStephan Aßmus } 50504c9d578SStephan Aßmus _AdoptModel(); 50604c9d578SStephan Aßmus break; 50704c9d578SStephan Aßmus 50804c9d578SStephan Aßmus case MSG_SHOW_DEVELOP_PACKAGES: 50904c9d578SStephan Aßmus { 51004c9d578SStephan Aßmus BAutolock locker(fModel.Lock()); 511363fc60bSAndrew Lindesay PackageFilterModel* filterModel = fModel.PackageFilter(); 512363fc60bSAndrew Lindesay filterModel->SetShowDevelopPackages(!filterModel->ShowDevelopPackages()); 51304c9d578SStephan Aßmus } 51404c9d578SStephan Aßmus _AdoptModel(); 51504c9d578SStephan Aßmus break; 51604c9d578SStephan Aßmus 517a9edb9bfSAndrew Lindesay // this may be triggered by, for example, a user rating being added 518a9edb9bfSAndrew Lindesay // or having been altered. 519a9edb9bfSAndrew Lindesay case MSG_SERVER_DATA_CHANGED: 520a9edb9bfSAndrew Lindesay { 521a9edb9bfSAndrew Lindesay BString name; 522a9edb9bfSAndrew Lindesay if (message->FindString("name", &name) == B_OK) { 523a9edb9bfSAndrew Lindesay BAutolock locker(fModel.Lock()); 524a9edb9bfSAndrew Lindesay if (fPackageInfoView->Package()->Name() == name) { 525a9edb9bfSAndrew Lindesay _PopulatePackageAsync(true); 526a9edb9bfSAndrew Lindesay } else { 527f96d1f4dSAndrew Lindesay HDDEBUG("pkg [%s] is updated on the server, but is " 528f96d1f4dSAndrew Lindesay "not selected so will not be updated.", 529fa5c8097SAndrew Lindesay name.String()); 530a9edb9bfSAndrew Lindesay } 531a9edb9bfSAndrew Lindesay } 532a9edb9bfSAndrew Lindesay break; 533a9edb9bfSAndrew Lindesay } 534a9edb9bfSAndrew Lindesay 53584674570SAndrew Lindesay case MSG_INCREMENT_VIEW_COUNTER: 53684674570SAndrew Lindesay _HandleIncrementViewCounter(message); 53784674570SAndrew Lindesay break; 53884674570SAndrew Lindesay 53904c9d578SStephan Aßmus case MSG_PACKAGE_SELECTED: 54004c9d578SStephan Aßmus { 54172992391SStephan Aßmus BString name; 54272992391SStephan Aßmus if (message->FindString("name", &name) == B_OK) { 543c4199192SAndrew Lindesay PackageInfoRef package; 544c4199192SAndrew Lindesay { 54575ba9dbfSStephan Aßmus BAutolock locker(fModel.Lock()); 546c4199192SAndrew Lindesay package = fModel.PackageForName(name); 547c4199192SAndrew Lindesay } 5486f07feadSAndrew Lindesay if (!package.IsSet() || name != package->Name()) 549c4199192SAndrew Lindesay debugger("unable to find the named package"); 550133ebab6SAndrew Lindesay else { 55104c9d578SStephan Aßmus _AdoptPackage(package); 55284674570SAndrew Lindesay _SetupDelayedIncrementViewCounter(package); 553133ebab6SAndrew Lindesay } 55404c9d578SStephan Aßmus } else { 55504c9d578SStephan Aßmus _ClearPackage(); 55604c9d578SStephan Aßmus } 55704c9d578SStephan Aßmus break; 55804c9d578SStephan Aßmus } 55904c9d578SStephan Aßmus 56004c9d578SStephan Aßmus case MSG_CATEGORY_SELECTED: 56104c9d578SStephan Aßmus { 56289b16bb4SAndrew Lindesay BString code; 56389b16bb4SAndrew Lindesay if (message->FindString("code", &code) != B_OK) 56489b16bb4SAndrew Lindesay code = ""; 56504c9d578SStephan Aßmus { 56604c9d578SStephan Aßmus BAutolock locker(fModel.Lock()); 567363fc60bSAndrew Lindesay fModel.PackageFilter()->SetCategory(code); 56804c9d578SStephan Aßmus } 56904c9d578SStephan Aßmus _AdoptModel(); 57004c9d578SStephan Aßmus break; 57104c9d578SStephan Aßmus } 57204c9d578SStephan Aßmus 57304c9d578SStephan Aßmus case MSG_DEPOT_SELECTED: 57404c9d578SStephan Aßmus { 57504c9d578SStephan Aßmus BString name; 57604c9d578SStephan Aßmus if (message->FindString("name", &name) != B_OK) 57704c9d578SStephan Aßmus name = ""; 57804c9d578SStephan Aßmus { 57904c9d578SStephan Aßmus BAutolock locker(fModel.Lock()); 580363fc60bSAndrew Lindesay fModel.PackageFilter()->SetDepotName(name); 58104c9d578SStephan Aßmus } 58204c9d578SStephan Aßmus _AdoptModel(); 583b965ce70SHumdinger _UpdateAvailableRepositories(); 58404c9d578SStephan Aßmus break; 58504c9d578SStephan Aßmus } 58604c9d578SStephan Aßmus 58704c9d578SStephan Aßmus case MSG_SEARCH_TERMS_MODIFIED: 58804c9d578SStephan Aßmus { 58904c9d578SStephan Aßmus // TODO: Do this with a delay! 59004c9d578SStephan Aßmus BString searchTerms; 59104c9d578SStephan Aßmus if (message->FindString("search terms", &searchTerms) != B_OK) 59204c9d578SStephan Aßmus searchTerms = ""; 59304c9d578SStephan Aßmus { 59404c9d578SStephan Aßmus BAutolock locker(fModel.Lock()); 595363fc60bSAndrew Lindesay fModel.PackageFilter()->SetSearchTerms(searchTerms); 59604c9d578SStephan Aßmus } 59704c9d578SStephan Aßmus _AdoptModel(); 59804c9d578SStephan Aßmus break; 59904c9d578SStephan Aßmus } 60004c9d578SStephan Aßmus 601da651104SStephan Aßmus case MSG_PACKAGE_CHANGED: 60204c9d578SStephan Aßmus { 60304c9d578SStephan Aßmus PackageInfo* info; 60404c9d578SStephan Aßmus if (message->FindPointer("package", (void**)&info) == B_OK) { 60504c9d578SStephan Aßmus PackageInfoRef ref(info, true); 6060b69420bSAndrew Lindesay fFeaturedPackagesView->BeginAddRemove(); 607c4199192SAndrew Lindesay _AddRemovePackageFromLists(ref); 6080b69420bSAndrew Lindesay fFeaturedPackagesView->EndAddRemove(); 60910cd325cSAndrew Lindesay } 61004c9d578SStephan Aßmus break; 61104c9d578SStephan Aßmus } 61204c9d578SStephan Aßmus 613409af934SAndrew Lindesay case MSG_PROCESS_COORDINATOR_CHANGED: 614409af934SAndrew Lindesay { 615409af934SAndrew Lindesay ProcessCoordinatorState state(message); 616409af934SAndrew Lindesay _HandleProcessCoordinatorChanged(state); 617409af934SAndrew Lindesay break; 618409af934SAndrew Lindesay } 619409af934SAndrew Lindesay 62004c9d578SStephan Aßmus case MSG_RATE_PACKAGE: 6211bbda92dSStephan Aßmus _RatePackage(); 62204c9d578SStephan Aßmus break; 62304c9d578SStephan Aßmus 624d5ef985eSStephan Aßmus case MSG_SHOW_SCREENSHOT: 625d5ef985eSStephan Aßmus _ShowScreenshot(); 626d5ef985eSStephan Aßmus break; 627d5ef985eSStephan Aßmus 628125d42d9SJulian Harnath case MSG_PACKAGE_WORKER_BUSY: 629125d42d9SJulian Harnath { 630125d42d9SJulian Harnath BString reason; 631125d42d9SJulian Harnath status_t status = message->FindString("reason", &reason); 632125d42d9SJulian Harnath if (status != B_OK) 633125d42d9SJulian Harnath break; 634125d42d9SJulian Harnath fWorkStatusView->SetBusy(reason); 635125d42d9SJulian Harnath break; 636125d42d9SJulian Harnath } 637125d42d9SJulian Harnath 638125d42d9SJulian Harnath case MSG_PACKAGE_WORKER_IDLE: 639125d42d9SJulian Harnath fWorkStatusView->SetIdle(); 640125d42d9SJulian Harnath break; 641125d42d9SJulian Harnath 64210cd325cSAndrew Lindesay case MSG_USER_USAGE_CONDITIONS_NOT_LATEST: 64310cd325cSAndrew Lindesay { 64410cd325cSAndrew Lindesay BMessage userDetailMsg; 64510cd325cSAndrew Lindesay if (message->FindMessage("userDetail", &userDetailMsg) != B_OK) { 64610cd325cSAndrew Lindesay debugger("expected the [userDetail] data to be carried in the " 64710cd325cSAndrew Lindesay "message."); 64810cd325cSAndrew Lindesay } 64910cd325cSAndrew Lindesay UserDetail userDetail(&userDetailMsg); 65010cd325cSAndrew Lindesay _HandleUserUsageConditionsNotLatest(userDetail); 65110cd325cSAndrew Lindesay break; 65210cd325cSAndrew Lindesay } 65310cd325cSAndrew Lindesay 65404c9d578SStephan Aßmus default: 65504c9d578SStephan Aßmus BWindow::MessageReceived(message); 65604c9d578SStephan Aßmus break; 65704c9d578SStephan Aßmus } 65804c9d578SStephan Aßmus } 65904c9d578SStephan Aßmus 66004c9d578SStephan Aßmus 661ccf707d0SAndrew Lindesay static const char* 662ccf707d0SAndrew Lindesay main_window_package_list_view_mode_str(package_list_view_mode mode) 663ccf707d0SAndrew Lindesay { 664ccf707d0SAndrew Lindesay if (mode == PROMINENT) 665ccf707d0SAndrew Lindesay return "PROMINENT"; 666ccf707d0SAndrew Lindesay return "ALL"; 667ccf707d0SAndrew Lindesay } 668ccf707d0SAndrew Lindesay 669ccf707d0SAndrew Lindesay 670ccf707d0SAndrew Lindesay static package_list_view_mode 671ccf707d0SAndrew Lindesay main_window_str_to_package_list_view_mode(const BString& str) 672ccf707d0SAndrew Lindesay { 673ccf707d0SAndrew Lindesay if (str == "PROMINENT") 674ccf707d0SAndrew Lindesay return PROMINENT; 675ccf707d0SAndrew Lindesay return ALL; 676ccf707d0SAndrew Lindesay } 677ccf707d0SAndrew Lindesay 678ccf707d0SAndrew Lindesay 67904c9d578SStephan Aßmus void 6804b347fccSAndrew Lindesay MainWindow::StoreSettings(BMessage& settings) 68104c9d578SStephan Aßmus { 682f7c2983eSAxel Dörfler settings.AddRect(_WindowFrameName(), Frame()); 683f7c2983eSAxel Dörfler if (!fSinglePackageMode) { 68404c9d578SStephan Aßmus settings.AddRect("window frame", Frame()); 68504c9d578SStephan Aßmus 68604c9d578SStephan Aßmus BMessage columnSettings; 6879883929bSAndrew Lindesay if (fPackageListView != NULL) 68804c9d578SStephan Aßmus fPackageListView->SaveState(&columnSettings); 68904c9d578SStephan Aßmus 69004c9d578SStephan Aßmus settings.AddMessage("column settings", &columnSettings); 69104c9d578SStephan Aßmus 692133ebab6SAndrew Lindesay settings.AddString(SETTING_PACKAGE_LIST_VIEW_MODE, 693ccf707d0SAndrew Lindesay main_window_package_list_view_mode_str( 694ccf707d0SAndrew Lindesay fModel.PackageListViewMode())); 695363fc60bSAndrew Lindesay 696133ebab6SAndrew Lindesay settings.AddBool(SETTING_SHOW_AVAILABLE_PACKAGES, 697363fc60bSAndrew Lindesay fModel.PackageFilter()->ShowAvailablePackages()); 698133ebab6SAndrew Lindesay settings.AddBool(SETTING_SHOW_INSTALLED_PACKAGES, 699363fc60bSAndrew Lindesay fModel.PackageFilter()->ShowInstalledPackages()); 700133ebab6SAndrew Lindesay settings.AddBool(SETTING_SHOW_DEVELOP_PACKAGES, 701363fc60bSAndrew Lindesay fModel.PackageFilter()->ShowDevelopPackages()); 702133ebab6SAndrew Lindesay settings.AddBool(SETTING_SHOW_SOURCE_PACKAGES, 703363fc60bSAndrew Lindesay fModel.PackageFilter()->ShowSourcePackages()); 704363fc60bSAndrew Lindesay 705133ebab6SAndrew Lindesay settings.AddBool(SETTING_CAN_SHARE_ANONYMOUS_USER_DATA, 706133ebab6SAndrew Lindesay fModel.CanShareAnonymousUsageData()); 7076d519fd1SStephan Aßmus } 7088f03a0f9SStephan Aßmus 709d2d4866dSAndrew Lindesay settings.AddString("username", fModel.Nickname()); 71004c9d578SStephan Aßmus } 71104c9d578SStephan Aßmus 71204c9d578SStephan Aßmus 71304c9d578SStephan Aßmus void 714a18f873fSAndrew Lindesay MainWindow::Consume(ProcessCoordinator *item) 715a18f873fSAndrew Lindesay { 716a18f873fSAndrew Lindesay _AddProcessCoordinator(item); 717a18f873fSAndrew Lindesay } 718a18f873fSAndrew Lindesay 719a18f873fSAndrew Lindesay 720a18f873fSAndrew Lindesay void 72104c9d578SStephan Aßmus MainWindow::PackageChanged(const PackageInfoEvent& event) 72204c9d578SStephan Aßmus { 723*8cc3ed34SAndrew Lindesay uint32 watchedChanges = PKG_CHANGED_STATE | PKG_CHANGED_CLASSIFICATION; 724a9edb9bfSAndrew Lindesay if ((event.Changes() & watchedChanges) != 0) { 72504c9d578SStephan Aßmus PackageInfoRef ref(event.Package()); 726da651104SStephan Aßmus BMessage message(MSG_PACKAGE_CHANGED); 72704c9d578SStephan Aßmus message.AddPointer("package", ref.Get()); 72804c9d578SStephan Aßmus ref.Detach(); 72904c9d578SStephan Aßmus // reference needs to be released by MessageReceived(); 73004c9d578SStephan Aßmus PostMessage(&message); 73104c9d578SStephan Aßmus } 73204c9d578SStephan Aßmus } 73304c9d578SStephan Aßmus 73404c9d578SStephan Aßmus 73504c9d578SStephan Aßmus void 73604c9d578SStephan Aßmus MainWindow::_BuildMenu(BMenuBar* menuBar) 73704c9d578SStephan Aßmus { 7380b6928f1SHumdinger BMenu* menu = new BMenu(B_TRANSLATE_SYSTEM_NAME("HaikuDepot")); 7393369e03dSAndrew Lindesay fRefreshRepositoriesItem = new BMenuItem( 7403369e03dSAndrew Lindesay B_TRANSLATE("Refresh repositories"), new BMessage(MSG_REFRESH_REPOS)); 7413369e03dSAndrew Lindesay menu->AddItem(fRefreshRepositoriesItem); 742d7f78130SHumdinger menu->AddItem(new BMenuItem(B_TRANSLATE("Manage repositories" 743d7f78130SHumdinger B_UTF8_ELLIPSIS), new BMessage(MSG_MANAGE_REPOS))); 744d144f952SAugustin Cavalier menu->AddItem(new BMenuItem(B_TRANSLATE("Check for updates" 745d144f952SAugustin Cavalier B_UTF8_ELLIPSIS), new BMessage(MSG_SOFTWARE_UPDATER))); 7460b6928f1SHumdinger menu->AddSeparatorItem(); 7470b6928f1SHumdinger menu->AddItem(new BMenuItem(B_TRANSLATE("Settings" B_UTF8_ELLIPSIS), 748e1ae57abSJoachim Mairböck new BMessage(MSG_SETTINGS), ',')); 7490b6928f1SHumdinger menu->AddItem(new BMenuItem(B_TRANSLATE("Quit"), 7500b6928f1SHumdinger new BMessage(B_QUIT_REQUESTED), 'Q')); 75104c9d578SStephan Aßmus menuBar->AddItem(menu); 75204c9d578SStephan Aßmus 753b965ce70SHumdinger fRepositoryMenu = new BMenu(B_TRANSLATE("Repositories")); 754b965ce70SHumdinger menuBar->AddItem(fRepositoryMenu); 755b965ce70SHumdinger 7564fade61fSStephan Aßmus menu = new BMenu(B_TRANSLATE("Show")); 7574fade61fSStephan Aßmus 758fdec4227SStephan Aßmus fShowAvailablePackagesItem = new BMenuItem( 7594fade61fSStephan Aßmus B_TRANSLATE("Available packages"), 760fdec4227SStephan Aßmus new BMessage(MSG_SHOW_AVAILABLE_PACKAGES)); 761fdec4227SStephan Aßmus menu->AddItem(fShowAvailablePackagesItem); 762fdec4227SStephan Aßmus 763fdec4227SStephan Aßmus fShowInstalledPackagesItem = new BMenuItem( 7644fade61fSStephan Aßmus B_TRANSLATE("Installed packages"), 765fdec4227SStephan Aßmus new BMessage(MSG_SHOW_INSTALLED_PACKAGES)); 766fdec4227SStephan Aßmus menu->AddItem(fShowInstalledPackagesItem); 767fdec4227SStephan Aßmus 768fdec4227SStephan Aßmus menu->AddSeparatorItem(); 769fdec4227SStephan Aßmus 770fdec4227SStephan Aßmus fShowDevelopPackagesItem = new BMenuItem( 7714fade61fSStephan Aßmus B_TRANSLATE("Develop packages"), 772fdec4227SStephan Aßmus new BMessage(MSG_SHOW_DEVELOP_PACKAGES)); 773fdec4227SStephan Aßmus menu->AddItem(fShowDevelopPackagesItem); 774fdec4227SStephan Aßmus 775fdec4227SStephan Aßmus fShowSourcePackagesItem = new BMenuItem( 7764fade61fSStephan Aßmus B_TRANSLATE("Source packages"), 777fdec4227SStephan Aßmus new BMessage(MSG_SHOW_SOURCE_PACKAGES)); 778fdec4227SStephan Aßmus menu->AddItem(fShowSourcePackagesItem); 779fdec4227SStephan Aßmus 780fdec4227SStephan Aßmus menuBar->AddItem(menu); 78104c9d578SStephan Aßmus } 78204c9d578SStephan Aßmus 78304c9d578SStephan Aßmus 78404c9d578SStephan Aßmus void 785e0a26dceSStephan Aßmus MainWindow::_BuildUserMenu(BMenuBar* menuBar) 786e0a26dceSStephan Aßmus { 787e0a26dceSStephan Aßmus fUserMenu = new BMenu(B_TRANSLATE("Not logged in")); 788e0a26dceSStephan Aßmus 789e0a26dceSStephan Aßmus fLogInItem = new BMenuItem(B_TRANSLATE("Log in" B_UTF8_ELLIPSIS), 790e0a26dceSStephan Aßmus new BMessage(MSG_LOG_IN)); 791e0a26dceSStephan Aßmus fUserMenu->AddItem(fLogInItem); 792e0a26dceSStephan Aßmus 793e0a26dceSStephan Aßmus fLogOutItem = new BMenuItem(B_TRANSLATE("Log out"), 794e0a26dceSStephan Aßmus new BMessage(MSG_LOG_OUT)); 795e0a26dceSStephan Aßmus fUserMenu->AddItem(fLogOutItem); 796e0a26dceSStephan Aßmus 7970c82f64bSAndrew Lindesay BMenuItem *latestUserUsageConditionsMenuItem = 7981448ced0SHumdinger new BMenuItem(B_TRANSLATE("View latest usage conditions" 79901339a54SAndrew Lindesay B_UTF8_ELLIPSIS), 80001339a54SAndrew Lindesay new BMessage(MSG_VIEW_LATEST_USER_USAGE_CONDITIONS)); 8010c82f64bSAndrew Lindesay fUserMenu->AddItem(latestUserUsageConditionsMenuItem); 80201339a54SAndrew Lindesay 803d2d4866dSAndrew Lindesay fUsersUserUsageConditionsMenuItem = 804d2d4866dSAndrew Lindesay new BMenuItem(B_TRANSLATE("View agreed usage conditions" 805d2d4866dSAndrew Lindesay B_UTF8_ELLIPSIS), 806d2d4866dSAndrew Lindesay new BMessage(MSG_VIEW_USERS_USER_USAGE_CONDITIONS)); 807d2d4866dSAndrew Lindesay fUserMenu->AddItem(fUsersUserUsageConditionsMenuItem); 808d2d4866dSAndrew Lindesay 809e0a26dceSStephan Aßmus menuBar->AddItem(fUserMenu); 810e0a26dceSStephan Aßmus } 811e0a26dceSStephan Aßmus 812e0a26dceSStephan Aßmus 813e0a26dceSStephan Aßmus void 814d2d4866dSAndrew Lindesay MainWindow::_RestoreNickname(const BMessage& settings) 815f7c2983eSAxel Dörfler { 816d2d4866dSAndrew Lindesay BString nickname; 817d2d4866dSAndrew Lindesay if (settings.FindString("username", &nickname) == B_OK 818d2d4866dSAndrew Lindesay && nickname.Length() > 0) { 819d2d4866dSAndrew Lindesay fModel.SetNickname(nickname); 820f7c2983eSAxel Dörfler } 821f7c2983eSAxel Dörfler } 822f7c2983eSAxel Dörfler 823f7c2983eSAxel Dörfler 824f7c2983eSAxel Dörfler const char* 825f7c2983eSAxel Dörfler MainWindow::_WindowFrameName() const 826f7c2983eSAxel Dörfler { 827f7c2983eSAxel Dörfler if (fSinglePackageMode) 828f7c2983eSAxel Dörfler return "small window frame"; 829f7c2983eSAxel Dörfler 830f7c2983eSAxel Dörfler return "window frame"; 831f7c2983eSAxel Dörfler } 832f7c2983eSAxel Dörfler 833f7c2983eSAxel Dörfler 834f7c2983eSAxel Dörfler void 835f7c2983eSAxel Dörfler MainWindow::_RestoreWindowFrame(const BMessage& settings) 836f7c2983eSAxel Dörfler { 837f7c2983eSAxel Dörfler BRect frame = Frame(); 838f7c2983eSAxel Dörfler 839f7c2983eSAxel Dörfler BRect windowFrame; 840f7c2983eSAxel Dörfler bool fromSettings = false; 841f7c2983eSAxel Dörfler if (settings.FindRect(_WindowFrameName(), &windowFrame) == B_OK) { 842f7c2983eSAxel Dörfler frame = windowFrame; 843f7c2983eSAxel Dörfler fromSettings = true; 844f7c2983eSAxel Dörfler } else if (!fSinglePackageMode) { 845f7c2983eSAxel Dörfler // Resize to occupy a certain screen size 846f7c2983eSAxel Dörfler BRect screenFrame = BScreen(this).Frame(); 847f7c2983eSAxel Dörfler float width = frame.Width(); 848f7c2983eSAxel Dörfler float height = frame.Height(); 849f7c2983eSAxel Dörfler if (width < screenFrame.Width() * .666f 850f7c2983eSAxel Dörfler && height < screenFrame.Height() * .666f) { 851f7c2983eSAxel Dörfler frame.bottom = frame.top + screenFrame.Height() * .666f; 852f7c2983eSAxel Dörfler frame.right = frame.left 853f7c2983eSAxel Dörfler + std::min(screenFrame.Width() * .666f, height * 7 / 5); 854f7c2983eSAxel Dörfler } 855f7c2983eSAxel Dörfler } 856f7c2983eSAxel Dörfler 857f7c2983eSAxel Dörfler MoveTo(frame.LeftTop()); 858f7c2983eSAxel Dörfler ResizeTo(frame.Width(), frame.Height()); 859f7c2983eSAxel Dörfler 860f7c2983eSAxel Dörfler if (fromSettings) 8618e96ec34SAxel Dörfler MoveOnScreen(); 862f7c2983eSAxel Dörfler else 863f7c2983eSAxel Dörfler CenterOnScreen(); 864f7c2983eSAxel Dörfler } 865f7c2983eSAxel Dörfler 866f7c2983eSAxel Dörfler 867f7c2983eSAxel Dörfler void 868ccf707d0SAndrew Lindesay MainWindow::_RestoreModelSettings(const BMessage& settings) 869ccf707d0SAndrew Lindesay { 870ccf707d0SAndrew Lindesay BString packageListViewMode; 871133ebab6SAndrew Lindesay if (settings.FindString(SETTING_PACKAGE_LIST_VIEW_MODE, 872ccf707d0SAndrew Lindesay &packageListViewMode) == B_OK) { 873ccf707d0SAndrew Lindesay fModel.SetPackageListViewMode( 874ccf707d0SAndrew Lindesay main_window_str_to_package_list_view_mode(packageListViewMode)); 875ccf707d0SAndrew Lindesay } 876ccf707d0SAndrew Lindesay 877ccf707d0SAndrew Lindesay bool showOption; 878363fc60bSAndrew Lindesay 879133ebab6SAndrew Lindesay if (settings.FindBool(SETTING_SHOW_AVAILABLE_PACKAGES, &showOption) == B_OK) 880363fc60bSAndrew Lindesay fModel.PackageFilter()->SetShowAvailablePackages(showOption); 881133ebab6SAndrew Lindesay if (settings.FindBool(SETTING_SHOW_INSTALLED_PACKAGES, &showOption) == B_OK) 882363fc60bSAndrew Lindesay fModel.PackageFilter()->SetShowInstalledPackages(showOption); 883133ebab6SAndrew Lindesay if (settings.FindBool(SETTING_SHOW_DEVELOP_PACKAGES, &showOption) == B_OK) 884363fc60bSAndrew Lindesay fModel.PackageFilter()->SetShowDevelopPackages(showOption); 885133ebab6SAndrew Lindesay if (settings.FindBool(SETTING_SHOW_SOURCE_PACKAGES, &showOption) == B_OK) 886363fc60bSAndrew Lindesay fModel.PackageFilter()->SetShowSourcePackages(showOption); 887363fc60bSAndrew Lindesay 888133ebab6SAndrew Lindesay if (settings.FindBool(SETTING_CAN_SHARE_ANONYMOUS_USER_DATA, 889133ebab6SAndrew Lindesay &showOption) == B_OK) { 890133ebab6SAndrew Lindesay fModel.SetCanShareAnonymousUsageData(showOption); 891133ebab6SAndrew Lindesay } 892133ebab6SAndrew Lindesay } 893133ebab6SAndrew Lindesay 894133ebab6SAndrew Lindesay 895133ebab6SAndrew Lindesay void 896133ebab6SAndrew Lindesay MainWindow::_MaybePromptCanShareAnonymousUserData(const BMessage& settings) 897133ebab6SAndrew Lindesay { 898133ebab6SAndrew Lindesay bool showOption; 899133ebab6SAndrew Lindesay if (settings.FindBool(SETTING_CAN_SHARE_ANONYMOUS_USER_DATA, 900133ebab6SAndrew Lindesay &showOption) == B_NAME_NOT_FOUND) { 901133ebab6SAndrew Lindesay _PromptCanShareAnonymousUserData(); 902133ebab6SAndrew Lindesay } 903133ebab6SAndrew Lindesay } 904133ebab6SAndrew Lindesay 905133ebab6SAndrew Lindesay 906133ebab6SAndrew Lindesay void 907133ebab6SAndrew Lindesay MainWindow::_PromptCanShareAnonymousUserData() 908133ebab6SAndrew Lindesay { 909133ebab6SAndrew Lindesay BAlert* alert = new(std::nothrow) BAlert( 910133ebab6SAndrew Lindesay B_TRANSLATE("Sending anonymous usage data"), 911133ebab6SAndrew Lindesay B_TRANSLATE("Would it be acceptable to send anonymous usage data to the" 912133ebab6SAndrew Lindesay " HaikuDepotServer system from this computer? You can change your" 913133ebab6SAndrew Lindesay " preference in the \"Settings\" window later."), 914133ebab6SAndrew Lindesay B_TRANSLATE("No"), 915133ebab6SAndrew Lindesay B_TRANSLATE("Yes")); 916133ebab6SAndrew Lindesay 917133ebab6SAndrew Lindesay int32 result = alert->Go(); 918133ebab6SAndrew Lindesay fModel.SetCanShareAnonymousUsageData(1 == result); 919ccf707d0SAndrew Lindesay } 920ccf707d0SAndrew Lindesay 921ccf707d0SAndrew Lindesay 922ccf707d0SAndrew Lindesay void 923d668d227SAndrew Lindesay MainWindow::_InitPreferredLanguage() 924d668d227SAndrew Lindesay { 925d668d227SAndrew Lindesay LanguageRepository* repository = fModel.Languages(); 926d668d227SAndrew Lindesay LanguageRef defaultLanguage = LocaleUtils::DeriveDefaultLanguage(repository); 927d668d227SAndrew Lindesay repository->AddLanguage(defaultLanguage); 928d668d227SAndrew Lindesay fModel.SetPreferredLanguage(defaultLanguage); 929d668d227SAndrew Lindesay } 930d668d227SAndrew Lindesay 931d668d227SAndrew Lindesay 932d668d227SAndrew Lindesay void 933c4199192SAndrew Lindesay MainWindow::_AdoptModelControls() 93404c9d578SStephan Aßmus { 9359883929bSAndrew Lindesay if (fSinglePackageMode) 9369883929bSAndrew Lindesay return; 9379883929bSAndrew Lindesay 93804c9d578SStephan Aßmus BAutolock locker(fModel.Lock()); 939363fc60bSAndrew Lindesay fShowAvailablePackagesItem->SetMarked(fModel.PackageFilter()->ShowAvailablePackages()); 940363fc60bSAndrew Lindesay fShowInstalledPackagesItem->SetMarked(fModel.PackageFilter()->ShowInstalledPackages()); 941363fc60bSAndrew Lindesay fShowSourcePackagesItem->SetMarked(fModel.PackageFilter()->ShowSourcePackages()); 942363fc60bSAndrew Lindesay fShowDevelopPackagesItem->SetMarked(fModel.PackageFilter()->ShowDevelopPackages()); 943da651104SStephan Aßmus 944ccf707d0SAndrew Lindesay if (fModel.PackageListViewMode() == PROMINENT) 945ccf707d0SAndrew Lindesay fListTabs->Select(TAB_PROMINENT_PACKAGES); 9464fade61fSStephan Aßmus else 947ccf707d0SAndrew Lindesay fListTabs->Select(TAB_ALL_PACKAGES); 948b965ce70SHumdinger 949b965ce70SHumdinger fFilterView->AdoptModel(fModel); 95004c9d578SStephan Aßmus } 95104c9d578SStephan Aßmus 95204c9d578SStephan Aßmus 95304c9d578SStephan Aßmus void 954c4199192SAndrew Lindesay MainWindow::_AdoptModel() 955c4199192SAndrew Lindesay { 956fa5c8097SAndrew Lindesay HDTRACE("adopting model to main window ui"); 957c4199192SAndrew Lindesay 958c4199192SAndrew Lindesay if (fSinglePackageMode) 959c4199192SAndrew Lindesay return; 960c4199192SAndrew Lindesay 96105880d13SAndrew Lindesay std::vector<DepotInfoRef> depots = _CreateSnapshotOfDepots(); 96205880d13SAndrew Lindesay std::vector<DepotInfoRef>::iterator it; 9630b69420bSAndrew Lindesay 9640b69420bSAndrew Lindesay fFeaturedPackagesView->BeginAddRemove(); 9650b69420bSAndrew Lindesay 96605880d13SAndrew Lindesay for (it = depots.begin(); it != depots.end(); it++) { 96705880d13SAndrew Lindesay DepotInfoRef depotInfoRef = *it; 968d75b4d61SAndrew Lindesay for (int i = 0; i < depotInfoRef->CountPackages(); i++) { 969d75b4d61SAndrew Lindesay PackageInfoRef package = depotInfoRef->PackageAtIndex(i); 970d75b4d61SAndrew Lindesay _AddRemovePackageFromLists(package); 971d75b4d61SAndrew Lindesay } 972c4199192SAndrew Lindesay } 973c4199192SAndrew Lindesay 9740b69420bSAndrew Lindesay fFeaturedPackagesView->EndAddRemove(); 9750b69420bSAndrew Lindesay 976c4199192SAndrew Lindesay _AdoptModelControls(); 977c4199192SAndrew Lindesay } 978c4199192SAndrew Lindesay 979c4199192SAndrew Lindesay 980c4199192SAndrew Lindesay void 981c4199192SAndrew Lindesay MainWindow::_AddRemovePackageFromLists(const PackageInfoRef& package) 982c4199192SAndrew Lindesay { 983c4199192SAndrew Lindesay bool matches; 984c4199192SAndrew Lindesay 985c4199192SAndrew Lindesay { 986c4199192SAndrew Lindesay AutoLocker<BLocker> modelLocker(fModel.Lock()); 987363fc60bSAndrew Lindesay matches = fModel.PackageFilter()->Filter()->AcceptsPackage(package); 988c4199192SAndrew Lindesay } 989c4199192SAndrew Lindesay 990c4199192SAndrew Lindesay if (matches) { 991*8cc3ed34SAndrew Lindesay PackageClassificationInfoRef classification = package->PackageClassificationInfo(); 992*8cc3ed34SAndrew Lindesay 993*8cc3ed34SAndrew Lindesay if (classification.IsSet()) { 994*8cc3ed34SAndrew Lindesay if (classification->IsProminent()) 995c4199192SAndrew Lindesay fFeaturedPackagesView->AddPackage(package); 996*8cc3ed34SAndrew Lindesay } 997*8cc3ed34SAndrew Lindesay 998c4199192SAndrew Lindesay fPackageListView->AddPackage(package); 999c4199192SAndrew Lindesay } else { 1000c4199192SAndrew Lindesay fFeaturedPackagesView->RemovePackage(package); 1001c4199192SAndrew Lindesay fPackageListView->RemovePackage(package); 1002c4199192SAndrew Lindesay } 1003c4199192SAndrew Lindesay } 1004c4199192SAndrew Lindesay 1005c4199192SAndrew Lindesay 1006c4199192SAndrew Lindesay void 100784674570SAndrew Lindesay MainWindow::_SetupDelayedIncrementViewCounter(const PackageInfoRef package) { 100884674570SAndrew Lindesay if (fIncrementViewCounterDelayedRunner != NULL) { 100984674570SAndrew Lindesay fIncrementViewCounterDelayedRunner->SetCount(0); 101084674570SAndrew Lindesay delete fIncrementViewCounterDelayedRunner; 101184674570SAndrew Lindesay } 101284674570SAndrew Lindesay BMessage message(MSG_INCREMENT_VIEW_COUNTER); 101384674570SAndrew Lindesay message.SetString("name", package->Name()); 101484674570SAndrew Lindesay fIncrementViewCounterDelayedRunner = 101584674570SAndrew Lindesay new BMessageRunner(BMessenger(this), &message, 101684674570SAndrew Lindesay kIncrementViewCounterDelayMicros, 1); 101784674570SAndrew Lindesay if (fIncrementViewCounterDelayedRunner->InitCheck() 101884674570SAndrew Lindesay != B_OK) { 101984674570SAndrew Lindesay HDERROR("unable to init the increment view counter"); 102084674570SAndrew Lindesay } 102184674570SAndrew Lindesay } 102284674570SAndrew Lindesay 102384674570SAndrew Lindesay 102484674570SAndrew Lindesay void 102584674570SAndrew Lindesay MainWindow::_HandleIncrementViewCounter(const BMessage* message) 102684674570SAndrew Lindesay { 102784674570SAndrew Lindesay BString name; 102884674570SAndrew Lindesay if (message->FindString("name", &name) == B_OK) { 102984674570SAndrew Lindesay const PackageInfoRef& viewedPackage = 103084674570SAndrew Lindesay fPackageInfoView->Package(); 103184674570SAndrew Lindesay if (viewedPackage.IsSet()) { 103284674570SAndrew Lindesay if (viewedPackage->Name() == name) 103384674570SAndrew Lindesay _IncrementViewCounter(viewedPackage); 103484674570SAndrew Lindesay else 103584674570SAndrew Lindesay HDINFO("incr. view counter; name mismatch"); 103684674570SAndrew Lindesay } else 103784674570SAndrew Lindesay HDINFO("incr. view counter; no viewed pkg"); 103884674570SAndrew Lindesay } else 103984674570SAndrew Lindesay HDERROR("incr. view counter; no name"); 104084674570SAndrew Lindesay fIncrementViewCounterDelayedRunner->SetCount(0); 104184674570SAndrew Lindesay delete fIncrementViewCounterDelayedRunner; 104284674570SAndrew Lindesay fIncrementViewCounterDelayedRunner = NULL; 104384674570SAndrew Lindesay } 104484674570SAndrew Lindesay 104584674570SAndrew Lindesay 104684674570SAndrew Lindesay void 1047409af934SAndrew Lindesay MainWindow::_IncrementViewCounter(const PackageInfoRef package) 1048133ebab6SAndrew Lindesay { 1049133ebab6SAndrew Lindesay bool shouldIncrementViewCounter = false; 1050133ebab6SAndrew Lindesay 1051133ebab6SAndrew Lindesay { 1052133ebab6SAndrew Lindesay AutoLocker<BLocker> modelLocker(fModel.Lock()); 1053133ebab6SAndrew Lindesay bool canShareAnonymousUsageData = fModel.CanShareAnonymousUsageData(); 1054133ebab6SAndrew Lindesay if (canShareAnonymousUsageData && !package->Viewed()) { 1055133ebab6SAndrew Lindesay package->SetViewed(); 1056133ebab6SAndrew Lindesay shouldIncrementViewCounter = true; 1057133ebab6SAndrew Lindesay } 1058133ebab6SAndrew Lindesay } 1059133ebab6SAndrew Lindesay 1060133ebab6SAndrew Lindesay if (shouldIncrementViewCounter) { 1061467ffecdSAugustin Cavalier ProcessCoordinator* incrementViewCoordinator = 1062133ebab6SAndrew Lindesay ProcessCoordinatorFactory::CreateIncrementViewCounter( 1063133ebab6SAndrew Lindesay &fModel, package); 1064467ffecdSAugustin Cavalier _AddProcessCoordinator(incrementViewCoordinator); 1065133ebab6SAndrew Lindesay } 1066133ebab6SAndrew Lindesay } 1067133ebab6SAndrew Lindesay 1068133ebab6SAndrew Lindesay 1069133ebab6SAndrew Lindesay void 107004c9d578SStephan Aßmus MainWindow::_AdoptPackage(const PackageInfoRef& package) 107104c9d578SStephan Aßmus { 107275ba9dbfSStephan Aßmus { 107375ba9dbfSStephan Aßmus BAutolock locker(fModel.Lock()); 107404c9d578SStephan Aßmus fPackageInfoView->SetPackage(package); 10751986ab9fSStephan Aßmus 1076664372abSStephan Aßmus if (fFeaturedPackagesView != NULL) 1077664372abSStephan Aßmus fFeaturedPackagesView->SelectPackage(package); 10781986ab9fSStephan Aßmus if (fPackageListView != NULL) 10791986ab9fSStephan Aßmus fPackageListView->SelectPackage(package); 108075ba9dbfSStephan Aßmus } 108104c9d578SStephan Aßmus 1082a9edb9bfSAndrew Lindesay _PopulatePackageAsync(false); 108304c9d578SStephan Aßmus } 108404c9d578SStephan Aßmus 108504c9d578SStephan Aßmus 108604c9d578SStephan Aßmus void 108704c9d578SStephan Aßmus MainWindow::_ClearPackage() 108804c9d578SStephan Aßmus { 108904c9d578SStephan Aßmus fPackageInfoView->Clear(); 109004c9d578SStephan Aßmus } 109104c9d578SStephan Aßmus 109204c9d578SStephan Aßmus 109304c9d578SStephan Aßmus void 10943369e03dSAndrew Lindesay MainWindow::_StartBulkLoad(bool force) 109504c9d578SStephan Aßmus { 1096c4199192SAndrew Lindesay if (fFeaturedPackagesView != NULL) 1097c4199192SAndrew Lindesay fFeaturedPackagesView->Clear(); 1098c4199192SAndrew Lindesay if (fPackageListView != NULL) 1099c4199192SAndrew Lindesay fPackageListView->Clear(); 1100c4199192SAndrew Lindesay fPackageInfoView->Clear(); 1101c4199192SAndrew Lindesay 110210cd325cSAndrew Lindesay fRefreshRepositoriesItem->SetEnabled(false); 110310cd325cSAndrew Lindesay ProcessCoordinator* bulkLoadCoordinator = 110410cd325cSAndrew Lindesay ProcessCoordinatorFactory::CreateBulkLoadCoordinator( 1105409af934SAndrew Lindesay fPackageInfoListener, &fModel, force); 110610cd325cSAndrew Lindesay _AddProcessCoordinator(bulkLoadCoordinator); 110704c9d578SStephan Aßmus } 110804c9d578SStephan Aßmus 110904c9d578SStephan Aßmus 111004c9d578SStephan Aßmus void 111110cd325cSAndrew Lindesay MainWindow::_BulkLoadCompleteReceived(status_t errorStatus) 111204c9d578SStephan Aßmus { 111310cd325cSAndrew Lindesay if (errorStatus != B_OK) { 11143369e03dSAndrew Lindesay AppUtils::NotifySimpleError( 11151448ced0SHumdinger B_TRANSLATE("Package update error"), 11163369e03dSAndrew Lindesay B_TRANSLATE("While updating package data, a problem has arisen " 11173369e03dSAndrew Lindesay "that may cause data to be outdated or missing from the " 11183369e03dSAndrew Lindesay "application's display. Additional details regarding this " 11193369e03dSAndrew Lindesay "problem may be able to be obtained from the application " 1120b21c9447SAndrew Lindesay "logs." 1121b21c9447SAndrew Lindesay ALERT_MSG_LOGS_USER_GUIDE)); 112204c9d578SStephan Aßmus } 112310cd325cSAndrew Lindesay 11243369e03dSAndrew Lindesay fRefreshRepositoriesItem->SetEnabled(true); 112510cd325cSAndrew Lindesay _AdoptModel(); 112610cd325cSAndrew Lindesay _UpdateAvailableRepositories(); 1127ccf707d0SAndrew Lindesay 1128ccf707d0SAndrew Lindesay // if after loading everything in, it transpires that there are no 1129ccf707d0SAndrew Lindesay // featured packages then the featured packages should be disabled 1130ccf707d0SAndrew Lindesay // and the user should be switched to the "all packages" view so 1131ccf707d0SAndrew Lindesay // that they are not presented with a blank window! 1132ccf707d0SAndrew Lindesay 1133ccf707d0SAndrew Lindesay bool hasProminentPackages = fModel.HasAnyProminentPackages(); 1134ccf707d0SAndrew Lindesay fListTabs->TabAt(TAB_PROMINENT_PACKAGES)->SetEnabled(hasProminentPackages); 1135ccf707d0SAndrew Lindesay if (!hasProminentPackages 1136ccf707d0SAndrew Lindesay && fListTabs->Selection() == TAB_PROMINENT_PACKAGES) { 1137ccf707d0SAndrew Lindesay fModel.SetPackageListViewMode(ALL); 1138ccf707d0SAndrew Lindesay fListTabs->Select(TAB_ALL_PACKAGES); 1139ccf707d0SAndrew Lindesay } 114004c9d578SStephan Aßmus } 114104c9d578SStephan Aßmus 114204c9d578SStephan Aßmus 11433369e03dSAndrew Lindesay void 114410cd325cSAndrew Lindesay MainWindow::_NotifyWorkStatusClear() 114504c9d578SStephan Aßmus { 114610cd325cSAndrew Lindesay BMessage message(MSG_WORK_STATUS_CLEAR); 114710cd325cSAndrew Lindesay this->PostMessage(&message, this); 114810cd325cSAndrew Lindesay } 114910cd325cSAndrew Lindesay 115010cd325cSAndrew Lindesay 115110cd325cSAndrew Lindesay void 115210cd325cSAndrew Lindesay MainWindow::_HandleWorkStatusClear() 115310cd325cSAndrew Lindesay { 115410cd325cSAndrew Lindesay fWorkStatusView->SetText(""); 11553369e03dSAndrew Lindesay fWorkStatusView->SetIdle(); 11563369e03dSAndrew Lindesay } 115704c9d578SStephan Aßmus 115804c9d578SStephan Aßmus 11593369e03dSAndrew Lindesay /*! Sends off a message to the Window so that it can change the status view 11603369e03dSAndrew Lindesay on the front-end in the UI thread. 11613369e03dSAndrew Lindesay */ 116204c9d578SStephan Aßmus 11633369e03dSAndrew Lindesay void 11643369e03dSAndrew Lindesay MainWindow::_NotifyWorkStatusChange(const BString& text, float progress) 11653369e03dSAndrew Lindesay { 11663369e03dSAndrew Lindesay BMessage message(MSG_WORK_STATUS_CHANGE); 116704c9d578SStephan Aßmus 11683369e03dSAndrew Lindesay if (!text.IsEmpty()) 11693369e03dSAndrew Lindesay message.AddString(KEY_WORK_STATUS_TEXT, text); 11703369e03dSAndrew Lindesay message.AddFloat(KEY_WORK_STATUS_PROGRESS, progress); 117104c9d578SStephan Aßmus 11723369e03dSAndrew Lindesay this->PostMessage(&message, this); 11733369e03dSAndrew Lindesay } 117404c9d578SStephan Aßmus 11753369e03dSAndrew Lindesay 1176f32d5c5cSAndrew Lindesay void 1177f32d5c5cSAndrew Lindesay MainWindow::_HandleExternalPackageUpdateMessageReceived(const BMessage* message) 1178f32d5c5cSAndrew Lindesay { 1179f32d5c5cSAndrew Lindesay BStringList addedPackageNames; 1180f32d5c5cSAndrew Lindesay BStringList removedPackageNames; 1181f32d5c5cSAndrew Lindesay 1182f32d5c5cSAndrew Lindesay if (message->FindStrings("added package names", 1183f32d5c5cSAndrew Lindesay &addedPackageNames) == B_OK) { 1184f32d5c5cSAndrew Lindesay addedPackageNames.Sort(); 11850ebb9177SAndrew Lindesay AutoLocker<BLocker> locker(fModel.Lock()); 11860ebb9177SAndrew Lindesay fModel.SetStateForPackagesByName(addedPackageNames, ACTIVATED); 1187f32d5c5cSAndrew Lindesay } 1188f32d5c5cSAndrew Lindesay else 1189f32d5c5cSAndrew Lindesay HDINFO("no [added package names] key in inbound message"); 1190f32d5c5cSAndrew Lindesay 1191f32d5c5cSAndrew Lindesay if (message->FindStrings("removed package names", 1192f32d5c5cSAndrew Lindesay &removedPackageNames) == B_OK) { 1193f32d5c5cSAndrew Lindesay removedPackageNames.Sort(); 11940ebb9177SAndrew Lindesay AutoLocker<BLocker> locker(fModel.Lock()); 11950ebb9177SAndrew Lindesay fModel.SetStateForPackagesByName(addedPackageNames, UNINSTALLED); 1196f32d5c5cSAndrew Lindesay } else 1197f32d5c5cSAndrew Lindesay HDINFO("no [removed package names] key in inbound message"); 1198f32d5c5cSAndrew Lindesay } 1199f32d5c5cSAndrew Lindesay 1200f32d5c5cSAndrew Lindesay 12013369e03dSAndrew Lindesay void 12023369e03dSAndrew Lindesay MainWindow::_HandleWorkStatusChangeMessageReceived(const BMessage* message) 12033369e03dSAndrew Lindesay { 12049883929bSAndrew Lindesay if (fWorkStatusView == NULL) 12059883929bSAndrew Lindesay return; 12069883929bSAndrew Lindesay 12073369e03dSAndrew Lindesay BString text; 12083369e03dSAndrew Lindesay float progress; 12093369e03dSAndrew Lindesay 12103369e03dSAndrew Lindesay if (message->FindString(KEY_WORK_STATUS_TEXT, &text) == B_OK) 12113369e03dSAndrew Lindesay fWorkStatusView->SetText(text); 12123369e03dSAndrew Lindesay 1213a18f873fSAndrew Lindesay if (message->FindFloat(KEY_WORK_STATUS_PROGRESS, &progress) == B_OK) { 1214a18f873fSAndrew Lindesay if (progress < 0.0f) 1215a18f873fSAndrew Lindesay fWorkStatusView->SetBusy(); 1216a18f873fSAndrew Lindesay else 12173369e03dSAndrew Lindesay fWorkStatusView->SetProgress(progress); 1218a18f873fSAndrew Lindesay } else { 1219a18f873fSAndrew Lindesay HDERROR("work status change missing progress on update message"); 1220a18f873fSAndrew Lindesay fWorkStatusView->SetProgress(0.0f); 122104c9d578SStephan Aßmus } 122204c9d578SStephan Aßmus } 122304c9d578SStephan Aßmus 122404c9d578SStephan Aßmus 12258266f4d7SAugustin Cavalier /*! Initially only superficial data is loaded from the server into the data 12268266f4d7SAugustin Cavalier model of the packages. When the package is viewed, additional data needs 12278266f4d7SAugustin Cavalier to be populated including ratings. 12288266f4d7SAugustin Cavalier 12298266f4d7SAugustin Cavalier This method will cause the package to have its data refreshed from 1230a9edb9bfSAndrew Lindesay the server application. The refresh happens in the background; this method 1231a9edb9bfSAndrew Lindesay is asynchronous. 1232a9edb9bfSAndrew Lindesay */ 1233a9edb9bfSAndrew Lindesay 1234a9edb9bfSAndrew Lindesay void 1235a9edb9bfSAndrew Lindesay MainWindow::_PopulatePackageAsync(bool forcePopulate) 1236a9edb9bfSAndrew Lindesay { 12378266f4d7SAugustin Cavalier const PackageInfoRef package = fPackageInfoView->Package(); 1238a9edb9bfSAndrew Lindesay 12398266f4d7SAugustin Cavalier if (!fModel.CanPopulatePackage(package)) 12408266f4d7SAugustin Cavalier return; 12418266f4d7SAugustin Cavalier 12428266f4d7SAugustin Cavalier const char* packageNameStr = package->Name().String(); 12438266f4d7SAugustin Cavalier 12448266f4d7SAugustin Cavalier if (package->HasChangelog() && (forcePopulate || package->Changelog().IsEmpty())) { 12458266f4d7SAugustin Cavalier _AddProcessCoordinator( 12468266f4d7SAugustin Cavalier ProcessCoordinatorFactory::PopulatePkgChangelogCoordinator(&fModel, package)); 12478266f4d7SAugustin Cavalier HDINFO("pkg [%s] will have changelog updated from server.", packageNameStr); 12488266f4d7SAugustin Cavalier } else { 12498266f4d7SAugustin Cavalier HDDEBUG("pkg [%s] not have changelog updated from server.", packageNameStr); 1250a9edb9bfSAndrew Lindesay } 1251a9edb9bfSAndrew Lindesay 12524b3c808eSAndrew Lindesay if (forcePopulate || RatingUtils::ShouldTryPopulateUserRatings(package->UserRatingInfo())) { 12538266f4d7SAugustin Cavalier _AddProcessCoordinator( 12548266f4d7SAugustin Cavalier ProcessCoordinatorFactory::PopulatePkgUserRatingsCoordinator(&fModel, package)); 12558266f4d7SAugustin Cavalier HDINFO("pkg [%s] will have user ratings updated from server.", packageNameStr); 12568266f4d7SAugustin Cavalier } else { 12578266f4d7SAugustin Cavalier HDDEBUG("pkg [%s] not have user ratings updated from server.", packageNameStr); 125804c9d578SStephan Aßmus } 125904c9d578SStephan Aßmus } 126004c9d578SStephan Aßmus 126104c9d578SStephan Aßmus 126204c9d578SStephan Aßmus void 1263133ebab6SAndrew Lindesay MainWindow::_OpenSettingsWindow() 1264133ebab6SAndrew Lindesay { 1265133ebab6SAndrew Lindesay SettingsWindow* window = new SettingsWindow(this, &fModel); 1266133ebab6SAndrew Lindesay window->Show(); 1267133ebab6SAndrew Lindesay } 1268133ebab6SAndrew Lindesay 1269133ebab6SAndrew Lindesay 1270133ebab6SAndrew Lindesay void 12711bbda92dSStephan Aßmus MainWindow::_OpenLoginWindow(const BMessage& onSuccessMessage) 127204c9d578SStephan Aßmus { 127304c9d578SStephan Aßmus UserLoginWindow* window = new UserLoginWindow(this, 127404c9d578SStephan Aßmus BRect(0, 0, 500, 400), fModel); 12751bbda92dSStephan Aßmus 12761bbda92dSStephan Aßmus if (onSuccessMessage.what != 0) 12771bbda92dSStephan Aßmus window->SetOnSuccessMessage(BMessenger(this), onSuccessMessage); 12781bbda92dSStephan Aßmus 127904c9d578SStephan Aßmus window->Show(); 128004c9d578SStephan Aßmus } 128104c9d578SStephan Aßmus 12828f03a0f9SStephan Aßmus 12838f03a0f9SStephan Aßmus void 128410cd325cSAndrew Lindesay MainWindow::_StartUserVerify() 128510cd325cSAndrew Lindesay { 128610cd325cSAndrew Lindesay if (!fModel.Nickname().IsEmpty()) { 128710cd325cSAndrew Lindesay _AddProcessCoordinator( 128810cd325cSAndrew Lindesay ProcessCoordinatorFactory::CreateUserDetailVerifierCoordinator( 128910cd325cSAndrew Lindesay this, 129010cd325cSAndrew Lindesay // UserDetailVerifierListener 129110cd325cSAndrew Lindesay &fModel) ); 129210cd325cSAndrew Lindesay } 129310cd325cSAndrew Lindesay } 129410cd325cSAndrew Lindesay 129510cd325cSAndrew Lindesay 129610cd325cSAndrew Lindesay void 12978f03a0f9SStephan Aßmus MainWindow::_UpdateAuthorization() 12988f03a0f9SStephan Aßmus { 1299d2d4866dSAndrew Lindesay BString nickname(fModel.Nickname()); 1300d2d4866dSAndrew Lindesay bool hasUser = !nickname.IsEmpty(); 1301e0a26dceSStephan Aßmus 13026d519fd1SStephan Aßmus if (fLogOutItem != NULL) 1303e0a26dceSStephan Aßmus fLogOutItem->SetEnabled(hasUser); 1304d2d4866dSAndrew Lindesay if (fUsersUserUsageConditionsMenuItem != NULL) 1305d2d4866dSAndrew Lindesay fUsersUserUsageConditionsMenuItem->SetEnabled(hasUser); 1306e0a26dceSStephan Aßmus if (fLogInItem != NULL) { 1307e0a26dceSStephan Aßmus if (hasUser) 1308e0a26dceSStephan Aßmus fLogInItem->SetLabel(B_TRANSLATE("Switch account" B_UTF8_ELLIPSIS)); 1309e0a26dceSStephan Aßmus else 1310e0a26dceSStephan Aßmus fLogInItem->SetLabel(B_TRANSLATE("Log in" B_UTF8_ELLIPSIS)); 1311e0a26dceSStephan Aßmus } 1312e0a26dceSStephan Aßmus 1313e0a26dceSStephan Aßmus if (fUserMenu != NULL) { 1314e0a26dceSStephan Aßmus BString label; 1315d2d4866dSAndrew Lindesay if (hasUser) { 1316e0a26dceSStephan Aßmus label = B_TRANSLATE("Logged in as %User%"); 1317d2d4866dSAndrew Lindesay label.ReplaceAll("%User%", nickname); 1318d2d4866dSAndrew Lindesay } else { 1319d2d4866dSAndrew Lindesay label = B_TRANSLATE("Not logged in"); 1320e0a26dceSStephan Aßmus } 1321e0a26dceSStephan Aßmus fUserMenu->Superitem()->SetLabel(label); 1322e0a26dceSStephan Aßmus } 13238f03a0f9SStephan Aßmus } 13241bbda92dSStephan Aßmus 13251bbda92dSStephan Aßmus 13261bbda92dSStephan Aßmus void 1327b965ce70SHumdinger MainWindow::_UpdateAvailableRepositories() 1328b965ce70SHumdinger { 1329b965ce70SHumdinger fRepositoryMenu->RemoveItems(0, fRepositoryMenu->CountItems(), true); 1330b965ce70SHumdinger 1331b965ce70SHumdinger fRepositoryMenu->AddItem(new BMenuItem(B_TRANSLATE("All repositories"), 1332b965ce70SHumdinger new BMessage(MSG_DEPOT_SELECTED))); 1333b965ce70SHumdinger 1334b965ce70SHumdinger fRepositoryMenu->AddItem(new BSeparatorItem()); 1335b965ce70SHumdinger 1336b965ce70SHumdinger bool foundSelectedDepot = false; 133705880d13SAndrew Lindesay std::vector<DepotInfoRef> depots = _CreateSnapshotOfDepots(); 133805880d13SAndrew Lindesay std::vector<DepotInfoRef>::iterator it; 1339d13c3d89SAndrew Lindesay 134005880d13SAndrew Lindesay for (it = depots.begin(); it != depots.end(); it++) { 134105880d13SAndrew Lindesay DepotInfoRef depot = *it; 134205880d13SAndrew Lindesay 134305880d13SAndrew Lindesay if (depot->Name().Length() != 0) { 1344b965ce70SHumdinger BMessage* message = new BMessage(MSG_DEPOT_SELECTED); 134505880d13SAndrew Lindesay message->AddString("name", depot->Name()); 134605880d13SAndrew Lindesay BMenuItem* item = new(std::nothrow) BMenuItem(depot->Name(), message); 134705880d13SAndrew Lindesay 134805880d13SAndrew Lindesay if (item == NULL) 134905880d13SAndrew Lindesay HDFATAL("memory exhaustion"); 135005880d13SAndrew Lindesay 1351b965ce70SHumdinger fRepositoryMenu->AddItem(item); 1352b965ce70SHumdinger 1353363fc60bSAndrew Lindesay if (depot->Name() == fModel.PackageFilter()->DepotName()) { 1354b965ce70SHumdinger item->SetMarked(true); 1355b965ce70SHumdinger foundSelectedDepot = true; 1356b965ce70SHumdinger } 1357b965ce70SHumdinger } 1358d13c3d89SAndrew Lindesay } 1359b965ce70SHumdinger 1360b965ce70SHumdinger if (!foundSelectedDepot) 1361b965ce70SHumdinger fRepositoryMenu->ItemAt(0)->SetMarked(true); 1362b965ce70SHumdinger } 1363b965ce70SHumdinger 1364b965ce70SHumdinger 1365a9edb9bfSAndrew Lindesay bool 1366a9edb9bfSAndrew Lindesay MainWindow::_SelectedPackageHasWebAppRepositoryCode() 1367a9edb9bfSAndrew Lindesay { 1368a9edb9bfSAndrew Lindesay const PackageInfoRef& package = fPackageInfoView->Package(); 13696ab878c0SAndrew Lindesay const BString depotName = package->DepotName(); 1370a9edb9bfSAndrew Lindesay 13716ab878c0SAndrew Lindesay if (depotName.IsEmpty()) { 1372fa5c8097SAndrew Lindesay HDDEBUG("the package [%s] has no depot name", package->Name().String()); 13736ab878c0SAndrew Lindesay } else { 13746ab878c0SAndrew Lindesay const DepotInfo* depot = fModel.DepotForName(depotName); 1375a9edb9bfSAndrew Lindesay 13766ab878c0SAndrew Lindesay if (depot == NULL) { 1377f96d1f4dSAndrew Lindesay HDINFO("the depot [%s] was not able to be found", 1378fa5c8097SAndrew Lindesay depotName.String()); 13796ab878c0SAndrew Lindesay } else { 13806ab878c0SAndrew Lindesay BString repositoryCode = depot->WebAppRepositoryCode(); 1381a9edb9bfSAndrew Lindesay 13826ab878c0SAndrew Lindesay if (repositoryCode.IsEmpty()) { 1383f96d1f4dSAndrew Lindesay HDINFO("the depot [%s] has no web app repository code", 1384fa5c8097SAndrew Lindesay depotName.String()); 1385fa5c8097SAndrew Lindesay } else 13866ab878c0SAndrew Lindesay return true; 13876ab878c0SAndrew Lindesay } 13886ab878c0SAndrew Lindesay } 13896ab878c0SAndrew Lindesay 13906ab878c0SAndrew Lindesay return false; 1391a9edb9bfSAndrew Lindesay } 1392a9edb9bfSAndrew Lindesay 1393a9edb9bfSAndrew Lindesay 1394b965ce70SHumdinger void 13951bbda92dSStephan Aßmus MainWindow::_RatePackage() 13961bbda92dSStephan Aßmus { 1397a9edb9bfSAndrew Lindesay if (!_SelectedPackageHasWebAppRepositoryCode()) { 1398a9edb9bfSAndrew Lindesay BAlert* alert = new(std::nothrow) BAlert( 1399cbadcae1SHumdinger B_TRANSLATE("Rating not possible"), 1400cbadcae1SHumdinger B_TRANSLATE("This package doesn't seem to be on the HaikuDepot " 1401cbadcae1SHumdinger "Server, so it's not possible to create a new rating " 1402cbadcae1SHumdinger "or edit an existing rating."), 1403a9edb9bfSAndrew Lindesay B_TRANSLATE("OK")); 1404a9edb9bfSAndrew Lindesay alert->Go(); 1405a9edb9bfSAndrew Lindesay return; 1406a9edb9bfSAndrew Lindesay } 1407a9edb9bfSAndrew Lindesay 1408d2d4866dSAndrew Lindesay if (fModel.Nickname().IsEmpty()) { 14091bbda92dSStephan Aßmus BAlert* alert = new(std::nothrow) BAlert( 14101bbda92dSStephan Aßmus B_TRANSLATE("Not logged in"), 14111bbda92dSStephan Aßmus B_TRANSLATE("You need to be logged into an account before you " 14121bbda92dSStephan Aßmus "can rate packages."), 14131bbda92dSStephan Aßmus B_TRANSLATE("Cancel"), 14141bbda92dSStephan Aßmus B_TRANSLATE("Login or Create account")); 14151bbda92dSStephan Aßmus 14161bbda92dSStephan Aßmus if (alert == NULL) 14171bbda92dSStephan Aßmus return; 14181bbda92dSStephan Aßmus 14191bbda92dSStephan Aßmus int32 choice = alert->Go(); 14201bbda92dSStephan Aßmus if (choice == 1) 14211bbda92dSStephan Aßmus _OpenLoginWindow(BMessage(MSG_RATE_PACKAGE)); 14221bbda92dSStephan Aßmus return; 14231bbda92dSStephan Aßmus } 14241bbda92dSStephan Aßmus 14251bbda92dSStephan Aßmus // TODO: Allow only one RatePackageWindow 14261bbda92dSStephan Aßmus // TODO: Mechanism for remembering the window frame 14271bbda92dSStephan Aßmus RatePackageWindow* window = new RatePackageWindow(this, 14281bbda92dSStephan Aßmus BRect(0, 0, 500, 400), fModel); 14291bbda92dSStephan Aßmus window->SetPackage(fPackageInfoView->Package()); 14301bbda92dSStephan Aßmus window->Show(); 14311bbda92dSStephan Aßmus } 1432d5ef985eSStephan Aßmus 1433d5ef985eSStephan Aßmus 1434d5ef985eSStephan Aßmus void 1435d5ef985eSStephan Aßmus MainWindow::_ShowScreenshot() 1436d5ef985eSStephan Aßmus { 1437d5ef985eSStephan Aßmus // TODO: Mechanism for remembering the window frame 1438d5ef985eSStephan Aßmus if (fScreenshotWindow == NULL) 143988af15cfSAndrew Lindesay fScreenshotWindow = new ScreenshotWindow(this, BRect(0, 0, 500, 400), &fModel); 1440d5ef985eSStephan Aßmus 1441d5ef985eSStephan Aßmus if (fScreenshotWindow->LockWithTimeout(1000) != B_OK) 1442d5ef985eSStephan Aßmus return; 1443d5ef985eSStephan Aßmus 1444d5ef985eSStephan Aßmus fScreenshotWindow->SetPackage(fPackageInfoView->Package()); 1445d5ef985eSStephan Aßmus 1446d5ef985eSStephan Aßmus if (fScreenshotWindow->IsHidden()) 1447d5ef985eSStephan Aßmus fScreenshotWindow->Show(); 1448d5ef985eSStephan Aßmus else 1449d5ef985eSStephan Aßmus fScreenshotWindow->Activate(); 1450d5ef985eSStephan Aßmus 1451d5ef985eSStephan Aßmus fScreenshotWindow->Unlock(); 1452d5ef985eSStephan Aßmus } 145301339a54SAndrew Lindesay 145401339a54SAndrew Lindesay 145501339a54SAndrew Lindesay void 1456d2d4866dSAndrew Lindesay MainWindow::_ViewUserUsageConditions( 1457d2d4866dSAndrew Lindesay UserUsageConditionsSelectionMode mode) 145801339a54SAndrew Lindesay { 145901339a54SAndrew Lindesay UserUsageConditionsWindow* window = new UserUsageConditionsWindow( 1460d2d4866dSAndrew Lindesay fModel, mode); 146101339a54SAndrew Lindesay window->Show(); 146201339a54SAndrew Lindesay } 146310cd325cSAndrew Lindesay 146410cd325cSAndrew Lindesay 146510cd325cSAndrew Lindesay void 146610cd325cSAndrew Lindesay MainWindow::UserCredentialsFailed() 146710cd325cSAndrew Lindesay { 146810cd325cSAndrew Lindesay BString message = B_TRANSLATE("The password previously " 146910cd325cSAndrew Lindesay "supplied for the user [%Nickname%] is not currently " 147010cd325cSAndrew Lindesay "valid. The user will be logged-out of this application " 147110cd325cSAndrew Lindesay "and you should login again with your updated password."); 147210cd325cSAndrew Lindesay message.ReplaceAll("%Nickname%", fModel.Nickname()); 147310cd325cSAndrew Lindesay 147410cd325cSAndrew Lindesay AppUtils::NotifySimpleError(B_TRANSLATE("Login issue"), 147510cd325cSAndrew Lindesay message); 147610cd325cSAndrew Lindesay 147710cd325cSAndrew Lindesay { 147810cd325cSAndrew Lindesay AutoLocker<BLocker> locker(fModel.Lock()); 147910cd325cSAndrew Lindesay fModel.SetNickname(""); 148010cd325cSAndrew Lindesay } 148110cd325cSAndrew Lindesay } 148210cd325cSAndrew Lindesay 148310cd325cSAndrew Lindesay 148410cd325cSAndrew Lindesay /*! \brief This method is invoked from the UserDetailVerifierProcess on a 148510cd325cSAndrew Lindesay background thread. For this reason it lodges a message into itself 148610cd325cSAndrew Lindesay which can then be handled on the main thread. 148710cd325cSAndrew Lindesay */ 148810cd325cSAndrew Lindesay 148910cd325cSAndrew Lindesay void 149010cd325cSAndrew Lindesay MainWindow::UserUsageConditionsNotLatest(const UserDetail& userDetail) 149110cd325cSAndrew Lindesay { 149210cd325cSAndrew Lindesay BMessage message(MSG_USER_USAGE_CONDITIONS_NOT_LATEST); 149310cd325cSAndrew Lindesay BMessage detailsMessage; 149410cd325cSAndrew Lindesay if (userDetail.Archive(&detailsMessage, true) != B_OK 149510cd325cSAndrew Lindesay || message.AddMessage("userDetail", &detailsMessage) != B_OK) { 1496fa5c8097SAndrew Lindesay HDERROR("unable to archive the user detail into a message"); 149710cd325cSAndrew Lindesay } 149810cd325cSAndrew Lindesay else 149910cd325cSAndrew Lindesay BMessenger(this).SendMessage(&message); 150010cd325cSAndrew Lindesay } 150110cd325cSAndrew Lindesay 150210cd325cSAndrew Lindesay 150310cd325cSAndrew Lindesay void 150410cd325cSAndrew Lindesay MainWindow::_HandleUserUsageConditionsNotLatest( 150510cd325cSAndrew Lindesay const UserDetail& userDetail) 150610cd325cSAndrew Lindesay { 150710cd325cSAndrew Lindesay ToLatestUserUsageConditionsWindow* window = 150810cd325cSAndrew Lindesay new ToLatestUserUsageConditionsWindow(this, fModel, userDetail); 150910cd325cSAndrew Lindesay window->Show(); 151010cd325cSAndrew Lindesay } 151110cd325cSAndrew Lindesay 151210cd325cSAndrew Lindesay 151310cd325cSAndrew Lindesay void 151410cd325cSAndrew Lindesay MainWindow::_AddProcessCoordinator(ProcessCoordinator* item) 151510cd325cSAndrew Lindesay { 151610cd325cSAndrew Lindesay AutoLocker<BLocker> lock(&fCoordinatorLock); 151710cd325cSAndrew Lindesay 151895c7b018SAndrew Lindesay if (fShouldCloseWhenNoProcessesToCoordinate) { 151995c7b018SAndrew Lindesay HDINFO("system shutting down --> new process coordinator [%s] rejected", 152095c7b018SAndrew Lindesay item->Name().String()); 152195c7b018SAndrew Lindesay return; 152295c7b018SAndrew Lindesay } 152395c7b018SAndrew Lindesay 1524a18f873fSAndrew Lindesay item->SetListener(this); 1525a18f873fSAndrew Lindesay 1526409af934SAndrew Lindesay if (fCoordinator == NULL) { 152710cd325cSAndrew Lindesay if (acquire_sem(fCoordinatorRunningSem) != B_OK) 152810cd325cSAndrew Lindesay debugger("unable to acquire the process coordinator sem"); 1529f96d1f4dSAndrew Lindesay HDINFO("adding and starting a process coordinator [%s]", 1530fa5c8097SAndrew Lindesay item->Name().String()); 1531409af934SAndrew Lindesay delete fCoordinator; 1532409af934SAndrew Lindesay fCoordinator = item; 153310cd325cSAndrew Lindesay fCoordinator->Start(); 15347d7de135SAugustin Cavalier } else { 1535f96d1f4dSAndrew Lindesay HDINFO("adding process coordinator [%s] to the queue", 153610cd325cSAndrew Lindesay item->Name().String()); 153710cd325cSAndrew Lindesay fCoordinatorQueue.push(item); 153810cd325cSAndrew Lindesay } 153910cd325cSAndrew Lindesay } 154010cd325cSAndrew Lindesay 154110cd325cSAndrew Lindesay 154210cd325cSAndrew Lindesay void 154310cd325cSAndrew Lindesay MainWindow::_SpinUntilProcessCoordinatorComplete() 154410cd325cSAndrew Lindesay { 154510cd325cSAndrew Lindesay while (true) { 154610cd325cSAndrew Lindesay if (acquire_sem(fCoordinatorRunningSem) != B_OK) 154710cd325cSAndrew Lindesay debugger("unable to acquire the process coordinator sem"); 154810cd325cSAndrew Lindesay if (release_sem(fCoordinatorRunningSem) != B_OK) 154910cd325cSAndrew Lindesay debugger("unable to release the process coordinator sem"); 155010cd325cSAndrew Lindesay { 155110cd325cSAndrew Lindesay AutoLocker<BLocker> lock(&fCoordinatorLock); 1552409af934SAndrew Lindesay if (fCoordinator == NULL) 155310cd325cSAndrew Lindesay return; 155410cd325cSAndrew Lindesay } 155510cd325cSAndrew Lindesay } 155610cd325cSAndrew Lindesay } 155710cd325cSAndrew Lindesay 155810cd325cSAndrew Lindesay 155910cd325cSAndrew Lindesay void 156010cd325cSAndrew Lindesay MainWindow::_StopProcessCoordinators() 156110cd325cSAndrew Lindesay { 156295c7b018SAndrew Lindesay HDINFO("will stop all queued process coordinators"); 156310cd325cSAndrew Lindesay AutoLocker<BLocker> lock(&fCoordinatorLock); 156410cd325cSAndrew Lindesay 156510cd325cSAndrew Lindesay while (!fCoordinatorQueue.empty()) { 1566409af934SAndrew Lindesay ProcessCoordinator* processCoordinator 1567f96d1f4dSAndrew Lindesay = fCoordinatorQueue.front(); 1568f96d1f4dSAndrew Lindesay HDINFO("will drop queued process coordinator [%s]", 1569fa5c8097SAndrew Lindesay processCoordinator->Name().String()); 157010cd325cSAndrew Lindesay fCoordinatorQueue.pop(); 1571409af934SAndrew Lindesay delete processCoordinator; 157210cd325cSAndrew Lindesay } 157310cd325cSAndrew Lindesay 1574409af934SAndrew Lindesay if (fCoordinator != NULL) 157595c7b018SAndrew Lindesay fCoordinator->RequestStop(); 157610cd325cSAndrew Lindesay } 157710cd325cSAndrew Lindesay 157810cd325cSAndrew Lindesay 157910cd325cSAndrew Lindesay /*! This method is called when there is some change in the bulk load process 158010cd325cSAndrew Lindesay or other process coordinator. 158110cd325cSAndrew Lindesay A change may mean that a new process has started / stopped etc... or it 158210cd325cSAndrew Lindesay may mean that the entire coordinator has finished. 158310cd325cSAndrew Lindesay */ 158410cd325cSAndrew Lindesay 158510cd325cSAndrew Lindesay void 158610cd325cSAndrew Lindesay MainWindow::CoordinatorChanged(ProcessCoordinatorState& coordinatorState) 158710cd325cSAndrew Lindesay { 1588409af934SAndrew Lindesay BMessage message(MSG_PROCESS_COORDINATOR_CHANGED); 1589409af934SAndrew Lindesay if (coordinatorState.Archive(&message, true) != B_OK) { 1590409af934SAndrew Lindesay HDFATAL("unable to archive message when the process coordinator" 1591409af934SAndrew Lindesay " has changed"); 1592409af934SAndrew Lindesay } 1593409af934SAndrew Lindesay BMessenger(this).SendMessage(&message); 1594409af934SAndrew Lindesay } 1595409af934SAndrew Lindesay 1596409af934SAndrew Lindesay 1597409af934SAndrew Lindesay void 1598409af934SAndrew Lindesay MainWindow::_HandleProcessCoordinatorChanged(ProcessCoordinatorState& coordinatorState) 1599409af934SAndrew Lindesay { 160010cd325cSAndrew Lindesay AutoLocker<BLocker> lock(&fCoordinatorLock); 160110cd325cSAndrew Lindesay 1602409af934SAndrew Lindesay if (fCoordinator->Identifier() 1603409af934SAndrew Lindesay == coordinatorState.ProcessCoordinatorIdentifier()) { 160410cd325cSAndrew Lindesay if (!coordinatorState.IsRunning()) { 160510cd325cSAndrew Lindesay if (release_sem(fCoordinatorRunningSem) != B_OK) 160610cd325cSAndrew Lindesay debugger("unable to release the process coordinator sem"); 1607f96d1f4dSAndrew Lindesay HDINFO("process coordinator [%s] did complete", 1608fa5c8097SAndrew Lindesay fCoordinator->Name().String()); 160910cd325cSAndrew Lindesay // complete the last one that just finished 161010cd325cSAndrew Lindesay BMessage* message = fCoordinator->Message(); 161110cd325cSAndrew Lindesay 161210cd325cSAndrew Lindesay if (message != NULL) { 161310cd325cSAndrew Lindesay BMessenger messenger(this); 161410cd325cSAndrew Lindesay message->AddInt64(KEY_ERROR_STATUS, 161510cd325cSAndrew Lindesay (int64) fCoordinator->ErrorStatus()); 161610cd325cSAndrew Lindesay messenger.SendMessage(message); 161710cd325cSAndrew Lindesay } 161810cd325cSAndrew Lindesay 16193538133fSAndrew Lindesay HDDEBUG("process coordinator report;\n---\n%s\n----", 16203538133fSAndrew Lindesay fCoordinator->LogReport().String()); 16213538133fSAndrew Lindesay 1622409af934SAndrew Lindesay delete fCoordinator; 1623409af934SAndrew Lindesay fCoordinator = NULL; 162410cd325cSAndrew Lindesay 162510cd325cSAndrew Lindesay // now schedule the next one. 162610cd325cSAndrew Lindesay if (!fCoordinatorQueue.empty()) { 162710cd325cSAndrew Lindesay if (acquire_sem(fCoordinatorRunningSem) != B_OK) 162810cd325cSAndrew Lindesay debugger("unable to acquire the process coordinator sem"); 162910cd325cSAndrew Lindesay fCoordinator = fCoordinatorQueue.front(); 1630f96d1f4dSAndrew Lindesay HDINFO("starting next process coordinator [%s]", 163110cd325cSAndrew Lindesay fCoordinator->Name().String()); 163210cd325cSAndrew Lindesay fCoordinatorQueue.pop(); 163310cd325cSAndrew Lindesay fCoordinator->Start(); 163410cd325cSAndrew Lindesay } 163510cd325cSAndrew Lindesay else { 163610cd325cSAndrew Lindesay _NotifyWorkStatusClear(); 163795c7b018SAndrew Lindesay if (fShouldCloseWhenNoProcessesToCoordinate) { 163895c7b018SAndrew Lindesay HDINFO("no more processes to coord --> will quit"); 163995c7b018SAndrew Lindesay BMessage message(B_QUIT_REQUESTED); 164095c7b018SAndrew Lindesay PostMessage(&message); 164195c7b018SAndrew Lindesay } 164210cd325cSAndrew Lindesay } 164310cd325cSAndrew Lindesay } 164410cd325cSAndrew Lindesay else { 164510cd325cSAndrew Lindesay _NotifyWorkStatusChange(coordinatorState.Message(), 164610cd325cSAndrew Lindesay coordinatorState.Progress()); 164710cd325cSAndrew Lindesay // show the progress to the user. 164810cd325cSAndrew Lindesay } 164995c7b018SAndrew Lindesay } else { 165095c7b018SAndrew Lindesay _NotifyWorkStatusClear(); 1651fa5c8097SAndrew Lindesay HDINFO("! unknown process coordinator changed"); 165210cd325cSAndrew Lindesay } 165395c7b018SAndrew Lindesay } 1654ccf707d0SAndrew Lindesay 1655ccf707d0SAndrew Lindesay 1656ccf707d0SAndrew Lindesay static package_list_view_mode 1657ccf707d0SAndrew Lindesay main_window_tab_to_package_list_view_mode(int32 tab) 1658ccf707d0SAndrew Lindesay { 1659ccf707d0SAndrew Lindesay if (tab == TAB_PROMINENT_PACKAGES) 1660ccf707d0SAndrew Lindesay return PROMINENT; 1661ccf707d0SAndrew Lindesay return ALL; 1662ccf707d0SAndrew Lindesay } 1663ccf707d0SAndrew Lindesay 1664ccf707d0SAndrew Lindesay 1665ccf707d0SAndrew Lindesay void 1666ccf707d0SAndrew Lindesay MainWindow::_HandleChangePackageListViewMode() 1667ccf707d0SAndrew Lindesay { 1668ccf707d0SAndrew Lindesay package_list_view_mode tabMode = main_window_tab_to_package_list_view_mode( 1669ccf707d0SAndrew Lindesay fListTabs->Selection()); 1670ccf707d0SAndrew Lindesay package_list_view_mode modelMode = fModel.PackageListViewMode(); 1671ccf707d0SAndrew Lindesay 1672ccf707d0SAndrew Lindesay if (tabMode != modelMode) { 1673ccf707d0SAndrew Lindesay BAutolock locker(fModel.Lock()); 1674ccf707d0SAndrew Lindesay fModel.SetPackageListViewMode(tabMode); 1675ccf707d0SAndrew Lindesay } 1676ccf707d0SAndrew Lindesay } 167705880d13SAndrew Lindesay 167805880d13SAndrew Lindesay 167905880d13SAndrew Lindesay std::vector<DepotInfoRef> 168005880d13SAndrew Lindesay MainWindow::_CreateSnapshotOfDepots() 168105880d13SAndrew Lindesay { 168205880d13SAndrew Lindesay std::vector<DepotInfoRef> result; 168305880d13SAndrew Lindesay BAutolock locker(fModel.Lock()); 168405880d13SAndrew Lindesay int32 countDepots = fModel.CountDepots(); 168505880d13SAndrew Lindesay for(int32 i = 0; i < countDepots; i++) 168605880d13SAndrew Lindesay result.push_back(fModel.DepotAtIndex(i)); 168705880d13SAndrew Lindesay return result; 168805880d13SAndrew Lindesay } 168988af15cfSAndrew Lindesay 169088af15cfSAndrew Lindesay 169188af15cfSAndrew Lindesay /*! This will get invoked in the case that a screenshot has been cached 169288af15cfSAndrew Lindesay and so could now be loaded by some UI element. This method will then 169388af15cfSAndrew Lindesay signal to other UI elements that they could load a screenshot should 169488af15cfSAndrew Lindesay they have been waiting for it. 169588af15cfSAndrew Lindesay */ 169688af15cfSAndrew Lindesay 169788af15cfSAndrew Lindesay void 169888af15cfSAndrew Lindesay MainWindow::_HandleScreenshotCached(const BMessage* message) 169988af15cfSAndrew Lindesay { 170088af15cfSAndrew Lindesay ScreenshotCoordinate coordinate(message); 170188af15cfSAndrew Lindesay fPackageInfoView->HandleScreenshotCached(coordinate); 170288af15cfSAndrew Lindesay } 1703