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. 6d75b4d61SAndrew Lindesay * Copyright 2016-2021, 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 11f7c2983eSAxel Dörfler 1204c9d578SStephan Aßmus #include "MainWindow.h" 1304c9d578SStephan Aßmus 1404c9d578SStephan Aßmus #include <map> 153b17d8ddSAndrew Lindesay #include <vector> 1604c9d578SStephan Aßmus 1704c9d578SStephan Aßmus #include <stdio.h> 1804c9d578SStephan Aßmus #include <Alert.h> 1904c9d578SStephan Aßmus #include <Autolock.h> 2004c9d578SStephan Aßmus #include <Application.h> 2104c9d578SStephan Aßmus #include <Button.h> 2204c9d578SStephan Aßmus #include <Catalog.h> 234b930ccaSStephan Aßmus #include <CardLayout.h> 2404c9d578SStephan Aßmus #include <LayoutBuilder.h> 2504c9d578SStephan Aßmus #include <MenuBar.h> 2604c9d578SStephan Aßmus #include <MenuItem.h> 2704c9d578SStephan Aßmus #include <Messenger.h> 285bf2b6ebSBrian Hill #include <Roster.h> 29f7c2983eSAxel Dörfler #include <Screen.h> 3004c9d578SStephan Aßmus #include <ScrollView.h> 3104c9d578SStephan Aßmus #include <StringList.h> 320a9c9029SStephan Aßmus #include <StringView.h> 3304c9d578SStephan Aßmus #include <TabView.h> 3404c9d578SStephan Aßmus 353369e03dSAndrew Lindesay #include "AppUtils.h" 3604c9d578SStephan Aßmus #include "AutoDeleter.h" 3704c9d578SStephan Aßmus #include "AutoLocker.h" 3804c9d578SStephan Aßmus #include "DecisionProvider.h" 394b930ccaSStephan Aßmus #include "FeaturedPackagesView.h" 4004c9d578SStephan Aßmus #include "FilterView.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" 48e0a26dceSStephan Aßmus #include "support.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" 5604c9d578SStephan Aßmus 5704c9d578SStephan Aßmus 5804c9d578SStephan Aßmus #undef B_TRANSLATION_CONTEXT 5904c9d578SStephan Aßmus #define B_TRANSLATION_CONTEXT "MainWindow" 6004c9d578SStephan Aßmus 6104c9d578SStephan Aßmus 6204c9d578SStephan Aßmus enum { 635bf2b6ebSBrian Hill MSG_REFRESH_REPOS = 'mrrp', 645bf2b6ebSBrian Hill MSG_MANAGE_REPOS = 'mmrp', 65d144f952SAugustin Cavalier MSG_SOFTWARE_UPDATER = 'mswu', 66133ebab6SAndrew Lindesay MSG_SETTINGS = 'stgs', 6704c9d578SStephan Aßmus MSG_LOG_IN = 'lgin', 688f03a0f9SStephan Aßmus MSG_AUTHORIZATION_CHANGED = 'athc', 6989b16bb4SAndrew Lindesay MSG_CATEGORIES_LIST_CHANGED = 'clic', 70da651104SStephan Aßmus MSG_PACKAGE_CHANGED = 'pchd', 713369e03dSAndrew Lindesay MSG_WORK_STATUS_CHANGE = 'wsch', 723369e03dSAndrew Lindesay MSG_WORK_STATUS_CLEAR = 'wscl', 73fdec4227SStephan Aßmus 74ccf707d0SAndrew Lindesay MSG_CHANGE_PACKAGE_LIST_VIEW_MODE = 'cplm', 75fdec4227SStephan Aßmus MSG_SHOW_AVAILABLE_PACKAGES = 'savl', 76fdec4227SStephan Aßmus MSG_SHOW_INSTALLED_PACKAGES = 'sins', 7704c9d578SStephan Aßmus MSG_SHOW_SOURCE_PACKAGES = 'ssrc', 7804c9d578SStephan Aßmus MSG_SHOW_DEVELOP_PACKAGES = 'sdvl' 7904c9d578SStephan Aßmus }; 8004c9d578SStephan Aßmus 8110cd325cSAndrew Lindesay #define KEY_ERROR_STATUS "errorStatus" 82ccf707d0SAndrew Lindesay 83ccf707d0SAndrew Lindesay #define TAB_PROMINENT_PACKAGES 0 84ccf707d0SAndrew Lindesay #define TAB_ALL_PACKAGES 1 8504c9d578SStephan Aßmus 8604c9d578SStephan Aßmus using namespace BPackageKit; 8704c9d578SStephan Aßmus using namespace BPackageKit::BManager::BPrivate; 8804c9d578SStephan Aßmus 8904c9d578SStephan Aßmus 9004c9d578SStephan Aßmus typedef std::map<BString, PackageInfoRef> PackageInfoMap; 9104c9d578SStephan Aßmus 9204c9d578SStephan Aßmus 9304c9d578SStephan Aßmus struct RefreshWorkerParameters { 9404c9d578SStephan Aßmus MainWindow* window; 9504c9d578SStephan Aßmus bool forceRefresh; 9604c9d578SStephan Aßmus 9704c9d578SStephan Aßmus RefreshWorkerParameters(MainWindow* window, bool forceRefresh) 9804c9d578SStephan Aßmus : 9904c9d578SStephan Aßmus window(window), 10004c9d578SStephan Aßmus forceRefresh(forceRefresh) 10104c9d578SStephan Aßmus { 10204c9d578SStephan Aßmus } 10304c9d578SStephan Aßmus }; 10404c9d578SStephan Aßmus 10504c9d578SStephan Aßmus 10689b16bb4SAndrew Lindesay class MainWindowModelListener : public ModelListener { 1078f03a0f9SStephan Aßmus public: 10889b16bb4SAndrew Lindesay MainWindowModelListener(const BMessenger& messenger) 1098f03a0f9SStephan Aßmus : 1108f03a0f9SStephan Aßmus fMessenger(messenger) 1118f03a0f9SStephan Aßmus { 1128f03a0f9SStephan Aßmus } 1138f03a0f9SStephan Aßmus 1148f03a0f9SStephan Aßmus virtual void AuthorizationChanged() 1158f03a0f9SStephan Aßmus { 1168f03a0f9SStephan Aßmus if (fMessenger.IsValid()) 1178f03a0f9SStephan Aßmus fMessenger.SendMessage(MSG_AUTHORIZATION_CHANGED); 1188f03a0f9SStephan Aßmus } 1198f03a0f9SStephan Aßmus 12089b16bb4SAndrew Lindesay virtual void CategoryListChanged() 12189b16bb4SAndrew Lindesay { 12289b16bb4SAndrew Lindesay if (fMessenger.IsValid()) 12389b16bb4SAndrew Lindesay fMessenger.SendMessage(MSG_CATEGORIES_LIST_CHANGED); 12489b16bb4SAndrew Lindesay } 12589b16bb4SAndrew Lindesay 1268f03a0f9SStephan Aßmus private: 1278f03a0f9SStephan Aßmus BMessenger fMessenger; 1288f03a0f9SStephan Aßmus }; 1298f03a0f9SStephan Aßmus 1308f03a0f9SStephan Aßmus 131f7c2983eSAxel Dörfler MainWindow::MainWindow(const BMessage& settings) 13204c9d578SStephan Aßmus : 133f7c2983eSAxel Dörfler BWindow(BRect(50, 50, 650, 550), B_TRANSLATE_SYSTEM_NAME("HaikuDepot"), 13404c9d578SStephan Aßmus B_DOCUMENT_WINDOW_LOOK, B_NORMAL_WINDOW_FEEL, 13504c9d578SStephan Aßmus B_ASYNCHRONOUS_CONTROLS | B_AUTO_UPDATE_SIZE_LIMITS), 136d5ef985eSStephan Aßmus fScreenshotWindow(NULL), 13795c7b018SAndrew Lindesay fShuttingDownWindow(NULL), 138e0a26dceSStephan Aßmus fUserMenu(NULL), 139e0a26dceSStephan Aßmus fLogInItem(NULL), 140e0a26dceSStephan Aßmus fLogOutItem(NULL), 141976cadf1SAndrew Lindesay fUsersUserUsageConditionsMenuItem(NULL), 14289b16bb4SAndrew Lindesay fModelListener(new MainWindowModelListener(BMessenger(this)), true), 14310cd325cSAndrew Lindesay fCoordinator(NULL), 14495c7b018SAndrew Lindesay fShouldCloseWhenNoProcessesToCoordinate(false), 1453369e03dSAndrew Lindesay fSinglePackageMode(false) 14604c9d578SStephan Aßmus { 14710cd325cSAndrew Lindesay if ((fCoordinatorRunningSem = create_sem(1, "ProcessCoordinatorSem")) < B_OK) 14810cd325cSAndrew Lindesay debugger("unable to create the process coordinator semaphore"); 14910cd325cSAndrew Lindesay 150cbadcae1SHumdinger BMenuBar* menuBar = new BMenuBar("Main Menu"); 15104c9d578SStephan Aßmus _BuildMenu(menuBar); 15204c9d578SStephan Aßmus 153cbadcae1SHumdinger BMenuBar* userMenuBar = new BMenuBar("User Menu"); 154e0a26dceSStephan Aßmus _BuildUserMenu(userMenuBar); 155e0a26dceSStephan Aßmus set_small_font(userMenuBar); 156e0a26dceSStephan Aßmus userMenuBar->SetExplicitMaxSize(BSize(B_SIZE_UNSET, 157e0a26dceSStephan Aßmus menuBar->MaxSize().height)); 158e0a26dceSStephan Aßmus 15904c9d578SStephan Aßmus fFilterView = new FilterView(); 160f0e491d3SAndrew Lindesay fFeaturedPackagesView = new FeaturedPackagesView(fModel); 161f0e491d3SAndrew Lindesay fPackageListView = new PackageListView(&fModel); 162f0e491d3SAndrew Lindesay fPackageInfoView = new PackageInfoView(&fModel, this); 16304c9d578SStephan Aßmus 16404c9d578SStephan Aßmus fSplitView = new BSplitView(B_VERTICAL, 5.0f); 16504c9d578SStephan Aßmus 166125d42d9SJulian Harnath fWorkStatusView = new WorkStatusView("work status"); 167125d42d9SJulian Harnath fPackageListView->AttachWorkStatusView(fWorkStatusView); 168125d42d9SJulian Harnath 169e00a489bSAugustin Cavalier fListTabs = new TabView(BMessenger(this), 170ccf707d0SAndrew Lindesay BMessage(MSG_CHANGE_PACKAGE_LIST_VIEW_MODE), "list tabs"); 171e00a489bSAugustin Cavalier fListTabs->AddTab(fFeaturedPackagesView); 172e00a489bSAugustin Cavalier fListTabs->AddTab(fPackageListView); 1734b930ccaSStephan Aßmus 17404c9d578SStephan Aßmus BLayoutBuilder::Group<>(this, B_VERTICAL, 0.0f) 175e0a26dceSStephan Aßmus .AddGroup(B_HORIZONTAL, 0.0f) 176e0a26dceSStephan Aßmus .Add(menuBar, 1.0f) 177e0a26dceSStephan Aßmus .Add(userMenuBar, 0.0f) 178e0a26dceSStephan Aßmus .End() 17904c9d578SStephan Aßmus .Add(fFilterView) 18004c9d578SStephan Aßmus .AddSplit(fSplitView) 18104c9d578SStephan Aßmus .AddGroup(B_VERTICAL) 182e00a489bSAugustin Cavalier .Add(fListTabs) 18304c9d578SStephan Aßmus .SetInsets( 18404c9d578SStephan Aßmus B_USE_DEFAULT_SPACING, 0.0f, 18504c9d578SStephan Aßmus B_USE_DEFAULT_SPACING, 0.0f) 18604c9d578SStephan Aßmus .End() 18704c9d578SStephan Aßmus .Add(fPackageInfoView) 18804c9d578SStephan Aßmus .End() 189125d42d9SJulian Harnath .Add(fWorkStatusView) 19004c9d578SStephan Aßmus ; 19104c9d578SStephan Aßmus 19204c9d578SStephan Aßmus fSplitView->SetCollapsible(0, false); 19304c9d578SStephan Aßmus fSplitView->SetCollapsible(1, false); 19404c9d578SStephan Aßmus 1958f03a0f9SStephan Aßmus fModel.AddListener(fModelListener); 1968f03a0f9SStephan Aßmus 19704c9d578SStephan Aßmus BMessage columnSettings; 19804c9d578SStephan Aßmus if (settings.FindMessage("column settings", &columnSettings) == B_OK) 19904c9d578SStephan Aßmus fPackageListView->LoadState(&columnSettings); 20004c9d578SStephan Aßmus 201ccf707d0SAndrew Lindesay _RestoreModelSettings(settings); 202133ebab6SAndrew Lindesay _MaybePromptCanShareAnonymousUserData(settings); 20304c9d578SStephan Aßmus 204ccf707d0SAndrew Lindesay if (fModel.PackageListViewMode() == PROMINENT) 205ccf707d0SAndrew Lindesay fListTabs->Select(TAB_PROMINENT_PACKAGES); 2062997e05bSStephan Aßmus else 207ccf707d0SAndrew Lindesay fListTabs->Select(TAB_ALL_PACKAGES); 2082997e05bSStephan Aßmus 209d2d4866dSAndrew Lindesay _RestoreNickname(settings); 21010cd325cSAndrew Lindesay _UpdateAuthorization(); 211f7c2983eSAxel Dörfler _RestoreWindowFrame(settings); 212f7c2983eSAxel Dörfler 2138f03a0f9SStephan Aßmus // start worker threads 21404c9d578SStephan Aßmus BPackageRoster().StartWatching(this, 21504c9d578SStephan Aßmus B_WATCH_PACKAGE_INSTALLATION_LOCATIONS); 21604c9d578SStephan Aßmus 21763975654SStephan Aßmus _InitWorkerThreads(); 2189883929bSAndrew Lindesay _AdoptModel(); 2199883929bSAndrew Lindesay _StartBulkLoad(); 22004c9d578SStephan Aßmus } 22104c9d578SStephan Aßmus 22204c9d578SStephan Aßmus 223afe7affbSAndrew Lindesay MainWindow::MainWindow(const BMessage& settings, PackageInfoRef& package) 2246d519fd1SStephan Aßmus : 225f7c2983eSAxel Dörfler BWindow(BRect(50, 50, 650, 350), B_TRANSLATE_SYSTEM_NAME("HaikuDepot"), 2266d519fd1SStephan Aßmus B_DOCUMENT_WINDOW_LOOK, B_NORMAL_WINDOW_FEEL, 2276d519fd1SStephan Aßmus B_ASYNCHRONOUS_CONTROLS | B_AUTO_UPDATE_SIZE_LIMITS), 2289883929bSAndrew Lindesay fFeaturedPackagesView(NULL), 2299883929bSAndrew Lindesay fPackageListView(NULL), 230d78bfd8dSJulian Harnath fWorkStatusView(NULL), 231d5ef985eSStephan Aßmus fScreenshotWindow(NULL), 23295c7b018SAndrew Lindesay fShuttingDownWindow(NULL), 233e0a26dceSStephan Aßmus fUserMenu(NULL), 234e0a26dceSStephan Aßmus fLogInItem(NULL), 2356d519fd1SStephan Aßmus fLogOutItem(NULL), 236976cadf1SAndrew Lindesay fUsersUserUsageConditionsMenuItem(NULL), 23789b16bb4SAndrew Lindesay fModelListener(new MainWindowModelListener(BMessenger(this)), true), 23810cd325cSAndrew Lindesay fCoordinator(NULL), 23995c7b018SAndrew Lindesay fShouldCloseWhenNoProcessesToCoordinate(false), 2403369e03dSAndrew Lindesay fSinglePackageMode(true) 2416d519fd1SStephan Aßmus { 24210cd325cSAndrew Lindesay if ((fCoordinatorRunningSem = create_sem(1, "ProcessCoordinatorSem")) < B_OK) 24310cd325cSAndrew Lindesay debugger("unable to create the process coordinator semaphore"); 24410cd325cSAndrew Lindesay 2456d519fd1SStephan Aßmus fFilterView = new FilterView(); 246f0e491d3SAndrew Lindesay fPackageInfoView = new PackageInfoView(&fModel, this); 24787016f8fSAndrew Lindesay fWorkStatusView = new WorkStatusView("work status"); 2486d519fd1SStephan Aßmus 2496d519fd1SStephan Aßmus BLayoutBuilder::Group<>(this, B_VERTICAL) 2506d519fd1SStephan Aßmus .Add(fPackageInfoView) 25187016f8fSAndrew Lindesay .Add(fWorkStatusView) 2526d519fd1SStephan Aßmus .SetInsets(0, B_USE_WINDOW_INSETS, 0, 0) 2536d519fd1SStephan Aßmus ; 2546d519fd1SStephan Aßmus 2556d519fd1SStephan Aßmus fModel.AddListener(fModelListener); 2566d519fd1SStephan Aßmus 257afe7affbSAndrew Lindesay // add the single package into the model so that any internal 258afe7affbSAndrew Lindesay // business logic is able to find the package. 259afe7affbSAndrew Lindesay DepotInfoRef depot(new DepotInfo("single-pkg-depot"), true); 260afe7affbSAndrew Lindesay depot->AddPackage(package); 261afe7affbSAndrew Lindesay fModel.MergeOrAddDepot(depot); 262afe7affbSAndrew Lindesay 2636d519fd1SStephan Aßmus // Restore settings 264d2d4866dSAndrew Lindesay _RestoreNickname(settings); 265ccf707d0SAndrew Lindesay _UpdateAuthorization(); 266f7c2983eSAxel Dörfler _RestoreWindowFrame(settings); 2676d519fd1SStephan Aßmus 2686d519fd1SStephan Aßmus fPackageInfoView->SetPackage(package); 26963975654SStephan Aßmus 270afe7affbSAndrew Lindesay // start worker threads 271afe7affbSAndrew Lindesay BPackageRoster().StartWatching(this, 272afe7affbSAndrew Lindesay B_WATCH_PACKAGE_INSTALLATION_LOCATIONS); 273afe7affbSAndrew Lindesay 27463975654SStephan Aßmus _InitWorkerThreads(); 2756d519fd1SStephan Aßmus } 2766d519fd1SStephan Aßmus 2776d519fd1SStephan Aßmus 27804c9d578SStephan Aßmus MainWindow::~MainWindow() 27904c9d578SStephan Aßmus { 28010cd325cSAndrew Lindesay _SpinUntilProcessCoordinatorComplete(); 28110cd325cSAndrew Lindesay delete_sem(fCoordinatorRunningSem); 28210cd325cSAndrew Lindesay fCoordinatorRunningSem = 0; 28310cd325cSAndrew Lindesay 28404c9d578SStephan Aßmus BPackageRoster().StopWatching(this); 28504c9d578SStephan Aßmus 28695c7b018SAndrew Lindesay if (fScreenshotWindow != NULL) { 28795c7b018SAndrew Lindesay if (fScreenshotWindow->Lock()) 288d5ef985eSStephan Aßmus fScreenshotWindow->Quit(); 28904c9d578SStephan Aßmus } 29004c9d578SStephan Aßmus 29195c7b018SAndrew Lindesay if (fShuttingDownWindow != NULL) { 29295c7b018SAndrew Lindesay if (fShuttingDownWindow->Lock()) 29395c7b018SAndrew Lindesay fShuttingDownWindow->Quit(); 29495c7b018SAndrew Lindesay } 295d5562247SAugustin Cavalier 296a3866854SAugustin Cavalier delete_sem(fPackageToPopulateSem); 297a3866854SAugustin Cavalier wait_for_thread(fPopulatePackageWorker, NULL); 298a3866854SAugustin Cavalier 2994329a83fSAugustin Cavalier // We must clear the model early to release references. 300d5562247SAugustin Cavalier fModel.Clear(); 30195c7b018SAndrew Lindesay } 30295c7b018SAndrew Lindesay 30304c9d578SStephan Aßmus 30404c9d578SStephan Aßmus bool 30504c9d578SStephan Aßmus MainWindow::QuitRequested() 30604c9d578SStephan Aßmus { 30704c9d578SStephan Aßmus 30810cd325cSAndrew Lindesay _StopProcessCoordinators(); 3093369e03dSAndrew Lindesay 31095c7b018SAndrew Lindesay // If there are any processes in flight we need to be careful to make 31195c7b018SAndrew Lindesay // sure that they are cleanly completed before actually quitting. By 31295c7b018SAndrew Lindesay // turning on the `fShouldCloseWhenNoProcessesToCoordinate` flag, when 31395c7b018SAndrew Lindesay // the process coordination has completed then it will detect this and 31495c7b018SAndrew Lindesay // quit again. 31595c7b018SAndrew Lindesay 31695c7b018SAndrew Lindesay { 31795c7b018SAndrew Lindesay AutoLocker<BLocker> lock(&fCoordinatorLock); 31895c7b018SAndrew Lindesay fShouldCloseWhenNoProcessesToCoordinate = true; 31995c7b018SAndrew Lindesay 32095c7b018SAndrew Lindesay if (fCoordinator.IsSet()) { 32195c7b018SAndrew Lindesay HDINFO("a coordinator is running --> will wait before quitting..."); 32295c7b018SAndrew Lindesay 32395c7b018SAndrew Lindesay if (fShuttingDownWindow == NULL) 32495c7b018SAndrew Lindesay fShuttingDownWindow = new ShuttingDownWindow(this); 32595c7b018SAndrew Lindesay fShuttingDownWindow->Show(); 32695c7b018SAndrew Lindesay 32795c7b018SAndrew Lindesay return false; 32895c7b018SAndrew Lindesay } 32995c7b018SAndrew Lindesay } 33095c7b018SAndrew Lindesay 33195c7b018SAndrew Lindesay BMessage settings; 33295c7b018SAndrew Lindesay StoreSettings(settings); 33395c7b018SAndrew Lindesay BMessage message(MSG_MAIN_WINDOW_CLOSED); 33495c7b018SAndrew Lindesay message.AddMessage(KEY_WINDOW_SETTINGS, &settings); 33595c7b018SAndrew Lindesay be_app->PostMessage(&message); 33695c7b018SAndrew Lindesay 33795c7b018SAndrew Lindesay if (fShuttingDownWindow != NULL) { 33895c7b018SAndrew Lindesay if (fShuttingDownWindow->Lock()) 33995c7b018SAndrew Lindesay fShuttingDownWindow->Quit(); 34095c7b018SAndrew Lindesay fShuttingDownWindow = NULL; 34195c7b018SAndrew Lindesay } 34295c7b018SAndrew Lindesay 34304c9d578SStephan Aßmus return true; 34404c9d578SStephan Aßmus } 34504c9d578SStephan Aßmus 34604c9d578SStephan Aßmus 34704c9d578SStephan Aßmus void 34804c9d578SStephan Aßmus MainWindow::MessageReceived(BMessage* message) 34904c9d578SStephan Aßmus { 35004c9d578SStephan Aßmus switch (message->what) { 3513369e03dSAndrew Lindesay case MSG_BULK_LOAD_DONE: 35210cd325cSAndrew Lindesay { 35310cd325cSAndrew Lindesay int64 errorStatus64; 35410cd325cSAndrew Lindesay if (message->FindInt64(KEY_ERROR_STATUS, &errorStatus64) == B_OK) 35510cd325cSAndrew Lindesay _BulkLoadCompleteReceived((status_t) errorStatus64); 35610cd325cSAndrew Lindesay else 357fa5c8097SAndrew Lindesay HDERROR("expected [%s] value in message", KEY_ERROR_STATUS); 35804c9d578SStephan Aßmus break; 35910cd325cSAndrew Lindesay } 36004c9d578SStephan Aßmus case B_SIMPLE_DATA: 36104c9d578SStephan Aßmus case B_REFS_RECEIVED: 36204c9d578SStephan Aßmus // TODO: ? 36304c9d578SStephan Aßmus break; 36404c9d578SStephan Aßmus 36504c9d578SStephan Aßmus case B_PACKAGE_UPDATE: 366f32d5c5cSAndrew Lindesay _HandleExternalPackageUpdateMessageReceived(message); 36704c9d578SStephan Aßmus break; 36804c9d578SStephan Aßmus 3695bf2b6ebSBrian Hill case MSG_REFRESH_REPOS: 3703369e03dSAndrew Lindesay _StartBulkLoad(true); 3713369e03dSAndrew Lindesay break; 3723369e03dSAndrew Lindesay 37310cd325cSAndrew Lindesay case MSG_WORK_STATUS_CLEAR: 37410cd325cSAndrew Lindesay _HandleWorkStatusClear(); 37510cd325cSAndrew Lindesay break; 37610cd325cSAndrew Lindesay 3773369e03dSAndrew Lindesay case MSG_WORK_STATUS_CHANGE: 3783369e03dSAndrew Lindesay _HandleWorkStatusChangeMessageReceived(message); 37904c9d578SStephan Aßmus break; 38004c9d578SStephan Aßmus 3815bf2b6ebSBrian Hill case MSG_MANAGE_REPOS: 3825bf2b6ebSBrian Hill be_roster->Launch("application/x-vnd.Haiku-Repositories"); 3835bf2b6ebSBrian Hill break; 3845bf2b6ebSBrian Hill 385d144f952SAugustin Cavalier case MSG_SOFTWARE_UPDATER: 386d144f952SAugustin Cavalier be_roster->Launch("application/x-vnd.haiku-softwareupdater"); 387d144f952SAugustin Cavalier break; 388d144f952SAugustin Cavalier 38904c9d578SStephan Aßmus case MSG_LOG_IN: 3901bbda92dSStephan Aßmus _OpenLoginWindow(BMessage()); 39104c9d578SStephan Aßmus break; 39204c9d578SStephan Aßmus 393133ebab6SAndrew Lindesay case MSG_SETTINGS: 394133ebab6SAndrew Lindesay _OpenSettingsWindow(); 395133ebab6SAndrew Lindesay break; 396133ebab6SAndrew Lindesay 3978f03a0f9SStephan Aßmus case MSG_LOG_OUT: 398d2d4866dSAndrew Lindesay fModel.SetNickname(""); 3998f03a0f9SStephan Aßmus break; 4008f03a0f9SStephan Aßmus 40101339a54SAndrew Lindesay case MSG_VIEW_LATEST_USER_USAGE_CONDITIONS: 402d2d4866dSAndrew Lindesay _ViewUserUsageConditions(LATEST); 403d2d4866dSAndrew Lindesay break; 404d2d4866dSAndrew Lindesay 405d2d4866dSAndrew Lindesay case MSG_VIEW_USERS_USER_USAGE_CONDITIONS: 406d2d4866dSAndrew Lindesay _ViewUserUsageConditions(USER); 40701339a54SAndrew Lindesay break; 40801339a54SAndrew Lindesay 4098f03a0f9SStephan Aßmus case MSG_AUTHORIZATION_CHANGED: 41010cd325cSAndrew Lindesay _StartUserVerify(); 4118f03a0f9SStephan Aßmus _UpdateAuthorization(); 4128f03a0f9SStephan Aßmus break; 4138f03a0f9SStephan Aßmus 41489b16bb4SAndrew Lindesay case MSG_CATEGORIES_LIST_CHANGED: 41589b16bb4SAndrew Lindesay fFilterView->AdoptModel(fModel); 41689b16bb4SAndrew Lindesay break; 41789b16bb4SAndrew Lindesay 418ccf707d0SAndrew Lindesay case MSG_CHANGE_PACKAGE_LIST_VIEW_MODE: 419ccf707d0SAndrew Lindesay _HandleChangePackageListViewMode(); 4204fade61fSStephan Aßmus break; 4214fade61fSStephan Aßmus 422fdec4227SStephan Aßmus case MSG_SHOW_AVAILABLE_PACKAGES: 423fdec4227SStephan Aßmus { 424fdec4227SStephan Aßmus BAutolock locker(fModel.Lock()); 425fdec4227SStephan Aßmus fModel.SetShowAvailablePackages( 426fdec4227SStephan Aßmus !fModel.ShowAvailablePackages()); 427fdec4227SStephan Aßmus } 428fdec4227SStephan Aßmus _AdoptModel(); 429fdec4227SStephan Aßmus break; 430fdec4227SStephan Aßmus 431fdec4227SStephan Aßmus case MSG_SHOW_INSTALLED_PACKAGES: 432fdec4227SStephan Aßmus { 433fdec4227SStephan Aßmus BAutolock locker(fModel.Lock()); 434fdec4227SStephan Aßmus fModel.SetShowInstalledPackages( 435fdec4227SStephan Aßmus !fModel.ShowInstalledPackages()); 436fdec4227SStephan Aßmus } 437fdec4227SStephan Aßmus _AdoptModel(); 438fdec4227SStephan Aßmus break; 439fdec4227SStephan Aßmus 44004c9d578SStephan Aßmus case MSG_SHOW_SOURCE_PACKAGES: 44104c9d578SStephan Aßmus { 44204c9d578SStephan Aßmus BAutolock locker(fModel.Lock()); 44304c9d578SStephan Aßmus fModel.SetShowSourcePackages(!fModel.ShowSourcePackages()); 44404c9d578SStephan Aßmus } 44504c9d578SStephan Aßmus _AdoptModel(); 44604c9d578SStephan Aßmus break; 44704c9d578SStephan Aßmus 44804c9d578SStephan Aßmus case MSG_SHOW_DEVELOP_PACKAGES: 44904c9d578SStephan Aßmus { 45004c9d578SStephan Aßmus BAutolock locker(fModel.Lock()); 45104c9d578SStephan Aßmus fModel.SetShowDevelopPackages(!fModel.ShowDevelopPackages()); 45204c9d578SStephan Aßmus } 45304c9d578SStephan Aßmus _AdoptModel(); 45404c9d578SStephan Aßmus break; 45504c9d578SStephan Aßmus 456a9edb9bfSAndrew Lindesay // this may be triggered by, for example, a user rating being added 457a9edb9bfSAndrew Lindesay // or having been altered. 458a9edb9bfSAndrew Lindesay case MSG_SERVER_DATA_CHANGED: 459a9edb9bfSAndrew Lindesay { 460a9edb9bfSAndrew Lindesay BString name; 461a9edb9bfSAndrew Lindesay if (message->FindString("name", &name) == B_OK) { 462a9edb9bfSAndrew Lindesay BAutolock locker(fModel.Lock()); 463a9edb9bfSAndrew Lindesay if (fPackageInfoView->Package()->Name() == name) { 464a9edb9bfSAndrew Lindesay _PopulatePackageAsync(true); 465a9edb9bfSAndrew Lindesay } else { 466f96d1f4dSAndrew Lindesay HDDEBUG("pkg [%s] is updated on the server, but is " 467f96d1f4dSAndrew Lindesay "not selected so will not be updated.", 468fa5c8097SAndrew Lindesay name.String()); 469a9edb9bfSAndrew Lindesay } 470a9edb9bfSAndrew Lindesay } 471a9edb9bfSAndrew Lindesay break; 472a9edb9bfSAndrew Lindesay } 473a9edb9bfSAndrew Lindesay 47404c9d578SStephan Aßmus case MSG_PACKAGE_SELECTED: 47504c9d578SStephan Aßmus { 47672992391SStephan Aßmus BString name; 47772992391SStephan Aßmus if (message->FindString("name", &name) == B_OK) { 478c4199192SAndrew Lindesay PackageInfoRef package; 479c4199192SAndrew Lindesay { 48075ba9dbfSStephan Aßmus BAutolock locker(fModel.Lock()); 481c4199192SAndrew Lindesay package = fModel.PackageForName(name); 482c4199192SAndrew Lindesay } 4836f07feadSAndrew Lindesay if (!package.IsSet() || name != package->Name()) 484c4199192SAndrew Lindesay debugger("unable to find the named package"); 485133ebab6SAndrew Lindesay else { 48604c9d578SStephan Aßmus _AdoptPackage(package); 487133ebab6SAndrew Lindesay _IncrementViewCounter(package); 488133ebab6SAndrew Lindesay } 48904c9d578SStephan Aßmus } else { 49004c9d578SStephan Aßmus _ClearPackage(); 49104c9d578SStephan Aßmus } 49204c9d578SStephan Aßmus break; 49304c9d578SStephan Aßmus } 49404c9d578SStephan Aßmus 49504c9d578SStephan Aßmus case MSG_CATEGORY_SELECTED: 49604c9d578SStephan Aßmus { 49789b16bb4SAndrew Lindesay BString code; 49889b16bb4SAndrew Lindesay if (message->FindString("code", &code) != B_OK) 49989b16bb4SAndrew Lindesay code = ""; 50004c9d578SStephan Aßmus { 50104c9d578SStephan Aßmus BAutolock locker(fModel.Lock()); 50289b16bb4SAndrew Lindesay fModel.SetCategory(code); 50304c9d578SStephan Aßmus } 50404c9d578SStephan Aßmus _AdoptModel(); 50504c9d578SStephan Aßmus break; 50604c9d578SStephan Aßmus } 50704c9d578SStephan Aßmus 50804c9d578SStephan Aßmus case MSG_DEPOT_SELECTED: 50904c9d578SStephan Aßmus { 51004c9d578SStephan Aßmus BString name; 51104c9d578SStephan Aßmus if (message->FindString("name", &name) != B_OK) 51204c9d578SStephan Aßmus name = ""; 51304c9d578SStephan Aßmus { 51404c9d578SStephan Aßmus BAutolock locker(fModel.Lock()); 51504c9d578SStephan Aßmus fModel.SetDepot(name); 51604c9d578SStephan Aßmus } 51704c9d578SStephan Aßmus _AdoptModel(); 518b965ce70SHumdinger _UpdateAvailableRepositories(); 51904c9d578SStephan Aßmus break; 52004c9d578SStephan Aßmus } 52104c9d578SStephan Aßmus 52204c9d578SStephan Aßmus case MSG_SEARCH_TERMS_MODIFIED: 52304c9d578SStephan Aßmus { 52404c9d578SStephan Aßmus // TODO: Do this with a delay! 52504c9d578SStephan Aßmus BString searchTerms; 52604c9d578SStephan Aßmus if (message->FindString("search terms", &searchTerms) != B_OK) 52704c9d578SStephan Aßmus searchTerms = ""; 52804c9d578SStephan Aßmus { 52904c9d578SStephan Aßmus BAutolock locker(fModel.Lock()); 53004c9d578SStephan Aßmus fModel.SetSearchTerms(searchTerms); 53104c9d578SStephan Aßmus } 53204c9d578SStephan Aßmus _AdoptModel(); 53304c9d578SStephan Aßmus break; 53404c9d578SStephan Aßmus } 53504c9d578SStephan Aßmus 536da651104SStephan Aßmus case MSG_PACKAGE_CHANGED: 53704c9d578SStephan Aßmus { 53804c9d578SStephan Aßmus PackageInfo* info; 53904c9d578SStephan Aßmus if (message->FindPointer("package", (void**)&info) == B_OK) { 54004c9d578SStephan Aßmus PackageInfoRef ref(info, true); 5410b69420bSAndrew Lindesay fFeaturedPackagesView->BeginAddRemove(); 542c4199192SAndrew Lindesay _AddRemovePackageFromLists(ref); 5430b69420bSAndrew Lindesay fFeaturedPackagesView->EndAddRemove(); 54410cd325cSAndrew Lindesay } 54504c9d578SStephan Aßmus break; 54604c9d578SStephan Aßmus } 54704c9d578SStephan Aßmus 54804c9d578SStephan Aßmus case MSG_RATE_PACKAGE: 5491bbda92dSStephan Aßmus _RatePackage(); 55004c9d578SStephan Aßmus break; 55104c9d578SStephan Aßmus 552d5ef985eSStephan Aßmus case MSG_SHOW_SCREENSHOT: 553d5ef985eSStephan Aßmus _ShowScreenshot(); 554d5ef985eSStephan Aßmus break; 555d5ef985eSStephan Aßmus 556125d42d9SJulian Harnath case MSG_PACKAGE_WORKER_BUSY: 557125d42d9SJulian Harnath { 558125d42d9SJulian Harnath BString reason; 559125d42d9SJulian Harnath status_t status = message->FindString("reason", &reason); 560125d42d9SJulian Harnath if (status != B_OK) 561125d42d9SJulian Harnath break; 562125d42d9SJulian Harnath fWorkStatusView->SetBusy(reason); 563125d42d9SJulian Harnath break; 564125d42d9SJulian Harnath } 565125d42d9SJulian Harnath 566125d42d9SJulian Harnath case MSG_PACKAGE_WORKER_IDLE: 567125d42d9SJulian Harnath fWorkStatusView->SetIdle(); 568125d42d9SJulian Harnath break; 569125d42d9SJulian Harnath 57010cd325cSAndrew Lindesay case MSG_USER_USAGE_CONDITIONS_NOT_LATEST: 57110cd325cSAndrew Lindesay { 57210cd325cSAndrew Lindesay BMessage userDetailMsg; 57310cd325cSAndrew Lindesay if (message->FindMessage("userDetail", &userDetailMsg) != B_OK) { 57410cd325cSAndrew Lindesay debugger("expected the [userDetail] data to be carried in the " 57510cd325cSAndrew Lindesay "message."); 57610cd325cSAndrew Lindesay } 57710cd325cSAndrew Lindesay UserDetail userDetail(&userDetailMsg); 57810cd325cSAndrew Lindesay _HandleUserUsageConditionsNotLatest(userDetail); 57910cd325cSAndrew Lindesay break; 58010cd325cSAndrew Lindesay } 58110cd325cSAndrew Lindesay 58204c9d578SStephan Aßmus default: 58304c9d578SStephan Aßmus BWindow::MessageReceived(message); 58404c9d578SStephan Aßmus break; 58504c9d578SStephan Aßmus } 58604c9d578SStephan Aßmus } 58704c9d578SStephan Aßmus 58804c9d578SStephan Aßmus 589ccf707d0SAndrew Lindesay static const char* 590ccf707d0SAndrew Lindesay main_window_package_list_view_mode_str(package_list_view_mode mode) 591ccf707d0SAndrew Lindesay { 592ccf707d0SAndrew Lindesay if (mode == PROMINENT) 593ccf707d0SAndrew Lindesay return "PROMINENT"; 594ccf707d0SAndrew Lindesay return "ALL"; 595ccf707d0SAndrew Lindesay } 596ccf707d0SAndrew Lindesay 597ccf707d0SAndrew Lindesay 598ccf707d0SAndrew Lindesay static package_list_view_mode 599ccf707d0SAndrew Lindesay main_window_str_to_package_list_view_mode(const BString& str) 600ccf707d0SAndrew Lindesay { 601ccf707d0SAndrew Lindesay if (str == "PROMINENT") 602ccf707d0SAndrew Lindesay return PROMINENT; 603ccf707d0SAndrew Lindesay return ALL; 604ccf707d0SAndrew Lindesay } 605ccf707d0SAndrew Lindesay 606ccf707d0SAndrew Lindesay 60704c9d578SStephan Aßmus void 60804c9d578SStephan Aßmus MainWindow::StoreSettings(BMessage& settings) const 60904c9d578SStephan Aßmus { 610f7c2983eSAxel Dörfler settings.AddRect(_WindowFrameName(), Frame()); 611f7c2983eSAxel Dörfler if (!fSinglePackageMode) { 61204c9d578SStephan Aßmus settings.AddRect("window frame", Frame()); 61304c9d578SStephan Aßmus 61404c9d578SStephan Aßmus BMessage columnSettings; 6159883929bSAndrew Lindesay if (fPackageListView != NULL) 61604c9d578SStephan Aßmus fPackageListView->SaveState(&columnSettings); 61704c9d578SStephan Aßmus 61804c9d578SStephan Aßmus settings.AddMessage("column settings", &columnSettings); 61904c9d578SStephan Aßmus 620133ebab6SAndrew Lindesay settings.AddString(SETTING_PACKAGE_LIST_VIEW_MODE, 621ccf707d0SAndrew Lindesay main_window_package_list_view_mode_str( 622ccf707d0SAndrew Lindesay fModel.PackageListViewMode())); 623133ebab6SAndrew Lindesay settings.AddBool(SETTING_SHOW_AVAILABLE_PACKAGES, 6242997e05bSStephan Aßmus fModel.ShowAvailablePackages()); 625133ebab6SAndrew Lindesay settings.AddBool(SETTING_SHOW_INSTALLED_PACKAGES, 6262997e05bSStephan Aßmus fModel.ShowInstalledPackages()); 627133ebab6SAndrew Lindesay settings.AddBool(SETTING_SHOW_DEVELOP_PACKAGES, 628133ebab6SAndrew Lindesay fModel.ShowDevelopPackages()); 629133ebab6SAndrew Lindesay settings.AddBool(SETTING_SHOW_SOURCE_PACKAGES, 630133ebab6SAndrew Lindesay fModel.ShowSourcePackages()); 631133ebab6SAndrew Lindesay settings.AddBool(SETTING_CAN_SHARE_ANONYMOUS_USER_DATA, 632133ebab6SAndrew Lindesay fModel.CanShareAnonymousUsageData()); 6336d519fd1SStephan Aßmus } 6348f03a0f9SStephan Aßmus 635d2d4866dSAndrew Lindesay settings.AddString("username", fModel.Nickname()); 63604c9d578SStephan Aßmus } 63704c9d578SStephan Aßmus 63804c9d578SStephan Aßmus 63904c9d578SStephan Aßmus void 640a18f873fSAndrew Lindesay MainWindow::Consume(ProcessCoordinator *item) 641a18f873fSAndrew Lindesay { 642a18f873fSAndrew Lindesay _AddProcessCoordinator(item); 643a18f873fSAndrew Lindesay } 644a18f873fSAndrew Lindesay 645a18f873fSAndrew Lindesay 646a18f873fSAndrew Lindesay void 64704c9d578SStephan Aßmus MainWindow::PackageChanged(const PackageInfoEvent& event) 64804c9d578SStephan Aßmus { 649a9edb9bfSAndrew Lindesay uint32 watchedChanges = PKG_CHANGED_STATE | PKG_CHANGED_PROMINENCE; 650a9edb9bfSAndrew Lindesay if ((event.Changes() & watchedChanges) != 0) { 65104c9d578SStephan Aßmus PackageInfoRef ref(event.Package()); 652da651104SStephan Aßmus BMessage message(MSG_PACKAGE_CHANGED); 65304c9d578SStephan Aßmus message.AddPointer("package", ref.Get()); 65404c9d578SStephan Aßmus ref.Detach(); 65504c9d578SStephan Aßmus // reference needs to be released by MessageReceived(); 65604c9d578SStephan Aßmus PostMessage(&message); 65704c9d578SStephan Aßmus } 65804c9d578SStephan Aßmus } 65904c9d578SStephan Aßmus 66004c9d578SStephan Aßmus 66104c9d578SStephan Aßmus void 66204c9d578SStephan Aßmus MainWindow::_BuildMenu(BMenuBar* menuBar) 66304c9d578SStephan Aßmus { 6640b6928f1SHumdinger BMenu* menu = new BMenu(B_TRANSLATE_SYSTEM_NAME("HaikuDepot")); 6653369e03dSAndrew Lindesay fRefreshRepositoriesItem = new BMenuItem( 6663369e03dSAndrew Lindesay B_TRANSLATE("Refresh repositories"), new BMessage(MSG_REFRESH_REPOS)); 6673369e03dSAndrew Lindesay menu->AddItem(fRefreshRepositoriesItem); 668d7f78130SHumdinger menu->AddItem(new BMenuItem(B_TRANSLATE("Manage repositories" 669d7f78130SHumdinger B_UTF8_ELLIPSIS), new BMessage(MSG_MANAGE_REPOS))); 670d144f952SAugustin Cavalier menu->AddItem(new BMenuItem(B_TRANSLATE("Check for updates" 671d144f952SAugustin Cavalier B_UTF8_ELLIPSIS), new BMessage(MSG_SOFTWARE_UPDATER))); 6720b6928f1SHumdinger menu->AddSeparatorItem(); 6730b6928f1SHumdinger menu->AddItem(new BMenuItem(B_TRANSLATE("Settings" B_UTF8_ELLIPSIS), 674e1ae57abSJoachim Mairböck new BMessage(MSG_SETTINGS), ',')); 6750b6928f1SHumdinger menu->AddItem(new BMenuItem(B_TRANSLATE("Quit"), 6760b6928f1SHumdinger new BMessage(B_QUIT_REQUESTED), 'Q')); 67704c9d578SStephan Aßmus menuBar->AddItem(menu); 67804c9d578SStephan Aßmus 679b965ce70SHumdinger fRepositoryMenu = new BMenu(B_TRANSLATE("Repositories")); 680b965ce70SHumdinger menuBar->AddItem(fRepositoryMenu); 681b965ce70SHumdinger 6824fade61fSStephan Aßmus menu = new BMenu(B_TRANSLATE("Show")); 6834fade61fSStephan Aßmus 684fdec4227SStephan Aßmus fShowAvailablePackagesItem = new BMenuItem( 6854fade61fSStephan Aßmus B_TRANSLATE("Available packages"), 686fdec4227SStephan Aßmus new BMessage(MSG_SHOW_AVAILABLE_PACKAGES)); 687fdec4227SStephan Aßmus menu->AddItem(fShowAvailablePackagesItem); 688fdec4227SStephan Aßmus 689fdec4227SStephan Aßmus fShowInstalledPackagesItem = new BMenuItem( 6904fade61fSStephan Aßmus B_TRANSLATE("Installed packages"), 691fdec4227SStephan Aßmus new BMessage(MSG_SHOW_INSTALLED_PACKAGES)); 692fdec4227SStephan Aßmus menu->AddItem(fShowInstalledPackagesItem); 693fdec4227SStephan Aßmus 694fdec4227SStephan Aßmus menu->AddSeparatorItem(); 695fdec4227SStephan Aßmus 696fdec4227SStephan Aßmus fShowDevelopPackagesItem = new BMenuItem( 6974fade61fSStephan Aßmus B_TRANSLATE("Develop packages"), 698fdec4227SStephan Aßmus new BMessage(MSG_SHOW_DEVELOP_PACKAGES)); 699fdec4227SStephan Aßmus menu->AddItem(fShowDevelopPackagesItem); 700fdec4227SStephan Aßmus 701fdec4227SStephan Aßmus fShowSourcePackagesItem = new BMenuItem( 7024fade61fSStephan Aßmus B_TRANSLATE("Source packages"), 703fdec4227SStephan Aßmus new BMessage(MSG_SHOW_SOURCE_PACKAGES)); 704fdec4227SStephan Aßmus menu->AddItem(fShowSourcePackagesItem); 705fdec4227SStephan Aßmus 706fdec4227SStephan Aßmus menuBar->AddItem(menu); 70704c9d578SStephan Aßmus } 70804c9d578SStephan Aßmus 70904c9d578SStephan Aßmus 71004c9d578SStephan Aßmus void 711e0a26dceSStephan Aßmus MainWindow::_BuildUserMenu(BMenuBar* menuBar) 712e0a26dceSStephan Aßmus { 713e0a26dceSStephan Aßmus fUserMenu = new BMenu(B_TRANSLATE("Not logged in")); 714e0a26dceSStephan Aßmus 715e0a26dceSStephan Aßmus fLogInItem = new BMenuItem(B_TRANSLATE("Log in" B_UTF8_ELLIPSIS), 716e0a26dceSStephan Aßmus new BMessage(MSG_LOG_IN)); 717e0a26dceSStephan Aßmus fUserMenu->AddItem(fLogInItem); 718e0a26dceSStephan Aßmus 719e0a26dceSStephan Aßmus fLogOutItem = new BMenuItem(B_TRANSLATE("Log out"), 720e0a26dceSStephan Aßmus new BMessage(MSG_LOG_OUT)); 721e0a26dceSStephan Aßmus fUserMenu->AddItem(fLogOutItem); 722e0a26dceSStephan Aßmus 7230c82f64bSAndrew Lindesay BMenuItem *latestUserUsageConditionsMenuItem = 7241448ced0SHumdinger new BMenuItem(B_TRANSLATE("View latest usage conditions" 72501339a54SAndrew Lindesay B_UTF8_ELLIPSIS), 72601339a54SAndrew Lindesay new BMessage(MSG_VIEW_LATEST_USER_USAGE_CONDITIONS)); 7270c82f64bSAndrew Lindesay fUserMenu->AddItem(latestUserUsageConditionsMenuItem); 72801339a54SAndrew Lindesay 729d2d4866dSAndrew Lindesay fUsersUserUsageConditionsMenuItem = 730d2d4866dSAndrew Lindesay new BMenuItem(B_TRANSLATE("View agreed usage conditions" 731d2d4866dSAndrew Lindesay B_UTF8_ELLIPSIS), 732d2d4866dSAndrew Lindesay new BMessage(MSG_VIEW_USERS_USER_USAGE_CONDITIONS)); 733d2d4866dSAndrew Lindesay fUserMenu->AddItem(fUsersUserUsageConditionsMenuItem); 734d2d4866dSAndrew Lindesay 735e0a26dceSStephan Aßmus menuBar->AddItem(fUserMenu); 736e0a26dceSStephan Aßmus } 737e0a26dceSStephan Aßmus 738e0a26dceSStephan Aßmus 739e0a26dceSStephan Aßmus void 740d2d4866dSAndrew Lindesay MainWindow::_RestoreNickname(const BMessage& settings) 741f7c2983eSAxel Dörfler { 742d2d4866dSAndrew Lindesay BString nickname; 743d2d4866dSAndrew Lindesay if (settings.FindString("username", &nickname) == B_OK 744d2d4866dSAndrew Lindesay && nickname.Length() > 0) { 745d2d4866dSAndrew Lindesay fModel.SetNickname(nickname); 746f7c2983eSAxel Dörfler } 747f7c2983eSAxel Dörfler } 748f7c2983eSAxel Dörfler 749f7c2983eSAxel Dörfler 750f7c2983eSAxel Dörfler const char* 751f7c2983eSAxel Dörfler MainWindow::_WindowFrameName() const 752f7c2983eSAxel Dörfler { 753f7c2983eSAxel Dörfler if (fSinglePackageMode) 754f7c2983eSAxel Dörfler return "small window frame"; 755f7c2983eSAxel Dörfler 756f7c2983eSAxel Dörfler return "window frame"; 757f7c2983eSAxel Dörfler } 758f7c2983eSAxel Dörfler 759f7c2983eSAxel Dörfler 760f7c2983eSAxel Dörfler void 761f7c2983eSAxel Dörfler MainWindow::_RestoreWindowFrame(const BMessage& settings) 762f7c2983eSAxel Dörfler { 763f7c2983eSAxel Dörfler BRect frame = Frame(); 764f7c2983eSAxel Dörfler 765f7c2983eSAxel Dörfler BRect windowFrame; 766f7c2983eSAxel Dörfler bool fromSettings = false; 767f7c2983eSAxel Dörfler if (settings.FindRect(_WindowFrameName(), &windowFrame) == B_OK) { 768f7c2983eSAxel Dörfler frame = windowFrame; 769f7c2983eSAxel Dörfler fromSettings = true; 770f7c2983eSAxel Dörfler } else if (!fSinglePackageMode) { 771f7c2983eSAxel Dörfler // Resize to occupy a certain screen size 772f7c2983eSAxel Dörfler BRect screenFrame = BScreen(this).Frame(); 773f7c2983eSAxel Dörfler float width = frame.Width(); 774f7c2983eSAxel Dörfler float height = frame.Height(); 775f7c2983eSAxel Dörfler if (width < screenFrame.Width() * .666f 776f7c2983eSAxel Dörfler && height < screenFrame.Height() * .666f) { 777f7c2983eSAxel Dörfler frame.bottom = frame.top + screenFrame.Height() * .666f; 778f7c2983eSAxel Dörfler frame.right = frame.left 779f7c2983eSAxel Dörfler + std::min(screenFrame.Width() * .666f, height * 7 / 5); 780f7c2983eSAxel Dörfler } 781f7c2983eSAxel Dörfler } 782f7c2983eSAxel Dörfler 783f7c2983eSAxel Dörfler MoveTo(frame.LeftTop()); 784f7c2983eSAxel Dörfler ResizeTo(frame.Width(), frame.Height()); 785f7c2983eSAxel Dörfler 786f7c2983eSAxel Dörfler if (fromSettings) 7878e96ec34SAxel Dörfler MoveOnScreen(); 788f7c2983eSAxel Dörfler else 789f7c2983eSAxel Dörfler CenterOnScreen(); 790f7c2983eSAxel Dörfler } 791f7c2983eSAxel Dörfler 792f7c2983eSAxel Dörfler 793f7c2983eSAxel Dörfler void 794ccf707d0SAndrew Lindesay MainWindow::_RestoreModelSettings(const BMessage& settings) 795ccf707d0SAndrew Lindesay { 796ccf707d0SAndrew Lindesay BString packageListViewMode; 797133ebab6SAndrew Lindesay if (settings.FindString(SETTING_PACKAGE_LIST_VIEW_MODE, 798ccf707d0SAndrew Lindesay &packageListViewMode) == B_OK) { 799ccf707d0SAndrew Lindesay fModel.SetPackageListViewMode( 800ccf707d0SAndrew Lindesay main_window_str_to_package_list_view_mode(packageListViewMode)); 801ccf707d0SAndrew Lindesay } 802ccf707d0SAndrew Lindesay 803ccf707d0SAndrew Lindesay bool showOption; 804133ebab6SAndrew Lindesay if (settings.FindBool(SETTING_SHOW_AVAILABLE_PACKAGES, &showOption) == B_OK) 805ccf707d0SAndrew Lindesay fModel.SetShowAvailablePackages(showOption); 806133ebab6SAndrew Lindesay if (settings.FindBool(SETTING_SHOW_INSTALLED_PACKAGES, &showOption) == B_OK) 807ccf707d0SAndrew Lindesay fModel.SetShowInstalledPackages(showOption); 808133ebab6SAndrew Lindesay if (settings.FindBool(SETTING_SHOW_DEVELOP_PACKAGES, &showOption) == B_OK) 809ccf707d0SAndrew Lindesay fModel.SetShowDevelopPackages(showOption); 810133ebab6SAndrew Lindesay if (settings.FindBool(SETTING_SHOW_SOURCE_PACKAGES, &showOption) == B_OK) 811ccf707d0SAndrew Lindesay fModel.SetShowSourcePackages(showOption); 812133ebab6SAndrew Lindesay if (settings.FindBool(SETTING_CAN_SHARE_ANONYMOUS_USER_DATA, 813133ebab6SAndrew Lindesay &showOption) == B_OK) { 814133ebab6SAndrew Lindesay fModel.SetCanShareAnonymousUsageData(showOption); 815133ebab6SAndrew Lindesay } 816133ebab6SAndrew Lindesay } 817133ebab6SAndrew Lindesay 818133ebab6SAndrew Lindesay 819133ebab6SAndrew Lindesay void 820133ebab6SAndrew Lindesay MainWindow::_MaybePromptCanShareAnonymousUserData(const BMessage& settings) 821133ebab6SAndrew Lindesay { 822133ebab6SAndrew Lindesay bool showOption; 823133ebab6SAndrew Lindesay if (settings.FindBool(SETTING_CAN_SHARE_ANONYMOUS_USER_DATA, 824133ebab6SAndrew Lindesay &showOption) == B_NAME_NOT_FOUND) { 825133ebab6SAndrew Lindesay _PromptCanShareAnonymousUserData(); 826133ebab6SAndrew Lindesay } 827133ebab6SAndrew Lindesay } 828133ebab6SAndrew Lindesay 829133ebab6SAndrew Lindesay 830133ebab6SAndrew Lindesay void 831133ebab6SAndrew Lindesay MainWindow::_PromptCanShareAnonymousUserData() 832133ebab6SAndrew Lindesay { 833133ebab6SAndrew Lindesay BAlert* alert = new(std::nothrow) BAlert( 834133ebab6SAndrew Lindesay B_TRANSLATE("Sending anonymous usage data"), 835133ebab6SAndrew Lindesay B_TRANSLATE("Would it be acceptable to send anonymous usage data to the" 836133ebab6SAndrew Lindesay " HaikuDepotServer system from this computer? You can change your" 837133ebab6SAndrew Lindesay " preference in the \"Settings\" window later."), 838133ebab6SAndrew Lindesay B_TRANSLATE("No"), 839133ebab6SAndrew Lindesay B_TRANSLATE("Yes")); 840133ebab6SAndrew Lindesay 841133ebab6SAndrew Lindesay int32 result = alert->Go(); 842133ebab6SAndrew Lindesay fModel.SetCanShareAnonymousUsageData(1 == result); 843ccf707d0SAndrew Lindesay } 844ccf707d0SAndrew Lindesay 845ccf707d0SAndrew Lindesay 846ccf707d0SAndrew Lindesay void 84763975654SStephan Aßmus MainWindow::_InitWorkerThreads() 84863975654SStephan Aßmus { 84963975654SStephan Aßmus fPackageToPopulateSem = create_sem(0, "PopulatePackage"); 85063975654SStephan Aßmus if (fPackageToPopulateSem >= 0) { 85163975654SStephan Aßmus fPopulatePackageWorker = spawn_thread(&_PopulatePackageWorker, 85263975654SStephan Aßmus "Package Populator", B_NORMAL_PRIORITY, this); 85363975654SStephan Aßmus if (fPopulatePackageWorker >= 0) 85463975654SStephan Aßmus resume_thread(fPopulatePackageWorker); 85509f82905SStephan Aßmus } else 85609f82905SStephan Aßmus fPopulatePackageWorker = -1; 85763975654SStephan Aßmus } 85863975654SStephan Aßmus 85963975654SStephan Aßmus 86063975654SStephan Aßmus void 861c4199192SAndrew Lindesay MainWindow::_AdoptModelControls() 86204c9d578SStephan Aßmus { 8639883929bSAndrew Lindesay if (fSinglePackageMode) 8649883929bSAndrew Lindesay return; 8659883929bSAndrew Lindesay 86604c9d578SStephan Aßmus BAutolock locker(fModel.Lock()); 867fdec4227SStephan Aßmus fShowAvailablePackagesItem->SetMarked(fModel.ShowAvailablePackages()); 868fdec4227SStephan Aßmus fShowInstalledPackagesItem->SetMarked(fModel.ShowInstalledPackages()); 869fdec4227SStephan Aßmus fShowSourcePackagesItem->SetMarked(fModel.ShowSourcePackages()); 870fdec4227SStephan Aßmus fShowDevelopPackagesItem->SetMarked(fModel.ShowDevelopPackages()); 871da651104SStephan Aßmus 872ccf707d0SAndrew Lindesay if (fModel.PackageListViewMode() == PROMINENT) 873ccf707d0SAndrew Lindesay fListTabs->Select(TAB_PROMINENT_PACKAGES); 8744fade61fSStephan Aßmus else 875ccf707d0SAndrew Lindesay fListTabs->Select(TAB_ALL_PACKAGES); 876b965ce70SHumdinger 877b965ce70SHumdinger fFilterView->AdoptModel(fModel); 87804c9d578SStephan Aßmus } 87904c9d578SStephan Aßmus 88004c9d578SStephan Aßmus 88104c9d578SStephan Aßmus void 882c4199192SAndrew Lindesay MainWindow::_AdoptModel() 883c4199192SAndrew Lindesay { 884fa5c8097SAndrew Lindesay HDTRACE("adopting model to main window ui"); 885c4199192SAndrew Lindesay 886c4199192SAndrew Lindesay if (fSinglePackageMode) 887c4199192SAndrew Lindesay return; 888c4199192SAndrew Lindesay 88905880d13SAndrew Lindesay std::vector<DepotInfoRef> depots = _CreateSnapshotOfDepots(); 89005880d13SAndrew Lindesay std::vector<DepotInfoRef>::iterator it; 8910b69420bSAndrew Lindesay 8920b69420bSAndrew Lindesay fFeaturedPackagesView->BeginAddRemove(); 8930b69420bSAndrew Lindesay 89405880d13SAndrew Lindesay for (it = depots.begin(); it != depots.end(); it++) { 89505880d13SAndrew Lindesay DepotInfoRef depotInfoRef = *it; 896d75b4d61SAndrew Lindesay for (int i = 0; i < depotInfoRef->CountPackages(); i++) { 897d75b4d61SAndrew Lindesay PackageInfoRef package = depotInfoRef->PackageAtIndex(i); 898d75b4d61SAndrew Lindesay _AddRemovePackageFromLists(package); 899d75b4d61SAndrew Lindesay } 900c4199192SAndrew Lindesay } 901c4199192SAndrew Lindesay 9020b69420bSAndrew Lindesay fFeaturedPackagesView->EndAddRemove(); 9030b69420bSAndrew Lindesay 904c4199192SAndrew Lindesay _AdoptModelControls(); 905c4199192SAndrew Lindesay } 906c4199192SAndrew Lindesay 907c4199192SAndrew Lindesay 908c4199192SAndrew Lindesay void 909c4199192SAndrew Lindesay MainWindow::_AddRemovePackageFromLists(const PackageInfoRef& package) 910c4199192SAndrew Lindesay { 911c4199192SAndrew Lindesay bool matches; 912c4199192SAndrew Lindesay 913c4199192SAndrew Lindesay { 914c4199192SAndrew Lindesay AutoLocker<BLocker> modelLocker(fModel.Lock()); 915c4199192SAndrew Lindesay matches = fModel.MatchesFilter(package); 916c4199192SAndrew Lindesay } 917c4199192SAndrew Lindesay 918c4199192SAndrew Lindesay if (matches) { 919c4199192SAndrew Lindesay if (package->IsProminent()) 920c4199192SAndrew Lindesay fFeaturedPackagesView->AddPackage(package); 921c4199192SAndrew Lindesay fPackageListView->AddPackage(package); 922c4199192SAndrew Lindesay } else { 923c4199192SAndrew Lindesay fFeaturedPackagesView->RemovePackage(package); 924c4199192SAndrew Lindesay fPackageListView->RemovePackage(package); 925c4199192SAndrew Lindesay } 926c4199192SAndrew Lindesay } 927c4199192SAndrew Lindesay 928c4199192SAndrew Lindesay 929c4199192SAndrew Lindesay void 930133ebab6SAndrew Lindesay MainWindow::_IncrementViewCounter(const PackageInfoRef& package) 931133ebab6SAndrew Lindesay { 932*467ffecdSAugustin Cavalier // Temporarily disabled, see tickets #16879 and #17689. 933*467ffecdSAugustin Cavalier #if 0 934133ebab6SAndrew Lindesay bool shouldIncrementViewCounter = false; 935133ebab6SAndrew Lindesay 936133ebab6SAndrew Lindesay { 937133ebab6SAndrew Lindesay AutoLocker<BLocker> modelLocker(fModel.Lock()); 938133ebab6SAndrew Lindesay bool canShareAnonymousUsageData = fModel.CanShareAnonymousUsageData(); 939133ebab6SAndrew Lindesay if (canShareAnonymousUsageData && !package->Viewed()) { 940133ebab6SAndrew Lindesay package->SetViewed(); 941133ebab6SAndrew Lindesay shouldIncrementViewCounter = true; 942133ebab6SAndrew Lindesay } 943133ebab6SAndrew Lindesay } 944133ebab6SAndrew Lindesay 945133ebab6SAndrew Lindesay if (shouldIncrementViewCounter) { 946*467ffecdSAugustin Cavalier ProcessCoordinator* incrementViewCoordinator = 947133ebab6SAndrew Lindesay ProcessCoordinatorFactory::CreateIncrementViewCounter( 948133ebab6SAndrew Lindesay &fModel, package); 949*467ffecdSAugustin Cavalier _AddProcessCoordinator(incrementViewCoordinator); 950133ebab6SAndrew Lindesay } 951*467ffecdSAugustin Cavalier #endif 952133ebab6SAndrew Lindesay } 953133ebab6SAndrew Lindesay 954133ebab6SAndrew Lindesay 955133ebab6SAndrew Lindesay void 95604c9d578SStephan Aßmus MainWindow::_AdoptPackage(const PackageInfoRef& package) 95704c9d578SStephan Aßmus { 95875ba9dbfSStephan Aßmus { 95975ba9dbfSStephan Aßmus BAutolock locker(fModel.Lock()); 96004c9d578SStephan Aßmus fPackageInfoView->SetPackage(package); 9611986ab9fSStephan Aßmus 962664372abSStephan Aßmus if (fFeaturedPackagesView != NULL) 963664372abSStephan Aßmus fFeaturedPackagesView->SelectPackage(package); 9641986ab9fSStephan Aßmus if (fPackageListView != NULL) 9651986ab9fSStephan Aßmus fPackageListView->SelectPackage(package); 96675ba9dbfSStephan Aßmus } 96704c9d578SStephan Aßmus 968a9edb9bfSAndrew Lindesay _PopulatePackageAsync(false); 96904c9d578SStephan Aßmus } 97004c9d578SStephan Aßmus 97104c9d578SStephan Aßmus 97204c9d578SStephan Aßmus void 97304c9d578SStephan Aßmus MainWindow::_ClearPackage() 97404c9d578SStephan Aßmus { 97504c9d578SStephan Aßmus fPackageInfoView->Clear(); 97604c9d578SStephan Aßmus } 97704c9d578SStephan Aßmus 97804c9d578SStephan Aßmus 97904c9d578SStephan Aßmus void 9803369e03dSAndrew Lindesay MainWindow::_StartBulkLoad(bool force) 98104c9d578SStephan Aßmus { 982c4199192SAndrew Lindesay if (fFeaturedPackagesView != NULL) 983c4199192SAndrew Lindesay fFeaturedPackagesView->Clear(); 984c4199192SAndrew Lindesay if (fPackageListView != NULL) 985c4199192SAndrew Lindesay fPackageListView->Clear(); 986c4199192SAndrew Lindesay fPackageInfoView->Clear(); 987c4199192SAndrew Lindesay 98810cd325cSAndrew Lindesay fRefreshRepositoriesItem->SetEnabled(false); 98910cd325cSAndrew Lindesay ProcessCoordinator* bulkLoadCoordinator = 99010cd325cSAndrew Lindesay ProcessCoordinatorFactory::CreateBulkLoadCoordinator( 9913369e03dSAndrew Lindesay this, 9923369e03dSAndrew Lindesay // PackageInfoListener 9933369e03dSAndrew Lindesay &fModel, force); 99410cd325cSAndrew Lindesay _AddProcessCoordinator(bulkLoadCoordinator); 99504c9d578SStephan Aßmus } 99604c9d578SStephan Aßmus 99704c9d578SStephan Aßmus 99804c9d578SStephan Aßmus void 99910cd325cSAndrew Lindesay MainWindow::_BulkLoadCompleteReceived(status_t errorStatus) 100004c9d578SStephan Aßmus { 100110cd325cSAndrew Lindesay if (errorStatus != B_OK) { 10023369e03dSAndrew Lindesay AppUtils::NotifySimpleError( 10031448ced0SHumdinger B_TRANSLATE("Package update error"), 10043369e03dSAndrew Lindesay B_TRANSLATE("While updating package data, a problem has arisen " 10053369e03dSAndrew Lindesay "that may cause data to be outdated or missing from the " 10063369e03dSAndrew Lindesay "application's display. Additional details regarding this " 10073369e03dSAndrew Lindesay "problem may be able to be obtained from the application " 1008b21c9447SAndrew Lindesay "logs." 1009b21c9447SAndrew Lindesay ALERT_MSG_LOGS_USER_GUIDE)); 101004c9d578SStephan Aßmus } 101110cd325cSAndrew Lindesay 10123369e03dSAndrew Lindesay fRefreshRepositoriesItem->SetEnabled(true); 101310cd325cSAndrew Lindesay _AdoptModel(); 101410cd325cSAndrew Lindesay _UpdateAvailableRepositories(); 1015ccf707d0SAndrew Lindesay 1016ccf707d0SAndrew Lindesay // if after loading everything in, it transpires that there are no 1017ccf707d0SAndrew Lindesay // featured packages then the featured packages should be disabled 1018ccf707d0SAndrew Lindesay // and the user should be switched to the "all packages" view so 1019ccf707d0SAndrew Lindesay // that they are not presented with a blank window! 1020ccf707d0SAndrew Lindesay 1021ccf707d0SAndrew Lindesay bool hasProminentPackages = fModel.HasAnyProminentPackages(); 1022ccf707d0SAndrew Lindesay fListTabs->TabAt(TAB_PROMINENT_PACKAGES)->SetEnabled(hasProminentPackages); 1023ccf707d0SAndrew Lindesay if (!hasProminentPackages 1024ccf707d0SAndrew Lindesay && fListTabs->Selection() == TAB_PROMINENT_PACKAGES) { 1025ccf707d0SAndrew Lindesay fModel.SetPackageListViewMode(ALL); 1026ccf707d0SAndrew Lindesay fListTabs->Select(TAB_ALL_PACKAGES); 1027ccf707d0SAndrew Lindesay } 102804c9d578SStephan Aßmus } 102904c9d578SStephan Aßmus 103004c9d578SStephan Aßmus 10313369e03dSAndrew Lindesay void 103210cd325cSAndrew Lindesay MainWindow::_NotifyWorkStatusClear() 103304c9d578SStephan Aßmus { 103410cd325cSAndrew Lindesay BMessage message(MSG_WORK_STATUS_CLEAR); 103510cd325cSAndrew Lindesay this->PostMessage(&message, this); 103610cd325cSAndrew Lindesay } 103710cd325cSAndrew Lindesay 103810cd325cSAndrew Lindesay 103910cd325cSAndrew Lindesay void 104010cd325cSAndrew Lindesay MainWindow::_HandleWorkStatusClear() 104110cd325cSAndrew Lindesay { 104210cd325cSAndrew Lindesay fWorkStatusView->SetText(""); 10433369e03dSAndrew Lindesay fWorkStatusView->SetIdle(); 10443369e03dSAndrew Lindesay } 104504c9d578SStephan Aßmus 104604c9d578SStephan Aßmus 10473369e03dSAndrew Lindesay /*! Sends off a message to the Window so that it can change the status view 10483369e03dSAndrew Lindesay on the front-end in the UI thread. 10493369e03dSAndrew Lindesay */ 105004c9d578SStephan Aßmus 10513369e03dSAndrew Lindesay void 10523369e03dSAndrew Lindesay MainWindow::_NotifyWorkStatusChange(const BString& text, float progress) 10533369e03dSAndrew Lindesay { 10543369e03dSAndrew Lindesay BMessage message(MSG_WORK_STATUS_CHANGE); 105504c9d578SStephan Aßmus 10563369e03dSAndrew Lindesay if (!text.IsEmpty()) 10573369e03dSAndrew Lindesay message.AddString(KEY_WORK_STATUS_TEXT, text); 10583369e03dSAndrew Lindesay message.AddFloat(KEY_WORK_STATUS_PROGRESS, progress); 105904c9d578SStephan Aßmus 10603369e03dSAndrew Lindesay this->PostMessage(&message, this); 10613369e03dSAndrew Lindesay } 106204c9d578SStephan Aßmus 10633369e03dSAndrew Lindesay 1064f32d5c5cSAndrew Lindesay void 1065f32d5c5cSAndrew Lindesay MainWindow::_HandleExternalPackageUpdateMessageReceived(const BMessage* message) 1066f32d5c5cSAndrew Lindesay { 1067f32d5c5cSAndrew Lindesay BStringList addedPackageNames; 1068f32d5c5cSAndrew Lindesay BStringList removedPackageNames; 1069f32d5c5cSAndrew Lindesay 1070f32d5c5cSAndrew Lindesay if (message->FindStrings("added package names", 1071f32d5c5cSAndrew Lindesay &addedPackageNames) == B_OK) { 1072f32d5c5cSAndrew Lindesay addedPackageNames.Sort(); 10730ebb9177SAndrew Lindesay AutoLocker<BLocker> locker(fModel.Lock()); 10740ebb9177SAndrew Lindesay fModel.SetStateForPackagesByName(addedPackageNames, ACTIVATED); 1075f32d5c5cSAndrew Lindesay } 1076f32d5c5cSAndrew Lindesay else 1077f32d5c5cSAndrew Lindesay HDINFO("no [added package names] key in inbound message"); 1078f32d5c5cSAndrew Lindesay 1079f32d5c5cSAndrew Lindesay if (message->FindStrings("removed package names", 1080f32d5c5cSAndrew Lindesay &removedPackageNames) == B_OK) { 1081f32d5c5cSAndrew Lindesay removedPackageNames.Sort(); 10820ebb9177SAndrew Lindesay AutoLocker<BLocker> locker(fModel.Lock()); 10830ebb9177SAndrew Lindesay fModel.SetStateForPackagesByName(addedPackageNames, UNINSTALLED); 1084f32d5c5cSAndrew Lindesay } else 1085f32d5c5cSAndrew Lindesay HDINFO("no [removed package names] key in inbound message"); 1086f32d5c5cSAndrew Lindesay } 1087f32d5c5cSAndrew Lindesay 1088f32d5c5cSAndrew Lindesay 10893369e03dSAndrew Lindesay void 10903369e03dSAndrew Lindesay MainWindow::_HandleWorkStatusChangeMessageReceived(const BMessage* message) 10913369e03dSAndrew Lindesay { 10929883929bSAndrew Lindesay if (fWorkStatusView == NULL) 10939883929bSAndrew Lindesay return; 10949883929bSAndrew Lindesay 10953369e03dSAndrew Lindesay BString text; 10963369e03dSAndrew Lindesay float progress; 10973369e03dSAndrew Lindesay 10983369e03dSAndrew Lindesay if (message->FindString(KEY_WORK_STATUS_TEXT, &text) == B_OK) 10993369e03dSAndrew Lindesay fWorkStatusView->SetText(text); 11003369e03dSAndrew Lindesay 1101a18f873fSAndrew Lindesay if (message->FindFloat(KEY_WORK_STATUS_PROGRESS, &progress) == B_OK) { 1102a18f873fSAndrew Lindesay if (progress < 0.0f) 1103a18f873fSAndrew Lindesay fWorkStatusView->SetBusy(); 1104a18f873fSAndrew Lindesay else 11053369e03dSAndrew Lindesay fWorkStatusView->SetProgress(progress); 1106a18f873fSAndrew Lindesay } else { 1107a18f873fSAndrew Lindesay HDERROR("work status change missing progress on update message"); 1108a18f873fSAndrew Lindesay fWorkStatusView->SetProgress(0.0f); 110904c9d578SStephan Aßmus } 111004c9d578SStephan Aßmus } 111104c9d578SStephan Aßmus 111204c9d578SStephan Aßmus 1113a9edb9bfSAndrew Lindesay /*! This method will cause the package to have its data refreshed from 1114a9edb9bfSAndrew Lindesay the server application. The refresh happens in the background; this method 1115a9edb9bfSAndrew Lindesay is asynchronous. 1116a9edb9bfSAndrew Lindesay */ 1117a9edb9bfSAndrew Lindesay 1118a9edb9bfSAndrew Lindesay void 1119a9edb9bfSAndrew Lindesay MainWindow::_PopulatePackageAsync(bool forcePopulate) 1120a9edb9bfSAndrew Lindesay { 1121a9edb9bfSAndrew Lindesay // Trigger asynchronous package population from the web-app 1122a9edb9bfSAndrew Lindesay { 1123a9edb9bfSAndrew Lindesay AutoLocker<BLocker> lock(&fPackageToPopulateLock); 1124a9edb9bfSAndrew Lindesay fPackageToPopulate = fPackageInfoView->Package(); 1125a9edb9bfSAndrew Lindesay fForcePopulatePackage = forcePopulate; 1126a9edb9bfSAndrew Lindesay } 1127a9edb9bfSAndrew Lindesay release_sem_etc(fPackageToPopulateSem, 1, 0); 1128a9edb9bfSAndrew Lindesay 1129f96d1f4dSAndrew Lindesay HDDEBUG("pkg [%s] will be updated from the server.", 1130fa5c8097SAndrew Lindesay fPackageToPopulate->Name().String()); 1131a9edb9bfSAndrew Lindesay } 1132a9edb9bfSAndrew Lindesay 1133a9edb9bfSAndrew Lindesay 1134a9edb9bfSAndrew Lindesay /*! This method will run in the background. The thread will block until there 1135a9edb9bfSAndrew Lindesay is a package to be updated. When the thread unblocks, it will update the 1136a9edb9bfSAndrew Lindesay package with information from the server. 1137a9edb9bfSAndrew Lindesay */ 1138a9edb9bfSAndrew Lindesay 113904c9d578SStephan Aßmus status_t 114004c9d578SStephan Aßmus MainWindow::_PopulatePackageWorker(void* arg) 114104c9d578SStephan Aßmus { 114204c9d578SStephan Aßmus MainWindow* window = reinterpret_cast<MainWindow*>(arg); 114304c9d578SStephan Aßmus 114404c9d578SStephan Aßmus while (acquire_sem(window->fPackageToPopulateSem) == B_OK) { 114504c9d578SStephan Aßmus PackageInfoRef package; 1146a9edb9bfSAndrew Lindesay bool force; 114704c9d578SStephan Aßmus { 114804c9d578SStephan Aßmus AutoLocker<BLocker> lock(&window->fPackageToPopulateLock); 114904c9d578SStephan Aßmus package = window->fPackageToPopulate; 1150a9edb9bfSAndrew Lindesay force = window->fForcePopulatePackage; 115104c9d578SStephan Aßmus } 115204c9d578SStephan Aßmus 1153779ab335SX512 if (package.IsSet()) { 1154a9edb9bfSAndrew Lindesay uint32 populateFlags = Model::POPULATE_USER_RATINGS 1155a9edb9bfSAndrew Lindesay | Model::POPULATE_SCREEN_SHOTS 1156a9edb9bfSAndrew Lindesay | Model::POPULATE_CHANGELOG; 1157a9edb9bfSAndrew Lindesay 1158a9edb9bfSAndrew Lindesay if (force) 1159a9edb9bfSAndrew Lindesay populateFlags |= Model::POPULATE_FORCE; 1160a9edb9bfSAndrew Lindesay 1161a9edb9bfSAndrew Lindesay window->fModel.PopulatePackage(package, populateFlags); 1162a9edb9bfSAndrew Lindesay 1163fa5c8097SAndrew Lindesay HDDEBUG("populating package [%s]", package->Name().String()); 116404c9d578SStephan Aßmus } 116504c9d578SStephan Aßmus } 116604c9d578SStephan Aßmus 116704c9d578SStephan Aßmus return 0; 116804c9d578SStephan Aßmus } 116904c9d578SStephan Aßmus 117004c9d578SStephan Aßmus 117104c9d578SStephan Aßmus void 1172133ebab6SAndrew Lindesay MainWindow::_OpenSettingsWindow() 1173133ebab6SAndrew Lindesay { 1174133ebab6SAndrew Lindesay SettingsWindow* window = new SettingsWindow(this, &fModel); 1175133ebab6SAndrew Lindesay window->Show(); 1176133ebab6SAndrew Lindesay } 1177133ebab6SAndrew Lindesay 1178133ebab6SAndrew Lindesay 1179133ebab6SAndrew Lindesay void 11801bbda92dSStephan Aßmus MainWindow::_OpenLoginWindow(const BMessage& onSuccessMessage) 118104c9d578SStephan Aßmus { 118204c9d578SStephan Aßmus UserLoginWindow* window = new UserLoginWindow(this, 118304c9d578SStephan Aßmus BRect(0, 0, 500, 400), fModel); 11841bbda92dSStephan Aßmus 11851bbda92dSStephan Aßmus if (onSuccessMessage.what != 0) 11861bbda92dSStephan Aßmus window->SetOnSuccessMessage(BMessenger(this), onSuccessMessage); 11871bbda92dSStephan Aßmus 118804c9d578SStephan Aßmus window->Show(); 118904c9d578SStephan Aßmus } 119004c9d578SStephan Aßmus 11918f03a0f9SStephan Aßmus 11928f03a0f9SStephan Aßmus void 119310cd325cSAndrew Lindesay MainWindow::_StartUserVerify() 119410cd325cSAndrew Lindesay { 119510cd325cSAndrew Lindesay if (!fModel.Nickname().IsEmpty()) { 119610cd325cSAndrew Lindesay _AddProcessCoordinator( 119710cd325cSAndrew Lindesay ProcessCoordinatorFactory::CreateUserDetailVerifierCoordinator( 119810cd325cSAndrew Lindesay this, 119910cd325cSAndrew Lindesay // UserDetailVerifierListener 120010cd325cSAndrew Lindesay &fModel) ); 120110cd325cSAndrew Lindesay } 120210cd325cSAndrew Lindesay } 120310cd325cSAndrew Lindesay 120410cd325cSAndrew Lindesay 120510cd325cSAndrew Lindesay void 12068f03a0f9SStephan Aßmus MainWindow::_UpdateAuthorization() 12078f03a0f9SStephan Aßmus { 1208d2d4866dSAndrew Lindesay BString nickname(fModel.Nickname()); 1209d2d4866dSAndrew Lindesay bool hasUser = !nickname.IsEmpty(); 1210e0a26dceSStephan Aßmus 12116d519fd1SStephan Aßmus if (fLogOutItem != NULL) 1212e0a26dceSStephan Aßmus fLogOutItem->SetEnabled(hasUser); 1213d2d4866dSAndrew Lindesay if (fUsersUserUsageConditionsMenuItem != NULL) 1214d2d4866dSAndrew Lindesay fUsersUserUsageConditionsMenuItem->SetEnabled(hasUser); 1215e0a26dceSStephan Aßmus if (fLogInItem != NULL) { 1216e0a26dceSStephan Aßmus if (hasUser) 1217e0a26dceSStephan Aßmus fLogInItem->SetLabel(B_TRANSLATE("Switch account" B_UTF8_ELLIPSIS)); 1218e0a26dceSStephan Aßmus else 1219e0a26dceSStephan Aßmus fLogInItem->SetLabel(B_TRANSLATE("Log in" B_UTF8_ELLIPSIS)); 1220e0a26dceSStephan Aßmus } 1221e0a26dceSStephan Aßmus 1222e0a26dceSStephan Aßmus if (fUserMenu != NULL) { 1223e0a26dceSStephan Aßmus BString label; 1224d2d4866dSAndrew Lindesay if (hasUser) { 1225e0a26dceSStephan Aßmus label = B_TRANSLATE("Logged in as %User%"); 1226d2d4866dSAndrew Lindesay label.ReplaceAll("%User%", nickname); 1227d2d4866dSAndrew Lindesay } else { 1228d2d4866dSAndrew Lindesay label = B_TRANSLATE("Not logged in"); 1229e0a26dceSStephan Aßmus } 1230e0a26dceSStephan Aßmus fUserMenu->Superitem()->SetLabel(label); 1231e0a26dceSStephan Aßmus } 12328f03a0f9SStephan Aßmus } 12331bbda92dSStephan Aßmus 12341bbda92dSStephan Aßmus 12351bbda92dSStephan Aßmus void 1236b965ce70SHumdinger MainWindow::_UpdateAvailableRepositories() 1237b965ce70SHumdinger { 1238b965ce70SHumdinger fRepositoryMenu->RemoveItems(0, fRepositoryMenu->CountItems(), true); 1239b965ce70SHumdinger 1240b965ce70SHumdinger fRepositoryMenu->AddItem(new BMenuItem(B_TRANSLATE("All repositories"), 1241b965ce70SHumdinger new BMessage(MSG_DEPOT_SELECTED))); 1242b965ce70SHumdinger 1243b965ce70SHumdinger fRepositoryMenu->AddItem(new BSeparatorItem()); 1244b965ce70SHumdinger 1245b965ce70SHumdinger bool foundSelectedDepot = false; 124605880d13SAndrew Lindesay std::vector<DepotInfoRef> depots = _CreateSnapshotOfDepots(); 124705880d13SAndrew Lindesay std::vector<DepotInfoRef>::iterator it; 1248d13c3d89SAndrew Lindesay 124905880d13SAndrew Lindesay for (it = depots.begin(); it != depots.end(); it++) { 125005880d13SAndrew Lindesay DepotInfoRef depot = *it; 125105880d13SAndrew Lindesay 125205880d13SAndrew Lindesay if (depot->Name().Length() != 0) { 1253b965ce70SHumdinger BMessage* message = new BMessage(MSG_DEPOT_SELECTED); 125405880d13SAndrew Lindesay message->AddString("name", depot->Name()); 125505880d13SAndrew Lindesay BMenuItem* item = new(std::nothrow) BMenuItem(depot->Name(), message); 125605880d13SAndrew Lindesay 125705880d13SAndrew Lindesay if (item == NULL) 125805880d13SAndrew Lindesay HDFATAL("memory exhaustion"); 125905880d13SAndrew Lindesay 1260b965ce70SHumdinger fRepositoryMenu->AddItem(item); 1261b965ce70SHumdinger 126205880d13SAndrew Lindesay if (depot->Name() == fModel.Depot()) { 1263b965ce70SHumdinger item->SetMarked(true); 1264b965ce70SHumdinger foundSelectedDepot = true; 1265b965ce70SHumdinger } 1266b965ce70SHumdinger } 1267d13c3d89SAndrew Lindesay } 1268b965ce70SHumdinger 1269b965ce70SHumdinger if (!foundSelectedDepot) 1270b965ce70SHumdinger fRepositoryMenu->ItemAt(0)->SetMarked(true); 1271b965ce70SHumdinger } 1272b965ce70SHumdinger 1273b965ce70SHumdinger 1274a9edb9bfSAndrew Lindesay bool 1275a9edb9bfSAndrew Lindesay MainWindow::_SelectedPackageHasWebAppRepositoryCode() 1276a9edb9bfSAndrew Lindesay { 1277a9edb9bfSAndrew Lindesay const PackageInfoRef& package = fPackageInfoView->Package(); 12786ab878c0SAndrew Lindesay const BString depotName = package->DepotName(); 1279a9edb9bfSAndrew Lindesay 12806ab878c0SAndrew Lindesay if (depotName.IsEmpty()) { 1281fa5c8097SAndrew Lindesay HDDEBUG("the package [%s] has no depot name", package->Name().String()); 12826ab878c0SAndrew Lindesay } else { 12836ab878c0SAndrew Lindesay const DepotInfo* depot = fModel.DepotForName(depotName); 1284a9edb9bfSAndrew Lindesay 12856ab878c0SAndrew Lindesay if (depot == NULL) { 1286f96d1f4dSAndrew Lindesay HDINFO("the depot [%s] was not able to be found", 1287fa5c8097SAndrew Lindesay depotName.String()); 12886ab878c0SAndrew Lindesay } else { 12896ab878c0SAndrew Lindesay BString repositoryCode = depot->WebAppRepositoryCode(); 1290a9edb9bfSAndrew Lindesay 12916ab878c0SAndrew Lindesay if (repositoryCode.IsEmpty()) { 1292f96d1f4dSAndrew Lindesay HDINFO("the depot [%s] has no web app repository code", 1293fa5c8097SAndrew Lindesay depotName.String()); 1294fa5c8097SAndrew Lindesay } else 12956ab878c0SAndrew Lindesay return true; 12966ab878c0SAndrew Lindesay } 12976ab878c0SAndrew Lindesay } 12986ab878c0SAndrew Lindesay 12996ab878c0SAndrew Lindesay return false; 1300a9edb9bfSAndrew Lindesay } 1301a9edb9bfSAndrew Lindesay 1302a9edb9bfSAndrew Lindesay 1303b965ce70SHumdinger void 13041bbda92dSStephan Aßmus MainWindow::_RatePackage() 13051bbda92dSStephan Aßmus { 1306a9edb9bfSAndrew Lindesay if (!_SelectedPackageHasWebAppRepositoryCode()) { 1307a9edb9bfSAndrew Lindesay BAlert* alert = new(std::nothrow) BAlert( 1308cbadcae1SHumdinger B_TRANSLATE("Rating not possible"), 1309cbadcae1SHumdinger B_TRANSLATE("This package doesn't seem to be on the HaikuDepot " 1310cbadcae1SHumdinger "Server, so it's not possible to create a new rating " 1311cbadcae1SHumdinger "or edit an existing rating."), 1312a9edb9bfSAndrew Lindesay B_TRANSLATE("OK")); 1313a9edb9bfSAndrew Lindesay alert->Go(); 1314a9edb9bfSAndrew Lindesay return; 1315a9edb9bfSAndrew Lindesay } 1316a9edb9bfSAndrew Lindesay 1317d2d4866dSAndrew Lindesay if (fModel.Nickname().IsEmpty()) { 13181bbda92dSStephan Aßmus BAlert* alert = new(std::nothrow) BAlert( 13191bbda92dSStephan Aßmus B_TRANSLATE("Not logged in"), 13201bbda92dSStephan Aßmus B_TRANSLATE("You need to be logged into an account before you " 13211bbda92dSStephan Aßmus "can rate packages."), 13221bbda92dSStephan Aßmus B_TRANSLATE("Cancel"), 13231bbda92dSStephan Aßmus B_TRANSLATE("Login or Create account")); 13241bbda92dSStephan Aßmus 13251bbda92dSStephan Aßmus if (alert == NULL) 13261bbda92dSStephan Aßmus return; 13271bbda92dSStephan Aßmus 13281bbda92dSStephan Aßmus int32 choice = alert->Go(); 13291bbda92dSStephan Aßmus if (choice == 1) 13301bbda92dSStephan Aßmus _OpenLoginWindow(BMessage(MSG_RATE_PACKAGE)); 13311bbda92dSStephan Aßmus return; 13321bbda92dSStephan Aßmus } 13331bbda92dSStephan Aßmus 13341bbda92dSStephan Aßmus // TODO: Allow only one RatePackageWindow 13351bbda92dSStephan Aßmus // TODO: Mechanism for remembering the window frame 13361bbda92dSStephan Aßmus RatePackageWindow* window = new RatePackageWindow(this, 13371bbda92dSStephan Aßmus BRect(0, 0, 500, 400), fModel); 13381bbda92dSStephan Aßmus window->SetPackage(fPackageInfoView->Package()); 13391bbda92dSStephan Aßmus window->Show(); 13401bbda92dSStephan Aßmus } 1341d5ef985eSStephan Aßmus 1342d5ef985eSStephan Aßmus 1343d5ef985eSStephan Aßmus void 1344d5ef985eSStephan Aßmus MainWindow::_ShowScreenshot() 1345d5ef985eSStephan Aßmus { 1346d5ef985eSStephan Aßmus // TODO: Mechanism for remembering the window frame 1347d5ef985eSStephan Aßmus if (fScreenshotWindow == NULL) 1348d5ef985eSStephan Aßmus fScreenshotWindow = new ScreenshotWindow(this, BRect(0, 0, 500, 400)); 1349d5ef985eSStephan Aßmus 1350d5ef985eSStephan Aßmus if (fScreenshotWindow->LockWithTimeout(1000) != B_OK) 1351d5ef985eSStephan Aßmus return; 1352d5ef985eSStephan Aßmus 1353d5ef985eSStephan Aßmus fScreenshotWindow->SetPackage(fPackageInfoView->Package()); 1354d5ef985eSStephan Aßmus 1355d5ef985eSStephan Aßmus if (fScreenshotWindow->IsHidden()) 1356d5ef985eSStephan Aßmus fScreenshotWindow->Show(); 1357d5ef985eSStephan Aßmus else 1358d5ef985eSStephan Aßmus fScreenshotWindow->Activate(); 1359d5ef985eSStephan Aßmus 1360d5ef985eSStephan Aßmus fScreenshotWindow->Unlock(); 1361d5ef985eSStephan Aßmus } 136201339a54SAndrew Lindesay 136301339a54SAndrew Lindesay 136401339a54SAndrew Lindesay void 1365d2d4866dSAndrew Lindesay MainWindow::_ViewUserUsageConditions( 1366d2d4866dSAndrew Lindesay UserUsageConditionsSelectionMode mode) 136701339a54SAndrew Lindesay { 136801339a54SAndrew Lindesay UserUsageConditionsWindow* window = new UserUsageConditionsWindow( 1369d2d4866dSAndrew Lindesay fModel, mode); 137001339a54SAndrew Lindesay window->Show(); 137101339a54SAndrew Lindesay } 137210cd325cSAndrew Lindesay 137310cd325cSAndrew Lindesay 137410cd325cSAndrew Lindesay void 137510cd325cSAndrew Lindesay MainWindow::UserCredentialsFailed() 137610cd325cSAndrew Lindesay { 137710cd325cSAndrew Lindesay BString message = B_TRANSLATE("The password previously " 137810cd325cSAndrew Lindesay "supplied for the user [%Nickname%] is not currently " 137910cd325cSAndrew Lindesay "valid. The user will be logged-out of this application " 138010cd325cSAndrew Lindesay "and you should login again with your updated password."); 138110cd325cSAndrew Lindesay message.ReplaceAll("%Nickname%", fModel.Nickname()); 138210cd325cSAndrew Lindesay 138310cd325cSAndrew Lindesay AppUtils::NotifySimpleError(B_TRANSLATE("Login issue"), 138410cd325cSAndrew Lindesay message); 138510cd325cSAndrew Lindesay 138610cd325cSAndrew Lindesay { 138710cd325cSAndrew Lindesay AutoLocker<BLocker> locker(fModel.Lock()); 138810cd325cSAndrew Lindesay fModel.SetNickname(""); 138910cd325cSAndrew Lindesay } 139010cd325cSAndrew Lindesay } 139110cd325cSAndrew Lindesay 139210cd325cSAndrew Lindesay 139310cd325cSAndrew Lindesay /*! \brief This method is invoked from the UserDetailVerifierProcess on a 139410cd325cSAndrew Lindesay background thread. For this reason it lodges a message into itself 139510cd325cSAndrew Lindesay which can then be handled on the main thread. 139610cd325cSAndrew Lindesay */ 139710cd325cSAndrew Lindesay 139810cd325cSAndrew Lindesay void 139910cd325cSAndrew Lindesay MainWindow::UserUsageConditionsNotLatest(const UserDetail& userDetail) 140010cd325cSAndrew Lindesay { 140110cd325cSAndrew Lindesay BMessage message(MSG_USER_USAGE_CONDITIONS_NOT_LATEST); 140210cd325cSAndrew Lindesay BMessage detailsMessage; 140310cd325cSAndrew Lindesay if (userDetail.Archive(&detailsMessage, true) != B_OK 140410cd325cSAndrew Lindesay || message.AddMessage("userDetail", &detailsMessage) != B_OK) { 1405fa5c8097SAndrew Lindesay HDERROR("unable to archive the user detail into a message"); 140610cd325cSAndrew Lindesay } 140710cd325cSAndrew Lindesay else 140810cd325cSAndrew Lindesay BMessenger(this).SendMessage(&message); 140910cd325cSAndrew Lindesay } 141010cd325cSAndrew Lindesay 141110cd325cSAndrew Lindesay 141210cd325cSAndrew Lindesay void 141310cd325cSAndrew Lindesay MainWindow::_HandleUserUsageConditionsNotLatest( 141410cd325cSAndrew Lindesay const UserDetail& userDetail) 141510cd325cSAndrew Lindesay { 141610cd325cSAndrew Lindesay ToLatestUserUsageConditionsWindow* window = 141710cd325cSAndrew Lindesay new ToLatestUserUsageConditionsWindow(this, fModel, userDetail); 141810cd325cSAndrew Lindesay window->Show(); 141910cd325cSAndrew Lindesay } 142010cd325cSAndrew Lindesay 142110cd325cSAndrew Lindesay 142210cd325cSAndrew Lindesay void 142310cd325cSAndrew Lindesay MainWindow::_AddProcessCoordinator(ProcessCoordinator* item) 142410cd325cSAndrew Lindesay { 14257d7de135SAugustin Cavalier BReference<ProcessCoordinator> itemRef(item, true); 142610cd325cSAndrew Lindesay AutoLocker<BLocker> lock(&fCoordinatorLock); 142710cd325cSAndrew Lindesay 142895c7b018SAndrew Lindesay if (fShouldCloseWhenNoProcessesToCoordinate) { 142995c7b018SAndrew Lindesay HDINFO("system shutting down --> new process coordinator [%s] rejected", 143095c7b018SAndrew Lindesay item->Name().String()); 143195c7b018SAndrew Lindesay return; 143295c7b018SAndrew Lindesay } 143395c7b018SAndrew Lindesay 1434a18f873fSAndrew Lindesay item->SetListener(this); 1435a18f873fSAndrew Lindesay 1436779ab335SX512 if (!fCoordinator.IsSet()) { 143710cd325cSAndrew Lindesay if (acquire_sem(fCoordinatorRunningSem) != B_OK) 143810cd325cSAndrew Lindesay debugger("unable to acquire the process coordinator sem"); 1439f96d1f4dSAndrew Lindesay HDINFO("adding and starting a process coordinator [%s]", 1440fa5c8097SAndrew Lindesay item->Name().String()); 14417d7de135SAugustin Cavalier fCoordinator = itemRef; 144210cd325cSAndrew Lindesay fCoordinator->Start(); 14437d7de135SAugustin Cavalier } else { 1444f96d1f4dSAndrew Lindesay HDINFO("adding process coordinator [%s] to the queue", 144510cd325cSAndrew Lindesay item->Name().String()); 144610cd325cSAndrew Lindesay fCoordinatorQueue.push(item); 144710cd325cSAndrew Lindesay } 144810cd325cSAndrew Lindesay } 144910cd325cSAndrew Lindesay 145010cd325cSAndrew Lindesay 145110cd325cSAndrew Lindesay void 145210cd325cSAndrew Lindesay MainWindow::_SpinUntilProcessCoordinatorComplete() 145310cd325cSAndrew Lindesay { 145410cd325cSAndrew Lindesay while (true) { 145510cd325cSAndrew Lindesay if (acquire_sem(fCoordinatorRunningSem) != B_OK) 145610cd325cSAndrew Lindesay debugger("unable to acquire the process coordinator sem"); 145710cd325cSAndrew Lindesay if (release_sem(fCoordinatorRunningSem) != B_OK) 145810cd325cSAndrew Lindesay debugger("unable to release the process coordinator sem"); 145910cd325cSAndrew Lindesay { 146010cd325cSAndrew Lindesay AutoLocker<BLocker> lock(&fCoordinatorLock); 1461779ab335SX512 if (!fCoordinator.IsSet()) 146210cd325cSAndrew Lindesay return; 146310cd325cSAndrew Lindesay } 146410cd325cSAndrew Lindesay } 146510cd325cSAndrew Lindesay } 146610cd325cSAndrew Lindesay 146710cd325cSAndrew Lindesay 146810cd325cSAndrew Lindesay void 146910cd325cSAndrew Lindesay MainWindow::_StopProcessCoordinators() 147010cd325cSAndrew Lindesay { 147195c7b018SAndrew Lindesay HDINFO("will stop all queued process coordinators"); 147210cd325cSAndrew Lindesay AutoLocker<BLocker> lock(&fCoordinatorLock); 147310cd325cSAndrew Lindesay 147410cd325cSAndrew Lindesay while (!fCoordinatorQueue.empty()) { 1475f96d1f4dSAndrew Lindesay BReference<ProcessCoordinator> processCoordinator 1476f96d1f4dSAndrew Lindesay = fCoordinatorQueue.front(); 1477f96d1f4dSAndrew Lindesay HDINFO("will drop queued process coordinator [%s]", 1478fa5c8097SAndrew Lindesay processCoordinator->Name().String()); 147910cd325cSAndrew Lindesay fCoordinatorQueue.pop(); 148010cd325cSAndrew Lindesay } 148110cd325cSAndrew Lindesay 148295c7b018SAndrew Lindesay if (fCoordinator.IsSet()) 148395c7b018SAndrew Lindesay fCoordinator->RequestStop(); 148410cd325cSAndrew Lindesay } 148510cd325cSAndrew Lindesay 148610cd325cSAndrew Lindesay 148710cd325cSAndrew Lindesay /*! This method is called when there is some change in the bulk load process 148810cd325cSAndrew Lindesay or other process coordinator. 148910cd325cSAndrew Lindesay A change may mean that a new process has started / stopped etc... or it 149010cd325cSAndrew Lindesay may mean that the entire coordinator has finished. 149110cd325cSAndrew Lindesay */ 149210cd325cSAndrew Lindesay 149310cd325cSAndrew Lindesay void 149410cd325cSAndrew Lindesay MainWindow::CoordinatorChanged(ProcessCoordinatorState& coordinatorState) 149510cd325cSAndrew Lindesay { 149610cd325cSAndrew Lindesay AutoLocker<BLocker> lock(&fCoordinatorLock); 149710cd325cSAndrew Lindesay 1498f95ec23eSAndrew Lindesay if (fCoordinator.Get() == coordinatorState.Coordinator()) { 149910cd325cSAndrew Lindesay if (!coordinatorState.IsRunning()) { 150010cd325cSAndrew Lindesay if (release_sem(fCoordinatorRunningSem) != B_OK) 150110cd325cSAndrew Lindesay debugger("unable to release the process coordinator sem"); 1502f96d1f4dSAndrew Lindesay HDINFO("process coordinator [%s] did complete", 1503fa5c8097SAndrew Lindesay fCoordinator->Name().String()); 150410cd325cSAndrew Lindesay // complete the last one that just finished 150510cd325cSAndrew Lindesay BMessage* message = fCoordinator->Message(); 150610cd325cSAndrew Lindesay 150710cd325cSAndrew Lindesay if (message != NULL) { 150810cd325cSAndrew Lindesay BMessenger messenger(this); 150910cd325cSAndrew Lindesay message->AddInt64(KEY_ERROR_STATUS, 151010cd325cSAndrew Lindesay (int64) fCoordinator->ErrorStatus()); 151110cd325cSAndrew Lindesay messenger.SendMessage(message); 151210cd325cSAndrew Lindesay } 151310cd325cSAndrew Lindesay 1514f95ec23eSAndrew Lindesay fCoordinator = BReference<ProcessCoordinator>(NULL); 1515f95ec23eSAndrew Lindesay // will delete the old process coordinator if it is not used 1516f95ec23eSAndrew Lindesay // elsewhere. 151710cd325cSAndrew Lindesay 151810cd325cSAndrew Lindesay // now schedule the next one. 151910cd325cSAndrew Lindesay if (!fCoordinatorQueue.empty()) { 152010cd325cSAndrew Lindesay if (acquire_sem(fCoordinatorRunningSem) != B_OK) 152110cd325cSAndrew Lindesay debugger("unable to acquire the process coordinator sem"); 152210cd325cSAndrew Lindesay fCoordinator = fCoordinatorQueue.front(); 1523f96d1f4dSAndrew Lindesay HDINFO("starting next process coordinator [%s]", 152410cd325cSAndrew Lindesay fCoordinator->Name().String()); 152510cd325cSAndrew Lindesay fCoordinatorQueue.pop(); 152610cd325cSAndrew Lindesay fCoordinator->Start(); 152710cd325cSAndrew Lindesay } 152810cd325cSAndrew Lindesay else { 152910cd325cSAndrew Lindesay _NotifyWorkStatusClear(); 153095c7b018SAndrew Lindesay if (fShouldCloseWhenNoProcessesToCoordinate) { 153195c7b018SAndrew Lindesay HDINFO("no more processes to coord --> will quit"); 153295c7b018SAndrew Lindesay BMessage message(B_QUIT_REQUESTED); 153395c7b018SAndrew Lindesay PostMessage(&message); 153495c7b018SAndrew Lindesay } 153510cd325cSAndrew Lindesay } 153610cd325cSAndrew Lindesay } 153710cd325cSAndrew Lindesay else { 153810cd325cSAndrew Lindesay _NotifyWorkStatusChange(coordinatorState.Message(), 153910cd325cSAndrew Lindesay coordinatorState.Progress()); 154010cd325cSAndrew Lindesay // show the progress to the user. 154110cd325cSAndrew Lindesay } 154295c7b018SAndrew Lindesay } else { 154395c7b018SAndrew Lindesay _NotifyWorkStatusClear(); 1544fa5c8097SAndrew Lindesay HDINFO("! unknown process coordinator changed"); 154510cd325cSAndrew Lindesay } 154695c7b018SAndrew Lindesay } 1547ccf707d0SAndrew Lindesay 1548ccf707d0SAndrew Lindesay 1549ccf707d0SAndrew Lindesay static package_list_view_mode 1550ccf707d0SAndrew Lindesay main_window_tab_to_package_list_view_mode(int32 tab) 1551ccf707d0SAndrew Lindesay { 1552ccf707d0SAndrew Lindesay if (tab == TAB_PROMINENT_PACKAGES) 1553ccf707d0SAndrew Lindesay return PROMINENT; 1554ccf707d0SAndrew Lindesay return ALL; 1555ccf707d0SAndrew Lindesay } 1556ccf707d0SAndrew Lindesay 1557ccf707d0SAndrew Lindesay 1558ccf707d0SAndrew Lindesay void 1559ccf707d0SAndrew Lindesay MainWindow::_HandleChangePackageListViewMode() 1560ccf707d0SAndrew Lindesay { 1561ccf707d0SAndrew Lindesay package_list_view_mode tabMode = main_window_tab_to_package_list_view_mode( 1562ccf707d0SAndrew Lindesay fListTabs->Selection()); 1563ccf707d0SAndrew Lindesay package_list_view_mode modelMode = fModel.PackageListViewMode(); 1564ccf707d0SAndrew Lindesay 1565ccf707d0SAndrew Lindesay if (tabMode != modelMode) { 1566ccf707d0SAndrew Lindesay BAutolock locker(fModel.Lock()); 1567ccf707d0SAndrew Lindesay fModel.SetPackageListViewMode(tabMode); 1568ccf707d0SAndrew Lindesay } 1569ccf707d0SAndrew Lindesay } 157005880d13SAndrew Lindesay 157105880d13SAndrew Lindesay 157205880d13SAndrew Lindesay std::vector<DepotInfoRef> 157305880d13SAndrew Lindesay MainWindow::_CreateSnapshotOfDepots() 157405880d13SAndrew Lindesay { 157505880d13SAndrew Lindesay std::vector<DepotInfoRef> result; 157605880d13SAndrew Lindesay BAutolock locker(fModel.Lock()); 157705880d13SAndrew Lindesay int32 countDepots = fModel.CountDepots(); 157805880d13SAndrew Lindesay for(int32 i = 0; i < countDepots; i++) 157905880d13SAndrew Lindesay result.push_back(fModel.DepotAtIndex(i)); 158005880d13SAndrew Lindesay return result; 158105880d13SAndrew Lindesay } 1582