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" 5110cd325cSAndrew Lindesay #include "ToLatestUserUsageConditionsWindow.h" 5204c9d578SStephan Aßmus #include "UserLoginWindow.h" 5301339a54SAndrew Lindesay #include "UserUsageConditionsWindow.h" 54125d42d9SJulian Harnath #include "WorkStatusView.h" 5504c9d578SStephan Aßmus 5604c9d578SStephan Aßmus 5704c9d578SStephan Aßmus #undef B_TRANSLATION_CONTEXT 5804c9d578SStephan Aßmus #define B_TRANSLATION_CONTEXT "MainWindow" 5904c9d578SStephan Aßmus 6004c9d578SStephan Aßmus 6104c9d578SStephan Aßmus enum { 625bf2b6ebSBrian Hill MSG_REFRESH_REPOS = 'mrrp', 635bf2b6ebSBrian Hill MSG_MANAGE_REPOS = 'mmrp', 64d144f952SAugustin Cavalier MSG_SOFTWARE_UPDATER = 'mswu', 65133ebab6SAndrew Lindesay MSG_SETTINGS = 'stgs', 6604c9d578SStephan Aßmus MSG_LOG_IN = 'lgin', 678f03a0f9SStephan Aßmus MSG_AUTHORIZATION_CHANGED = 'athc', 6889b16bb4SAndrew Lindesay MSG_CATEGORIES_LIST_CHANGED = 'clic', 69da651104SStephan Aßmus MSG_PACKAGE_CHANGED = 'pchd', 703369e03dSAndrew Lindesay MSG_WORK_STATUS_CHANGE = 'wsch', 713369e03dSAndrew Lindesay MSG_WORK_STATUS_CLEAR = 'wscl', 72fdec4227SStephan Aßmus 73ccf707d0SAndrew Lindesay MSG_CHANGE_PACKAGE_LIST_VIEW_MODE = 'cplm', 74fdec4227SStephan Aßmus MSG_SHOW_AVAILABLE_PACKAGES = 'savl', 75fdec4227SStephan Aßmus MSG_SHOW_INSTALLED_PACKAGES = 'sins', 7604c9d578SStephan Aßmus MSG_SHOW_SOURCE_PACKAGES = 'ssrc', 7704c9d578SStephan Aßmus MSG_SHOW_DEVELOP_PACKAGES = 'sdvl' 7804c9d578SStephan Aßmus }; 7904c9d578SStephan Aßmus 8010cd325cSAndrew Lindesay #define KEY_ERROR_STATUS "errorStatus" 81ccf707d0SAndrew Lindesay 82ccf707d0SAndrew Lindesay #define TAB_PROMINENT_PACKAGES 0 83ccf707d0SAndrew Lindesay #define TAB_ALL_PACKAGES 1 8404c9d578SStephan Aßmus 8504c9d578SStephan Aßmus using namespace BPackageKit; 8604c9d578SStephan Aßmus using namespace BPackageKit::BManager::BPrivate; 8704c9d578SStephan Aßmus 8804c9d578SStephan Aßmus 8904c9d578SStephan Aßmus typedef std::map<BString, PackageInfoRef> PackageInfoMap; 9004c9d578SStephan Aßmus 9104c9d578SStephan Aßmus 9204c9d578SStephan Aßmus struct RefreshWorkerParameters { 9304c9d578SStephan Aßmus MainWindow* window; 9404c9d578SStephan Aßmus bool forceRefresh; 9504c9d578SStephan Aßmus 9604c9d578SStephan Aßmus RefreshWorkerParameters(MainWindow* window, bool forceRefresh) 9704c9d578SStephan Aßmus : 9804c9d578SStephan Aßmus window(window), 9904c9d578SStephan Aßmus forceRefresh(forceRefresh) 10004c9d578SStephan Aßmus { 10104c9d578SStephan Aßmus } 10204c9d578SStephan Aßmus }; 10304c9d578SStephan Aßmus 10404c9d578SStephan Aßmus 10589b16bb4SAndrew Lindesay class MainWindowModelListener : public ModelListener { 1068f03a0f9SStephan Aßmus public: 10789b16bb4SAndrew Lindesay MainWindowModelListener(const BMessenger& messenger) 1088f03a0f9SStephan Aßmus : 1098f03a0f9SStephan Aßmus fMessenger(messenger) 1108f03a0f9SStephan Aßmus { 1118f03a0f9SStephan Aßmus } 1128f03a0f9SStephan Aßmus 1138f03a0f9SStephan Aßmus virtual void AuthorizationChanged() 1148f03a0f9SStephan Aßmus { 1158f03a0f9SStephan Aßmus if (fMessenger.IsValid()) 1168f03a0f9SStephan Aßmus fMessenger.SendMessage(MSG_AUTHORIZATION_CHANGED); 1178f03a0f9SStephan Aßmus } 1188f03a0f9SStephan Aßmus 11989b16bb4SAndrew Lindesay virtual void CategoryListChanged() 12089b16bb4SAndrew Lindesay { 12189b16bb4SAndrew Lindesay if (fMessenger.IsValid()) 12289b16bb4SAndrew Lindesay fMessenger.SendMessage(MSG_CATEGORIES_LIST_CHANGED); 12389b16bb4SAndrew Lindesay } 12489b16bb4SAndrew Lindesay 1258f03a0f9SStephan Aßmus private: 1268f03a0f9SStephan Aßmus BMessenger fMessenger; 1278f03a0f9SStephan Aßmus }; 1288f03a0f9SStephan Aßmus 1298f03a0f9SStephan Aßmus 130f7c2983eSAxel Dörfler MainWindow::MainWindow(const BMessage& settings) 13104c9d578SStephan Aßmus : 132f7c2983eSAxel Dörfler BWindow(BRect(50, 50, 650, 550), B_TRANSLATE_SYSTEM_NAME("HaikuDepot"), 13304c9d578SStephan Aßmus B_DOCUMENT_WINDOW_LOOK, B_NORMAL_WINDOW_FEEL, 13404c9d578SStephan Aßmus B_ASYNCHRONOUS_CONTROLS | B_AUTO_UPDATE_SIZE_LIMITS), 135d5ef985eSStephan Aßmus fScreenshotWindow(NULL), 136e0a26dceSStephan Aßmus fUserMenu(NULL), 137e0a26dceSStephan Aßmus fLogInItem(NULL), 138e0a26dceSStephan Aßmus fLogOutItem(NULL), 139976cadf1SAndrew Lindesay fUsersUserUsageConditionsMenuItem(NULL), 14089b16bb4SAndrew Lindesay fModelListener(new MainWindowModelListener(BMessenger(this)), true), 14110cd325cSAndrew Lindesay fCoordinator(NULL), 1423369e03dSAndrew Lindesay fSinglePackageMode(false) 14304c9d578SStephan Aßmus { 14410cd325cSAndrew Lindesay if ((fCoordinatorRunningSem = create_sem(1, "ProcessCoordinatorSem")) < B_OK) 14510cd325cSAndrew Lindesay debugger("unable to create the process coordinator semaphore"); 14610cd325cSAndrew Lindesay 147cbadcae1SHumdinger BMenuBar* menuBar = new BMenuBar("Main Menu"); 14804c9d578SStephan Aßmus _BuildMenu(menuBar); 14904c9d578SStephan Aßmus 150cbadcae1SHumdinger BMenuBar* userMenuBar = new BMenuBar("User Menu"); 151e0a26dceSStephan Aßmus _BuildUserMenu(userMenuBar); 152e0a26dceSStephan Aßmus set_small_font(userMenuBar); 153e0a26dceSStephan Aßmus userMenuBar->SetExplicitMaxSize(BSize(B_SIZE_UNSET, 154e0a26dceSStephan Aßmus menuBar->MaxSize().height)); 155e0a26dceSStephan Aßmus 15604c9d578SStephan Aßmus fFilterView = new FilterView(); 157f0e491d3SAndrew Lindesay fFeaturedPackagesView = new FeaturedPackagesView(fModel); 158f0e491d3SAndrew Lindesay fPackageListView = new PackageListView(&fModel); 159f0e491d3SAndrew Lindesay fPackageInfoView = new PackageInfoView(&fModel, this); 16004c9d578SStephan Aßmus 16104c9d578SStephan Aßmus fSplitView = new BSplitView(B_VERTICAL, 5.0f); 16204c9d578SStephan Aßmus 163125d42d9SJulian Harnath fWorkStatusView = new WorkStatusView("work status"); 164125d42d9SJulian Harnath fPackageListView->AttachWorkStatusView(fWorkStatusView); 165125d42d9SJulian Harnath 166e00a489bSAugustin Cavalier fListTabs = new TabView(BMessenger(this), 167ccf707d0SAndrew Lindesay BMessage(MSG_CHANGE_PACKAGE_LIST_VIEW_MODE), "list tabs"); 168e00a489bSAugustin Cavalier fListTabs->AddTab(fFeaturedPackagesView); 169e00a489bSAugustin Cavalier fListTabs->AddTab(fPackageListView); 1704b930ccaSStephan Aßmus 17104c9d578SStephan Aßmus BLayoutBuilder::Group<>(this, B_VERTICAL, 0.0f) 172e0a26dceSStephan Aßmus .AddGroup(B_HORIZONTAL, 0.0f) 173e0a26dceSStephan Aßmus .Add(menuBar, 1.0f) 174e0a26dceSStephan Aßmus .Add(userMenuBar, 0.0f) 175e0a26dceSStephan Aßmus .End() 17604c9d578SStephan Aßmus .Add(fFilterView) 17704c9d578SStephan Aßmus .AddSplit(fSplitView) 17804c9d578SStephan Aßmus .AddGroup(B_VERTICAL) 179e00a489bSAugustin Cavalier .Add(fListTabs) 18004c9d578SStephan Aßmus .SetInsets( 18104c9d578SStephan Aßmus B_USE_DEFAULT_SPACING, 0.0f, 18204c9d578SStephan Aßmus B_USE_DEFAULT_SPACING, 0.0f) 18304c9d578SStephan Aßmus .End() 18404c9d578SStephan Aßmus .Add(fPackageInfoView) 18504c9d578SStephan Aßmus .End() 186125d42d9SJulian Harnath .Add(fWorkStatusView) 18704c9d578SStephan Aßmus ; 18804c9d578SStephan Aßmus 18904c9d578SStephan Aßmus fSplitView->SetCollapsible(0, false); 19004c9d578SStephan Aßmus fSplitView->SetCollapsible(1, false); 19104c9d578SStephan Aßmus 1928f03a0f9SStephan Aßmus fModel.AddListener(fModelListener); 1938f03a0f9SStephan Aßmus 19404c9d578SStephan Aßmus BMessage columnSettings; 19504c9d578SStephan Aßmus if (settings.FindMessage("column settings", &columnSettings) == B_OK) 19604c9d578SStephan Aßmus fPackageListView->LoadState(&columnSettings); 19704c9d578SStephan Aßmus 198ccf707d0SAndrew Lindesay _RestoreModelSettings(settings); 199133ebab6SAndrew Lindesay _MaybePromptCanShareAnonymousUserData(settings); 20004c9d578SStephan Aßmus 201ccf707d0SAndrew Lindesay if (fModel.PackageListViewMode() == PROMINENT) 202ccf707d0SAndrew Lindesay fListTabs->Select(TAB_PROMINENT_PACKAGES); 2032997e05bSStephan Aßmus else 204ccf707d0SAndrew Lindesay fListTabs->Select(TAB_ALL_PACKAGES); 2052997e05bSStephan Aßmus 206d2d4866dSAndrew Lindesay _RestoreNickname(settings); 20710cd325cSAndrew Lindesay _UpdateAuthorization(); 208f7c2983eSAxel Dörfler _RestoreWindowFrame(settings); 209f7c2983eSAxel Dörfler 2108f03a0f9SStephan Aßmus // start worker threads 21104c9d578SStephan Aßmus BPackageRoster().StartWatching(this, 21204c9d578SStephan Aßmus B_WATCH_PACKAGE_INSTALLATION_LOCATIONS); 21304c9d578SStephan Aßmus 21463975654SStephan Aßmus _InitWorkerThreads(); 2159883929bSAndrew Lindesay _AdoptModel(); 2169883929bSAndrew Lindesay _StartBulkLoad(); 21704c9d578SStephan Aßmus } 21804c9d578SStephan Aßmus 21904c9d578SStephan Aßmus 220f7c2983eSAxel Dörfler MainWindow::MainWindow(const BMessage& settings, const PackageInfoRef& package) 2216d519fd1SStephan Aßmus : 222f7c2983eSAxel Dörfler BWindow(BRect(50, 50, 650, 350), B_TRANSLATE_SYSTEM_NAME("HaikuDepot"), 2236d519fd1SStephan Aßmus B_DOCUMENT_WINDOW_LOOK, B_NORMAL_WINDOW_FEEL, 2246d519fd1SStephan Aßmus B_ASYNCHRONOUS_CONTROLS | B_AUTO_UPDATE_SIZE_LIMITS), 2259883929bSAndrew Lindesay fFeaturedPackagesView(NULL), 2269883929bSAndrew Lindesay fPackageListView(NULL), 227d78bfd8dSJulian Harnath fWorkStatusView(NULL), 228d5ef985eSStephan Aßmus fScreenshotWindow(NULL), 229e0a26dceSStephan Aßmus fUserMenu(NULL), 230e0a26dceSStephan Aßmus fLogInItem(NULL), 2316d519fd1SStephan Aßmus fLogOutItem(NULL), 232976cadf1SAndrew Lindesay fUsersUserUsageConditionsMenuItem(NULL), 23389b16bb4SAndrew Lindesay fModelListener(new MainWindowModelListener(BMessenger(this)), true), 23410cd325cSAndrew Lindesay fCoordinator(NULL), 2353369e03dSAndrew Lindesay fSinglePackageMode(true) 2366d519fd1SStephan Aßmus { 23710cd325cSAndrew Lindesay if ((fCoordinatorRunningSem = create_sem(1, "ProcessCoordinatorSem")) < B_OK) 23810cd325cSAndrew Lindesay debugger("unable to create the process coordinator semaphore"); 23910cd325cSAndrew Lindesay 2406d519fd1SStephan Aßmus fFilterView = new FilterView(); 241f0e491d3SAndrew Lindesay fPackageInfoView = new PackageInfoView(&fModel, this); 24287016f8fSAndrew Lindesay fWorkStatusView = new WorkStatusView("work status"); 2436d519fd1SStephan Aßmus 2446d519fd1SStephan Aßmus BLayoutBuilder::Group<>(this, B_VERTICAL) 2456d519fd1SStephan Aßmus .Add(fPackageInfoView) 24687016f8fSAndrew Lindesay .Add(fWorkStatusView) 2476d519fd1SStephan Aßmus .SetInsets(0, B_USE_WINDOW_INSETS, 0, 0) 2486d519fd1SStephan Aßmus ; 2496d519fd1SStephan Aßmus 2506d519fd1SStephan Aßmus fModel.AddListener(fModelListener); 2516d519fd1SStephan Aßmus 2526d519fd1SStephan Aßmus // Restore settings 253d2d4866dSAndrew Lindesay _RestoreNickname(settings); 254ccf707d0SAndrew Lindesay _UpdateAuthorization(); 255f7c2983eSAxel Dörfler _RestoreWindowFrame(settings); 2566d519fd1SStephan Aßmus 2576d519fd1SStephan Aßmus fPackageInfoView->SetPackage(package); 25863975654SStephan Aßmus 25963975654SStephan Aßmus _InitWorkerThreads(); 2606d519fd1SStephan Aßmus } 2616d519fd1SStephan Aßmus 2626d519fd1SStephan Aßmus 26304c9d578SStephan Aßmus MainWindow::~MainWindow() 26404c9d578SStephan Aßmus { 26510cd325cSAndrew Lindesay _SpinUntilProcessCoordinatorComplete(); 26610cd325cSAndrew Lindesay delete_sem(fCoordinatorRunningSem); 26710cd325cSAndrew Lindesay fCoordinatorRunningSem = 0; 26810cd325cSAndrew Lindesay 26904c9d578SStephan Aßmus BPackageRoster().StopWatching(this); 27004c9d578SStephan Aßmus 271d5ef985eSStephan Aßmus if (fScreenshotWindow != NULL && fScreenshotWindow->Lock()) 272d5ef985eSStephan Aßmus fScreenshotWindow->Quit(); 27304c9d578SStephan Aßmus } 27404c9d578SStephan Aßmus 27504c9d578SStephan Aßmus 27604c9d578SStephan Aßmus bool 27704c9d578SStephan Aßmus MainWindow::QuitRequested() 27804c9d578SStephan Aßmus { 27904c9d578SStephan Aßmus BMessage settings; 28004c9d578SStephan Aßmus StoreSettings(settings); 28104c9d578SStephan Aßmus 28204c9d578SStephan Aßmus BMessage message(MSG_MAIN_WINDOW_CLOSED); 2833369e03dSAndrew Lindesay message.AddMessage(KEY_WINDOW_SETTINGS, &settings); 28404c9d578SStephan Aßmus 28504c9d578SStephan Aßmus be_app->PostMessage(&message); 28604c9d578SStephan Aßmus 28710cd325cSAndrew Lindesay _StopProcessCoordinators(); 2883369e03dSAndrew Lindesay 28904c9d578SStephan Aßmus return true; 29004c9d578SStephan Aßmus } 29104c9d578SStephan Aßmus 29204c9d578SStephan Aßmus 29304c9d578SStephan Aßmus void 29404c9d578SStephan Aßmus MainWindow::MessageReceived(BMessage* message) 29504c9d578SStephan Aßmus { 29604c9d578SStephan Aßmus switch (message->what) { 2973369e03dSAndrew Lindesay case MSG_BULK_LOAD_DONE: 29810cd325cSAndrew Lindesay { 29910cd325cSAndrew Lindesay int64 errorStatus64; 30010cd325cSAndrew Lindesay if (message->FindInt64(KEY_ERROR_STATUS, &errorStatus64) == B_OK) 30110cd325cSAndrew Lindesay _BulkLoadCompleteReceived((status_t) errorStatus64); 30210cd325cSAndrew Lindesay else 303fa5c8097SAndrew Lindesay HDERROR("expected [%s] value in message", KEY_ERROR_STATUS); 30404c9d578SStephan Aßmus break; 30510cd325cSAndrew Lindesay } 30604c9d578SStephan Aßmus case B_SIMPLE_DATA: 30704c9d578SStephan Aßmus case B_REFS_RECEIVED: 30804c9d578SStephan Aßmus // TODO: ? 30904c9d578SStephan Aßmus break; 31004c9d578SStephan Aßmus 31104c9d578SStephan Aßmus case B_PACKAGE_UPDATE: 312*f32d5c5cSAndrew Lindesay _HandleExternalPackageUpdateMessageReceived(message); 31304c9d578SStephan Aßmus break; 31404c9d578SStephan Aßmus 3155bf2b6ebSBrian Hill case MSG_REFRESH_REPOS: 3163369e03dSAndrew Lindesay _StartBulkLoad(true); 3173369e03dSAndrew Lindesay break; 3183369e03dSAndrew Lindesay 31910cd325cSAndrew Lindesay case MSG_WORK_STATUS_CLEAR: 32010cd325cSAndrew Lindesay _HandleWorkStatusClear(); 32110cd325cSAndrew Lindesay break; 32210cd325cSAndrew Lindesay 3233369e03dSAndrew Lindesay case MSG_WORK_STATUS_CHANGE: 3243369e03dSAndrew Lindesay _HandleWorkStatusChangeMessageReceived(message); 32504c9d578SStephan Aßmus break; 32604c9d578SStephan Aßmus 3275bf2b6ebSBrian Hill case MSG_MANAGE_REPOS: 3285bf2b6ebSBrian Hill be_roster->Launch("application/x-vnd.Haiku-Repositories"); 3295bf2b6ebSBrian Hill break; 3305bf2b6ebSBrian Hill 331d144f952SAugustin Cavalier case MSG_SOFTWARE_UPDATER: 332d144f952SAugustin Cavalier be_roster->Launch("application/x-vnd.haiku-softwareupdater"); 333d144f952SAugustin Cavalier break; 334d144f952SAugustin Cavalier 33504c9d578SStephan Aßmus case MSG_LOG_IN: 3361bbda92dSStephan Aßmus _OpenLoginWindow(BMessage()); 33704c9d578SStephan Aßmus break; 33804c9d578SStephan Aßmus 339133ebab6SAndrew Lindesay case MSG_SETTINGS: 340133ebab6SAndrew Lindesay _OpenSettingsWindow(); 341133ebab6SAndrew Lindesay break; 342133ebab6SAndrew Lindesay 3438f03a0f9SStephan Aßmus case MSG_LOG_OUT: 344d2d4866dSAndrew Lindesay fModel.SetNickname(""); 3458f03a0f9SStephan Aßmus break; 3468f03a0f9SStephan Aßmus 34701339a54SAndrew Lindesay case MSG_VIEW_LATEST_USER_USAGE_CONDITIONS: 348d2d4866dSAndrew Lindesay _ViewUserUsageConditions(LATEST); 349d2d4866dSAndrew Lindesay break; 350d2d4866dSAndrew Lindesay 351d2d4866dSAndrew Lindesay case MSG_VIEW_USERS_USER_USAGE_CONDITIONS: 352d2d4866dSAndrew Lindesay _ViewUserUsageConditions(USER); 35301339a54SAndrew Lindesay break; 35401339a54SAndrew Lindesay 3558f03a0f9SStephan Aßmus case MSG_AUTHORIZATION_CHANGED: 35610cd325cSAndrew Lindesay _StartUserVerify(); 3578f03a0f9SStephan Aßmus _UpdateAuthorization(); 3588f03a0f9SStephan Aßmus break; 3598f03a0f9SStephan Aßmus 36089b16bb4SAndrew Lindesay case MSG_CATEGORIES_LIST_CHANGED: 36189b16bb4SAndrew Lindesay fFilterView->AdoptModel(fModel); 36289b16bb4SAndrew Lindesay break; 36389b16bb4SAndrew Lindesay 364ccf707d0SAndrew Lindesay case MSG_CHANGE_PACKAGE_LIST_VIEW_MODE: 365ccf707d0SAndrew Lindesay _HandleChangePackageListViewMode(); 3664fade61fSStephan Aßmus break; 3674fade61fSStephan Aßmus 368fdec4227SStephan Aßmus case MSG_SHOW_AVAILABLE_PACKAGES: 369fdec4227SStephan Aßmus { 370fdec4227SStephan Aßmus BAutolock locker(fModel.Lock()); 371fdec4227SStephan Aßmus fModel.SetShowAvailablePackages( 372fdec4227SStephan Aßmus !fModel.ShowAvailablePackages()); 373fdec4227SStephan Aßmus } 374fdec4227SStephan Aßmus _AdoptModel(); 375fdec4227SStephan Aßmus break; 376fdec4227SStephan Aßmus 377fdec4227SStephan Aßmus case MSG_SHOW_INSTALLED_PACKAGES: 378fdec4227SStephan Aßmus { 379fdec4227SStephan Aßmus BAutolock locker(fModel.Lock()); 380fdec4227SStephan Aßmus fModel.SetShowInstalledPackages( 381fdec4227SStephan Aßmus !fModel.ShowInstalledPackages()); 382fdec4227SStephan Aßmus } 383fdec4227SStephan Aßmus _AdoptModel(); 384fdec4227SStephan Aßmus break; 385fdec4227SStephan Aßmus 38604c9d578SStephan Aßmus case MSG_SHOW_SOURCE_PACKAGES: 38704c9d578SStephan Aßmus { 38804c9d578SStephan Aßmus BAutolock locker(fModel.Lock()); 38904c9d578SStephan Aßmus fModel.SetShowSourcePackages(!fModel.ShowSourcePackages()); 39004c9d578SStephan Aßmus } 39104c9d578SStephan Aßmus _AdoptModel(); 39204c9d578SStephan Aßmus break; 39304c9d578SStephan Aßmus 39404c9d578SStephan Aßmus case MSG_SHOW_DEVELOP_PACKAGES: 39504c9d578SStephan Aßmus { 39604c9d578SStephan Aßmus BAutolock locker(fModel.Lock()); 39704c9d578SStephan Aßmus fModel.SetShowDevelopPackages(!fModel.ShowDevelopPackages()); 39804c9d578SStephan Aßmus } 39904c9d578SStephan Aßmus _AdoptModel(); 40004c9d578SStephan Aßmus break; 40104c9d578SStephan Aßmus 402a9edb9bfSAndrew Lindesay // this may be triggered by, for example, a user rating being added 403a9edb9bfSAndrew Lindesay // or having been altered. 404a9edb9bfSAndrew Lindesay case MSG_SERVER_DATA_CHANGED: 405a9edb9bfSAndrew Lindesay { 406a9edb9bfSAndrew Lindesay BString name; 407a9edb9bfSAndrew Lindesay if (message->FindString("name", &name) == B_OK) { 408a9edb9bfSAndrew Lindesay BAutolock locker(fModel.Lock()); 409a9edb9bfSAndrew Lindesay if (fPackageInfoView->Package()->Name() == name) { 410a9edb9bfSAndrew Lindesay _PopulatePackageAsync(true); 411a9edb9bfSAndrew Lindesay } else { 412f96d1f4dSAndrew Lindesay HDDEBUG("pkg [%s] is updated on the server, but is " 413f96d1f4dSAndrew Lindesay "not selected so will not be updated.", 414fa5c8097SAndrew Lindesay name.String()); 415a9edb9bfSAndrew Lindesay } 416a9edb9bfSAndrew Lindesay } 417a9edb9bfSAndrew Lindesay break; 418a9edb9bfSAndrew Lindesay } 419a9edb9bfSAndrew Lindesay 42004c9d578SStephan Aßmus case MSG_PACKAGE_SELECTED: 42104c9d578SStephan Aßmus { 42272992391SStephan Aßmus BString name; 42372992391SStephan Aßmus if (message->FindString("name", &name) == B_OK) { 424c4199192SAndrew Lindesay PackageInfoRef package; 425c4199192SAndrew Lindesay { 42675ba9dbfSStephan Aßmus BAutolock locker(fModel.Lock()); 427c4199192SAndrew Lindesay package = fModel.PackageForName(name); 428c4199192SAndrew Lindesay } 4296f07feadSAndrew Lindesay if (!package.IsSet() || name != package->Name()) 430c4199192SAndrew Lindesay debugger("unable to find the named package"); 431133ebab6SAndrew Lindesay else { 43204c9d578SStephan Aßmus _AdoptPackage(package); 433133ebab6SAndrew Lindesay _IncrementViewCounter(package); 434133ebab6SAndrew Lindesay } 43504c9d578SStephan Aßmus } else { 43604c9d578SStephan Aßmus _ClearPackage(); 43704c9d578SStephan Aßmus } 43804c9d578SStephan Aßmus break; 43904c9d578SStephan Aßmus } 44004c9d578SStephan Aßmus 44104c9d578SStephan Aßmus case MSG_CATEGORY_SELECTED: 44204c9d578SStephan Aßmus { 44389b16bb4SAndrew Lindesay BString code; 44489b16bb4SAndrew Lindesay if (message->FindString("code", &code) != B_OK) 44589b16bb4SAndrew Lindesay code = ""; 44604c9d578SStephan Aßmus { 44704c9d578SStephan Aßmus BAutolock locker(fModel.Lock()); 44889b16bb4SAndrew Lindesay fModel.SetCategory(code); 44904c9d578SStephan Aßmus } 45004c9d578SStephan Aßmus _AdoptModel(); 45104c9d578SStephan Aßmus break; 45204c9d578SStephan Aßmus } 45304c9d578SStephan Aßmus 45404c9d578SStephan Aßmus case MSG_DEPOT_SELECTED: 45504c9d578SStephan Aßmus { 45604c9d578SStephan Aßmus BString name; 45704c9d578SStephan Aßmus if (message->FindString("name", &name) != B_OK) 45804c9d578SStephan Aßmus name = ""; 45904c9d578SStephan Aßmus { 46004c9d578SStephan Aßmus BAutolock locker(fModel.Lock()); 46104c9d578SStephan Aßmus fModel.SetDepot(name); 46204c9d578SStephan Aßmus } 46304c9d578SStephan Aßmus _AdoptModel(); 464b965ce70SHumdinger _UpdateAvailableRepositories(); 46504c9d578SStephan Aßmus break; 46604c9d578SStephan Aßmus } 46704c9d578SStephan Aßmus 46804c9d578SStephan Aßmus case MSG_SEARCH_TERMS_MODIFIED: 46904c9d578SStephan Aßmus { 47004c9d578SStephan Aßmus // TODO: Do this with a delay! 47104c9d578SStephan Aßmus BString searchTerms; 47204c9d578SStephan Aßmus if (message->FindString("search terms", &searchTerms) != B_OK) 47304c9d578SStephan Aßmus searchTerms = ""; 47404c9d578SStephan Aßmus { 47504c9d578SStephan Aßmus BAutolock locker(fModel.Lock()); 47604c9d578SStephan Aßmus fModel.SetSearchTerms(searchTerms); 47704c9d578SStephan Aßmus } 47804c9d578SStephan Aßmus _AdoptModel(); 47904c9d578SStephan Aßmus break; 48004c9d578SStephan Aßmus } 48104c9d578SStephan Aßmus 482da651104SStephan Aßmus case MSG_PACKAGE_CHANGED: 48304c9d578SStephan Aßmus { 48404c9d578SStephan Aßmus PackageInfo* info; 48504c9d578SStephan Aßmus if (message->FindPointer("package", (void**)&info) == B_OK) { 48604c9d578SStephan Aßmus PackageInfoRef ref(info, true); 487da651104SStephan Aßmus uint32 changes; 488da651104SStephan Aßmus if (message->FindUInt32("changes", &changes) != B_OK) 489da651104SStephan Aßmus changes = 0; 490da651104SStephan Aßmus if ((changes & PKG_CHANGED_STATE) != 0) { 49104c9d578SStephan Aßmus BAutolock locker(fModel.Lock()); 49204c9d578SStephan Aßmus fModel.SetPackageState(ref, ref->State()); 49304c9d578SStephan Aßmus } 4940b69420bSAndrew Lindesay 4950b69420bSAndrew Lindesay fFeaturedPackagesView->BeginAddRemove(); 496c4199192SAndrew Lindesay _AddRemovePackageFromLists(ref); 4970b69420bSAndrew Lindesay fFeaturedPackagesView->EndAddRemove(); 4980b69420bSAndrew Lindesay 49987016f8fSAndrew Lindesay if ((changes & PKG_CHANGED_STATE) != 0 500779ab335SX512 && !fCoordinator.IsSet()) { 5014e6fbe03SJulian Harnath fWorkStatusView->PackageStatusChanged(ref); 50257e51fffSStephan Aßmus } 50310cd325cSAndrew Lindesay } 50404c9d578SStephan Aßmus break; 50504c9d578SStephan Aßmus } 50604c9d578SStephan Aßmus 50704c9d578SStephan Aßmus case MSG_RATE_PACKAGE: 5081bbda92dSStephan Aßmus _RatePackage(); 50904c9d578SStephan Aßmus break; 51004c9d578SStephan Aßmus 511d5ef985eSStephan Aßmus case MSG_SHOW_SCREENSHOT: 512d5ef985eSStephan Aßmus _ShowScreenshot(); 513d5ef985eSStephan Aßmus break; 514d5ef985eSStephan Aßmus 515125d42d9SJulian Harnath case MSG_PACKAGE_WORKER_BUSY: 516125d42d9SJulian Harnath { 517125d42d9SJulian Harnath BString reason; 518125d42d9SJulian Harnath status_t status = message->FindString("reason", &reason); 519125d42d9SJulian Harnath if (status != B_OK) 520125d42d9SJulian Harnath break; 521125d42d9SJulian Harnath fWorkStatusView->SetBusy(reason); 522125d42d9SJulian Harnath break; 523125d42d9SJulian Harnath } 524125d42d9SJulian Harnath 525125d42d9SJulian Harnath case MSG_PACKAGE_WORKER_IDLE: 526125d42d9SJulian Harnath fWorkStatusView->SetIdle(); 527125d42d9SJulian Harnath break; 528125d42d9SJulian Harnath 52910cd325cSAndrew Lindesay case MSG_USER_USAGE_CONDITIONS_NOT_LATEST: 53010cd325cSAndrew Lindesay { 53110cd325cSAndrew Lindesay BMessage userDetailMsg; 53210cd325cSAndrew Lindesay if (message->FindMessage("userDetail", &userDetailMsg) != B_OK) { 53310cd325cSAndrew Lindesay debugger("expected the [userDetail] data to be carried in the " 53410cd325cSAndrew Lindesay "message."); 53510cd325cSAndrew Lindesay } 53610cd325cSAndrew Lindesay UserDetail userDetail(&userDetailMsg); 53710cd325cSAndrew Lindesay _HandleUserUsageConditionsNotLatest(userDetail); 53810cd325cSAndrew Lindesay break; 53910cd325cSAndrew Lindesay } 54010cd325cSAndrew Lindesay 54104c9d578SStephan Aßmus default: 54204c9d578SStephan Aßmus BWindow::MessageReceived(message); 54304c9d578SStephan Aßmus break; 54404c9d578SStephan Aßmus } 54504c9d578SStephan Aßmus } 54604c9d578SStephan Aßmus 54704c9d578SStephan Aßmus 548ccf707d0SAndrew Lindesay static const char* 549ccf707d0SAndrew Lindesay main_window_package_list_view_mode_str(package_list_view_mode mode) 550ccf707d0SAndrew Lindesay { 551ccf707d0SAndrew Lindesay if (mode == PROMINENT) 552ccf707d0SAndrew Lindesay return "PROMINENT"; 553ccf707d0SAndrew Lindesay return "ALL"; 554ccf707d0SAndrew Lindesay } 555ccf707d0SAndrew Lindesay 556ccf707d0SAndrew Lindesay 557ccf707d0SAndrew Lindesay static package_list_view_mode 558ccf707d0SAndrew Lindesay main_window_str_to_package_list_view_mode(const BString& str) 559ccf707d0SAndrew Lindesay { 560ccf707d0SAndrew Lindesay if (str == "PROMINENT") 561ccf707d0SAndrew Lindesay return PROMINENT; 562ccf707d0SAndrew Lindesay return ALL; 563ccf707d0SAndrew Lindesay } 564ccf707d0SAndrew Lindesay 565ccf707d0SAndrew Lindesay 56604c9d578SStephan Aßmus void 56704c9d578SStephan Aßmus MainWindow::StoreSettings(BMessage& settings) const 56804c9d578SStephan Aßmus { 569f7c2983eSAxel Dörfler settings.AddRect(_WindowFrameName(), Frame()); 570f7c2983eSAxel Dörfler if (!fSinglePackageMode) { 57104c9d578SStephan Aßmus settings.AddRect("window frame", Frame()); 57204c9d578SStephan Aßmus 57304c9d578SStephan Aßmus BMessage columnSettings; 5749883929bSAndrew Lindesay if (fPackageListView != NULL) 57504c9d578SStephan Aßmus fPackageListView->SaveState(&columnSettings); 57604c9d578SStephan Aßmus 57704c9d578SStephan Aßmus settings.AddMessage("column settings", &columnSettings); 57804c9d578SStephan Aßmus 579133ebab6SAndrew Lindesay settings.AddString(SETTING_PACKAGE_LIST_VIEW_MODE, 580ccf707d0SAndrew Lindesay main_window_package_list_view_mode_str( 581ccf707d0SAndrew Lindesay fModel.PackageListViewMode())); 582133ebab6SAndrew Lindesay settings.AddBool(SETTING_SHOW_AVAILABLE_PACKAGES, 5832997e05bSStephan Aßmus fModel.ShowAvailablePackages()); 584133ebab6SAndrew Lindesay settings.AddBool(SETTING_SHOW_INSTALLED_PACKAGES, 5852997e05bSStephan Aßmus fModel.ShowInstalledPackages()); 586133ebab6SAndrew Lindesay settings.AddBool(SETTING_SHOW_DEVELOP_PACKAGES, 587133ebab6SAndrew Lindesay fModel.ShowDevelopPackages()); 588133ebab6SAndrew Lindesay settings.AddBool(SETTING_SHOW_SOURCE_PACKAGES, 589133ebab6SAndrew Lindesay fModel.ShowSourcePackages()); 590133ebab6SAndrew Lindesay settings.AddBool(SETTING_CAN_SHARE_ANONYMOUS_USER_DATA, 591133ebab6SAndrew Lindesay fModel.CanShareAnonymousUsageData()); 5926d519fd1SStephan Aßmus } 5938f03a0f9SStephan Aßmus 594d2d4866dSAndrew Lindesay settings.AddString("username", fModel.Nickname()); 59504c9d578SStephan Aßmus } 59604c9d578SStephan Aßmus 59704c9d578SStephan Aßmus 59804c9d578SStephan Aßmus void 599a18f873fSAndrew Lindesay MainWindow::Consume(ProcessCoordinator *item) 600a18f873fSAndrew Lindesay { 601a18f873fSAndrew Lindesay _AddProcessCoordinator(item); 602a18f873fSAndrew Lindesay } 603a18f873fSAndrew Lindesay 604a18f873fSAndrew Lindesay 605a18f873fSAndrew Lindesay void 60604c9d578SStephan Aßmus MainWindow::PackageChanged(const PackageInfoEvent& event) 60704c9d578SStephan Aßmus { 608a9edb9bfSAndrew Lindesay uint32 watchedChanges = PKG_CHANGED_STATE | PKG_CHANGED_PROMINENCE; 609a9edb9bfSAndrew Lindesay if ((event.Changes() & watchedChanges) != 0) { 61004c9d578SStephan Aßmus PackageInfoRef ref(event.Package()); 611da651104SStephan Aßmus BMessage message(MSG_PACKAGE_CHANGED); 61204c9d578SStephan Aßmus message.AddPointer("package", ref.Get()); 613da651104SStephan Aßmus message.AddUInt32("changes", event.Changes()); 61404c9d578SStephan Aßmus ref.Detach(); 61504c9d578SStephan Aßmus // reference needs to be released by MessageReceived(); 61604c9d578SStephan Aßmus PostMessage(&message); 61704c9d578SStephan Aßmus } 61804c9d578SStephan Aßmus } 61904c9d578SStephan Aßmus 62004c9d578SStephan Aßmus 62104c9d578SStephan Aßmus void 62204c9d578SStephan Aßmus MainWindow::_BuildMenu(BMenuBar* menuBar) 62304c9d578SStephan Aßmus { 6240b6928f1SHumdinger BMenu* menu = new BMenu(B_TRANSLATE_SYSTEM_NAME("HaikuDepot")); 6253369e03dSAndrew Lindesay fRefreshRepositoriesItem = new BMenuItem( 6263369e03dSAndrew Lindesay B_TRANSLATE("Refresh repositories"), new BMessage(MSG_REFRESH_REPOS)); 6273369e03dSAndrew Lindesay menu->AddItem(fRefreshRepositoriesItem); 628d7f78130SHumdinger menu->AddItem(new BMenuItem(B_TRANSLATE("Manage repositories" 629d7f78130SHumdinger B_UTF8_ELLIPSIS), new BMessage(MSG_MANAGE_REPOS))); 630d144f952SAugustin Cavalier menu->AddItem(new BMenuItem(B_TRANSLATE("Check for updates" 631d144f952SAugustin Cavalier B_UTF8_ELLIPSIS), new BMessage(MSG_SOFTWARE_UPDATER))); 6320b6928f1SHumdinger menu->AddSeparatorItem(); 6330b6928f1SHumdinger menu->AddItem(new BMenuItem(B_TRANSLATE("Settings" B_UTF8_ELLIPSIS), 634e1ae57abSJoachim Mairböck new BMessage(MSG_SETTINGS), ',')); 6350b6928f1SHumdinger menu->AddItem(new BMenuItem(B_TRANSLATE("Quit"), 6360b6928f1SHumdinger new BMessage(B_QUIT_REQUESTED), 'Q')); 63704c9d578SStephan Aßmus menuBar->AddItem(menu); 63804c9d578SStephan Aßmus 639b965ce70SHumdinger fRepositoryMenu = new BMenu(B_TRANSLATE("Repositories")); 640b965ce70SHumdinger menuBar->AddItem(fRepositoryMenu); 641b965ce70SHumdinger 6424fade61fSStephan Aßmus menu = new BMenu(B_TRANSLATE("Show")); 6434fade61fSStephan Aßmus 644fdec4227SStephan Aßmus fShowAvailablePackagesItem = new BMenuItem( 6454fade61fSStephan Aßmus B_TRANSLATE("Available packages"), 646fdec4227SStephan Aßmus new BMessage(MSG_SHOW_AVAILABLE_PACKAGES)); 647fdec4227SStephan Aßmus menu->AddItem(fShowAvailablePackagesItem); 648fdec4227SStephan Aßmus 649fdec4227SStephan Aßmus fShowInstalledPackagesItem = new BMenuItem( 6504fade61fSStephan Aßmus B_TRANSLATE("Installed packages"), 651fdec4227SStephan Aßmus new BMessage(MSG_SHOW_INSTALLED_PACKAGES)); 652fdec4227SStephan Aßmus menu->AddItem(fShowInstalledPackagesItem); 653fdec4227SStephan Aßmus 654fdec4227SStephan Aßmus menu->AddSeparatorItem(); 655fdec4227SStephan Aßmus 656fdec4227SStephan Aßmus fShowDevelopPackagesItem = new BMenuItem( 6574fade61fSStephan Aßmus B_TRANSLATE("Develop packages"), 658fdec4227SStephan Aßmus new BMessage(MSG_SHOW_DEVELOP_PACKAGES)); 659fdec4227SStephan Aßmus menu->AddItem(fShowDevelopPackagesItem); 660fdec4227SStephan Aßmus 661fdec4227SStephan Aßmus fShowSourcePackagesItem = new BMenuItem( 6624fade61fSStephan Aßmus B_TRANSLATE("Source packages"), 663fdec4227SStephan Aßmus new BMessage(MSG_SHOW_SOURCE_PACKAGES)); 664fdec4227SStephan Aßmus menu->AddItem(fShowSourcePackagesItem); 665fdec4227SStephan Aßmus 666fdec4227SStephan Aßmus menuBar->AddItem(menu); 66704c9d578SStephan Aßmus } 66804c9d578SStephan Aßmus 66904c9d578SStephan Aßmus 67004c9d578SStephan Aßmus void 671e0a26dceSStephan Aßmus MainWindow::_BuildUserMenu(BMenuBar* menuBar) 672e0a26dceSStephan Aßmus { 673e0a26dceSStephan Aßmus fUserMenu = new BMenu(B_TRANSLATE("Not logged in")); 674e0a26dceSStephan Aßmus 675e0a26dceSStephan Aßmus fLogInItem = new BMenuItem(B_TRANSLATE("Log in" B_UTF8_ELLIPSIS), 676e0a26dceSStephan Aßmus new BMessage(MSG_LOG_IN)); 677e0a26dceSStephan Aßmus fUserMenu->AddItem(fLogInItem); 678e0a26dceSStephan Aßmus 679e0a26dceSStephan Aßmus fLogOutItem = new BMenuItem(B_TRANSLATE("Log out"), 680e0a26dceSStephan Aßmus new BMessage(MSG_LOG_OUT)); 681e0a26dceSStephan Aßmus fUserMenu->AddItem(fLogOutItem); 682e0a26dceSStephan Aßmus 6830c82f64bSAndrew Lindesay BMenuItem *latestUserUsageConditionsMenuItem = 6841448ced0SHumdinger new BMenuItem(B_TRANSLATE("View latest usage conditions" 68501339a54SAndrew Lindesay B_UTF8_ELLIPSIS), 68601339a54SAndrew Lindesay new BMessage(MSG_VIEW_LATEST_USER_USAGE_CONDITIONS)); 6870c82f64bSAndrew Lindesay fUserMenu->AddItem(latestUserUsageConditionsMenuItem); 68801339a54SAndrew Lindesay 689d2d4866dSAndrew Lindesay fUsersUserUsageConditionsMenuItem = 690d2d4866dSAndrew Lindesay new BMenuItem(B_TRANSLATE("View agreed usage conditions" 691d2d4866dSAndrew Lindesay B_UTF8_ELLIPSIS), 692d2d4866dSAndrew Lindesay new BMessage(MSG_VIEW_USERS_USER_USAGE_CONDITIONS)); 693d2d4866dSAndrew Lindesay fUserMenu->AddItem(fUsersUserUsageConditionsMenuItem); 694d2d4866dSAndrew Lindesay 695e0a26dceSStephan Aßmus menuBar->AddItem(fUserMenu); 696e0a26dceSStephan Aßmus } 697e0a26dceSStephan Aßmus 698e0a26dceSStephan Aßmus 699e0a26dceSStephan Aßmus void 700d2d4866dSAndrew Lindesay MainWindow::_RestoreNickname(const BMessage& settings) 701f7c2983eSAxel Dörfler { 702d2d4866dSAndrew Lindesay BString nickname; 703d2d4866dSAndrew Lindesay if (settings.FindString("username", &nickname) == B_OK 704d2d4866dSAndrew Lindesay && nickname.Length() > 0) { 705d2d4866dSAndrew Lindesay fModel.SetNickname(nickname); 706f7c2983eSAxel Dörfler } 707f7c2983eSAxel Dörfler } 708f7c2983eSAxel Dörfler 709f7c2983eSAxel Dörfler 710f7c2983eSAxel Dörfler const char* 711f7c2983eSAxel Dörfler MainWindow::_WindowFrameName() const 712f7c2983eSAxel Dörfler { 713f7c2983eSAxel Dörfler if (fSinglePackageMode) 714f7c2983eSAxel Dörfler return "small window frame"; 715f7c2983eSAxel Dörfler 716f7c2983eSAxel Dörfler return "window frame"; 717f7c2983eSAxel Dörfler } 718f7c2983eSAxel Dörfler 719f7c2983eSAxel Dörfler 720f7c2983eSAxel Dörfler void 721f7c2983eSAxel Dörfler MainWindow::_RestoreWindowFrame(const BMessage& settings) 722f7c2983eSAxel Dörfler { 723f7c2983eSAxel Dörfler BRect frame = Frame(); 724f7c2983eSAxel Dörfler 725f7c2983eSAxel Dörfler BRect windowFrame; 726f7c2983eSAxel Dörfler bool fromSettings = false; 727f7c2983eSAxel Dörfler if (settings.FindRect(_WindowFrameName(), &windowFrame) == B_OK) { 728f7c2983eSAxel Dörfler frame = windowFrame; 729f7c2983eSAxel Dörfler fromSettings = true; 730f7c2983eSAxel Dörfler } else if (!fSinglePackageMode) { 731f7c2983eSAxel Dörfler // Resize to occupy a certain screen size 732f7c2983eSAxel Dörfler BRect screenFrame = BScreen(this).Frame(); 733f7c2983eSAxel Dörfler float width = frame.Width(); 734f7c2983eSAxel Dörfler float height = frame.Height(); 735f7c2983eSAxel Dörfler if (width < screenFrame.Width() * .666f 736f7c2983eSAxel Dörfler && height < screenFrame.Height() * .666f) { 737f7c2983eSAxel Dörfler frame.bottom = frame.top + screenFrame.Height() * .666f; 738f7c2983eSAxel Dörfler frame.right = frame.left 739f7c2983eSAxel Dörfler + std::min(screenFrame.Width() * .666f, height * 7 / 5); 740f7c2983eSAxel Dörfler } 741f7c2983eSAxel Dörfler } 742f7c2983eSAxel Dörfler 743f7c2983eSAxel Dörfler MoveTo(frame.LeftTop()); 744f7c2983eSAxel Dörfler ResizeTo(frame.Width(), frame.Height()); 745f7c2983eSAxel Dörfler 746f7c2983eSAxel Dörfler if (fromSettings) 7478e96ec34SAxel Dörfler MoveOnScreen(); 748f7c2983eSAxel Dörfler else 749f7c2983eSAxel Dörfler CenterOnScreen(); 750f7c2983eSAxel Dörfler } 751f7c2983eSAxel Dörfler 752f7c2983eSAxel Dörfler 753f7c2983eSAxel Dörfler void 754ccf707d0SAndrew Lindesay MainWindow::_RestoreModelSettings(const BMessage& settings) 755ccf707d0SAndrew Lindesay { 756ccf707d0SAndrew Lindesay BString packageListViewMode; 757133ebab6SAndrew Lindesay if (settings.FindString(SETTING_PACKAGE_LIST_VIEW_MODE, 758ccf707d0SAndrew Lindesay &packageListViewMode) == B_OK) { 759ccf707d0SAndrew Lindesay fModel.SetPackageListViewMode( 760ccf707d0SAndrew Lindesay main_window_str_to_package_list_view_mode(packageListViewMode)); 761ccf707d0SAndrew Lindesay } 762ccf707d0SAndrew Lindesay 763ccf707d0SAndrew Lindesay bool showOption; 764133ebab6SAndrew Lindesay if (settings.FindBool(SETTING_SHOW_AVAILABLE_PACKAGES, &showOption) == B_OK) 765ccf707d0SAndrew Lindesay fModel.SetShowAvailablePackages(showOption); 766133ebab6SAndrew Lindesay if (settings.FindBool(SETTING_SHOW_INSTALLED_PACKAGES, &showOption) == B_OK) 767ccf707d0SAndrew Lindesay fModel.SetShowInstalledPackages(showOption); 768133ebab6SAndrew Lindesay if (settings.FindBool(SETTING_SHOW_DEVELOP_PACKAGES, &showOption) == B_OK) 769ccf707d0SAndrew Lindesay fModel.SetShowDevelopPackages(showOption); 770133ebab6SAndrew Lindesay if (settings.FindBool(SETTING_SHOW_SOURCE_PACKAGES, &showOption) == B_OK) 771ccf707d0SAndrew Lindesay fModel.SetShowSourcePackages(showOption); 772133ebab6SAndrew Lindesay if (settings.FindBool(SETTING_CAN_SHARE_ANONYMOUS_USER_DATA, 773133ebab6SAndrew Lindesay &showOption) == B_OK) { 774133ebab6SAndrew Lindesay fModel.SetCanShareAnonymousUsageData(showOption); 775133ebab6SAndrew Lindesay } 776133ebab6SAndrew Lindesay } 777133ebab6SAndrew Lindesay 778133ebab6SAndrew Lindesay 779133ebab6SAndrew Lindesay void 780133ebab6SAndrew Lindesay MainWindow::_MaybePromptCanShareAnonymousUserData(const BMessage& settings) 781133ebab6SAndrew Lindesay { 782133ebab6SAndrew Lindesay bool showOption; 783133ebab6SAndrew Lindesay if (settings.FindBool(SETTING_CAN_SHARE_ANONYMOUS_USER_DATA, 784133ebab6SAndrew Lindesay &showOption) == B_NAME_NOT_FOUND) { 785133ebab6SAndrew Lindesay _PromptCanShareAnonymousUserData(); 786133ebab6SAndrew Lindesay } 787133ebab6SAndrew Lindesay } 788133ebab6SAndrew Lindesay 789133ebab6SAndrew Lindesay 790133ebab6SAndrew Lindesay void 791133ebab6SAndrew Lindesay MainWindow::_PromptCanShareAnonymousUserData() 792133ebab6SAndrew Lindesay { 793133ebab6SAndrew Lindesay BAlert* alert = new(std::nothrow) BAlert( 794133ebab6SAndrew Lindesay B_TRANSLATE("Sending anonymous usage data"), 795133ebab6SAndrew Lindesay B_TRANSLATE("Would it be acceptable to send anonymous usage data to the" 796133ebab6SAndrew Lindesay " HaikuDepotServer system from this computer? You can change your" 797133ebab6SAndrew Lindesay " preference in the \"Settings\" window later."), 798133ebab6SAndrew Lindesay B_TRANSLATE("No"), 799133ebab6SAndrew Lindesay B_TRANSLATE("Yes")); 800133ebab6SAndrew Lindesay 801133ebab6SAndrew Lindesay int32 result = alert->Go(); 802133ebab6SAndrew Lindesay fModel.SetCanShareAnonymousUsageData(1 == result); 803ccf707d0SAndrew Lindesay } 804ccf707d0SAndrew Lindesay 805ccf707d0SAndrew Lindesay 806ccf707d0SAndrew Lindesay void 80763975654SStephan Aßmus MainWindow::_InitWorkerThreads() 80863975654SStephan Aßmus { 80963975654SStephan Aßmus fPackageToPopulateSem = create_sem(0, "PopulatePackage"); 81063975654SStephan Aßmus if (fPackageToPopulateSem >= 0) { 81163975654SStephan Aßmus fPopulatePackageWorker = spawn_thread(&_PopulatePackageWorker, 81263975654SStephan Aßmus "Package Populator", B_NORMAL_PRIORITY, this); 81363975654SStephan Aßmus if (fPopulatePackageWorker >= 0) 81463975654SStephan Aßmus resume_thread(fPopulatePackageWorker); 81509f82905SStephan Aßmus } else 81609f82905SStephan Aßmus fPopulatePackageWorker = -1; 81763975654SStephan Aßmus } 81863975654SStephan Aßmus 81963975654SStephan Aßmus 82063975654SStephan Aßmus void 821c4199192SAndrew Lindesay MainWindow::_AdoptModelControls() 82204c9d578SStephan Aßmus { 8239883929bSAndrew Lindesay if (fSinglePackageMode) 8249883929bSAndrew Lindesay return; 8259883929bSAndrew Lindesay 82604c9d578SStephan Aßmus BAutolock locker(fModel.Lock()); 827fdec4227SStephan Aßmus fShowAvailablePackagesItem->SetMarked(fModel.ShowAvailablePackages()); 828fdec4227SStephan Aßmus fShowInstalledPackagesItem->SetMarked(fModel.ShowInstalledPackages()); 829fdec4227SStephan Aßmus fShowSourcePackagesItem->SetMarked(fModel.ShowSourcePackages()); 830fdec4227SStephan Aßmus fShowDevelopPackagesItem->SetMarked(fModel.ShowDevelopPackages()); 831da651104SStephan Aßmus 832ccf707d0SAndrew Lindesay if (fModel.PackageListViewMode() == PROMINENT) 833ccf707d0SAndrew Lindesay fListTabs->Select(TAB_PROMINENT_PACKAGES); 8344fade61fSStephan Aßmus else 835ccf707d0SAndrew Lindesay fListTabs->Select(TAB_ALL_PACKAGES); 836b965ce70SHumdinger 837b965ce70SHumdinger fFilterView->AdoptModel(fModel); 83804c9d578SStephan Aßmus } 83904c9d578SStephan Aßmus 84004c9d578SStephan Aßmus 84104c9d578SStephan Aßmus void 842c4199192SAndrew Lindesay MainWindow::_AdoptModel() 843c4199192SAndrew Lindesay { 844fa5c8097SAndrew Lindesay HDTRACE("adopting model to main window ui"); 845c4199192SAndrew Lindesay 846c4199192SAndrew Lindesay if (fSinglePackageMode) 847c4199192SAndrew Lindesay return; 848c4199192SAndrew Lindesay 84905880d13SAndrew Lindesay std::vector<DepotInfoRef> depots = _CreateSnapshotOfDepots(); 85005880d13SAndrew Lindesay std::vector<DepotInfoRef>::iterator it; 8510b69420bSAndrew Lindesay 8520b69420bSAndrew Lindesay fFeaturedPackagesView->BeginAddRemove(); 8530b69420bSAndrew Lindesay 85405880d13SAndrew Lindesay for (it = depots.begin(); it != depots.end(); it++) { 85505880d13SAndrew Lindesay DepotInfoRef depotInfoRef = *it; 856d75b4d61SAndrew Lindesay for (int i = 0; i < depotInfoRef->CountPackages(); i++) { 857d75b4d61SAndrew Lindesay PackageInfoRef package = depotInfoRef->PackageAtIndex(i); 858d75b4d61SAndrew Lindesay _AddRemovePackageFromLists(package); 859d75b4d61SAndrew Lindesay } 860c4199192SAndrew Lindesay } 861c4199192SAndrew Lindesay 8620b69420bSAndrew Lindesay fFeaturedPackagesView->EndAddRemove(); 8630b69420bSAndrew Lindesay 864c4199192SAndrew Lindesay _AdoptModelControls(); 865c4199192SAndrew Lindesay } 866c4199192SAndrew Lindesay 867c4199192SAndrew Lindesay 868c4199192SAndrew Lindesay void 869c4199192SAndrew Lindesay MainWindow::_AddRemovePackageFromLists(const PackageInfoRef& package) 870c4199192SAndrew Lindesay { 871c4199192SAndrew Lindesay bool matches; 872c4199192SAndrew Lindesay 873c4199192SAndrew Lindesay { 874c4199192SAndrew Lindesay AutoLocker<BLocker> modelLocker(fModel.Lock()); 875c4199192SAndrew Lindesay matches = fModel.MatchesFilter(package); 876c4199192SAndrew Lindesay } 877c4199192SAndrew Lindesay 878c4199192SAndrew Lindesay if (matches) { 879c4199192SAndrew Lindesay if (package->IsProminent()) 880c4199192SAndrew Lindesay fFeaturedPackagesView->AddPackage(package); 881c4199192SAndrew Lindesay fPackageListView->AddPackage(package); 882c4199192SAndrew Lindesay } else { 883c4199192SAndrew Lindesay fFeaturedPackagesView->RemovePackage(package); 884c4199192SAndrew Lindesay fPackageListView->RemovePackage(package); 885c4199192SAndrew Lindesay } 886c4199192SAndrew Lindesay } 887c4199192SAndrew Lindesay 888c4199192SAndrew Lindesay 889c4199192SAndrew Lindesay void 890133ebab6SAndrew Lindesay MainWindow::_IncrementViewCounter(const PackageInfoRef& package) 891133ebab6SAndrew Lindesay { 892133ebab6SAndrew Lindesay bool shouldIncrementViewCounter = false; 893133ebab6SAndrew Lindesay 894133ebab6SAndrew Lindesay { 895133ebab6SAndrew Lindesay AutoLocker<BLocker> modelLocker(fModel.Lock()); 896133ebab6SAndrew Lindesay bool canShareAnonymousUsageData = fModel.CanShareAnonymousUsageData(); 897133ebab6SAndrew Lindesay if (canShareAnonymousUsageData && !package->Viewed()) { 898133ebab6SAndrew Lindesay package->SetViewed(); 899133ebab6SAndrew Lindesay shouldIncrementViewCounter = true; 900133ebab6SAndrew Lindesay } 901133ebab6SAndrew Lindesay } 902133ebab6SAndrew Lindesay 903133ebab6SAndrew Lindesay if (shouldIncrementViewCounter) { 904133ebab6SAndrew Lindesay ProcessCoordinator* bulkLoadCoordinator = 905133ebab6SAndrew Lindesay ProcessCoordinatorFactory::CreateIncrementViewCounter( 906133ebab6SAndrew Lindesay &fModel, package); 907133ebab6SAndrew Lindesay _AddProcessCoordinator(bulkLoadCoordinator); 908133ebab6SAndrew Lindesay } 909133ebab6SAndrew Lindesay } 910133ebab6SAndrew Lindesay 911133ebab6SAndrew Lindesay 912133ebab6SAndrew Lindesay void 91304c9d578SStephan Aßmus MainWindow::_AdoptPackage(const PackageInfoRef& package) 91404c9d578SStephan Aßmus { 91575ba9dbfSStephan Aßmus { 91675ba9dbfSStephan Aßmus BAutolock locker(fModel.Lock()); 91704c9d578SStephan Aßmus fPackageInfoView->SetPackage(package); 9181986ab9fSStephan Aßmus 919664372abSStephan Aßmus if (fFeaturedPackagesView != NULL) 920664372abSStephan Aßmus fFeaturedPackagesView->SelectPackage(package); 9211986ab9fSStephan Aßmus if (fPackageListView != NULL) 9221986ab9fSStephan Aßmus fPackageListView->SelectPackage(package); 92375ba9dbfSStephan Aßmus } 92404c9d578SStephan Aßmus 925a9edb9bfSAndrew Lindesay _PopulatePackageAsync(false); 92604c9d578SStephan Aßmus } 92704c9d578SStephan Aßmus 92804c9d578SStephan Aßmus 92904c9d578SStephan Aßmus void 93004c9d578SStephan Aßmus MainWindow::_ClearPackage() 93104c9d578SStephan Aßmus { 93204c9d578SStephan Aßmus fPackageInfoView->Clear(); 93304c9d578SStephan Aßmus } 93404c9d578SStephan Aßmus 93504c9d578SStephan Aßmus 93604c9d578SStephan Aßmus void 9373369e03dSAndrew Lindesay MainWindow::_StartBulkLoad(bool force) 93804c9d578SStephan Aßmus { 939c4199192SAndrew Lindesay if (fFeaturedPackagesView != NULL) 940c4199192SAndrew Lindesay fFeaturedPackagesView->Clear(); 941c4199192SAndrew Lindesay if (fPackageListView != NULL) 942c4199192SAndrew Lindesay fPackageListView->Clear(); 943c4199192SAndrew Lindesay fPackageInfoView->Clear(); 944c4199192SAndrew Lindesay 94510cd325cSAndrew Lindesay fRefreshRepositoriesItem->SetEnabled(false); 94610cd325cSAndrew Lindesay ProcessCoordinator* bulkLoadCoordinator = 94710cd325cSAndrew Lindesay ProcessCoordinatorFactory::CreateBulkLoadCoordinator( 9483369e03dSAndrew Lindesay this, 9493369e03dSAndrew Lindesay // PackageInfoListener 9503369e03dSAndrew Lindesay &fModel, force); 95110cd325cSAndrew Lindesay _AddProcessCoordinator(bulkLoadCoordinator); 95204c9d578SStephan Aßmus } 95304c9d578SStephan Aßmus 95404c9d578SStephan Aßmus 95504c9d578SStephan Aßmus void 95610cd325cSAndrew Lindesay MainWindow::_BulkLoadCompleteReceived(status_t errorStatus) 95704c9d578SStephan Aßmus { 95810cd325cSAndrew Lindesay if (errorStatus != B_OK) { 9593369e03dSAndrew Lindesay AppUtils::NotifySimpleError( 9601448ced0SHumdinger B_TRANSLATE("Package update error"), 9613369e03dSAndrew Lindesay B_TRANSLATE("While updating package data, a problem has arisen " 9623369e03dSAndrew Lindesay "that may cause data to be outdated or missing from the " 9633369e03dSAndrew Lindesay "application's display. Additional details regarding this " 9643369e03dSAndrew Lindesay "problem may be able to be obtained from the application " 965b21c9447SAndrew Lindesay "logs." 966b21c9447SAndrew Lindesay ALERT_MSG_LOGS_USER_GUIDE)); 96704c9d578SStephan Aßmus } 96810cd325cSAndrew Lindesay 9693369e03dSAndrew Lindesay fRefreshRepositoriesItem->SetEnabled(true); 97010cd325cSAndrew Lindesay _AdoptModel(); 97110cd325cSAndrew Lindesay _UpdateAvailableRepositories(); 972ccf707d0SAndrew Lindesay 973ccf707d0SAndrew Lindesay // if after loading everything in, it transpires that there are no 974ccf707d0SAndrew Lindesay // featured packages then the featured packages should be disabled 975ccf707d0SAndrew Lindesay // and the user should be switched to the "all packages" view so 976ccf707d0SAndrew Lindesay // that they are not presented with a blank window! 977ccf707d0SAndrew Lindesay 978ccf707d0SAndrew Lindesay bool hasProminentPackages = fModel.HasAnyProminentPackages(); 979ccf707d0SAndrew Lindesay fListTabs->TabAt(TAB_PROMINENT_PACKAGES)->SetEnabled(hasProminentPackages); 980ccf707d0SAndrew Lindesay if (!hasProminentPackages 981ccf707d0SAndrew Lindesay && fListTabs->Selection() == TAB_PROMINENT_PACKAGES) { 982ccf707d0SAndrew Lindesay fModel.SetPackageListViewMode(ALL); 983ccf707d0SAndrew Lindesay fListTabs->Select(TAB_ALL_PACKAGES); 984ccf707d0SAndrew Lindesay } 98504c9d578SStephan Aßmus } 98604c9d578SStephan Aßmus 98704c9d578SStephan Aßmus 9883369e03dSAndrew Lindesay void 98910cd325cSAndrew Lindesay MainWindow::_NotifyWorkStatusClear() 99004c9d578SStephan Aßmus { 99110cd325cSAndrew Lindesay BMessage message(MSG_WORK_STATUS_CLEAR); 99210cd325cSAndrew Lindesay this->PostMessage(&message, this); 99310cd325cSAndrew Lindesay } 99410cd325cSAndrew Lindesay 99510cd325cSAndrew Lindesay 99610cd325cSAndrew Lindesay void 99710cd325cSAndrew Lindesay MainWindow::_HandleWorkStatusClear() 99810cd325cSAndrew Lindesay { 99910cd325cSAndrew Lindesay fWorkStatusView->SetText(""); 10003369e03dSAndrew Lindesay fWorkStatusView->SetIdle(); 10013369e03dSAndrew Lindesay } 100204c9d578SStephan Aßmus 100304c9d578SStephan Aßmus 10043369e03dSAndrew Lindesay /*! Sends off a message to the Window so that it can change the status view 10053369e03dSAndrew Lindesay on the front-end in the UI thread. 10063369e03dSAndrew Lindesay */ 100704c9d578SStephan Aßmus 10083369e03dSAndrew Lindesay void 10093369e03dSAndrew Lindesay MainWindow::_NotifyWorkStatusChange(const BString& text, float progress) 10103369e03dSAndrew Lindesay { 10113369e03dSAndrew Lindesay BMessage message(MSG_WORK_STATUS_CHANGE); 101204c9d578SStephan Aßmus 10133369e03dSAndrew Lindesay if (!text.IsEmpty()) 10143369e03dSAndrew Lindesay message.AddString(KEY_WORK_STATUS_TEXT, text); 10153369e03dSAndrew Lindesay message.AddFloat(KEY_WORK_STATUS_PROGRESS, progress); 101604c9d578SStephan Aßmus 10173369e03dSAndrew Lindesay this->PostMessage(&message, this); 10183369e03dSAndrew Lindesay } 101904c9d578SStephan Aßmus 10203369e03dSAndrew Lindesay 1021*f32d5c5cSAndrew Lindesay // needs to be implemented to update details for added / removed packages. 1022*f32d5c5cSAndrew Lindesay // TODO: see ticket #15879 1023*f32d5c5cSAndrew Lindesay 1024*f32d5c5cSAndrew Lindesay void 1025*f32d5c5cSAndrew Lindesay MainWindow::_HandleExternalPackageUpdateMessageReceived(const BMessage* message) 1026*f32d5c5cSAndrew Lindesay { 1027*f32d5c5cSAndrew Lindesay BStringList addedPackageNames; 1028*f32d5c5cSAndrew Lindesay BStringList removedPackageNames; 1029*f32d5c5cSAndrew Lindesay 1030*f32d5c5cSAndrew Lindesay if (message->FindStrings("added package names", 1031*f32d5c5cSAndrew Lindesay &addedPackageNames) == B_OK) { 1032*f32d5c5cSAndrew Lindesay addedPackageNames.Sort(); 1033*f32d5c5cSAndrew Lindesay for (int32 i = 0; i < addedPackageNames.CountStrings(); i++) { 1034*f32d5c5cSAndrew Lindesay HDINFO("added package name; %s", 1035*f32d5c5cSAndrew Lindesay addedPackageNames.StringAt(i).String()); 1036*f32d5c5cSAndrew Lindesay } 1037*f32d5c5cSAndrew Lindesay } 1038*f32d5c5cSAndrew Lindesay else 1039*f32d5c5cSAndrew Lindesay HDINFO("no [added package names] key in inbound message"); 1040*f32d5c5cSAndrew Lindesay 1041*f32d5c5cSAndrew Lindesay if (message->FindStrings("removed package names", 1042*f32d5c5cSAndrew Lindesay &removedPackageNames) == B_OK) { 1043*f32d5c5cSAndrew Lindesay removedPackageNames.Sort(); 1044*f32d5c5cSAndrew Lindesay for (int32 i = 0; i < removedPackageNames.CountStrings(); i++) { 1045*f32d5c5cSAndrew Lindesay HDINFO("removed package name; %s", 1046*f32d5c5cSAndrew Lindesay removedPackageNames.StringAt(i).String()); 1047*f32d5c5cSAndrew Lindesay } 1048*f32d5c5cSAndrew Lindesay } else 1049*f32d5c5cSAndrew Lindesay HDINFO("no [removed package names] key in inbound message"); 1050*f32d5c5cSAndrew Lindesay } 1051*f32d5c5cSAndrew Lindesay 1052*f32d5c5cSAndrew Lindesay 10533369e03dSAndrew Lindesay void 10543369e03dSAndrew Lindesay MainWindow::_HandleWorkStatusChangeMessageReceived(const BMessage* message) 10553369e03dSAndrew Lindesay { 10569883929bSAndrew Lindesay if (fWorkStatusView == NULL) 10579883929bSAndrew Lindesay return; 10589883929bSAndrew Lindesay 10593369e03dSAndrew Lindesay BString text; 10603369e03dSAndrew Lindesay float progress; 10613369e03dSAndrew Lindesay 10623369e03dSAndrew Lindesay if (message->FindString(KEY_WORK_STATUS_TEXT, &text) == B_OK) 10633369e03dSAndrew Lindesay fWorkStatusView->SetText(text); 10643369e03dSAndrew Lindesay 1065a18f873fSAndrew Lindesay if (message->FindFloat(KEY_WORK_STATUS_PROGRESS, &progress) == B_OK) { 1066a18f873fSAndrew Lindesay if (progress < 0.0f) 1067a18f873fSAndrew Lindesay fWorkStatusView->SetBusy(); 1068a18f873fSAndrew Lindesay else 10693369e03dSAndrew Lindesay fWorkStatusView->SetProgress(progress); 1070a18f873fSAndrew Lindesay } else { 1071a18f873fSAndrew Lindesay HDERROR("work status change missing progress on update message"); 1072a18f873fSAndrew Lindesay fWorkStatusView->SetProgress(0.0f); 107304c9d578SStephan Aßmus } 107404c9d578SStephan Aßmus } 107504c9d578SStephan Aßmus 107604c9d578SStephan Aßmus 1077a9edb9bfSAndrew Lindesay /*! This method will cause the package to have its data refreshed from 1078a9edb9bfSAndrew Lindesay the server application. The refresh happens in the background; this method 1079a9edb9bfSAndrew Lindesay is asynchronous. 1080a9edb9bfSAndrew Lindesay */ 1081a9edb9bfSAndrew Lindesay 1082a9edb9bfSAndrew Lindesay void 1083a9edb9bfSAndrew Lindesay MainWindow::_PopulatePackageAsync(bool forcePopulate) 1084a9edb9bfSAndrew Lindesay { 1085a9edb9bfSAndrew Lindesay // Trigger asynchronous package population from the web-app 1086a9edb9bfSAndrew Lindesay { 1087a9edb9bfSAndrew Lindesay AutoLocker<BLocker> lock(&fPackageToPopulateLock); 1088a9edb9bfSAndrew Lindesay fPackageToPopulate = fPackageInfoView->Package(); 1089a9edb9bfSAndrew Lindesay fForcePopulatePackage = forcePopulate; 1090a9edb9bfSAndrew Lindesay } 1091a9edb9bfSAndrew Lindesay release_sem_etc(fPackageToPopulateSem, 1, 0); 1092a9edb9bfSAndrew Lindesay 1093f96d1f4dSAndrew Lindesay HDDEBUG("pkg [%s] will be updated from the server.", 1094fa5c8097SAndrew Lindesay fPackageToPopulate->Name().String()); 1095a9edb9bfSAndrew Lindesay } 1096a9edb9bfSAndrew Lindesay 1097a9edb9bfSAndrew Lindesay 1098a9edb9bfSAndrew Lindesay /*! This method will run in the background. The thread will block until there 1099a9edb9bfSAndrew Lindesay is a package to be updated. When the thread unblocks, it will update the 1100a9edb9bfSAndrew Lindesay package with information from the server. 1101a9edb9bfSAndrew Lindesay */ 1102a9edb9bfSAndrew Lindesay 110304c9d578SStephan Aßmus status_t 110404c9d578SStephan Aßmus MainWindow::_PopulatePackageWorker(void* arg) 110504c9d578SStephan Aßmus { 110604c9d578SStephan Aßmus MainWindow* window = reinterpret_cast<MainWindow*>(arg); 110704c9d578SStephan Aßmus 110804c9d578SStephan Aßmus while (acquire_sem(window->fPackageToPopulateSem) == B_OK) { 110904c9d578SStephan Aßmus PackageInfoRef package; 1110a9edb9bfSAndrew Lindesay bool force; 111104c9d578SStephan Aßmus { 111204c9d578SStephan Aßmus AutoLocker<BLocker> lock(&window->fPackageToPopulateLock); 111304c9d578SStephan Aßmus package = window->fPackageToPopulate; 1114a9edb9bfSAndrew Lindesay force = window->fForcePopulatePackage; 111504c9d578SStephan Aßmus } 111604c9d578SStephan Aßmus 1117779ab335SX512 if (package.IsSet()) { 1118a9edb9bfSAndrew Lindesay uint32 populateFlags = Model::POPULATE_USER_RATINGS 1119a9edb9bfSAndrew Lindesay | Model::POPULATE_SCREEN_SHOTS 1120a9edb9bfSAndrew Lindesay | Model::POPULATE_CHANGELOG; 1121a9edb9bfSAndrew Lindesay 1122a9edb9bfSAndrew Lindesay if (force) 1123a9edb9bfSAndrew Lindesay populateFlags |= Model::POPULATE_FORCE; 1124a9edb9bfSAndrew Lindesay 1125a9edb9bfSAndrew Lindesay window->fModel.PopulatePackage(package, populateFlags); 1126a9edb9bfSAndrew Lindesay 1127fa5c8097SAndrew Lindesay HDDEBUG("populating package [%s]", package->Name().String()); 112804c9d578SStephan Aßmus } 112904c9d578SStephan Aßmus } 113004c9d578SStephan Aßmus 113104c9d578SStephan Aßmus return 0; 113204c9d578SStephan Aßmus } 113304c9d578SStephan Aßmus 113404c9d578SStephan Aßmus 113504c9d578SStephan Aßmus void 1136133ebab6SAndrew Lindesay MainWindow::_OpenSettingsWindow() 1137133ebab6SAndrew Lindesay { 1138133ebab6SAndrew Lindesay SettingsWindow* window = new SettingsWindow(this, &fModel); 1139133ebab6SAndrew Lindesay window->Show(); 1140133ebab6SAndrew Lindesay } 1141133ebab6SAndrew Lindesay 1142133ebab6SAndrew Lindesay 1143133ebab6SAndrew Lindesay void 11441bbda92dSStephan Aßmus MainWindow::_OpenLoginWindow(const BMessage& onSuccessMessage) 114504c9d578SStephan Aßmus { 114604c9d578SStephan Aßmus UserLoginWindow* window = new UserLoginWindow(this, 114704c9d578SStephan Aßmus BRect(0, 0, 500, 400), fModel); 11481bbda92dSStephan Aßmus 11491bbda92dSStephan Aßmus if (onSuccessMessage.what != 0) 11501bbda92dSStephan Aßmus window->SetOnSuccessMessage(BMessenger(this), onSuccessMessage); 11511bbda92dSStephan Aßmus 115204c9d578SStephan Aßmus window->Show(); 115304c9d578SStephan Aßmus } 115404c9d578SStephan Aßmus 11558f03a0f9SStephan Aßmus 11568f03a0f9SStephan Aßmus void 115710cd325cSAndrew Lindesay MainWindow::_StartUserVerify() 115810cd325cSAndrew Lindesay { 115910cd325cSAndrew Lindesay if (!fModel.Nickname().IsEmpty()) { 116010cd325cSAndrew Lindesay _AddProcessCoordinator( 116110cd325cSAndrew Lindesay ProcessCoordinatorFactory::CreateUserDetailVerifierCoordinator( 116210cd325cSAndrew Lindesay this, 116310cd325cSAndrew Lindesay // UserDetailVerifierListener 116410cd325cSAndrew Lindesay &fModel) ); 116510cd325cSAndrew Lindesay } 116610cd325cSAndrew Lindesay } 116710cd325cSAndrew Lindesay 116810cd325cSAndrew Lindesay 116910cd325cSAndrew Lindesay void 11708f03a0f9SStephan Aßmus MainWindow::_UpdateAuthorization() 11718f03a0f9SStephan Aßmus { 1172d2d4866dSAndrew Lindesay BString nickname(fModel.Nickname()); 1173d2d4866dSAndrew Lindesay bool hasUser = !nickname.IsEmpty(); 1174e0a26dceSStephan Aßmus 11756d519fd1SStephan Aßmus if (fLogOutItem != NULL) 1176e0a26dceSStephan Aßmus fLogOutItem->SetEnabled(hasUser); 1177d2d4866dSAndrew Lindesay if (fUsersUserUsageConditionsMenuItem != NULL) 1178d2d4866dSAndrew Lindesay fUsersUserUsageConditionsMenuItem->SetEnabled(hasUser); 1179e0a26dceSStephan Aßmus if (fLogInItem != NULL) { 1180e0a26dceSStephan Aßmus if (hasUser) 1181e0a26dceSStephan Aßmus fLogInItem->SetLabel(B_TRANSLATE("Switch account" B_UTF8_ELLIPSIS)); 1182e0a26dceSStephan Aßmus else 1183e0a26dceSStephan Aßmus fLogInItem->SetLabel(B_TRANSLATE("Log in" B_UTF8_ELLIPSIS)); 1184e0a26dceSStephan Aßmus } 1185e0a26dceSStephan Aßmus 1186e0a26dceSStephan Aßmus if (fUserMenu != NULL) { 1187e0a26dceSStephan Aßmus BString label; 1188d2d4866dSAndrew Lindesay if (hasUser) { 1189e0a26dceSStephan Aßmus label = B_TRANSLATE("Logged in as %User%"); 1190d2d4866dSAndrew Lindesay label.ReplaceAll("%User%", nickname); 1191d2d4866dSAndrew Lindesay } else { 1192d2d4866dSAndrew Lindesay label = B_TRANSLATE("Not logged in"); 1193e0a26dceSStephan Aßmus } 1194e0a26dceSStephan Aßmus fUserMenu->Superitem()->SetLabel(label); 1195e0a26dceSStephan Aßmus } 11968f03a0f9SStephan Aßmus } 11971bbda92dSStephan Aßmus 11981bbda92dSStephan Aßmus 11991bbda92dSStephan Aßmus void 1200b965ce70SHumdinger MainWindow::_UpdateAvailableRepositories() 1201b965ce70SHumdinger { 1202b965ce70SHumdinger fRepositoryMenu->RemoveItems(0, fRepositoryMenu->CountItems(), true); 1203b965ce70SHumdinger 1204b965ce70SHumdinger fRepositoryMenu->AddItem(new BMenuItem(B_TRANSLATE("All repositories"), 1205b965ce70SHumdinger new BMessage(MSG_DEPOT_SELECTED))); 1206b965ce70SHumdinger 1207b965ce70SHumdinger fRepositoryMenu->AddItem(new BSeparatorItem()); 1208b965ce70SHumdinger 1209b965ce70SHumdinger bool foundSelectedDepot = false; 121005880d13SAndrew Lindesay std::vector<DepotInfoRef> depots = _CreateSnapshotOfDepots(); 121105880d13SAndrew Lindesay std::vector<DepotInfoRef>::iterator it; 1212d13c3d89SAndrew Lindesay 121305880d13SAndrew Lindesay for (it = depots.begin(); it != depots.end(); it++) { 121405880d13SAndrew Lindesay DepotInfoRef depot = *it; 121505880d13SAndrew Lindesay 121605880d13SAndrew Lindesay if (depot->Name().Length() != 0) { 1217b965ce70SHumdinger BMessage* message = new BMessage(MSG_DEPOT_SELECTED); 121805880d13SAndrew Lindesay message->AddString("name", depot->Name()); 121905880d13SAndrew Lindesay BMenuItem* item = new(std::nothrow) BMenuItem(depot->Name(), message); 122005880d13SAndrew Lindesay 122105880d13SAndrew Lindesay if (item == NULL) 122205880d13SAndrew Lindesay HDFATAL("memory exhaustion"); 122305880d13SAndrew Lindesay 1224b965ce70SHumdinger fRepositoryMenu->AddItem(item); 1225b965ce70SHumdinger 122605880d13SAndrew Lindesay if (depot->Name() == fModel.Depot()) { 1227b965ce70SHumdinger item->SetMarked(true); 1228b965ce70SHumdinger foundSelectedDepot = true; 1229b965ce70SHumdinger } 1230b965ce70SHumdinger } 1231d13c3d89SAndrew Lindesay } 1232b965ce70SHumdinger 1233b965ce70SHumdinger if (!foundSelectedDepot) 1234b965ce70SHumdinger fRepositoryMenu->ItemAt(0)->SetMarked(true); 1235b965ce70SHumdinger } 1236b965ce70SHumdinger 1237b965ce70SHumdinger 1238a9edb9bfSAndrew Lindesay bool 1239a9edb9bfSAndrew Lindesay MainWindow::_SelectedPackageHasWebAppRepositoryCode() 1240a9edb9bfSAndrew Lindesay { 1241a9edb9bfSAndrew Lindesay const PackageInfoRef& package = fPackageInfoView->Package(); 12426ab878c0SAndrew Lindesay const BString depotName = package->DepotName(); 1243a9edb9bfSAndrew Lindesay 12446ab878c0SAndrew Lindesay if (depotName.IsEmpty()) { 1245fa5c8097SAndrew Lindesay HDDEBUG("the package [%s] has no depot name", package->Name().String()); 12466ab878c0SAndrew Lindesay } else { 12476ab878c0SAndrew Lindesay const DepotInfo* depot = fModel.DepotForName(depotName); 1248a9edb9bfSAndrew Lindesay 12496ab878c0SAndrew Lindesay if (depot == NULL) { 1250f96d1f4dSAndrew Lindesay HDINFO("the depot [%s] was not able to be found", 1251fa5c8097SAndrew Lindesay depotName.String()); 12526ab878c0SAndrew Lindesay } else { 12536ab878c0SAndrew Lindesay BString repositoryCode = depot->WebAppRepositoryCode(); 1254a9edb9bfSAndrew Lindesay 12556ab878c0SAndrew Lindesay if (repositoryCode.IsEmpty()) { 1256f96d1f4dSAndrew Lindesay HDINFO("the depot [%s] has no web app repository code", 1257fa5c8097SAndrew Lindesay depotName.String()); 1258fa5c8097SAndrew Lindesay } else 12596ab878c0SAndrew Lindesay return true; 12606ab878c0SAndrew Lindesay } 12616ab878c0SAndrew Lindesay } 12626ab878c0SAndrew Lindesay 12636ab878c0SAndrew Lindesay return false; 1264a9edb9bfSAndrew Lindesay } 1265a9edb9bfSAndrew Lindesay 1266a9edb9bfSAndrew Lindesay 1267b965ce70SHumdinger void 12681bbda92dSStephan Aßmus MainWindow::_RatePackage() 12691bbda92dSStephan Aßmus { 1270a9edb9bfSAndrew Lindesay if (!_SelectedPackageHasWebAppRepositoryCode()) { 1271a9edb9bfSAndrew Lindesay BAlert* alert = new(std::nothrow) BAlert( 1272cbadcae1SHumdinger B_TRANSLATE("Rating not possible"), 1273cbadcae1SHumdinger B_TRANSLATE("This package doesn't seem to be on the HaikuDepot " 1274cbadcae1SHumdinger "Server, so it's not possible to create a new rating " 1275cbadcae1SHumdinger "or edit an existing rating."), 1276a9edb9bfSAndrew Lindesay B_TRANSLATE("OK")); 1277a9edb9bfSAndrew Lindesay alert->Go(); 1278a9edb9bfSAndrew Lindesay return; 1279a9edb9bfSAndrew Lindesay } 1280a9edb9bfSAndrew Lindesay 1281d2d4866dSAndrew Lindesay if (fModel.Nickname().IsEmpty()) { 12821bbda92dSStephan Aßmus BAlert* alert = new(std::nothrow) BAlert( 12831bbda92dSStephan Aßmus B_TRANSLATE("Not logged in"), 12841bbda92dSStephan Aßmus B_TRANSLATE("You need to be logged into an account before you " 12851bbda92dSStephan Aßmus "can rate packages."), 12861bbda92dSStephan Aßmus B_TRANSLATE("Cancel"), 12871bbda92dSStephan Aßmus B_TRANSLATE("Login or Create account")); 12881bbda92dSStephan Aßmus 12891bbda92dSStephan Aßmus if (alert == NULL) 12901bbda92dSStephan Aßmus return; 12911bbda92dSStephan Aßmus 12921bbda92dSStephan Aßmus int32 choice = alert->Go(); 12931bbda92dSStephan Aßmus if (choice == 1) 12941bbda92dSStephan Aßmus _OpenLoginWindow(BMessage(MSG_RATE_PACKAGE)); 12951bbda92dSStephan Aßmus return; 12961bbda92dSStephan Aßmus } 12971bbda92dSStephan Aßmus 12981bbda92dSStephan Aßmus // TODO: Allow only one RatePackageWindow 12991bbda92dSStephan Aßmus // TODO: Mechanism for remembering the window frame 13001bbda92dSStephan Aßmus RatePackageWindow* window = new RatePackageWindow(this, 13011bbda92dSStephan Aßmus BRect(0, 0, 500, 400), fModel); 13021bbda92dSStephan Aßmus window->SetPackage(fPackageInfoView->Package()); 13031bbda92dSStephan Aßmus window->Show(); 13041bbda92dSStephan Aßmus } 1305d5ef985eSStephan Aßmus 1306d5ef985eSStephan Aßmus 1307d5ef985eSStephan Aßmus void 1308d5ef985eSStephan Aßmus MainWindow::_ShowScreenshot() 1309d5ef985eSStephan Aßmus { 1310d5ef985eSStephan Aßmus // TODO: Mechanism for remembering the window frame 1311d5ef985eSStephan Aßmus if (fScreenshotWindow == NULL) 1312d5ef985eSStephan Aßmus fScreenshotWindow = new ScreenshotWindow(this, BRect(0, 0, 500, 400)); 1313d5ef985eSStephan Aßmus 1314d5ef985eSStephan Aßmus if (fScreenshotWindow->LockWithTimeout(1000) != B_OK) 1315d5ef985eSStephan Aßmus return; 1316d5ef985eSStephan Aßmus 1317d5ef985eSStephan Aßmus fScreenshotWindow->SetPackage(fPackageInfoView->Package()); 1318d5ef985eSStephan Aßmus 1319d5ef985eSStephan Aßmus if (fScreenshotWindow->IsHidden()) 1320d5ef985eSStephan Aßmus fScreenshotWindow->Show(); 1321d5ef985eSStephan Aßmus else 1322d5ef985eSStephan Aßmus fScreenshotWindow->Activate(); 1323d5ef985eSStephan Aßmus 1324d5ef985eSStephan Aßmus fScreenshotWindow->Unlock(); 1325d5ef985eSStephan Aßmus } 132601339a54SAndrew Lindesay 132701339a54SAndrew Lindesay 132801339a54SAndrew Lindesay void 1329d2d4866dSAndrew Lindesay MainWindow::_ViewUserUsageConditions( 1330d2d4866dSAndrew Lindesay UserUsageConditionsSelectionMode mode) 133101339a54SAndrew Lindesay { 133201339a54SAndrew Lindesay UserUsageConditionsWindow* window = new UserUsageConditionsWindow( 1333d2d4866dSAndrew Lindesay fModel, mode); 133401339a54SAndrew Lindesay window->Show(); 133501339a54SAndrew Lindesay } 133610cd325cSAndrew Lindesay 133710cd325cSAndrew Lindesay 133810cd325cSAndrew Lindesay void 133910cd325cSAndrew Lindesay MainWindow::UserCredentialsFailed() 134010cd325cSAndrew Lindesay { 134110cd325cSAndrew Lindesay BString message = B_TRANSLATE("The password previously " 134210cd325cSAndrew Lindesay "supplied for the user [%Nickname%] is not currently " 134310cd325cSAndrew Lindesay "valid. The user will be logged-out of this application " 134410cd325cSAndrew Lindesay "and you should login again with your updated password."); 134510cd325cSAndrew Lindesay message.ReplaceAll("%Nickname%", fModel.Nickname()); 134610cd325cSAndrew Lindesay 134710cd325cSAndrew Lindesay AppUtils::NotifySimpleError(B_TRANSLATE("Login issue"), 134810cd325cSAndrew Lindesay message); 134910cd325cSAndrew Lindesay 135010cd325cSAndrew Lindesay { 135110cd325cSAndrew Lindesay AutoLocker<BLocker> locker(fModel.Lock()); 135210cd325cSAndrew Lindesay fModel.SetNickname(""); 135310cd325cSAndrew Lindesay } 135410cd325cSAndrew Lindesay } 135510cd325cSAndrew Lindesay 135610cd325cSAndrew Lindesay 135710cd325cSAndrew Lindesay /*! \brief This method is invoked from the UserDetailVerifierProcess on a 135810cd325cSAndrew Lindesay background thread. For this reason it lodges a message into itself 135910cd325cSAndrew Lindesay which can then be handled on the main thread. 136010cd325cSAndrew Lindesay */ 136110cd325cSAndrew Lindesay 136210cd325cSAndrew Lindesay void 136310cd325cSAndrew Lindesay MainWindow::UserUsageConditionsNotLatest(const UserDetail& userDetail) 136410cd325cSAndrew Lindesay { 136510cd325cSAndrew Lindesay BMessage message(MSG_USER_USAGE_CONDITIONS_NOT_LATEST); 136610cd325cSAndrew Lindesay BMessage detailsMessage; 136710cd325cSAndrew Lindesay if (userDetail.Archive(&detailsMessage, true) != B_OK 136810cd325cSAndrew Lindesay || message.AddMessage("userDetail", &detailsMessage) != B_OK) { 1369fa5c8097SAndrew Lindesay HDERROR("unable to archive the user detail into a message"); 137010cd325cSAndrew Lindesay } 137110cd325cSAndrew Lindesay else 137210cd325cSAndrew Lindesay BMessenger(this).SendMessage(&message); 137310cd325cSAndrew Lindesay } 137410cd325cSAndrew Lindesay 137510cd325cSAndrew Lindesay 137610cd325cSAndrew Lindesay void 137710cd325cSAndrew Lindesay MainWindow::_HandleUserUsageConditionsNotLatest( 137810cd325cSAndrew Lindesay const UserDetail& userDetail) 137910cd325cSAndrew Lindesay { 138010cd325cSAndrew Lindesay ToLatestUserUsageConditionsWindow* window = 138110cd325cSAndrew Lindesay new ToLatestUserUsageConditionsWindow(this, fModel, userDetail); 138210cd325cSAndrew Lindesay window->Show(); 138310cd325cSAndrew Lindesay } 138410cd325cSAndrew Lindesay 138510cd325cSAndrew Lindesay 138610cd325cSAndrew Lindesay void 138710cd325cSAndrew Lindesay MainWindow::_AddProcessCoordinator(ProcessCoordinator* item) 138810cd325cSAndrew Lindesay { 138910cd325cSAndrew Lindesay AutoLocker<BLocker> lock(&fCoordinatorLock); 139010cd325cSAndrew Lindesay 1391a18f873fSAndrew Lindesay item->SetListener(this); 1392a18f873fSAndrew Lindesay 1393779ab335SX512 if (!fCoordinator.IsSet()) { 139410cd325cSAndrew Lindesay if (acquire_sem(fCoordinatorRunningSem) != B_OK) 139510cd325cSAndrew Lindesay debugger("unable to acquire the process coordinator sem"); 1396f96d1f4dSAndrew Lindesay HDINFO("adding and starting a process coordinator [%s]", 1397fa5c8097SAndrew Lindesay item->Name().String()); 1398f95ec23eSAndrew Lindesay fCoordinator = BReference<ProcessCoordinator>(item); 139910cd325cSAndrew Lindesay fCoordinator->Start(); 140010cd325cSAndrew Lindesay } 140110cd325cSAndrew Lindesay else { 1402f96d1f4dSAndrew Lindesay HDINFO("adding process coordinator [%s] to the queue", 140310cd325cSAndrew Lindesay item->Name().String()); 140410cd325cSAndrew Lindesay fCoordinatorQueue.push(item); 140510cd325cSAndrew Lindesay } 140610cd325cSAndrew Lindesay } 140710cd325cSAndrew Lindesay 140810cd325cSAndrew Lindesay 140910cd325cSAndrew Lindesay void 141010cd325cSAndrew Lindesay MainWindow::_SpinUntilProcessCoordinatorComplete() 141110cd325cSAndrew Lindesay { 141210cd325cSAndrew Lindesay while (true) { 141310cd325cSAndrew Lindesay if (acquire_sem(fCoordinatorRunningSem) != B_OK) 141410cd325cSAndrew Lindesay debugger("unable to acquire the process coordinator sem"); 141510cd325cSAndrew Lindesay if (release_sem(fCoordinatorRunningSem) != B_OK) 141610cd325cSAndrew Lindesay debugger("unable to release the process coordinator sem"); 141710cd325cSAndrew Lindesay { 141810cd325cSAndrew Lindesay AutoLocker<BLocker> lock(&fCoordinatorLock); 1419779ab335SX512 if (!fCoordinator.IsSet()) 142010cd325cSAndrew Lindesay return; 142110cd325cSAndrew Lindesay } 142210cd325cSAndrew Lindesay } 142310cd325cSAndrew Lindesay } 142410cd325cSAndrew Lindesay 142510cd325cSAndrew Lindesay 142610cd325cSAndrew Lindesay void 142710cd325cSAndrew Lindesay MainWindow::_StopProcessCoordinators() 142810cd325cSAndrew Lindesay { 1429fa5c8097SAndrew Lindesay HDINFO("will stop all process coordinators"); 143010cd325cSAndrew Lindesay 143110cd325cSAndrew Lindesay { 143210cd325cSAndrew Lindesay AutoLocker<BLocker> lock(&fCoordinatorLock); 143310cd325cSAndrew Lindesay 143410cd325cSAndrew Lindesay while (!fCoordinatorQueue.empty()) { 1435f96d1f4dSAndrew Lindesay BReference<ProcessCoordinator> processCoordinator 1436f96d1f4dSAndrew Lindesay = fCoordinatorQueue.front(); 1437f96d1f4dSAndrew Lindesay HDINFO("will drop queued process coordinator [%s]", 1438fa5c8097SAndrew Lindesay processCoordinator->Name().String()); 143910cd325cSAndrew Lindesay fCoordinatorQueue.pop(); 144010cd325cSAndrew Lindesay } 144110cd325cSAndrew Lindesay 1442779ab335SX512 if (fCoordinator.IsSet()) { 144310cd325cSAndrew Lindesay fCoordinator->Stop(); 144410cd325cSAndrew Lindesay } 144510cd325cSAndrew Lindesay } 144610cd325cSAndrew Lindesay 1447fa5c8097SAndrew Lindesay HDINFO("will wait until the process coordinator has stopped"); 144810cd325cSAndrew Lindesay 144910cd325cSAndrew Lindesay _SpinUntilProcessCoordinatorComplete(); 145010cd325cSAndrew Lindesay 1451fa5c8097SAndrew Lindesay HDINFO("did stop all process coordinators"); 145210cd325cSAndrew Lindesay } 145310cd325cSAndrew Lindesay 145410cd325cSAndrew Lindesay 145510cd325cSAndrew Lindesay /*! This method is called when there is some change in the bulk load process 145610cd325cSAndrew Lindesay or other process coordinator. 145710cd325cSAndrew Lindesay A change may mean that a new process has started / stopped etc... or it 145810cd325cSAndrew Lindesay may mean that the entire coordinator has finished. 145910cd325cSAndrew Lindesay */ 146010cd325cSAndrew Lindesay 146110cd325cSAndrew Lindesay void 146210cd325cSAndrew Lindesay MainWindow::CoordinatorChanged(ProcessCoordinatorState& coordinatorState) 146310cd325cSAndrew Lindesay { 146410cd325cSAndrew Lindesay AutoLocker<BLocker> lock(&fCoordinatorLock); 146510cd325cSAndrew Lindesay 1466f95ec23eSAndrew Lindesay if (fCoordinator.Get() == coordinatorState.Coordinator()) { 146710cd325cSAndrew Lindesay if (!coordinatorState.IsRunning()) { 146810cd325cSAndrew Lindesay if (release_sem(fCoordinatorRunningSem) != B_OK) 146910cd325cSAndrew Lindesay debugger("unable to release the process coordinator sem"); 1470f96d1f4dSAndrew Lindesay HDINFO("process coordinator [%s] did complete", 1471fa5c8097SAndrew Lindesay fCoordinator->Name().String()); 147210cd325cSAndrew Lindesay // complete the last one that just finished 147310cd325cSAndrew Lindesay BMessage* message = fCoordinator->Message(); 147410cd325cSAndrew Lindesay 147510cd325cSAndrew Lindesay if (message != NULL) { 147610cd325cSAndrew Lindesay BMessenger messenger(this); 147710cd325cSAndrew Lindesay message->AddInt64(KEY_ERROR_STATUS, 147810cd325cSAndrew Lindesay (int64) fCoordinator->ErrorStatus()); 147910cd325cSAndrew Lindesay messenger.SendMessage(message); 148010cd325cSAndrew Lindesay } 148110cd325cSAndrew Lindesay 1482f95ec23eSAndrew Lindesay fCoordinator = BReference<ProcessCoordinator>(NULL); 1483f95ec23eSAndrew Lindesay // will delete the old process coordinator if it is not used 1484f95ec23eSAndrew Lindesay // elsewhere. 148510cd325cSAndrew Lindesay 148610cd325cSAndrew Lindesay // now schedule the next one. 148710cd325cSAndrew Lindesay if (!fCoordinatorQueue.empty()) { 148810cd325cSAndrew Lindesay if (acquire_sem(fCoordinatorRunningSem) != B_OK) 148910cd325cSAndrew Lindesay debugger("unable to acquire the process coordinator sem"); 149010cd325cSAndrew Lindesay fCoordinator = fCoordinatorQueue.front(); 1491f96d1f4dSAndrew Lindesay HDINFO("starting next process coordinator [%s]", 149210cd325cSAndrew Lindesay fCoordinator->Name().String()); 149310cd325cSAndrew Lindesay fCoordinatorQueue.pop(); 149410cd325cSAndrew Lindesay fCoordinator->Start(); 149510cd325cSAndrew Lindesay } 149610cd325cSAndrew Lindesay else { 149710cd325cSAndrew Lindesay _NotifyWorkStatusClear(); 149810cd325cSAndrew Lindesay } 149910cd325cSAndrew Lindesay } 150010cd325cSAndrew Lindesay else { 150110cd325cSAndrew Lindesay _NotifyWorkStatusChange(coordinatorState.Message(), 150210cd325cSAndrew Lindesay coordinatorState.Progress()); 150310cd325cSAndrew Lindesay // show the progress to the user. 150410cd325cSAndrew Lindesay } 1505fa5c8097SAndrew Lindesay } else 1506fa5c8097SAndrew Lindesay HDINFO("! unknown process coordinator changed"); 150710cd325cSAndrew Lindesay } 1508ccf707d0SAndrew Lindesay 1509ccf707d0SAndrew Lindesay 1510ccf707d0SAndrew Lindesay static package_list_view_mode 1511ccf707d0SAndrew Lindesay main_window_tab_to_package_list_view_mode(int32 tab) 1512ccf707d0SAndrew Lindesay { 1513ccf707d0SAndrew Lindesay if (tab == TAB_PROMINENT_PACKAGES) 1514ccf707d0SAndrew Lindesay return PROMINENT; 1515ccf707d0SAndrew Lindesay return ALL; 1516ccf707d0SAndrew Lindesay } 1517ccf707d0SAndrew Lindesay 1518ccf707d0SAndrew Lindesay 1519ccf707d0SAndrew Lindesay void 1520ccf707d0SAndrew Lindesay MainWindow::_HandleChangePackageListViewMode() 1521ccf707d0SAndrew Lindesay { 1522ccf707d0SAndrew Lindesay package_list_view_mode tabMode = main_window_tab_to_package_list_view_mode( 1523ccf707d0SAndrew Lindesay fListTabs->Selection()); 1524ccf707d0SAndrew Lindesay package_list_view_mode modelMode = fModel.PackageListViewMode(); 1525ccf707d0SAndrew Lindesay 1526ccf707d0SAndrew Lindesay if (tabMode != modelMode) { 1527ccf707d0SAndrew Lindesay BAutolock locker(fModel.Lock()); 1528ccf707d0SAndrew Lindesay fModel.SetPackageListViewMode(tabMode); 1529ccf707d0SAndrew Lindesay } 1530ccf707d0SAndrew Lindesay } 153105880d13SAndrew Lindesay 153205880d13SAndrew Lindesay 153305880d13SAndrew Lindesay std::vector<DepotInfoRef> 153405880d13SAndrew Lindesay MainWindow::_CreateSnapshotOfDepots() 153505880d13SAndrew Lindesay { 153605880d13SAndrew Lindesay std::vector<DepotInfoRef> result; 153705880d13SAndrew Lindesay BAutolock locker(fModel.Lock()); 153805880d13SAndrew Lindesay int32 countDepots = fModel.CountDepots(); 153905880d13SAndrew Lindesay for(int32 i = 0; i < countDepots; i++) 154005880d13SAndrew Lindesay result.push_back(fModel.DepotAtIndex(i)); 154105880d13SAndrew Lindesay return result; 154205880d13SAndrew Lindesay } 1543