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. 610cd325cSAndrew Lindesay * Copyright 2016-2020, 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" 5010cd325cSAndrew Lindesay #include "ToLatestUserUsageConditionsWindow.h" 5104c9d578SStephan Aßmus #include "UserLoginWindow.h" 5201339a54SAndrew Lindesay #include "UserUsageConditionsWindow.h" 53125d42d9SJulian Harnath #include "WorkStatusView.h" 5404c9d578SStephan Aßmus 5504c9d578SStephan Aßmus 5604c9d578SStephan Aßmus #undef B_TRANSLATION_CONTEXT 5704c9d578SStephan Aßmus #define B_TRANSLATION_CONTEXT "MainWindow" 5804c9d578SStephan Aßmus 5904c9d578SStephan Aßmus 6004c9d578SStephan Aßmus enum { 615bf2b6ebSBrian Hill MSG_REFRESH_REPOS = 'mrrp', 625bf2b6ebSBrian Hill MSG_MANAGE_REPOS = 'mmrp', 63d144f952SAugustin Cavalier MSG_SOFTWARE_UPDATER = 'mswu', 6404c9d578SStephan Aßmus MSG_LOG_IN = 'lgin', 658f03a0f9SStephan Aßmus MSG_AUTHORIZATION_CHANGED = 'athc', 6689b16bb4SAndrew Lindesay MSG_CATEGORIES_LIST_CHANGED = 'clic', 67da651104SStephan Aßmus MSG_PACKAGE_CHANGED = 'pchd', 683369e03dSAndrew Lindesay MSG_WORK_STATUS_CHANGE = 'wsch', 693369e03dSAndrew Lindesay MSG_WORK_STATUS_CLEAR = 'wscl', 70fdec4227SStephan Aßmus 71ccf707d0SAndrew Lindesay MSG_CHANGE_PACKAGE_LIST_VIEW_MODE = 'cplm', 72fdec4227SStephan Aßmus MSG_SHOW_AVAILABLE_PACKAGES = 'savl', 73fdec4227SStephan Aßmus MSG_SHOW_INSTALLED_PACKAGES = 'sins', 7404c9d578SStephan Aßmus MSG_SHOW_SOURCE_PACKAGES = 'ssrc', 7504c9d578SStephan Aßmus MSG_SHOW_DEVELOP_PACKAGES = 'sdvl' 7604c9d578SStephan Aßmus }; 7704c9d578SStephan Aßmus 7810cd325cSAndrew Lindesay #define KEY_ERROR_STATUS "errorStatus" 79ccf707d0SAndrew Lindesay #define KEY_PACKAGE_LIST_VIEW_MODE "packageListViewMode" 80ccf707d0SAndrew Lindesay 81ccf707d0SAndrew Lindesay #define TAB_PROMINENT_PACKAGES 0 82ccf707d0SAndrew Lindesay #define TAB_ALL_PACKAGES 1 8304c9d578SStephan Aßmus 8404c9d578SStephan Aßmus using namespace BPackageKit; 8504c9d578SStephan Aßmus using namespace BPackageKit::BManager::BPrivate; 8604c9d578SStephan Aßmus 8704c9d578SStephan Aßmus 8804c9d578SStephan Aßmus typedef std::map<BString, PackageInfoRef> PackageInfoMap; 8904c9d578SStephan Aßmus 9004c9d578SStephan Aßmus 9104c9d578SStephan Aßmus struct RefreshWorkerParameters { 9204c9d578SStephan Aßmus MainWindow* window; 9304c9d578SStephan Aßmus bool forceRefresh; 9404c9d578SStephan Aßmus 9504c9d578SStephan Aßmus RefreshWorkerParameters(MainWindow* window, bool forceRefresh) 9604c9d578SStephan Aßmus : 9704c9d578SStephan Aßmus window(window), 9804c9d578SStephan Aßmus forceRefresh(forceRefresh) 9904c9d578SStephan Aßmus { 10004c9d578SStephan Aßmus } 10104c9d578SStephan Aßmus }; 10204c9d578SStephan Aßmus 10304c9d578SStephan Aßmus 10489b16bb4SAndrew Lindesay class MainWindowModelListener : public ModelListener { 1058f03a0f9SStephan Aßmus public: 10689b16bb4SAndrew Lindesay MainWindowModelListener(const BMessenger& messenger) 1078f03a0f9SStephan Aßmus : 1088f03a0f9SStephan Aßmus fMessenger(messenger) 1098f03a0f9SStephan Aßmus { 1108f03a0f9SStephan Aßmus } 1118f03a0f9SStephan Aßmus 1128f03a0f9SStephan Aßmus virtual void AuthorizationChanged() 1138f03a0f9SStephan Aßmus { 1148f03a0f9SStephan Aßmus if (fMessenger.IsValid()) 1158f03a0f9SStephan Aßmus fMessenger.SendMessage(MSG_AUTHORIZATION_CHANGED); 1168f03a0f9SStephan Aßmus } 1178f03a0f9SStephan Aßmus 11889b16bb4SAndrew Lindesay virtual void CategoryListChanged() 11989b16bb4SAndrew Lindesay { 12089b16bb4SAndrew Lindesay if (fMessenger.IsValid()) 12189b16bb4SAndrew Lindesay fMessenger.SendMessage(MSG_CATEGORIES_LIST_CHANGED); 12289b16bb4SAndrew Lindesay } 12389b16bb4SAndrew Lindesay 1248f03a0f9SStephan Aßmus private: 1258f03a0f9SStephan Aßmus BMessenger fMessenger; 1268f03a0f9SStephan Aßmus }; 1278f03a0f9SStephan Aßmus 1288f03a0f9SStephan Aßmus 129f7c2983eSAxel Dörfler MainWindow::MainWindow(const BMessage& settings) 13004c9d578SStephan Aßmus : 131f7c2983eSAxel Dörfler BWindow(BRect(50, 50, 650, 550), B_TRANSLATE_SYSTEM_NAME("HaikuDepot"), 13204c9d578SStephan Aßmus B_DOCUMENT_WINDOW_LOOK, B_NORMAL_WINDOW_FEEL, 13304c9d578SStephan Aßmus B_ASYNCHRONOUS_CONTROLS | B_AUTO_UPDATE_SIZE_LIMITS), 134d5ef985eSStephan Aßmus fScreenshotWindow(NULL), 135e0a26dceSStephan Aßmus fUserMenu(NULL), 136e0a26dceSStephan Aßmus fLogInItem(NULL), 137e0a26dceSStephan Aßmus fLogOutItem(NULL), 138976cadf1SAndrew Lindesay fUsersUserUsageConditionsMenuItem(NULL), 13989b16bb4SAndrew Lindesay fModelListener(new MainWindowModelListener(BMessenger(this)), true), 14010cd325cSAndrew Lindesay fCoordinator(NULL), 1413369e03dSAndrew Lindesay fSinglePackageMode(false) 14204c9d578SStephan Aßmus { 14310cd325cSAndrew Lindesay if ((fCoordinatorRunningSem = create_sem(1, "ProcessCoordinatorSem")) < B_OK) 14410cd325cSAndrew Lindesay debugger("unable to create the process coordinator semaphore"); 14510cd325cSAndrew Lindesay 146cbadcae1SHumdinger BMenuBar* menuBar = new BMenuBar("Main Menu"); 14704c9d578SStephan Aßmus _BuildMenu(menuBar); 14804c9d578SStephan Aßmus 149cbadcae1SHumdinger BMenuBar* userMenuBar = new BMenuBar("User Menu"); 150e0a26dceSStephan Aßmus _BuildUserMenu(userMenuBar); 151e0a26dceSStephan Aßmus set_small_font(userMenuBar); 152e0a26dceSStephan Aßmus userMenuBar->SetExplicitMaxSize(BSize(B_SIZE_UNSET, 153e0a26dceSStephan Aßmus menuBar->MaxSize().height)); 154e0a26dceSStephan Aßmus 15504c9d578SStephan Aßmus fFilterView = new FilterView(); 156f0e491d3SAndrew Lindesay fFeaturedPackagesView = new FeaturedPackagesView(fModel); 157f0e491d3SAndrew Lindesay fPackageListView = new PackageListView(&fModel); 158f0e491d3SAndrew Lindesay fPackageInfoView = new PackageInfoView(&fModel, this); 15904c9d578SStephan Aßmus 16004c9d578SStephan Aßmus fSplitView = new BSplitView(B_VERTICAL, 5.0f); 16104c9d578SStephan Aßmus 162125d42d9SJulian Harnath fWorkStatusView = new WorkStatusView("work status"); 163125d42d9SJulian Harnath fPackageListView->AttachWorkStatusView(fWorkStatusView); 164125d42d9SJulian Harnath 165e00a489bSAugustin Cavalier fListTabs = new TabView(BMessenger(this), 166ccf707d0SAndrew Lindesay BMessage(MSG_CHANGE_PACKAGE_LIST_VIEW_MODE), "list tabs"); 167e00a489bSAugustin Cavalier fListTabs->AddTab(fFeaturedPackagesView); 168e00a489bSAugustin Cavalier fListTabs->AddTab(fPackageListView); 1694b930ccaSStephan Aßmus 17004c9d578SStephan Aßmus BLayoutBuilder::Group<>(this, B_VERTICAL, 0.0f) 171e0a26dceSStephan Aßmus .AddGroup(B_HORIZONTAL, 0.0f) 172e0a26dceSStephan Aßmus .Add(menuBar, 1.0f) 173e0a26dceSStephan Aßmus .Add(userMenuBar, 0.0f) 174e0a26dceSStephan Aßmus .End() 17504c9d578SStephan Aßmus .Add(fFilterView) 17604c9d578SStephan Aßmus .AddSplit(fSplitView) 17704c9d578SStephan Aßmus .AddGroup(B_VERTICAL) 178e00a489bSAugustin Cavalier .Add(fListTabs) 17904c9d578SStephan Aßmus .SetInsets( 18004c9d578SStephan Aßmus B_USE_DEFAULT_SPACING, 0.0f, 18104c9d578SStephan Aßmus B_USE_DEFAULT_SPACING, 0.0f) 18204c9d578SStephan Aßmus .End() 18304c9d578SStephan Aßmus .Add(fPackageInfoView) 18404c9d578SStephan Aßmus .End() 185125d42d9SJulian Harnath .Add(fWorkStatusView) 18604c9d578SStephan Aßmus ; 18704c9d578SStephan Aßmus 18804c9d578SStephan Aßmus fSplitView->SetCollapsible(0, false); 18904c9d578SStephan Aßmus fSplitView->SetCollapsible(1, false); 19004c9d578SStephan Aßmus 1918f03a0f9SStephan Aßmus fModel.AddListener(fModelListener); 1928f03a0f9SStephan Aßmus 19304c9d578SStephan Aßmus BMessage columnSettings; 19404c9d578SStephan Aßmus if (settings.FindMessage("column settings", &columnSettings) == B_OK) 19504c9d578SStephan Aßmus fPackageListView->LoadState(&columnSettings); 19604c9d578SStephan Aßmus 197ccf707d0SAndrew Lindesay _RestoreModelSettings(settings); 19804c9d578SStephan Aßmus 199ccf707d0SAndrew Lindesay if (fModel.PackageListViewMode() == PROMINENT) 200ccf707d0SAndrew Lindesay fListTabs->Select(TAB_PROMINENT_PACKAGES); 2012997e05bSStephan Aßmus else 202ccf707d0SAndrew Lindesay fListTabs->Select(TAB_ALL_PACKAGES); 2032997e05bSStephan Aßmus 204d2d4866dSAndrew Lindesay _RestoreNickname(settings); 20510cd325cSAndrew Lindesay _UpdateAuthorization(); 206f7c2983eSAxel Dörfler _RestoreWindowFrame(settings); 207f7c2983eSAxel Dörfler 2088f03a0f9SStephan Aßmus // start worker threads 20904c9d578SStephan Aßmus BPackageRoster().StartWatching(this, 21004c9d578SStephan Aßmus B_WATCH_PACKAGE_INSTALLATION_LOCATIONS); 21104c9d578SStephan Aßmus 21263975654SStephan Aßmus _InitWorkerThreads(); 2139883929bSAndrew Lindesay _AdoptModel(); 2149883929bSAndrew Lindesay _StartBulkLoad(); 21504c9d578SStephan Aßmus } 21604c9d578SStephan Aßmus 21704c9d578SStephan Aßmus 218f7c2983eSAxel Dörfler MainWindow::MainWindow(const BMessage& settings, const PackageInfoRef& package) 2196d519fd1SStephan Aßmus : 220f7c2983eSAxel Dörfler BWindow(BRect(50, 50, 650, 350), B_TRANSLATE_SYSTEM_NAME("HaikuDepot"), 2216d519fd1SStephan Aßmus B_DOCUMENT_WINDOW_LOOK, B_NORMAL_WINDOW_FEEL, 2226d519fd1SStephan Aßmus B_ASYNCHRONOUS_CONTROLS | B_AUTO_UPDATE_SIZE_LIMITS), 2239883929bSAndrew Lindesay fFeaturedPackagesView(NULL), 2249883929bSAndrew Lindesay fPackageListView(NULL), 225d78bfd8dSJulian Harnath fWorkStatusView(NULL), 226d5ef985eSStephan Aßmus fScreenshotWindow(NULL), 227e0a26dceSStephan Aßmus fUserMenu(NULL), 228e0a26dceSStephan Aßmus fLogInItem(NULL), 2296d519fd1SStephan Aßmus fLogOutItem(NULL), 230976cadf1SAndrew Lindesay fUsersUserUsageConditionsMenuItem(NULL), 23189b16bb4SAndrew Lindesay fModelListener(new MainWindowModelListener(BMessenger(this)), true), 23210cd325cSAndrew Lindesay fCoordinator(NULL), 2333369e03dSAndrew Lindesay fSinglePackageMode(true) 2346d519fd1SStephan Aßmus { 23510cd325cSAndrew Lindesay if ((fCoordinatorRunningSem = create_sem(1, "ProcessCoordinatorSem")) < B_OK) 23610cd325cSAndrew Lindesay debugger("unable to create the process coordinator semaphore"); 23710cd325cSAndrew Lindesay 2386d519fd1SStephan Aßmus fFilterView = new FilterView(); 239f0e491d3SAndrew Lindesay fPackageInfoView = new PackageInfoView(&fModel, this); 24087016f8fSAndrew Lindesay fWorkStatusView = new WorkStatusView("work status"); 2416d519fd1SStephan Aßmus 2426d519fd1SStephan Aßmus BLayoutBuilder::Group<>(this, B_VERTICAL) 2436d519fd1SStephan Aßmus .Add(fPackageInfoView) 24487016f8fSAndrew Lindesay .Add(fWorkStatusView) 2456d519fd1SStephan Aßmus .SetInsets(0, B_USE_WINDOW_INSETS, 0, 0) 2466d519fd1SStephan Aßmus ; 2476d519fd1SStephan Aßmus 2486d519fd1SStephan Aßmus fModel.AddListener(fModelListener); 2496d519fd1SStephan Aßmus 2506d519fd1SStephan Aßmus // Restore settings 251d2d4866dSAndrew Lindesay _RestoreNickname(settings); 252ccf707d0SAndrew Lindesay _UpdateAuthorization(); 253f7c2983eSAxel Dörfler _RestoreWindowFrame(settings); 2546d519fd1SStephan Aßmus 2556d519fd1SStephan Aßmus fPackageInfoView->SetPackage(package); 25663975654SStephan Aßmus 25763975654SStephan Aßmus _InitWorkerThreads(); 2586d519fd1SStephan Aßmus } 2596d519fd1SStephan Aßmus 2606d519fd1SStephan Aßmus 26104c9d578SStephan Aßmus MainWindow::~MainWindow() 26204c9d578SStephan Aßmus { 26310cd325cSAndrew Lindesay _SpinUntilProcessCoordinatorComplete(); 26410cd325cSAndrew Lindesay delete_sem(fCoordinatorRunningSem); 26510cd325cSAndrew Lindesay fCoordinatorRunningSem = 0; 26610cd325cSAndrew Lindesay 26704c9d578SStephan Aßmus BPackageRoster().StopWatching(this); 26804c9d578SStephan Aßmus 26904c9d578SStephan Aßmus delete_sem(fPendingActionsSem); 27005bffa62SStephan Aßmus if (fPendingActionsWorker >= 0) 27104c9d578SStephan Aßmus wait_for_thread(fPendingActionsWorker, NULL); 27204c9d578SStephan Aßmus 273d5ef985eSStephan Aßmus if (fScreenshotWindow != NULL && fScreenshotWindow->Lock()) 274d5ef985eSStephan Aßmus fScreenshotWindow->Quit(); 27504c9d578SStephan Aßmus } 27604c9d578SStephan Aßmus 27704c9d578SStephan Aßmus 27804c9d578SStephan Aßmus bool 27904c9d578SStephan Aßmus MainWindow::QuitRequested() 28004c9d578SStephan Aßmus { 28104c9d578SStephan Aßmus BMessage settings; 28204c9d578SStephan Aßmus StoreSettings(settings); 28304c9d578SStephan Aßmus 28404c9d578SStephan Aßmus BMessage message(MSG_MAIN_WINDOW_CLOSED); 2853369e03dSAndrew Lindesay message.AddMessage(KEY_WINDOW_SETTINGS, &settings); 28604c9d578SStephan Aßmus 28704c9d578SStephan Aßmus be_app->PostMessage(&message); 28804c9d578SStephan Aßmus 28910cd325cSAndrew Lindesay _StopProcessCoordinators(); 2903369e03dSAndrew Lindesay 29104c9d578SStephan Aßmus return true; 29204c9d578SStephan Aßmus } 29304c9d578SStephan Aßmus 29404c9d578SStephan Aßmus 29504c9d578SStephan Aßmus void 29604c9d578SStephan Aßmus MainWindow::MessageReceived(BMessage* message) 29704c9d578SStephan Aßmus { 29804c9d578SStephan Aßmus switch (message->what) { 2993369e03dSAndrew Lindesay case MSG_BULK_LOAD_DONE: 30010cd325cSAndrew Lindesay { 30110cd325cSAndrew Lindesay int64 errorStatus64; 30210cd325cSAndrew Lindesay if (message->FindInt64(KEY_ERROR_STATUS, &errorStatus64) == B_OK) 30310cd325cSAndrew Lindesay _BulkLoadCompleteReceived((status_t) errorStatus64); 30410cd325cSAndrew Lindesay else 305fa5c8097SAndrew Lindesay HDERROR("expected [%s] value in message", KEY_ERROR_STATUS); 30604c9d578SStephan Aßmus break; 30710cd325cSAndrew Lindesay } 30804c9d578SStephan Aßmus case B_SIMPLE_DATA: 30904c9d578SStephan Aßmus case B_REFS_RECEIVED: 31004c9d578SStephan Aßmus // TODO: ? 31104c9d578SStephan Aßmus break; 31204c9d578SStephan Aßmus 31304c9d578SStephan Aßmus case B_PACKAGE_UPDATE: 3145ad01608SAndrew Lindesay // TODO: see ticket #15879 3155ad01608SAndrew Lindesay // work needs to be done here to selectively update package data in 3165ad01608SAndrew Lindesay // the running HaikuDepot application when there are changes on the 3175ad01608SAndrew Lindesay // system. There is now too much data to just load everything when 3185ad01608SAndrew Lindesay // there is a change. 3195ad01608SAndrew Lindesay //_StartBulkLoad(false); 32004c9d578SStephan Aßmus break; 32104c9d578SStephan Aßmus 3225bf2b6ebSBrian Hill case MSG_REFRESH_REPOS: 3233369e03dSAndrew Lindesay _StartBulkLoad(true); 3243369e03dSAndrew Lindesay break; 3253369e03dSAndrew Lindesay 32610cd325cSAndrew Lindesay case MSG_WORK_STATUS_CLEAR: 32710cd325cSAndrew Lindesay _HandleWorkStatusClear(); 32810cd325cSAndrew Lindesay break; 32910cd325cSAndrew Lindesay 3303369e03dSAndrew Lindesay case MSG_WORK_STATUS_CHANGE: 3313369e03dSAndrew Lindesay _HandleWorkStatusChangeMessageReceived(message); 33204c9d578SStephan Aßmus break; 33304c9d578SStephan Aßmus 3345bf2b6ebSBrian Hill case MSG_MANAGE_REPOS: 3355bf2b6ebSBrian Hill be_roster->Launch("application/x-vnd.Haiku-Repositories"); 3365bf2b6ebSBrian Hill break; 3375bf2b6ebSBrian Hill 338d144f952SAugustin Cavalier case MSG_SOFTWARE_UPDATER: 339d144f952SAugustin Cavalier be_roster->Launch("application/x-vnd.haiku-softwareupdater"); 340d144f952SAugustin Cavalier break; 341d144f952SAugustin Cavalier 34204c9d578SStephan Aßmus case MSG_LOG_IN: 3431bbda92dSStephan Aßmus _OpenLoginWindow(BMessage()); 34404c9d578SStephan Aßmus break; 34504c9d578SStephan Aßmus 3468f03a0f9SStephan Aßmus case MSG_LOG_OUT: 347d2d4866dSAndrew Lindesay fModel.SetNickname(""); 3488f03a0f9SStephan Aßmus break; 3498f03a0f9SStephan Aßmus 35001339a54SAndrew Lindesay case MSG_VIEW_LATEST_USER_USAGE_CONDITIONS: 351d2d4866dSAndrew Lindesay _ViewUserUsageConditions(LATEST); 352d2d4866dSAndrew Lindesay break; 353d2d4866dSAndrew Lindesay 354d2d4866dSAndrew Lindesay case MSG_VIEW_USERS_USER_USAGE_CONDITIONS: 355d2d4866dSAndrew Lindesay _ViewUserUsageConditions(USER); 35601339a54SAndrew Lindesay break; 35701339a54SAndrew Lindesay 3588f03a0f9SStephan Aßmus case MSG_AUTHORIZATION_CHANGED: 35910cd325cSAndrew Lindesay _StartUserVerify(); 3608f03a0f9SStephan Aßmus _UpdateAuthorization(); 3618f03a0f9SStephan Aßmus break; 3628f03a0f9SStephan Aßmus 36389b16bb4SAndrew Lindesay case MSG_CATEGORIES_LIST_CHANGED: 36489b16bb4SAndrew Lindesay fFilterView->AdoptModel(fModel); 36589b16bb4SAndrew Lindesay break; 36689b16bb4SAndrew Lindesay 367ccf707d0SAndrew Lindesay case MSG_CHANGE_PACKAGE_LIST_VIEW_MODE: 368ccf707d0SAndrew Lindesay _HandleChangePackageListViewMode(); 3694fade61fSStephan Aßmus break; 3704fade61fSStephan Aßmus 371fdec4227SStephan Aßmus case MSG_SHOW_AVAILABLE_PACKAGES: 372fdec4227SStephan Aßmus { 373fdec4227SStephan Aßmus BAutolock locker(fModel.Lock()); 374fdec4227SStephan Aßmus fModel.SetShowAvailablePackages( 375fdec4227SStephan Aßmus !fModel.ShowAvailablePackages()); 376fdec4227SStephan Aßmus } 377fdec4227SStephan Aßmus _AdoptModel(); 378fdec4227SStephan Aßmus break; 379fdec4227SStephan Aßmus 380fdec4227SStephan Aßmus case MSG_SHOW_INSTALLED_PACKAGES: 381fdec4227SStephan Aßmus { 382fdec4227SStephan Aßmus BAutolock locker(fModel.Lock()); 383fdec4227SStephan Aßmus fModel.SetShowInstalledPackages( 384fdec4227SStephan Aßmus !fModel.ShowInstalledPackages()); 385fdec4227SStephan Aßmus } 386fdec4227SStephan Aßmus _AdoptModel(); 387fdec4227SStephan Aßmus break; 388fdec4227SStephan Aßmus 38904c9d578SStephan Aßmus case MSG_SHOW_SOURCE_PACKAGES: 39004c9d578SStephan Aßmus { 39104c9d578SStephan Aßmus BAutolock locker(fModel.Lock()); 39204c9d578SStephan Aßmus fModel.SetShowSourcePackages(!fModel.ShowSourcePackages()); 39304c9d578SStephan Aßmus } 39404c9d578SStephan Aßmus _AdoptModel(); 39504c9d578SStephan Aßmus break; 39604c9d578SStephan Aßmus 39704c9d578SStephan Aßmus case MSG_SHOW_DEVELOP_PACKAGES: 39804c9d578SStephan Aßmus { 39904c9d578SStephan Aßmus BAutolock locker(fModel.Lock()); 40004c9d578SStephan Aßmus fModel.SetShowDevelopPackages(!fModel.ShowDevelopPackages()); 40104c9d578SStephan Aßmus } 40204c9d578SStephan Aßmus _AdoptModel(); 40304c9d578SStephan Aßmus break; 40404c9d578SStephan Aßmus 405a9edb9bfSAndrew Lindesay // this may be triggered by, for example, a user rating being added 406a9edb9bfSAndrew Lindesay // or having been altered. 407a9edb9bfSAndrew Lindesay case MSG_SERVER_DATA_CHANGED: 408a9edb9bfSAndrew Lindesay { 409a9edb9bfSAndrew Lindesay BString name; 410a9edb9bfSAndrew Lindesay if (message->FindString("name", &name) == B_OK) { 411a9edb9bfSAndrew Lindesay BAutolock locker(fModel.Lock()); 412a9edb9bfSAndrew Lindesay if (fPackageInfoView->Package()->Name() == name) { 413a9edb9bfSAndrew Lindesay _PopulatePackageAsync(true); 414a9edb9bfSAndrew Lindesay } else { 415f96d1f4dSAndrew Lindesay HDDEBUG("pkg [%s] is updated on the server, but is " 416f96d1f4dSAndrew Lindesay "not selected so will not be updated.", 417fa5c8097SAndrew Lindesay name.String()); 418a9edb9bfSAndrew Lindesay } 419a9edb9bfSAndrew Lindesay } 420a9edb9bfSAndrew Lindesay break; 421a9edb9bfSAndrew Lindesay } 422a9edb9bfSAndrew Lindesay 42304c9d578SStephan Aßmus case MSG_PACKAGE_SELECTED: 42404c9d578SStephan Aßmus { 42572992391SStephan Aßmus BString name; 42672992391SStephan Aßmus if (message->FindString("name", &name) == B_OK) { 427c4199192SAndrew Lindesay PackageInfoRef package; 428c4199192SAndrew Lindesay { 42975ba9dbfSStephan Aßmus BAutolock locker(fModel.Lock()); 430c4199192SAndrew Lindesay package = fModel.PackageForName(name); 431c4199192SAndrew Lindesay } 432*779ab335SX512 if (!package.IsSet()) 433c4199192SAndrew Lindesay debugger("unable to find the named package"); 434c4199192SAndrew Lindesay else 43504c9d578SStephan Aßmus _AdoptPackage(package); 43604c9d578SStephan Aßmus } else { 43704c9d578SStephan Aßmus _ClearPackage(); 43804c9d578SStephan Aßmus } 43904c9d578SStephan Aßmus break; 44004c9d578SStephan Aßmus } 44104c9d578SStephan Aßmus 44204c9d578SStephan Aßmus case MSG_CATEGORY_SELECTED: 44304c9d578SStephan Aßmus { 44489b16bb4SAndrew Lindesay BString code; 44589b16bb4SAndrew Lindesay if (message->FindString("code", &code) != B_OK) 44689b16bb4SAndrew Lindesay code = ""; 44704c9d578SStephan Aßmus { 44804c9d578SStephan Aßmus BAutolock locker(fModel.Lock()); 44989b16bb4SAndrew Lindesay fModel.SetCategory(code); 45004c9d578SStephan Aßmus } 45104c9d578SStephan Aßmus _AdoptModel(); 45204c9d578SStephan Aßmus break; 45304c9d578SStephan Aßmus } 45404c9d578SStephan Aßmus 45504c9d578SStephan Aßmus case MSG_DEPOT_SELECTED: 45604c9d578SStephan Aßmus { 45704c9d578SStephan Aßmus BString name; 45804c9d578SStephan Aßmus if (message->FindString("name", &name) != B_OK) 45904c9d578SStephan Aßmus name = ""; 46004c9d578SStephan Aßmus { 46104c9d578SStephan Aßmus BAutolock locker(fModel.Lock()); 46204c9d578SStephan Aßmus fModel.SetDepot(name); 46304c9d578SStephan Aßmus } 46404c9d578SStephan Aßmus _AdoptModel(); 465b965ce70SHumdinger _UpdateAvailableRepositories(); 46604c9d578SStephan Aßmus break; 46704c9d578SStephan Aßmus } 46804c9d578SStephan Aßmus 46904c9d578SStephan Aßmus case MSG_SEARCH_TERMS_MODIFIED: 47004c9d578SStephan Aßmus { 47104c9d578SStephan Aßmus // TODO: Do this with a delay! 47204c9d578SStephan Aßmus BString searchTerms; 47304c9d578SStephan Aßmus if (message->FindString("search terms", &searchTerms) != B_OK) 47404c9d578SStephan Aßmus searchTerms = ""; 47504c9d578SStephan Aßmus { 47604c9d578SStephan Aßmus BAutolock locker(fModel.Lock()); 47704c9d578SStephan Aßmus fModel.SetSearchTerms(searchTerms); 47804c9d578SStephan Aßmus } 47904c9d578SStephan Aßmus _AdoptModel(); 48004c9d578SStephan Aßmus break; 48104c9d578SStephan Aßmus } 48204c9d578SStephan Aßmus 483da651104SStephan Aßmus case MSG_PACKAGE_CHANGED: 48404c9d578SStephan Aßmus { 48504c9d578SStephan Aßmus PackageInfo* info; 48604c9d578SStephan Aßmus if (message->FindPointer("package", (void**)&info) == B_OK) { 48704c9d578SStephan Aßmus PackageInfoRef ref(info, true); 488da651104SStephan Aßmus uint32 changes; 489da651104SStephan Aßmus if (message->FindUInt32("changes", &changes) != B_OK) 490da651104SStephan Aßmus changes = 0; 491da651104SStephan Aßmus if ((changes & PKG_CHANGED_STATE) != 0) { 49204c9d578SStephan Aßmus BAutolock locker(fModel.Lock()); 49304c9d578SStephan Aßmus fModel.SetPackageState(ref, ref->State()); 49404c9d578SStephan Aßmus } 495c4199192SAndrew Lindesay _AddRemovePackageFromLists(ref); 49687016f8fSAndrew Lindesay if ((changes & PKG_CHANGED_STATE) != 0 497*779ab335SX512 && !fCoordinator.IsSet()) { 4984e6fbe03SJulian Harnath fWorkStatusView->PackageStatusChanged(ref); 49957e51fffSStephan Aßmus } 50010cd325cSAndrew Lindesay } 50104c9d578SStephan Aßmus break; 50204c9d578SStephan Aßmus } 50304c9d578SStephan Aßmus 50404c9d578SStephan Aßmus case MSG_RATE_PACKAGE: 5051bbda92dSStephan Aßmus _RatePackage(); 50604c9d578SStephan Aßmus break; 50704c9d578SStephan Aßmus 508d5ef985eSStephan Aßmus case MSG_SHOW_SCREENSHOT: 509d5ef985eSStephan Aßmus _ShowScreenshot(); 510d5ef985eSStephan Aßmus break; 511d5ef985eSStephan Aßmus 512125d42d9SJulian Harnath case MSG_PACKAGE_WORKER_BUSY: 513125d42d9SJulian Harnath { 514125d42d9SJulian Harnath BString reason; 515125d42d9SJulian Harnath status_t status = message->FindString("reason", &reason); 516125d42d9SJulian Harnath if (status != B_OK) 517125d42d9SJulian Harnath break; 518125d42d9SJulian Harnath fWorkStatusView->SetBusy(reason); 519125d42d9SJulian Harnath break; 520125d42d9SJulian Harnath } 521125d42d9SJulian Harnath 522125d42d9SJulian Harnath case MSG_PACKAGE_WORKER_IDLE: 523125d42d9SJulian Harnath fWorkStatusView->SetIdle(); 524125d42d9SJulian Harnath break; 525125d42d9SJulian Harnath 52610cd325cSAndrew Lindesay case MSG_USER_USAGE_CONDITIONS_NOT_LATEST: 52710cd325cSAndrew Lindesay { 52810cd325cSAndrew Lindesay BMessage userDetailMsg; 52910cd325cSAndrew Lindesay if (message->FindMessage("userDetail", &userDetailMsg) != B_OK) { 53010cd325cSAndrew Lindesay debugger("expected the [userDetail] data to be carried in the " 53110cd325cSAndrew Lindesay "message."); 53210cd325cSAndrew Lindesay } 53310cd325cSAndrew Lindesay UserDetail userDetail(&userDetailMsg); 53410cd325cSAndrew Lindesay _HandleUserUsageConditionsNotLatest(userDetail); 53510cd325cSAndrew Lindesay break; 53610cd325cSAndrew Lindesay } 53710cd325cSAndrew Lindesay 53804c9d578SStephan Aßmus default: 53904c9d578SStephan Aßmus BWindow::MessageReceived(message); 54004c9d578SStephan Aßmus break; 54104c9d578SStephan Aßmus } 54204c9d578SStephan Aßmus } 54304c9d578SStephan Aßmus 54404c9d578SStephan Aßmus 545ccf707d0SAndrew Lindesay static const char* 546ccf707d0SAndrew Lindesay main_window_package_list_view_mode_str(package_list_view_mode mode) 547ccf707d0SAndrew Lindesay { 548ccf707d0SAndrew Lindesay if (mode == PROMINENT) 549ccf707d0SAndrew Lindesay return "PROMINENT"; 550ccf707d0SAndrew Lindesay return "ALL"; 551ccf707d0SAndrew Lindesay } 552ccf707d0SAndrew Lindesay 553ccf707d0SAndrew Lindesay 554ccf707d0SAndrew Lindesay static package_list_view_mode 555ccf707d0SAndrew Lindesay main_window_str_to_package_list_view_mode(const BString& str) 556ccf707d0SAndrew Lindesay { 557ccf707d0SAndrew Lindesay if (str == "PROMINENT") 558ccf707d0SAndrew Lindesay return PROMINENT; 559ccf707d0SAndrew Lindesay return ALL; 560ccf707d0SAndrew Lindesay } 561ccf707d0SAndrew Lindesay 562ccf707d0SAndrew Lindesay 56304c9d578SStephan Aßmus void 56404c9d578SStephan Aßmus MainWindow::StoreSettings(BMessage& settings) const 56504c9d578SStephan Aßmus { 566f7c2983eSAxel Dörfler settings.AddRect(_WindowFrameName(), Frame()); 567f7c2983eSAxel Dörfler if (!fSinglePackageMode) { 56804c9d578SStephan Aßmus settings.AddRect("window frame", Frame()); 56904c9d578SStephan Aßmus 57004c9d578SStephan Aßmus BMessage columnSettings; 5719883929bSAndrew Lindesay if (fPackageListView != NULL) 57204c9d578SStephan Aßmus fPackageListView->SaveState(&columnSettings); 57304c9d578SStephan Aßmus 57404c9d578SStephan Aßmus settings.AddMessage("column settings", &columnSettings); 57504c9d578SStephan Aßmus 576ccf707d0SAndrew Lindesay settings.AddString(KEY_PACKAGE_LIST_VIEW_MODE, 577ccf707d0SAndrew Lindesay main_window_package_list_view_mode_str( 578ccf707d0SAndrew Lindesay fModel.PackageListViewMode())); 5792997e05bSStephan Aßmus settings.AddBool("show available packages", 5802997e05bSStephan Aßmus fModel.ShowAvailablePackages()); 5812997e05bSStephan Aßmus settings.AddBool("show installed packages", 5822997e05bSStephan Aßmus fModel.ShowInstalledPackages()); 58304c9d578SStephan Aßmus settings.AddBool("show develop packages", fModel.ShowDevelopPackages()); 58404c9d578SStephan Aßmus settings.AddBool("show source packages", fModel.ShowSourcePackages()); 5856d519fd1SStephan Aßmus } 5868f03a0f9SStephan Aßmus 587d2d4866dSAndrew Lindesay settings.AddString("username", fModel.Nickname()); 58804c9d578SStephan Aßmus } 58904c9d578SStephan Aßmus 59004c9d578SStephan Aßmus 59104c9d578SStephan Aßmus void 59204c9d578SStephan Aßmus MainWindow::PackageChanged(const PackageInfoEvent& event) 59304c9d578SStephan Aßmus { 594a9edb9bfSAndrew Lindesay uint32 watchedChanges = PKG_CHANGED_STATE | PKG_CHANGED_PROMINENCE; 595a9edb9bfSAndrew Lindesay if ((event.Changes() & watchedChanges) != 0) { 59604c9d578SStephan Aßmus PackageInfoRef ref(event.Package()); 597da651104SStephan Aßmus BMessage message(MSG_PACKAGE_CHANGED); 59804c9d578SStephan Aßmus message.AddPointer("package", ref.Get()); 599da651104SStephan Aßmus message.AddUInt32("changes", event.Changes()); 60004c9d578SStephan Aßmus ref.Detach(); 60104c9d578SStephan Aßmus // reference needs to be released by MessageReceived(); 60204c9d578SStephan Aßmus PostMessage(&message); 60304c9d578SStephan Aßmus } 60404c9d578SStephan Aßmus } 60504c9d578SStephan Aßmus 60604c9d578SStephan Aßmus 60704c9d578SStephan Aßmus status_t 60804c9d578SStephan Aßmus MainWindow::SchedulePackageActions(PackageActionList& list) 60904c9d578SStephan Aßmus { 61004c9d578SStephan Aßmus AutoLocker<BLocker> lock(&fPendingActionsLock); 61104c9d578SStephan Aßmus for (int32 i = 0; i < list.CountItems(); i++) { 61204c9d578SStephan Aßmus if (!fPendingActions.Add(list.ItemAtFast(i))) 61304c9d578SStephan Aßmus return B_NO_MEMORY; 61404c9d578SStephan Aßmus } 61504c9d578SStephan Aßmus 61604c9d578SStephan Aßmus return release_sem_etc(fPendingActionsSem, list.CountItems(), 0); 61704c9d578SStephan Aßmus } 61804c9d578SStephan Aßmus 61904c9d578SStephan Aßmus 62004c9d578SStephan Aßmus Model* 62104c9d578SStephan Aßmus MainWindow::GetModel() 62204c9d578SStephan Aßmus { 62304c9d578SStephan Aßmus return &fModel; 62404c9d578SStephan Aßmus } 62504c9d578SStephan Aßmus 62604c9d578SStephan Aßmus 62704c9d578SStephan Aßmus void 62804c9d578SStephan Aßmus MainWindow::_BuildMenu(BMenuBar* menuBar) 62904c9d578SStephan Aßmus { 63004c9d578SStephan Aßmus BMenu* menu = new BMenu(B_TRANSLATE("Tools")); 6313369e03dSAndrew Lindesay fRefreshRepositoriesItem = new BMenuItem( 6323369e03dSAndrew Lindesay B_TRANSLATE("Refresh repositories"), new BMessage(MSG_REFRESH_REPOS)); 6333369e03dSAndrew Lindesay menu->AddItem(fRefreshRepositoriesItem); 634d7f78130SHumdinger menu->AddItem(new BMenuItem(B_TRANSLATE("Manage repositories" 635d7f78130SHumdinger B_UTF8_ELLIPSIS), new BMessage(MSG_MANAGE_REPOS))); 636d144f952SAugustin Cavalier menu->AddItem(new BMenuItem(B_TRANSLATE("Check for updates" 637d144f952SAugustin Cavalier B_UTF8_ELLIPSIS), new BMessage(MSG_SOFTWARE_UPDATER))); 638e0a26dceSStephan Aßmus 63904c9d578SStephan Aßmus menuBar->AddItem(menu); 64004c9d578SStephan Aßmus 641b965ce70SHumdinger fRepositoryMenu = new BMenu(B_TRANSLATE("Repositories")); 642b965ce70SHumdinger menuBar->AddItem(fRepositoryMenu); 643b965ce70SHumdinger 6444fade61fSStephan Aßmus menu = new BMenu(B_TRANSLATE("Show")); 6454fade61fSStephan Aßmus 646fdec4227SStephan Aßmus fShowAvailablePackagesItem = new BMenuItem( 6474fade61fSStephan Aßmus B_TRANSLATE("Available packages"), 648fdec4227SStephan Aßmus new BMessage(MSG_SHOW_AVAILABLE_PACKAGES)); 649fdec4227SStephan Aßmus menu->AddItem(fShowAvailablePackagesItem); 650fdec4227SStephan Aßmus 651fdec4227SStephan Aßmus fShowInstalledPackagesItem = new BMenuItem( 6524fade61fSStephan Aßmus B_TRANSLATE("Installed packages"), 653fdec4227SStephan Aßmus new BMessage(MSG_SHOW_INSTALLED_PACKAGES)); 654fdec4227SStephan Aßmus menu->AddItem(fShowInstalledPackagesItem); 655fdec4227SStephan Aßmus 656fdec4227SStephan Aßmus menu->AddSeparatorItem(); 657fdec4227SStephan Aßmus 658fdec4227SStephan Aßmus fShowDevelopPackagesItem = new BMenuItem( 6594fade61fSStephan Aßmus B_TRANSLATE("Develop packages"), 660fdec4227SStephan Aßmus new BMessage(MSG_SHOW_DEVELOP_PACKAGES)); 661fdec4227SStephan Aßmus menu->AddItem(fShowDevelopPackagesItem); 662fdec4227SStephan Aßmus 663fdec4227SStephan Aßmus fShowSourcePackagesItem = new BMenuItem( 6644fade61fSStephan Aßmus B_TRANSLATE("Source packages"), 665fdec4227SStephan Aßmus new BMessage(MSG_SHOW_SOURCE_PACKAGES)); 666fdec4227SStephan Aßmus menu->AddItem(fShowSourcePackagesItem); 667fdec4227SStephan Aßmus 668fdec4227SStephan Aßmus menuBar->AddItem(menu); 66904c9d578SStephan Aßmus } 67004c9d578SStephan Aßmus 67104c9d578SStephan Aßmus 67204c9d578SStephan Aßmus void 673e0a26dceSStephan Aßmus MainWindow::_BuildUserMenu(BMenuBar* menuBar) 674e0a26dceSStephan Aßmus { 675e0a26dceSStephan Aßmus fUserMenu = new BMenu(B_TRANSLATE("Not logged in")); 676e0a26dceSStephan Aßmus 677e0a26dceSStephan Aßmus fLogInItem = new BMenuItem(B_TRANSLATE("Log in" B_UTF8_ELLIPSIS), 678e0a26dceSStephan Aßmus new BMessage(MSG_LOG_IN)); 679e0a26dceSStephan Aßmus fUserMenu->AddItem(fLogInItem); 680e0a26dceSStephan Aßmus 681e0a26dceSStephan Aßmus fLogOutItem = new BMenuItem(B_TRANSLATE("Log out"), 682e0a26dceSStephan Aßmus new BMessage(MSG_LOG_OUT)); 683e0a26dceSStephan Aßmus fUserMenu->AddItem(fLogOutItem); 684e0a26dceSStephan Aßmus 6850c82f64bSAndrew Lindesay BMenuItem *latestUserUsageConditionsMenuItem = 6861448ced0SHumdinger new BMenuItem(B_TRANSLATE("View latest usage conditions" 68701339a54SAndrew Lindesay B_UTF8_ELLIPSIS), 68801339a54SAndrew Lindesay new BMessage(MSG_VIEW_LATEST_USER_USAGE_CONDITIONS)); 6890c82f64bSAndrew Lindesay fUserMenu->AddItem(latestUserUsageConditionsMenuItem); 69001339a54SAndrew Lindesay 691d2d4866dSAndrew Lindesay fUsersUserUsageConditionsMenuItem = 692d2d4866dSAndrew Lindesay new BMenuItem(B_TRANSLATE("View agreed usage conditions" 693d2d4866dSAndrew Lindesay B_UTF8_ELLIPSIS), 694d2d4866dSAndrew Lindesay new BMessage(MSG_VIEW_USERS_USER_USAGE_CONDITIONS)); 695d2d4866dSAndrew Lindesay fUserMenu->AddItem(fUsersUserUsageConditionsMenuItem); 696d2d4866dSAndrew Lindesay 697e0a26dceSStephan Aßmus menuBar->AddItem(fUserMenu); 698e0a26dceSStephan Aßmus } 699e0a26dceSStephan Aßmus 700e0a26dceSStephan Aßmus 701e0a26dceSStephan Aßmus void 702d2d4866dSAndrew Lindesay MainWindow::_RestoreNickname(const BMessage& settings) 703f7c2983eSAxel Dörfler { 704d2d4866dSAndrew Lindesay BString nickname; 705d2d4866dSAndrew Lindesay if (settings.FindString("username", &nickname) == B_OK 706d2d4866dSAndrew Lindesay && nickname.Length() > 0) { 707d2d4866dSAndrew Lindesay fModel.SetNickname(nickname); 708f7c2983eSAxel Dörfler } 709f7c2983eSAxel Dörfler } 710f7c2983eSAxel Dörfler 711f7c2983eSAxel Dörfler 712f7c2983eSAxel Dörfler const char* 713f7c2983eSAxel Dörfler MainWindow::_WindowFrameName() const 714f7c2983eSAxel Dörfler { 715f7c2983eSAxel Dörfler if (fSinglePackageMode) 716f7c2983eSAxel Dörfler return "small window frame"; 717f7c2983eSAxel Dörfler 718f7c2983eSAxel Dörfler return "window frame"; 719f7c2983eSAxel Dörfler } 720f7c2983eSAxel Dörfler 721f7c2983eSAxel Dörfler 722f7c2983eSAxel Dörfler void 723f7c2983eSAxel Dörfler MainWindow::_RestoreWindowFrame(const BMessage& settings) 724f7c2983eSAxel Dörfler { 725f7c2983eSAxel Dörfler BRect frame = Frame(); 726f7c2983eSAxel Dörfler 727f7c2983eSAxel Dörfler BRect windowFrame; 728f7c2983eSAxel Dörfler bool fromSettings = false; 729f7c2983eSAxel Dörfler if (settings.FindRect(_WindowFrameName(), &windowFrame) == B_OK) { 730f7c2983eSAxel Dörfler frame = windowFrame; 731f7c2983eSAxel Dörfler fromSettings = true; 732f7c2983eSAxel Dörfler } else if (!fSinglePackageMode) { 733f7c2983eSAxel Dörfler // Resize to occupy a certain screen size 734f7c2983eSAxel Dörfler BRect screenFrame = BScreen(this).Frame(); 735f7c2983eSAxel Dörfler float width = frame.Width(); 736f7c2983eSAxel Dörfler float height = frame.Height(); 737f7c2983eSAxel Dörfler if (width < screenFrame.Width() * .666f 738f7c2983eSAxel Dörfler && height < screenFrame.Height() * .666f) { 739f7c2983eSAxel Dörfler frame.bottom = frame.top + screenFrame.Height() * .666f; 740f7c2983eSAxel Dörfler frame.right = frame.left 741f7c2983eSAxel Dörfler + std::min(screenFrame.Width() * .666f, height * 7 / 5); 742f7c2983eSAxel Dörfler } 743f7c2983eSAxel Dörfler } 744f7c2983eSAxel Dörfler 745f7c2983eSAxel Dörfler MoveTo(frame.LeftTop()); 746f7c2983eSAxel Dörfler ResizeTo(frame.Width(), frame.Height()); 747f7c2983eSAxel Dörfler 748f7c2983eSAxel Dörfler if (fromSettings) 7498e96ec34SAxel Dörfler MoveOnScreen(); 750f7c2983eSAxel Dörfler else 751f7c2983eSAxel Dörfler CenterOnScreen(); 752f7c2983eSAxel Dörfler } 753f7c2983eSAxel Dörfler 754f7c2983eSAxel Dörfler 755f7c2983eSAxel Dörfler void 756ccf707d0SAndrew Lindesay MainWindow::_RestoreModelSettings(const BMessage& settings) 757ccf707d0SAndrew Lindesay { 758ccf707d0SAndrew Lindesay BString packageListViewMode; 759ccf707d0SAndrew Lindesay if (settings.FindString(KEY_PACKAGE_LIST_VIEW_MODE, 760ccf707d0SAndrew Lindesay &packageListViewMode) == B_OK) { 761ccf707d0SAndrew Lindesay fModel.SetPackageListViewMode( 762ccf707d0SAndrew Lindesay main_window_str_to_package_list_view_mode(packageListViewMode)); 763ccf707d0SAndrew Lindesay } 764ccf707d0SAndrew Lindesay 765ccf707d0SAndrew Lindesay bool showOption; 766ccf707d0SAndrew Lindesay if (settings.FindBool("show available packages", &showOption) == B_OK) 767ccf707d0SAndrew Lindesay fModel.SetShowAvailablePackages(showOption); 768ccf707d0SAndrew Lindesay if (settings.FindBool("show installed packages", &showOption) == B_OK) 769ccf707d0SAndrew Lindesay fModel.SetShowInstalledPackages(showOption); 770ccf707d0SAndrew Lindesay if (settings.FindBool("show develop packages", &showOption) == B_OK) 771ccf707d0SAndrew Lindesay fModel.SetShowDevelopPackages(showOption); 772ccf707d0SAndrew Lindesay if (settings.FindBool("show source packages", &showOption) == B_OK) 773ccf707d0SAndrew Lindesay fModel.SetShowSourcePackages(showOption); 774ccf707d0SAndrew Lindesay } 775ccf707d0SAndrew Lindesay 776ccf707d0SAndrew Lindesay 777ccf707d0SAndrew Lindesay void 77863975654SStephan Aßmus MainWindow::_InitWorkerThreads() 77963975654SStephan Aßmus { 78063975654SStephan Aßmus fPendingActionsSem = create_sem(0, "PendingPackageActions"); 78163975654SStephan Aßmus if (fPendingActionsSem >= 0) { 78263975654SStephan Aßmus fPendingActionsWorker = spawn_thread(&_PackageActionWorker, 78363975654SStephan Aßmus "Planet Express", B_NORMAL_PRIORITY, this); 78463975654SStephan Aßmus if (fPendingActionsWorker >= 0) 78563975654SStephan Aßmus resume_thread(fPendingActionsWorker); 78609f82905SStephan Aßmus } else 78709f82905SStephan Aßmus fPendingActionsWorker = -1; 78863975654SStephan Aßmus 78963975654SStephan Aßmus fPackageToPopulateSem = create_sem(0, "PopulatePackage"); 79063975654SStephan Aßmus if (fPackageToPopulateSem >= 0) { 79163975654SStephan Aßmus fPopulatePackageWorker = spawn_thread(&_PopulatePackageWorker, 79263975654SStephan Aßmus "Package Populator", B_NORMAL_PRIORITY, this); 79363975654SStephan Aßmus if (fPopulatePackageWorker >= 0) 79463975654SStephan Aßmus resume_thread(fPopulatePackageWorker); 79509f82905SStephan Aßmus } else 79609f82905SStephan Aßmus fPopulatePackageWorker = -1; 79763975654SStephan Aßmus } 79863975654SStephan Aßmus 79963975654SStephan Aßmus 80063975654SStephan Aßmus void 801c4199192SAndrew Lindesay MainWindow::_AdoptModelControls() 80204c9d578SStephan Aßmus { 8039883929bSAndrew Lindesay if (fSinglePackageMode) 8049883929bSAndrew Lindesay return; 8059883929bSAndrew Lindesay 80604c9d578SStephan Aßmus BAutolock locker(fModel.Lock()); 807fdec4227SStephan Aßmus fShowAvailablePackagesItem->SetMarked(fModel.ShowAvailablePackages()); 808fdec4227SStephan Aßmus fShowInstalledPackagesItem->SetMarked(fModel.ShowInstalledPackages()); 809fdec4227SStephan Aßmus fShowSourcePackagesItem->SetMarked(fModel.ShowSourcePackages()); 810fdec4227SStephan Aßmus fShowDevelopPackagesItem->SetMarked(fModel.ShowDevelopPackages()); 811da651104SStephan Aßmus 812ccf707d0SAndrew Lindesay if (fModel.PackageListViewMode() == PROMINENT) 813ccf707d0SAndrew Lindesay fListTabs->Select(TAB_PROMINENT_PACKAGES); 8144fade61fSStephan Aßmus else 815ccf707d0SAndrew Lindesay fListTabs->Select(TAB_ALL_PACKAGES); 816b965ce70SHumdinger 817b965ce70SHumdinger fFilterView->AdoptModel(fModel); 81804c9d578SStephan Aßmus } 81904c9d578SStephan Aßmus 82004c9d578SStephan Aßmus 82104c9d578SStephan Aßmus void 822c4199192SAndrew Lindesay MainWindow::_AdoptModel() 823c4199192SAndrew Lindesay { 824fa5c8097SAndrew Lindesay HDTRACE("adopting model to main window ui"); 825c4199192SAndrew Lindesay 826c4199192SAndrew Lindesay if (fSinglePackageMode) 827c4199192SAndrew Lindesay return; 828c4199192SAndrew Lindesay 82905880d13SAndrew Lindesay std::vector<DepotInfoRef> depots = _CreateSnapshotOfDepots(); 83005880d13SAndrew Lindesay std::vector<DepotInfoRef>::iterator it; 83105880d13SAndrew Lindesay for (it = depots.begin(); it != depots.end(); it++) { 83205880d13SAndrew Lindesay DepotInfoRef depotInfoRef = *it; 83305880d13SAndrew Lindesay const PackageList& packages = depotInfoRef->Packages(); 834c4199192SAndrew Lindesay for (int32 p = 0; p < packages.CountItems(); p++) 835c4199192SAndrew Lindesay _AddRemovePackageFromLists(packages.ItemAtFast(p)); 836c4199192SAndrew Lindesay } 837c4199192SAndrew Lindesay 838c4199192SAndrew Lindesay _AdoptModelControls(); 839c4199192SAndrew Lindesay } 840c4199192SAndrew Lindesay 841c4199192SAndrew Lindesay 842c4199192SAndrew Lindesay void 843c4199192SAndrew Lindesay MainWindow::_AddRemovePackageFromLists(const PackageInfoRef& package) 844c4199192SAndrew Lindesay { 845c4199192SAndrew Lindesay bool matches; 846c4199192SAndrew Lindesay 847c4199192SAndrew Lindesay { 848c4199192SAndrew Lindesay AutoLocker<BLocker> modelLocker(fModel.Lock()); 849c4199192SAndrew Lindesay matches = fModel.MatchesFilter(package); 850c4199192SAndrew Lindesay } 851c4199192SAndrew Lindesay 852c4199192SAndrew Lindesay if (matches) { 853c4199192SAndrew Lindesay if (package->IsProminent()) 854c4199192SAndrew Lindesay fFeaturedPackagesView->AddPackage(package); 855c4199192SAndrew Lindesay fPackageListView->AddPackage(package); 856c4199192SAndrew Lindesay } else { 857c4199192SAndrew Lindesay fFeaturedPackagesView->RemovePackage(package); 858c4199192SAndrew Lindesay fPackageListView->RemovePackage(package); 859c4199192SAndrew Lindesay } 860c4199192SAndrew Lindesay } 861c4199192SAndrew Lindesay 862c4199192SAndrew Lindesay 863c4199192SAndrew Lindesay void 86404c9d578SStephan Aßmus MainWindow::_AdoptPackage(const PackageInfoRef& package) 86504c9d578SStephan Aßmus { 86675ba9dbfSStephan Aßmus { 86775ba9dbfSStephan Aßmus BAutolock locker(fModel.Lock()); 86804c9d578SStephan Aßmus fPackageInfoView->SetPackage(package); 8691986ab9fSStephan Aßmus 870664372abSStephan Aßmus if (fFeaturedPackagesView != NULL) 871664372abSStephan Aßmus fFeaturedPackagesView->SelectPackage(package); 8721986ab9fSStephan Aßmus if (fPackageListView != NULL) 8731986ab9fSStephan Aßmus fPackageListView->SelectPackage(package); 87475ba9dbfSStephan Aßmus } 87504c9d578SStephan Aßmus 876a9edb9bfSAndrew Lindesay _PopulatePackageAsync(false); 87704c9d578SStephan Aßmus } 87804c9d578SStephan Aßmus 87904c9d578SStephan Aßmus 88004c9d578SStephan Aßmus void 88104c9d578SStephan Aßmus MainWindow::_ClearPackage() 88204c9d578SStephan Aßmus { 88304c9d578SStephan Aßmus fPackageInfoView->Clear(); 88404c9d578SStephan Aßmus } 88504c9d578SStephan Aßmus 88604c9d578SStephan Aßmus 88704c9d578SStephan Aßmus void 8883369e03dSAndrew Lindesay MainWindow::_StartBulkLoad(bool force) 88904c9d578SStephan Aßmus { 890c4199192SAndrew Lindesay if (fFeaturedPackagesView != NULL) 891c4199192SAndrew Lindesay fFeaturedPackagesView->Clear(); 892c4199192SAndrew Lindesay if (fPackageListView != NULL) 893c4199192SAndrew Lindesay fPackageListView->Clear(); 894c4199192SAndrew Lindesay fPackageInfoView->Clear(); 895c4199192SAndrew Lindesay 89610cd325cSAndrew Lindesay fRefreshRepositoriesItem->SetEnabled(false); 89710cd325cSAndrew Lindesay ProcessCoordinator* bulkLoadCoordinator = 89810cd325cSAndrew Lindesay ProcessCoordinatorFactory::CreateBulkLoadCoordinator( 8993369e03dSAndrew Lindesay this, 9003369e03dSAndrew Lindesay // PackageInfoListener 9013369e03dSAndrew Lindesay this, 9023369e03dSAndrew Lindesay // ProcessCoordinatorListener 9033369e03dSAndrew Lindesay &fModel, force); 90410cd325cSAndrew Lindesay _AddProcessCoordinator(bulkLoadCoordinator); 90504c9d578SStephan Aßmus } 90604c9d578SStephan Aßmus 90704c9d578SStephan Aßmus 90804c9d578SStephan Aßmus void 90910cd325cSAndrew Lindesay MainWindow::_BulkLoadCompleteReceived(status_t errorStatus) 91004c9d578SStephan Aßmus { 91110cd325cSAndrew Lindesay if (errorStatus != B_OK) { 9123369e03dSAndrew Lindesay AppUtils::NotifySimpleError( 9131448ced0SHumdinger B_TRANSLATE("Package update error"), 9143369e03dSAndrew Lindesay B_TRANSLATE("While updating package data, a problem has arisen " 9153369e03dSAndrew Lindesay "that may cause data to be outdated or missing from the " 9163369e03dSAndrew Lindesay "application's display. Additional details regarding this " 9173369e03dSAndrew Lindesay "problem may be able to be obtained from the application " 918b21c9447SAndrew Lindesay "logs." 919b21c9447SAndrew Lindesay ALERT_MSG_LOGS_USER_GUIDE)); 92004c9d578SStephan Aßmus } 92110cd325cSAndrew Lindesay 9223369e03dSAndrew Lindesay fRefreshRepositoriesItem->SetEnabled(true); 92310cd325cSAndrew Lindesay _AdoptModel(); 92410cd325cSAndrew Lindesay _UpdateAvailableRepositories(); 925ccf707d0SAndrew Lindesay 926ccf707d0SAndrew Lindesay // if after loading everything in, it transpires that there are no 927ccf707d0SAndrew Lindesay // featured packages then the featured packages should be disabled 928ccf707d0SAndrew Lindesay // and the user should be switched to the "all packages" view so 929ccf707d0SAndrew Lindesay // that they are not presented with a blank window! 930ccf707d0SAndrew Lindesay 931ccf707d0SAndrew Lindesay bool hasProminentPackages = fModel.HasAnyProminentPackages(); 932ccf707d0SAndrew Lindesay fListTabs->TabAt(TAB_PROMINENT_PACKAGES)->SetEnabled(hasProminentPackages); 933ccf707d0SAndrew Lindesay if (!hasProminentPackages 934ccf707d0SAndrew Lindesay && fListTabs->Selection() == TAB_PROMINENT_PACKAGES) { 935ccf707d0SAndrew Lindesay fModel.SetPackageListViewMode(ALL); 936ccf707d0SAndrew Lindesay fListTabs->Select(TAB_ALL_PACKAGES); 937ccf707d0SAndrew Lindesay } 93804c9d578SStephan Aßmus } 93904c9d578SStephan Aßmus 94004c9d578SStephan Aßmus 9413369e03dSAndrew Lindesay void 94210cd325cSAndrew Lindesay MainWindow::_NotifyWorkStatusClear() 94304c9d578SStephan Aßmus { 94410cd325cSAndrew Lindesay BMessage message(MSG_WORK_STATUS_CLEAR); 94510cd325cSAndrew Lindesay this->PostMessage(&message, this); 94610cd325cSAndrew Lindesay } 94710cd325cSAndrew Lindesay 94810cd325cSAndrew Lindesay 94910cd325cSAndrew Lindesay void 95010cd325cSAndrew Lindesay MainWindow::_HandleWorkStatusClear() 95110cd325cSAndrew Lindesay { 95210cd325cSAndrew Lindesay fWorkStatusView->SetText(""); 9533369e03dSAndrew Lindesay fWorkStatusView->SetIdle(); 9543369e03dSAndrew Lindesay } 95504c9d578SStephan Aßmus 95604c9d578SStephan Aßmus 9573369e03dSAndrew Lindesay /*! Sends off a message to the Window so that it can change the status view 9583369e03dSAndrew Lindesay on the front-end in the UI thread. 9593369e03dSAndrew Lindesay */ 96004c9d578SStephan Aßmus 9613369e03dSAndrew Lindesay void 9623369e03dSAndrew Lindesay MainWindow::_NotifyWorkStatusChange(const BString& text, float progress) 9633369e03dSAndrew Lindesay { 9643369e03dSAndrew Lindesay BMessage message(MSG_WORK_STATUS_CHANGE); 96504c9d578SStephan Aßmus 9663369e03dSAndrew Lindesay if (!text.IsEmpty()) 9673369e03dSAndrew Lindesay message.AddString(KEY_WORK_STATUS_TEXT, text); 9683369e03dSAndrew Lindesay message.AddFloat(KEY_WORK_STATUS_PROGRESS, progress); 96904c9d578SStephan Aßmus 9703369e03dSAndrew Lindesay this->PostMessage(&message, this); 9713369e03dSAndrew Lindesay } 97204c9d578SStephan Aßmus 9733369e03dSAndrew Lindesay 9743369e03dSAndrew Lindesay void 9753369e03dSAndrew Lindesay MainWindow::_HandleWorkStatusChangeMessageReceived(const BMessage* message) 9763369e03dSAndrew Lindesay { 9779883929bSAndrew Lindesay if (fWorkStatusView == NULL) 9789883929bSAndrew Lindesay return; 9799883929bSAndrew Lindesay 9803369e03dSAndrew Lindesay BString text; 9813369e03dSAndrew Lindesay float progress; 9823369e03dSAndrew Lindesay 9833369e03dSAndrew Lindesay if (message->FindString(KEY_WORK_STATUS_TEXT, &text) == B_OK) 9843369e03dSAndrew Lindesay fWorkStatusView->SetText(text); 9853369e03dSAndrew Lindesay 9863369e03dSAndrew Lindesay if (message->FindFloat(KEY_WORK_STATUS_PROGRESS, &progress) == B_OK) 9873369e03dSAndrew Lindesay fWorkStatusView->SetProgress(progress); 98804c9d578SStephan Aßmus } 98904c9d578SStephan Aßmus 99004c9d578SStephan Aßmus 99104c9d578SStephan Aßmus status_t 99204c9d578SStephan Aßmus MainWindow::_PackageActionWorker(void* arg) 99304c9d578SStephan Aßmus { 99404c9d578SStephan Aßmus MainWindow* window = reinterpret_cast<MainWindow*>(arg); 99504c9d578SStephan Aßmus 99604c9d578SStephan Aßmus while (acquire_sem(window->fPendingActionsSem) == B_OK) { 99704c9d578SStephan Aßmus PackageActionRef ref; 99804c9d578SStephan Aßmus { 99904c9d578SStephan Aßmus AutoLocker<BLocker> lock(&window->fPendingActionsLock); 100004c9d578SStephan Aßmus ref = window->fPendingActions.ItemAt(0); 1001*779ab335SX512 if (!ref.IsSet()) 100204c9d578SStephan Aßmus break; 100304c9d578SStephan Aßmus window->fPendingActions.Remove(0); 100404c9d578SStephan Aßmus } 100504c9d578SStephan Aßmus 1006125d42d9SJulian Harnath BMessenger messenger(window); 1007125d42d9SJulian Harnath BMessage busyMessage(MSG_PACKAGE_WORKER_BUSY); 1008125d42d9SJulian Harnath BString text(ref->Label()); 1009bc622f6bSHumdinger text << B_UTF8_ELLIPSIS; 1010125d42d9SJulian Harnath busyMessage.AddString("reason", text); 1011125d42d9SJulian Harnath 1012125d42d9SJulian Harnath messenger.SendMessage(&busyMessage); 101304c9d578SStephan Aßmus ref->Perform(); 1014125d42d9SJulian Harnath messenger.SendMessage(MSG_PACKAGE_WORKER_IDLE); 101504c9d578SStephan Aßmus } 101604c9d578SStephan Aßmus 101704c9d578SStephan Aßmus return 0; 101804c9d578SStephan Aßmus } 101904c9d578SStephan Aßmus 102004c9d578SStephan Aßmus 1021a9edb9bfSAndrew Lindesay /*! This method will cause the package to have its data refreshed from 1022a9edb9bfSAndrew Lindesay the server application. The refresh happens in the background; this method 1023a9edb9bfSAndrew Lindesay is asynchronous. 1024a9edb9bfSAndrew Lindesay */ 1025a9edb9bfSAndrew Lindesay 1026a9edb9bfSAndrew Lindesay void 1027a9edb9bfSAndrew Lindesay MainWindow::_PopulatePackageAsync(bool forcePopulate) 1028a9edb9bfSAndrew Lindesay { 1029a9edb9bfSAndrew Lindesay // Trigger asynchronous package population from the web-app 1030a9edb9bfSAndrew Lindesay { 1031a9edb9bfSAndrew Lindesay AutoLocker<BLocker> lock(&fPackageToPopulateLock); 1032a9edb9bfSAndrew Lindesay fPackageToPopulate = fPackageInfoView->Package(); 1033a9edb9bfSAndrew Lindesay fForcePopulatePackage = forcePopulate; 1034a9edb9bfSAndrew Lindesay } 1035a9edb9bfSAndrew Lindesay release_sem_etc(fPackageToPopulateSem, 1, 0); 1036a9edb9bfSAndrew Lindesay 1037f96d1f4dSAndrew Lindesay HDDEBUG("pkg [%s] will be updated from the server.", 1038fa5c8097SAndrew Lindesay fPackageToPopulate->Name().String()); 1039a9edb9bfSAndrew Lindesay } 1040a9edb9bfSAndrew Lindesay 1041a9edb9bfSAndrew Lindesay 1042a9edb9bfSAndrew Lindesay /*! This method will run in the background. The thread will block until there 1043a9edb9bfSAndrew Lindesay is a package to be updated. When the thread unblocks, it will update the 1044a9edb9bfSAndrew Lindesay package with information from the server. 1045a9edb9bfSAndrew Lindesay */ 1046a9edb9bfSAndrew Lindesay 104704c9d578SStephan Aßmus status_t 104804c9d578SStephan Aßmus MainWindow::_PopulatePackageWorker(void* arg) 104904c9d578SStephan Aßmus { 105004c9d578SStephan Aßmus MainWindow* window = reinterpret_cast<MainWindow*>(arg); 105104c9d578SStephan Aßmus 105204c9d578SStephan Aßmus while (acquire_sem(window->fPackageToPopulateSem) == B_OK) { 105304c9d578SStephan Aßmus PackageInfoRef package; 1054a9edb9bfSAndrew Lindesay bool force; 105504c9d578SStephan Aßmus { 105604c9d578SStephan Aßmus AutoLocker<BLocker> lock(&window->fPackageToPopulateLock); 105704c9d578SStephan Aßmus package = window->fPackageToPopulate; 1058a9edb9bfSAndrew Lindesay force = window->fForcePopulatePackage; 105904c9d578SStephan Aßmus } 106004c9d578SStephan Aßmus 1061*779ab335SX512 if (package.IsSet()) { 1062a9edb9bfSAndrew Lindesay uint32 populateFlags = Model::POPULATE_USER_RATINGS 1063a9edb9bfSAndrew Lindesay | Model::POPULATE_SCREEN_SHOTS 1064a9edb9bfSAndrew Lindesay | Model::POPULATE_CHANGELOG; 1065a9edb9bfSAndrew Lindesay 1066a9edb9bfSAndrew Lindesay if (force) 1067a9edb9bfSAndrew Lindesay populateFlags |= Model::POPULATE_FORCE; 1068a9edb9bfSAndrew Lindesay 1069a9edb9bfSAndrew Lindesay window->fModel.PopulatePackage(package, populateFlags); 1070a9edb9bfSAndrew Lindesay 1071fa5c8097SAndrew Lindesay HDDEBUG("populating package [%s]", package->Name().String()); 107204c9d578SStephan Aßmus } 107304c9d578SStephan Aßmus } 107404c9d578SStephan Aßmus 107504c9d578SStephan Aßmus return 0; 107604c9d578SStephan Aßmus } 107704c9d578SStephan Aßmus 107804c9d578SStephan Aßmus 107904c9d578SStephan Aßmus void 10801bbda92dSStephan Aßmus MainWindow::_OpenLoginWindow(const BMessage& onSuccessMessage) 108104c9d578SStephan Aßmus { 108204c9d578SStephan Aßmus UserLoginWindow* window = new UserLoginWindow(this, 108304c9d578SStephan Aßmus BRect(0, 0, 500, 400), fModel); 10841bbda92dSStephan Aßmus 10851bbda92dSStephan Aßmus if (onSuccessMessage.what != 0) 10861bbda92dSStephan Aßmus window->SetOnSuccessMessage(BMessenger(this), onSuccessMessage); 10871bbda92dSStephan Aßmus 108804c9d578SStephan Aßmus window->Show(); 108904c9d578SStephan Aßmus } 109004c9d578SStephan Aßmus 10918f03a0f9SStephan Aßmus 10928f03a0f9SStephan Aßmus void 109310cd325cSAndrew Lindesay MainWindow::_StartUserVerify() 109410cd325cSAndrew Lindesay { 109510cd325cSAndrew Lindesay if (!fModel.Nickname().IsEmpty()) { 109610cd325cSAndrew Lindesay _AddProcessCoordinator( 109710cd325cSAndrew Lindesay ProcessCoordinatorFactory::CreateUserDetailVerifierCoordinator( 109810cd325cSAndrew Lindesay this, 109910cd325cSAndrew Lindesay // UserDetailVerifierListener 110010cd325cSAndrew Lindesay this, 110110cd325cSAndrew Lindesay // ProcessCoordinatorListener 110210cd325cSAndrew Lindesay &fModel) ); 110310cd325cSAndrew Lindesay } 110410cd325cSAndrew Lindesay } 110510cd325cSAndrew Lindesay 110610cd325cSAndrew Lindesay 110710cd325cSAndrew Lindesay void 11088f03a0f9SStephan Aßmus MainWindow::_UpdateAuthorization() 11098f03a0f9SStephan Aßmus { 1110d2d4866dSAndrew Lindesay BString nickname(fModel.Nickname()); 1111d2d4866dSAndrew Lindesay bool hasUser = !nickname.IsEmpty(); 1112e0a26dceSStephan Aßmus 11136d519fd1SStephan Aßmus if (fLogOutItem != NULL) 1114e0a26dceSStephan Aßmus fLogOutItem->SetEnabled(hasUser); 1115d2d4866dSAndrew Lindesay if (fUsersUserUsageConditionsMenuItem != NULL) 1116d2d4866dSAndrew Lindesay fUsersUserUsageConditionsMenuItem->SetEnabled(hasUser); 1117e0a26dceSStephan Aßmus if (fLogInItem != NULL) { 1118e0a26dceSStephan Aßmus if (hasUser) 1119e0a26dceSStephan Aßmus fLogInItem->SetLabel(B_TRANSLATE("Switch account" B_UTF8_ELLIPSIS)); 1120e0a26dceSStephan Aßmus else 1121e0a26dceSStephan Aßmus fLogInItem->SetLabel(B_TRANSLATE("Log in" B_UTF8_ELLIPSIS)); 1122e0a26dceSStephan Aßmus } 1123e0a26dceSStephan Aßmus 1124e0a26dceSStephan Aßmus if (fUserMenu != NULL) { 1125e0a26dceSStephan Aßmus BString label; 1126d2d4866dSAndrew Lindesay if (hasUser) { 1127e0a26dceSStephan Aßmus label = B_TRANSLATE("Logged in as %User%"); 1128d2d4866dSAndrew Lindesay label.ReplaceAll("%User%", nickname); 1129d2d4866dSAndrew Lindesay } else { 1130d2d4866dSAndrew Lindesay label = B_TRANSLATE("Not logged in"); 1131e0a26dceSStephan Aßmus } 1132e0a26dceSStephan Aßmus fUserMenu->Superitem()->SetLabel(label); 1133e0a26dceSStephan Aßmus } 11348f03a0f9SStephan Aßmus } 11351bbda92dSStephan Aßmus 11361bbda92dSStephan Aßmus 11371bbda92dSStephan Aßmus void 1138b965ce70SHumdinger MainWindow::_UpdateAvailableRepositories() 1139b965ce70SHumdinger { 1140b965ce70SHumdinger fRepositoryMenu->RemoveItems(0, fRepositoryMenu->CountItems(), true); 1141b965ce70SHumdinger 1142b965ce70SHumdinger fRepositoryMenu->AddItem(new BMenuItem(B_TRANSLATE("All repositories"), 1143b965ce70SHumdinger new BMessage(MSG_DEPOT_SELECTED))); 1144b965ce70SHumdinger 1145b965ce70SHumdinger fRepositoryMenu->AddItem(new BSeparatorItem()); 1146b965ce70SHumdinger 1147b965ce70SHumdinger bool foundSelectedDepot = false; 114805880d13SAndrew Lindesay std::vector<DepotInfoRef> depots = _CreateSnapshotOfDepots(); 114905880d13SAndrew Lindesay std::vector<DepotInfoRef>::iterator it; 1150d13c3d89SAndrew Lindesay 115105880d13SAndrew Lindesay for (it = depots.begin(); it != depots.end(); it++) { 115205880d13SAndrew Lindesay DepotInfoRef depot = *it; 115305880d13SAndrew Lindesay 115405880d13SAndrew Lindesay if (depot->Name().Length() != 0) { 1155b965ce70SHumdinger BMessage* message = new BMessage(MSG_DEPOT_SELECTED); 115605880d13SAndrew Lindesay message->AddString("name", depot->Name()); 115705880d13SAndrew Lindesay BMenuItem* item = new(std::nothrow) BMenuItem(depot->Name(), message); 115805880d13SAndrew Lindesay 115905880d13SAndrew Lindesay if (item == NULL) 116005880d13SAndrew Lindesay HDFATAL("memory exhaustion"); 116105880d13SAndrew Lindesay 1162b965ce70SHumdinger fRepositoryMenu->AddItem(item); 1163b965ce70SHumdinger 116405880d13SAndrew Lindesay if (depot->Name() == fModel.Depot()) { 1165b965ce70SHumdinger item->SetMarked(true); 1166b965ce70SHumdinger foundSelectedDepot = true; 1167b965ce70SHumdinger } 1168b965ce70SHumdinger } 1169d13c3d89SAndrew Lindesay } 1170b965ce70SHumdinger 1171b965ce70SHumdinger if (!foundSelectedDepot) 1172b965ce70SHumdinger fRepositoryMenu->ItemAt(0)->SetMarked(true); 1173b965ce70SHumdinger } 1174b965ce70SHumdinger 1175b965ce70SHumdinger 1176a9edb9bfSAndrew Lindesay bool 1177a9edb9bfSAndrew Lindesay MainWindow::_SelectedPackageHasWebAppRepositoryCode() 1178a9edb9bfSAndrew Lindesay { 1179a9edb9bfSAndrew Lindesay const PackageInfoRef& package = fPackageInfoView->Package(); 11806ab878c0SAndrew Lindesay const BString depotName = package->DepotName(); 1181a9edb9bfSAndrew Lindesay 11826ab878c0SAndrew Lindesay if (depotName.IsEmpty()) { 1183fa5c8097SAndrew Lindesay HDDEBUG("the package [%s] has no depot name", package->Name().String()); 11846ab878c0SAndrew Lindesay } else { 11856ab878c0SAndrew Lindesay const DepotInfo* depot = fModel.DepotForName(depotName); 1186a9edb9bfSAndrew Lindesay 11876ab878c0SAndrew Lindesay if (depot == NULL) { 1188f96d1f4dSAndrew Lindesay HDINFO("the depot [%s] was not able to be found", 1189fa5c8097SAndrew Lindesay depotName.String()); 11906ab878c0SAndrew Lindesay } else { 11916ab878c0SAndrew Lindesay BString repositoryCode = depot->WebAppRepositoryCode(); 1192a9edb9bfSAndrew Lindesay 11936ab878c0SAndrew Lindesay if (repositoryCode.IsEmpty()) { 1194f96d1f4dSAndrew Lindesay HDINFO("the depot [%s] has no web app repository code", 1195fa5c8097SAndrew Lindesay depotName.String()); 1196fa5c8097SAndrew Lindesay } else 11976ab878c0SAndrew Lindesay return true; 11986ab878c0SAndrew Lindesay } 11996ab878c0SAndrew Lindesay } 12006ab878c0SAndrew Lindesay 12016ab878c0SAndrew Lindesay return false; 1202a9edb9bfSAndrew Lindesay } 1203a9edb9bfSAndrew Lindesay 1204a9edb9bfSAndrew Lindesay 1205b965ce70SHumdinger void 12061bbda92dSStephan Aßmus MainWindow::_RatePackage() 12071bbda92dSStephan Aßmus { 1208a9edb9bfSAndrew Lindesay if (!_SelectedPackageHasWebAppRepositoryCode()) { 1209a9edb9bfSAndrew Lindesay BAlert* alert = new(std::nothrow) BAlert( 1210cbadcae1SHumdinger B_TRANSLATE("Rating not possible"), 1211cbadcae1SHumdinger B_TRANSLATE("This package doesn't seem to be on the HaikuDepot " 1212cbadcae1SHumdinger "Server, so it's not possible to create a new rating " 1213cbadcae1SHumdinger "or edit an existing rating."), 1214a9edb9bfSAndrew Lindesay B_TRANSLATE("OK")); 1215a9edb9bfSAndrew Lindesay alert->Go(); 1216a9edb9bfSAndrew Lindesay return; 1217a9edb9bfSAndrew Lindesay } 1218a9edb9bfSAndrew Lindesay 1219d2d4866dSAndrew Lindesay if (fModel.Nickname().IsEmpty()) { 12201bbda92dSStephan Aßmus BAlert* alert = new(std::nothrow) BAlert( 12211bbda92dSStephan Aßmus B_TRANSLATE("Not logged in"), 12221bbda92dSStephan Aßmus B_TRANSLATE("You need to be logged into an account before you " 12231bbda92dSStephan Aßmus "can rate packages."), 12241bbda92dSStephan Aßmus B_TRANSLATE("Cancel"), 12251bbda92dSStephan Aßmus B_TRANSLATE("Login or Create account")); 12261bbda92dSStephan Aßmus 12271bbda92dSStephan Aßmus if (alert == NULL) 12281bbda92dSStephan Aßmus return; 12291bbda92dSStephan Aßmus 12301bbda92dSStephan Aßmus int32 choice = alert->Go(); 12311bbda92dSStephan Aßmus if (choice == 1) 12321bbda92dSStephan Aßmus _OpenLoginWindow(BMessage(MSG_RATE_PACKAGE)); 12331bbda92dSStephan Aßmus return; 12341bbda92dSStephan Aßmus } 12351bbda92dSStephan Aßmus 12361bbda92dSStephan Aßmus // TODO: Allow only one RatePackageWindow 12371bbda92dSStephan Aßmus // TODO: Mechanism for remembering the window frame 12381bbda92dSStephan Aßmus RatePackageWindow* window = new RatePackageWindow(this, 12391bbda92dSStephan Aßmus BRect(0, 0, 500, 400), fModel); 12401bbda92dSStephan Aßmus window->SetPackage(fPackageInfoView->Package()); 12411bbda92dSStephan Aßmus window->Show(); 12421bbda92dSStephan Aßmus } 1243d5ef985eSStephan Aßmus 1244d5ef985eSStephan Aßmus 1245d5ef985eSStephan Aßmus void 1246d5ef985eSStephan Aßmus MainWindow::_ShowScreenshot() 1247d5ef985eSStephan Aßmus { 1248d5ef985eSStephan Aßmus // TODO: Mechanism for remembering the window frame 1249d5ef985eSStephan Aßmus if (fScreenshotWindow == NULL) 1250d5ef985eSStephan Aßmus fScreenshotWindow = new ScreenshotWindow(this, BRect(0, 0, 500, 400)); 1251d5ef985eSStephan Aßmus 1252d5ef985eSStephan Aßmus if (fScreenshotWindow->LockWithTimeout(1000) != B_OK) 1253d5ef985eSStephan Aßmus return; 1254d5ef985eSStephan Aßmus 1255d5ef985eSStephan Aßmus fScreenshotWindow->SetPackage(fPackageInfoView->Package()); 1256d5ef985eSStephan Aßmus 1257d5ef985eSStephan Aßmus if (fScreenshotWindow->IsHidden()) 1258d5ef985eSStephan Aßmus fScreenshotWindow->Show(); 1259d5ef985eSStephan Aßmus else 1260d5ef985eSStephan Aßmus fScreenshotWindow->Activate(); 1261d5ef985eSStephan Aßmus 1262d5ef985eSStephan Aßmus fScreenshotWindow->Unlock(); 1263d5ef985eSStephan Aßmus } 126401339a54SAndrew Lindesay 126501339a54SAndrew Lindesay 126601339a54SAndrew Lindesay void 1267d2d4866dSAndrew Lindesay MainWindow::_ViewUserUsageConditions( 1268d2d4866dSAndrew Lindesay UserUsageConditionsSelectionMode mode) 126901339a54SAndrew Lindesay { 127001339a54SAndrew Lindesay UserUsageConditionsWindow* window = new UserUsageConditionsWindow( 1271d2d4866dSAndrew Lindesay fModel, mode); 127201339a54SAndrew Lindesay window->Show(); 127301339a54SAndrew Lindesay } 127410cd325cSAndrew Lindesay 127510cd325cSAndrew Lindesay 127610cd325cSAndrew Lindesay void 127710cd325cSAndrew Lindesay MainWindow::UserCredentialsFailed() 127810cd325cSAndrew Lindesay { 127910cd325cSAndrew Lindesay BString message = B_TRANSLATE("The password previously " 128010cd325cSAndrew Lindesay "supplied for the user [%Nickname%] is not currently " 128110cd325cSAndrew Lindesay "valid. The user will be logged-out of this application " 128210cd325cSAndrew Lindesay "and you should login again with your updated password."); 128310cd325cSAndrew Lindesay message.ReplaceAll("%Nickname%", fModel.Nickname()); 128410cd325cSAndrew Lindesay 128510cd325cSAndrew Lindesay AppUtils::NotifySimpleError(B_TRANSLATE("Login issue"), 128610cd325cSAndrew Lindesay message); 128710cd325cSAndrew Lindesay 128810cd325cSAndrew Lindesay { 128910cd325cSAndrew Lindesay AutoLocker<BLocker> locker(fModel.Lock()); 129010cd325cSAndrew Lindesay fModel.SetNickname(""); 129110cd325cSAndrew Lindesay } 129210cd325cSAndrew Lindesay } 129310cd325cSAndrew Lindesay 129410cd325cSAndrew Lindesay 129510cd325cSAndrew Lindesay /*! \brief This method is invoked from the UserDetailVerifierProcess on a 129610cd325cSAndrew Lindesay background thread. For this reason it lodges a message into itself 129710cd325cSAndrew Lindesay which can then be handled on the main thread. 129810cd325cSAndrew Lindesay */ 129910cd325cSAndrew Lindesay 130010cd325cSAndrew Lindesay void 130110cd325cSAndrew Lindesay MainWindow::UserUsageConditionsNotLatest(const UserDetail& userDetail) 130210cd325cSAndrew Lindesay { 130310cd325cSAndrew Lindesay BMessage message(MSG_USER_USAGE_CONDITIONS_NOT_LATEST); 130410cd325cSAndrew Lindesay BMessage detailsMessage; 130510cd325cSAndrew Lindesay if (userDetail.Archive(&detailsMessage, true) != B_OK 130610cd325cSAndrew Lindesay || message.AddMessage("userDetail", &detailsMessage) != B_OK) { 1307fa5c8097SAndrew Lindesay HDERROR("unable to archive the user detail into a message"); 130810cd325cSAndrew Lindesay } 130910cd325cSAndrew Lindesay else 131010cd325cSAndrew Lindesay BMessenger(this).SendMessage(&message); 131110cd325cSAndrew Lindesay } 131210cd325cSAndrew Lindesay 131310cd325cSAndrew Lindesay 131410cd325cSAndrew Lindesay void 131510cd325cSAndrew Lindesay MainWindow::_HandleUserUsageConditionsNotLatest( 131610cd325cSAndrew Lindesay const UserDetail& userDetail) 131710cd325cSAndrew Lindesay { 131810cd325cSAndrew Lindesay ToLatestUserUsageConditionsWindow* window = 131910cd325cSAndrew Lindesay new ToLatestUserUsageConditionsWindow(this, fModel, userDetail); 132010cd325cSAndrew Lindesay window->Show(); 132110cd325cSAndrew Lindesay } 132210cd325cSAndrew Lindesay 132310cd325cSAndrew Lindesay 132410cd325cSAndrew Lindesay void 132510cd325cSAndrew Lindesay MainWindow::_AddProcessCoordinator(ProcessCoordinator* item) 132610cd325cSAndrew Lindesay { 132710cd325cSAndrew Lindesay AutoLocker<BLocker> lock(&fCoordinatorLock); 132810cd325cSAndrew Lindesay 1329*779ab335SX512 if (!fCoordinator.IsSet()) { 133010cd325cSAndrew Lindesay if (acquire_sem(fCoordinatorRunningSem) != B_OK) 133110cd325cSAndrew Lindesay debugger("unable to acquire the process coordinator sem"); 1332f96d1f4dSAndrew Lindesay HDINFO("adding and starting a process coordinator [%s]", 1333fa5c8097SAndrew Lindesay item->Name().String()); 1334f95ec23eSAndrew Lindesay fCoordinator = BReference<ProcessCoordinator>(item); 133510cd325cSAndrew Lindesay fCoordinator->Start(); 133610cd325cSAndrew Lindesay } 133710cd325cSAndrew Lindesay else { 1338f96d1f4dSAndrew Lindesay HDINFO("adding process coordinator [%s] to the queue", 133910cd325cSAndrew Lindesay item->Name().String()); 134010cd325cSAndrew Lindesay fCoordinatorQueue.push(item); 134110cd325cSAndrew Lindesay } 134210cd325cSAndrew Lindesay } 134310cd325cSAndrew Lindesay 134410cd325cSAndrew Lindesay 134510cd325cSAndrew Lindesay void 134610cd325cSAndrew Lindesay MainWindow::_SpinUntilProcessCoordinatorComplete() 134710cd325cSAndrew Lindesay { 134810cd325cSAndrew Lindesay while (true) { 134910cd325cSAndrew Lindesay if (acquire_sem(fCoordinatorRunningSem) != B_OK) 135010cd325cSAndrew Lindesay debugger("unable to acquire the process coordinator sem"); 135110cd325cSAndrew Lindesay if (release_sem(fCoordinatorRunningSem) != B_OK) 135210cd325cSAndrew Lindesay debugger("unable to release the process coordinator sem"); 135310cd325cSAndrew Lindesay { 135410cd325cSAndrew Lindesay AutoLocker<BLocker> lock(&fCoordinatorLock); 1355*779ab335SX512 if (!fCoordinator.IsSet()) 135610cd325cSAndrew Lindesay return; 135710cd325cSAndrew Lindesay } 135810cd325cSAndrew Lindesay } 135910cd325cSAndrew Lindesay } 136010cd325cSAndrew Lindesay 136110cd325cSAndrew Lindesay 136210cd325cSAndrew Lindesay void 136310cd325cSAndrew Lindesay MainWindow::_StopProcessCoordinators() 136410cd325cSAndrew Lindesay { 1365fa5c8097SAndrew Lindesay HDINFO("will stop all process coordinators"); 136610cd325cSAndrew Lindesay 136710cd325cSAndrew Lindesay { 136810cd325cSAndrew Lindesay AutoLocker<BLocker> lock(&fCoordinatorLock); 136910cd325cSAndrew Lindesay 137010cd325cSAndrew Lindesay while (!fCoordinatorQueue.empty()) { 1371f96d1f4dSAndrew Lindesay BReference<ProcessCoordinator> processCoordinator 1372f96d1f4dSAndrew Lindesay = fCoordinatorQueue.front(); 1373f96d1f4dSAndrew Lindesay HDINFO("will drop queued process coordinator [%s]", 1374fa5c8097SAndrew Lindesay processCoordinator->Name().String()); 137510cd325cSAndrew Lindesay fCoordinatorQueue.pop(); 137610cd325cSAndrew Lindesay } 137710cd325cSAndrew Lindesay 1378*779ab335SX512 if (fCoordinator.IsSet()) { 137910cd325cSAndrew Lindesay fCoordinator->Stop(); 138010cd325cSAndrew Lindesay } 138110cd325cSAndrew Lindesay } 138210cd325cSAndrew Lindesay 1383fa5c8097SAndrew Lindesay HDINFO("will wait until the process coordinator has stopped"); 138410cd325cSAndrew Lindesay 138510cd325cSAndrew Lindesay _SpinUntilProcessCoordinatorComplete(); 138610cd325cSAndrew Lindesay 1387fa5c8097SAndrew Lindesay HDINFO("did stop all process coordinators"); 138810cd325cSAndrew Lindesay } 138910cd325cSAndrew Lindesay 139010cd325cSAndrew Lindesay 139110cd325cSAndrew Lindesay /*! This method is called when there is some change in the bulk load process 139210cd325cSAndrew Lindesay or other process coordinator. 139310cd325cSAndrew Lindesay A change may mean that a new process has started / stopped etc... or it 139410cd325cSAndrew Lindesay may mean that the entire coordinator has finished. 139510cd325cSAndrew Lindesay */ 139610cd325cSAndrew Lindesay 139710cd325cSAndrew Lindesay void 139810cd325cSAndrew Lindesay MainWindow::CoordinatorChanged(ProcessCoordinatorState& coordinatorState) 139910cd325cSAndrew Lindesay { 140010cd325cSAndrew Lindesay AutoLocker<BLocker> lock(&fCoordinatorLock); 140110cd325cSAndrew Lindesay 1402f95ec23eSAndrew Lindesay if (fCoordinator.Get() == coordinatorState.Coordinator()) { 140310cd325cSAndrew Lindesay if (!coordinatorState.IsRunning()) { 140410cd325cSAndrew Lindesay if (release_sem(fCoordinatorRunningSem) != B_OK) 140510cd325cSAndrew Lindesay debugger("unable to release the process coordinator sem"); 1406f96d1f4dSAndrew Lindesay HDINFO("process coordinator [%s] did complete", 1407fa5c8097SAndrew Lindesay fCoordinator->Name().String()); 140810cd325cSAndrew Lindesay // complete the last one that just finished 140910cd325cSAndrew Lindesay BMessage* message = fCoordinator->Message(); 141010cd325cSAndrew Lindesay 141110cd325cSAndrew Lindesay if (message != NULL) { 141210cd325cSAndrew Lindesay BMessenger messenger(this); 141310cd325cSAndrew Lindesay message->AddInt64(KEY_ERROR_STATUS, 141410cd325cSAndrew Lindesay (int64) fCoordinator->ErrorStatus()); 141510cd325cSAndrew Lindesay messenger.SendMessage(message); 141610cd325cSAndrew Lindesay } 141710cd325cSAndrew Lindesay 1418f95ec23eSAndrew Lindesay fCoordinator = BReference<ProcessCoordinator>(NULL); 1419f95ec23eSAndrew Lindesay // will delete the old process coordinator if it is not used 1420f95ec23eSAndrew Lindesay // elsewhere. 142110cd325cSAndrew Lindesay 142210cd325cSAndrew Lindesay // now schedule the next one. 142310cd325cSAndrew Lindesay if (!fCoordinatorQueue.empty()) { 142410cd325cSAndrew Lindesay if (acquire_sem(fCoordinatorRunningSem) != B_OK) 142510cd325cSAndrew Lindesay debugger("unable to acquire the process coordinator sem"); 142610cd325cSAndrew Lindesay fCoordinator = fCoordinatorQueue.front(); 1427f96d1f4dSAndrew Lindesay HDINFO("starting next process coordinator [%s]", 142810cd325cSAndrew Lindesay fCoordinator->Name().String()); 142910cd325cSAndrew Lindesay fCoordinatorQueue.pop(); 143010cd325cSAndrew Lindesay fCoordinator->Start(); 143110cd325cSAndrew Lindesay } 143210cd325cSAndrew Lindesay else { 143310cd325cSAndrew Lindesay _NotifyWorkStatusClear(); 143410cd325cSAndrew Lindesay } 143510cd325cSAndrew Lindesay } 143610cd325cSAndrew Lindesay else { 143710cd325cSAndrew Lindesay _NotifyWorkStatusChange(coordinatorState.Message(), 143810cd325cSAndrew Lindesay coordinatorState.Progress()); 143910cd325cSAndrew Lindesay // show the progress to the user. 144010cd325cSAndrew Lindesay } 1441fa5c8097SAndrew Lindesay } else 1442fa5c8097SAndrew Lindesay HDINFO("! unknown process coordinator changed"); 144310cd325cSAndrew Lindesay } 1444ccf707d0SAndrew Lindesay 1445ccf707d0SAndrew Lindesay 1446ccf707d0SAndrew Lindesay static package_list_view_mode 1447ccf707d0SAndrew Lindesay main_window_tab_to_package_list_view_mode(int32 tab) 1448ccf707d0SAndrew Lindesay { 1449ccf707d0SAndrew Lindesay if (tab == TAB_PROMINENT_PACKAGES) 1450ccf707d0SAndrew Lindesay return PROMINENT; 1451ccf707d0SAndrew Lindesay return ALL; 1452ccf707d0SAndrew Lindesay } 1453ccf707d0SAndrew Lindesay 1454ccf707d0SAndrew Lindesay 1455ccf707d0SAndrew Lindesay void 1456ccf707d0SAndrew Lindesay MainWindow::_HandleChangePackageListViewMode() 1457ccf707d0SAndrew Lindesay { 1458ccf707d0SAndrew Lindesay package_list_view_mode tabMode = main_window_tab_to_package_list_view_mode( 1459ccf707d0SAndrew Lindesay fListTabs->Selection()); 1460ccf707d0SAndrew Lindesay package_list_view_mode modelMode = fModel.PackageListViewMode(); 1461ccf707d0SAndrew Lindesay 1462ccf707d0SAndrew Lindesay if (tabMode != modelMode) { 1463ccf707d0SAndrew Lindesay BAutolock locker(fModel.Lock()); 1464ccf707d0SAndrew Lindesay fModel.SetPackageListViewMode(tabMode); 1465ccf707d0SAndrew Lindesay } 1466ccf707d0SAndrew Lindesay } 146705880d13SAndrew Lindesay 146805880d13SAndrew Lindesay 146905880d13SAndrew Lindesay std::vector<DepotInfoRef> 147005880d13SAndrew Lindesay MainWindow::_CreateSnapshotOfDepots() 147105880d13SAndrew Lindesay { 147205880d13SAndrew Lindesay std::vector<DepotInfoRef> result; 147305880d13SAndrew Lindesay BAutolock locker(fModel.Lock()); 147405880d13SAndrew Lindesay int32 countDepots = fModel.CountDepots(); 147505880d13SAndrew Lindesay for(int32 i = 0; i < countDepots; i++) 147605880d13SAndrew Lindesay result.push_back(fModel.DepotAtIndex(i)); 147705880d13SAndrew Lindesay return result; 147805880d13SAndrew Lindesay } 1479