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" 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 } 4326f07feadSAndrew Lindesay if (!package.IsSet() || name != package->Name()) 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 } 495*0b69420bSAndrew Lindesay 496*0b69420bSAndrew Lindesay fFeaturedPackagesView->BeginAddRemove(); 497c4199192SAndrew Lindesay _AddRemovePackageFromLists(ref); 498*0b69420bSAndrew Lindesay fFeaturedPackagesView->EndAddRemove(); 499*0b69420bSAndrew Lindesay 50087016f8fSAndrew Lindesay if ((changes & PKG_CHANGED_STATE) != 0 501779ab335SX512 && !fCoordinator.IsSet()) { 5024e6fbe03SJulian Harnath fWorkStatusView->PackageStatusChanged(ref); 50357e51fffSStephan Aßmus } 50410cd325cSAndrew Lindesay } 50504c9d578SStephan Aßmus break; 50604c9d578SStephan Aßmus } 50704c9d578SStephan Aßmus 50804c9d578SStephan Aßmus case MSG_RATE_PACKAGE: 5091bbda92dSStephan Aßmus _RatePackage(); 51004c9d578SStephan Aßmus break; 51104c9d578SStephan Aßmus 512d5ef985eSStephan Aßmus case MSG_SHOW_SCREENSHOT: 513d5ef985eSStephan Aßmus _ShowScreenshot(); 514d5ef985eSStephan Aßmus break; 515d5ef985eSStephan Aßmus 516125d42d9SJulian Harnath case MSG_PACKAGE_WORKER_BUSY: 517125d42d9SJulian Harnath { 518125d42d9SJulian Harnath BString reason; 519125d42d9SJulian Harnath status_t status = message->FindString("reason", &reason); 520125d42d9SJulian Harnath if (status != B_OK) 521125d42d9SJulian Harnath break; 522125d42d9SJulian Harnath fWorkStatusView->SetBusy(reason); 523125d42d9SJulian Harnath break; 524125d42d9SJulian Harnath } 525125d42d9SJulian Harnath 526125d42d9SJulian Harnath case MSG_PACKAGE_WORKER_IDLE: 527125d42d9SJulian Harnath fWorkStatusView->SetIdle(); 528125d42d9SJulian Harnath break; 529125d42d9SJulian Harnath 53010cd325cSAndrew Lindesay case MSG_USER_USAGE_CONDITIONS_NOT_LATEST: 53110cd325cSAndrew Lindesay { 53210cd325cSAndrew Lindesay BMessage userDetailMsg; 53310cd325cSAndrew Lindesay if (message->FindMessage("userDetail", &userDetailMsg) != B_OK) { 53410cd325cSAndrew Lindesay debugger("expected the [userDetail] data to be carried in the " 53510cd325cSAndrew Lindesay "message."); 53610cd325cSAndrew Lindesay } 53710cd325cSAndrew Lindesay UserDetail userDetail(&userDetailMsg); 53810cd325cSAndrew Lindesay _HandleUserUsageConditionsNotLatest(userDetail); 53910cd325cSAndrew Lindesay break; 54010cd325cSAndrew Lindesay } 54110cd325cSAndrew Lindesay 54204c9d578SStephan Aßmus default: 54304c9d578SStephan Aßmus BWindow::MessageReceived(message); 54404c9d578SStephan Aßmus break; 54504c9d578SStephan Aßmus } 54604c9d578SStephan Aßmus } 54704c9d578SStephan Aßmus 54804c9d578SStephan Aßmus 549ccf707d0SAndrew Lindesay static const char* 550ccf707d0SAndrew Lindesay main_window_package_list_view_mode_str(package_list_view_mode mode) 551ccf707d0SAndrew Lindesay { 552ccf707d0SAndrew Lindesay if (mode == PROMINENT) 553ccf707d0SAndrew Lindesay return "PROMINENT"; 554ccf707d0SAndrew Lindesay return "ALL"; 555ccf707d0SAndrew Lindesay } 556ccf707d0SAndrew Lindesay 557ccf707d0SAndrew Lindesay 558ccf707d0SAndrew Lindesay static package_list_view_mode 559ccf707d0SAndrew Lindesay main_window_str_to_package_list_view_mode(const BString& str) 560ccf707d0SAndrew Lindesay { 561ccf707d0SAndrew Lindesay if (str == "PROMINENT") 562ccf707d0SAndrew Lindesay return PROMINENT; 563ccf707d0SAndrew Lindesay return ALL; 564ccf707d0SAndrew Lindesay } 565ccf707d0SAndrew Lindesay 566ccf707d0SAndrew Lindesay 56704c9d578SStephan Aßmus void 56804c9d578SStephan Aßmus MainWindow::StoreSettings(BMessage& settings) const 56904c9d578SStephan Aßmus { 570f7c2983eSAxel Dörfler settings.AddRect(_WindowFrameName(), Frame()); 571f7c2983eSAxel Dörfler if (!fSinglePackageMode) { 57204c9d578SStephan Aßmus settings.AddRect("window frame", Frame()); 57304c9d578SStephan Aßmus 57404c9d578SStephan Aßmus BMessage columnSettings; 5759883929bSAndrew Lindesay if (fPackageListView != NULL) 57604c9d578SStephan Aßmus fPackageListView->SaveState(&columnSettings); 57704c9d578SStephan Aßmus 57804c9d578SStephan Aßmus settings.AddMessage("column settings", &columnSettings); 57904c9d578SStephan Aßmus 580ccf707d0SAndrew Lindesay settings.AddString(KEY_PACKAGE_LIST_VIEW_MODE, 581ccf707d0SAndrew Lindesay main_window_package_list_view_mode_str( 582ccf707d0SAndrew Lindesay fModel.PackageListViewMode())); 5832997e05bSStephan Aßmus settings.AddBool("show available packages", 5842997e05bSStephan Aßmus fModel.ShowAvailablePackages()); 5852997e05bSStephan Aßmus settings.AddBool("show installed packages", 5862997e05bSStephan Aßmus fModel.ShowInstalledPackages()); 58704c9d578SStephan Aßmus settings.AddBool("show develop packages", fModel.ShowDevelopPackages()); 58804c9d578SStephan Aßmus settings.AddBool("show source packages", fModel.ShowSourcePackages()); 5896d519fd1SStephan Aßmus } 5908f03a0f9SStephan Aßmus 591d2d4866dSAndrew Lindesay settings.AddString("username", fModel.Nickname()); 59204c9d578SStephan Aßmus } 59304c9d578SStephan Aßmus 59404c9d578SStephan Aßmus 59504c9d578SStephan Aßmus void 59604c9d578SStephan Aßmus MainWindow::PackageChanged(const PackageInfoEvent& event) 59704c9d578SStephan Aßmus { 598a9edb9bfSAndrew Lindesay uint32 watchedChanges = PKG_CHANGED_STATE | PKG_CHANGED_PROMINENCE; 599a9edb9bfSAndrew Lindesay if ((event.Changes() & watchedChanges) != 0) { 60004c9d578SStephan Aßmus PackageInfoRef ref(event.Package()); 601da651104SStephan Aßmus BMessage message(MSG_PACKAGE_CHANGED); 60204c9d578SStephan Aßmus message.AddPointer("package", ref.Get()); 603da651104SStephan Aßmus message.AddUInt32("changes", event.Changes()); 60404c9d578SStephan Aßmus ref.Detach(); 60504c9d578SStephan Aßmus // reference needs to be released by MessageReceived(); 60604c9d578SStephan Aßmus PostMessage(&message); 60704c9d578SStephan Aßmus } 60804c9d578SStephan Aßmus } 60904c9d578SStephan Aßmus 61004c9d578SStephan Aßmus 61104c9d578SStephan Aßmus status_t 6126f07feadSAndrew Lindesay MainWindow::SchedulePackageAction(PackageActionRef action) 61304c9d578SStephan Aßmus { 61404c9d578SStephan Aßmus AutoLocker<BLocker> lock(&fPendingActionsLock); 6156f07feadSAndrew Lindesay fPendingActions.push(action); 6166f07feadSAndrew Lindesay return release_sem_etc(fPendingActionsSem, 1, 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; 831*0b69420bSAndrew Lindesay 832*0b69420bSAndrew Lindesay fFeaturedPackagesView->BeginAddRemove(); 833*0b69420bSAndrew Lindesay 83405880d13SAndrew Lindesay for (it = depots.begin(); it != depots.end(); it++) { 83505880d13SAndrew Lindesay DepotInfoRef depotInfoRef = *it; 836d75b4d61SAndrew Lindesay for (int i = 0; i < depotInfoRef->CountPackages(); i++) { 837d75b4d61SAndrew Lindesay PackageInfoRef package = depotInfoRef->PackageAtIndex(i); 838d75b4d61SAndrew Lindesay _AddRemovePackageFromLists(package); 839d75b4d61SAndrew Lindesay } 840c4199192SAndrew Lindesay } 841c4199192SAndrew Lindesay 842*0b69420bSAndrew Lindesay fFeaturedPackagesView->EndAddRemove(); 843*0b69420bSAndrew Lindesay 844c4199192SAndrew Lindesay _AdoptModelControls(); 845c4199192SAndrew Lindesay } 846c4199192SAndrew Lindesay 847c4199192SAndrew Lindesay 848c4199192SAndrew Lindesay void 849c4199192SAndrew Lindesay MainWindow::_AddRemovePackageFromLists(const PackageInfoRef& package) 850c4199192SAndrew Lindesay { 851c4199192SAndrew Lindesay bool matches; 852c4199192SAndrew Lindesay 853c4199192SAndrew Lindesay { 854c4199192SAndrew Lindesay AutoLocker<BLocker> modelLocker(fModel.Lock()); 855c4199192SAndrew Lindesay matches = fModel.MatchesFilter(package); 856c4199192SAndrew Lindesay } 857c4199192SAndrew Lindesay 858c4199192SAndrew Lindesay if (matches) { 859c4199192SAndrew Lindesay if (package->IsProminent()) 860c4199192SAndrew Lindesay fFeaturedPackagesView->AddPackage(package); 861c4199192SAndrew Lindesay fPackageListView->AddPackage(package); 862c4199192SAndrew Lindesay } else { 863c4199192SAndrew Lindesay fFeaturedPackagesView->RemovePackage(package); 864c4199192SAndrew Lindesay fPackageListView->RemovePackage(package); 865c4199192SAndrew Lindesay } 866c4199192SAndrew Lindesay } 867c4199192SAndrew Lindesay 868c4199192SAndrew Lindesay 869c4199192SAndrew Lindesay void 87004c9d578SStephan Aßmus MainWindow::_AdoptPackage(const PackageInfoRef& package) 87104c9d578SStephan Aßmus { 87275ba9dbfSStephan Aßmus { 87375ba9dbfSStephan Aßmus BAutolock locker(fModel.Lock()); 87404c9d578SStephan Aßmus fPackageInfoView->SetPackage(package); 8751986ab9fSStephan Aßmus 876664372abSStephan Aßmus if (fFeaturedPackagesView != NULL) 877664372abSStephan Aßmus fFeaturedPackagesView->SelectPackage(package); 8781986ab9fSStephan Aßmus if (fPackageListView != NULL) 8791986ab9fSStephan Aßmus fPackageListView->SelectPackage(package); 88075ba9dbfSStephan Aßmus } 88104c9d578SStephan Aßmus 882a9edb9bfSAndrew Lindesay _PopulatePackageAsync(false); 88304c9d578SStephan Aßmus } 88404c9d578SStephan Aßmus 88504c9d578SStephan Aßmus 88604c9d578SStephan Aßmus void 88704c9d578SStephan Aßmus MainWindow::_ClearPackage() 88804c9d578SStephan Aßmus { 88904c9d578SStephan Aßmus fPackageInfoView->Clear(); 89004c9d578SStephan Aßmus } 89104c9d578SStephan Aßmus 89204c9d578SStephan Aßmus 89304c9d578SStephan Aßmus void 8943369e03dSAndrew Lindesay MainWindow::_StartBulkLoad(bool force) 89504c9d578SStephan Aßmus { 896c4199192SAndrew Lindesay if (fFeaturedPackagesView != NULL) 897c4199192SAndrew Lindesay fFeaturedPackagesView->Clear(); 898c4199192SAndrew Lindesay if (fPackageListView != NULL) 899c4199192SAndrew Lindesay fPackageListView->Clear(); 900c4199192SAndrew Lindesay fPackageInfoView->Clear(); 901c4199192SAndrew Lindesay 90210cd325cSAndrew Lindesay fRefreshRepositoriesItem->SetEnabled(false); 90310cd325cSAndrew Lindesay ProcessCoordinator* bulkLoadCoordinator = 90410cd325cSAndrew Lindesay ProcessCoordinatorFactory::CreateBulkLoadCoordinator( 9053369e03dSAndrew Lindesay this, 9063369e03dSAndrew Lindesay // PackageInfoListener 9073369e03dSAndrew Lindesay this, 9083369e03dSAndrew Lindesay // ProcessCoordinatorListener 9093369e03dSAndrew Lindesay &fModel, force); 91010cd325cSAndrew Lindesay _AddProcessCoordinator(bulkLoadCoordinator); 91104c9d578SStephan Aßmus } 91204c9d578SStephan Aßmus 91304c9d578SStephan Aßmus 91404c9d578SStephan Aßmus void 91510cd325cSAndrew Lindesay MainWindow::_BulkLoadCompleteReceived(status_t errorStatus) 91604c9d578SStephan Aßmus { 91710cd325cSAndrew Lindesay if (errorStatus != B_OK) { 9183369e03dSAndrew Lindesay AppUtils::NotifySimpleError( 9191448ced0SHumdinger B_TRANSLATE("Package update error"), 9203369e03dSAndrew Lindesay B_TRANSLATE("While updating package data, a problem has arisen " 9213369e03dSAndrew Lindesay "that may cause data to be outdated or missing from the " 9223369e03dSAndrew Lindesay "application's display. Additional details regarding this " 9233369e03dSAndrew Lindesay "problem may be able to be obtained from the application " 924b21c9447SAndrew Lindesay "logs." 925b21c9447SAndrew Lindesay ALERT_MSG_LOGS_USER_GUIDE)); 92604c9d578SStephan Aßmus } 92710cd325cSAndrew Lindesay 9283369e03dSAndrew Lindesay fRefreshRepositoriesItem->SetEnabled(true); 92910cd325cSAndrew Lindesay _AdoptModel(); 93010cd325cSAndrew Lindesay _UpdateAvailableRepositories(); 931ccf707d0SAndrew Lindesay 932ccf707d0SAndrew Lindesay // if after loading everything in, it transpires that there are no 933ccf707d0SAndrew Lindesay // featured packages then the featured packages should be disabled 934ccf707d0SAndrew Lindesay // and the user should be switched to the "all packages" view so 935ccf707d0SAndrew Lindesay // that they are not presented with a blank window! 936ccf707d0SAndrew Lindesay 937ccf707d0SAndrew Lindesay bool hasProminentPackages = fModel.HasAnyProminentPackages(); 938ccf707d0SAndrew Lindesay fListTabs->TabAt(TAB_PROMINENT_PACKAGES)->SetEnabled(hasProminentPackages); 939ccf707d0SAndrew Lindesay if (!hasProminentPackages 940ccf707d0SAndrew Lindesay && fListTabs->Selection() == TAB_PROMINENT_PACKAGES) { 941ccf707d0SAndrew Lindesay fModel.SetPackageListViewMode(ALL); 942ccf707d0SAndrew Lindesay fListTabs->Select(TAB_ALL_PACKAGES); 943ccf707d0SAndrew Lindesay } 94404c9d578SStephan Aßmus } 94504c9d578SStephan Aßmus 94604c9d578SStephan Aßmus 9473369e03dSAndrew Lindesay void 94810cd325cSAndrew Lindesay MainWindow::_NotifyWorkStatusClear() 94904c9d578SStephan Aßmus { 95010cd325cSAndrew Lindesay BMessage message(MSG_WORK_STATUS_CLEAR); 95110cd325cSAndrew Lindesay this->PostMessage(&message, this); 95210cd325cSAndrew Lindesay } 95310cd325cSAndrew Lindesay 95410cd325cSAndrew Lindesay 95510cd325cSAndrew Lindesay void 95610cd325cSAndrew Lindesay MainWindow::_HandleWorkStatusClear() 95710cd325cSAndrew Lindesay { 95810cd325cSAndrew Lindesay fWorkStatusView->SetText(""); 9593369e03dSAndrew Lindesay fWorkStatusView->SetIdle(); 9603369e03dSAndrew Lindesay } 96104c9d578SStephan Aßmus 96204c9d578SStephan Aßmus 9633369e03dSAndrew Lindesay /*! Sends off a message to the Window so that it can change the status view 9643369e03dSAndrew Lindesay on the front-end in the UI thread. 9653369e03dSAndrew Lindesay */ 96604c9d578SStephan Aßmus 9673369e03dSAndrew Lindesay void 9683369e03dSAndrew Lindesay MainWindow::_NotifyWorkStatusChange(const BString& text, float progress) 9693369e03dSAndrew Lindesay { 9703369e03dSAndrew Lindesay BMessage message(MSG_WORK_STATUS_CHANGE); 97104c9d578SStephan Aßmus 9723369e03dSAndrew Lindesay if (!text.IsEmpty()) 9733369e03dSAndrew Lindesay message.AddString(KEY_WORK_STATUS_TEXT, text); 9743369e03dSAndrew Lindesay message.AddFloat(KEY_WORK_STATUS_PROGRESS, progress); 97504c9d578SStephan Aßmus 9763369e03dSAndrew Lindesay this->PostMessage(&message, this); 9773369e03dSAndrew Lindesay } 97804c9d578SStephan Aßmus 9793369e03dSAndrew Lindesay 9803369e03dSAndrew Lindesay void 9813369e03dSAndrew Lindesay MainWindow::_HandleWorkStatusChangeMessageReceived(const BMessage* message) 9823369e03dSAndrew Lindesay { 9839883929bSAndrew Lindesay if (fWorkStatusView == NULL) 9849883929bSAndrew Lindesay return; 9859883929bSAndrew Lindesay 9863369e03dSAndrew Lindesay BString text; 9873369e03dSAndrew Lindesay float progress; 9883369e03dSAndrew Lindesay 9893369e03dSAndrew Lindesay if (message->FindString(KEY_WORK_STATUS_TEXT, &text) == B_OK) 9903369e03dSAndrew Lindesay fWorkStatusView->SetText(text); 9913369e03dSAndrew Lindesay 9923369e03dSAndrew Lindesay if (message->FindFloat(KEY_WORK_STATUS_PROGRESS, &progress) == B_OK) 9933369e03dSAndrew Lindesay fWorkStatusView->SetProgress(progress); 99404c9d578SStephan Aßmus } 99504c9d578SStephan Aßmus 99604c9d578SStephan Aßmus 9976f07feadSAndrew Lindesay /*static*/ status_t 99804c9d578SStephan Aßmus MainWindow::_PackageActionWorker(void* arg) 99904c9d578SStephan Aßmus { 100004c9d578SStephan Aßmus MainWindow* window = reinterpret_cast<MainWindow*>(arg); 100104c9d578SStephan Aßmus 100204c9d578SStephan Aßmus while (acquire_sem(window->fPendingActionsSem) == B_OK) { 100304c9d578SStephan Aßmus PackageActionRef ref; 100404c9d578SStephan Aßmus { 100504c9d578SStephan Aßmus AutoLocker<BLocker> lock(&window->fPendingActionsLock); 10066f07feadSAndrew Lindesay ref = window->fPendingActions.front(); 10076f07feadSAndrew Lindesay window->fPendingActions.pop(); 1008779ab335SX512 if (!ref.IsSet()) 100904c9d578SStephan Aßmus break; 101004c9d578SStephan Aßmus } 101104c9d578SStephan Aßmus 1012125d42d9SJulian Harnath BMessenger messenger(window); 1013125d42d9SJulian Harnath BMessage busyMessage(MSG_PACKAGE_WORKER_BUSY); 1014125d42d9SJulian Harnath BString text(ref->Label()); 1015bc622f6bSHumdinger text << B_UTF8_ELLIPSIS; 1016125d42d9SJulian Harnath busyMessage.AddString("reason", text); 1017125d42d9SJulian Harnath 1018125d42d9SJulian Harnath messenger.SendMessage(&busyMessage); 101904c9d578SStephan Aßmus ref->Perform(); 1020125d42d9SJulian Harnath messenger.SendMessage(MSG_PACKAGE_WORKER_IDLE); 102104c9d578SStephan Aßmus } 102204c9d578SStephan Aßmus 102304c9d578SStephan Aßmus return 0; 102404c9d578SStephan Aßmus } 102504c9d578SStephan Aßmus 102604c9d578SStephan Aßmus 1027a9edb9bfSAndrew Lindesay /*! This method will cause the package to have its data refreshed from 1028a9edb9bfSAndrew Lindesay the server application. The refresh happens in the background; this method 1029a9edb9bfSAndrew Lindesay is asynchronous. 1030a9edb9bfSAndrew Lindesay */ 1031a9edb9bfSAndrew Lindesay 1032a9edb9bfSAndrew Lindesay void 1033a9edb9bfSAndrew Lindesay MainWindow::_PopulatePackageAsync(bool forcePopulate) 1034a9edb9bfSAndrew Lindesay { 1035a9edb9bfSAndrew Lindesay // Trigger asynchronous package population from the web-app 1036a9edb9bfSAndrew Lindesay { 1037a9edb9bfSAndrew Lindesay AutoLocker<BLocker> lock(&fPackageToPopulateLock); 1038a9edb9bfSAndrew Lindesay fPackageToPopulate = fPackageInfoView->Package(); 1039a9edb9bfSAndrew Lindesay fForcePopulatePackage = forcePopulate; 1040a9edb9bfSAndrew Lindesay } 1041a9edb9bfSAndrew Lindesay release_sem_etc(fPackageToPopulateSem, 1, 0); 1042a9edb9bfSAndrew Lindesay 1043f96d1f4dSAndrew Lindesay HDDEBUG("pkg [%s] will be updated from the server.", 1044fa5c8097SAndrew Lindesay fPackageToPopulate->Name().String()); 1045a9edb9bfSAndrew Lindesay } 1046a9edb9bfSAndrew Lindesay 1047a9edb9bfSAndrew Lindesay 1048a9edb9bfSAndrew Lindesay /*! This method will run in the background. The thread will block until there 1049a9edb9bfSAndrew Lindesay is a package to be updated. When the thread unblocks, it will update the 1050a9edb9bfSAndrew Lindesay package with information from the server. 1051a9edb9bfSAndrew Lindesay */ 1052a9edb9bfSAndrew Lindesay 105304c9d578SStephan Aßmus status_t 105404c9d578SStephan Aßmus MainWindow::_PopulatePackageWorker(void* arg) 105504c9d578SStephan Aßmus { 105604c9d578SStephan Aßmus MainWindow* window = reinterpret_cast<MainWindow*>(arg); 105704c9d578SStephan Aßmus 105804c9d578SStephan Aßmus while (acquire_sem(window->fPackageToPopulateSem) == B_OK) { 105904c9d578SStephan Aßmus PackageInfoRef package; 1060a9edb9bfSAndrew Lindesay bool force; 106104c9d578SStephan Aßmus { 106204c9d578SStephan Aßmus AutoLocker<BLocker> lock(&window->fPackageToPopulateLock); 106304c9d578SStephan Aßmus package = window->fPackageToPopulate; 1064a9edb9bfSAndrew Lindesay force = window->fForcePopulatePackage; 106504c9d578SStephan Aßmus } 106604c9d578SStephan Aßmus 1067779ab335SX512 if (package.IsSet()) { 1068a9edb9bfSAndrew Lindesay uint32 populateFlags = Model::POPULATE_USER_RATINGS 1069a9edb9bfSAndrew Lindesay | Model::POPULATE_SCREEN_SHOTS 1070a9edb9bfSAndrew Lindesay | Model::POPULATE_CHANGELOG; 1071a9edb9bfSAndrew Lindesay 1072a9edb9bfSAndrew Lindesay if (force) 1073a9edb9bfSAndrew Lindesay populateFlags |= Model::POPULATE_FORCE; 1074a9edb9bfSAndrew Lindesay 1075a9edb9bfSAndrew Lindesay window->fModel.PopulatePackage(package, populateFlags); 1076a9edb9bfSAndrew Lindesay 1077fa5c8097SAndrew Lindesay HDDEBUG("populating package [%s]", package->Name().String()); 107804c9d578SStephan Aßmus } 107904c9d578SStephan Aßmus } 108004c9d578SStephan Aßmus 108104c9d578SStephan Aßmus return 0; 108204c9d578SStephan Aßmus } 108304c9d578SStephan Aßmus 108404c9d578SStephan Aßmus 108504c9d578SStephan Aßmus void 10861bbda92dSStephan Aßmus MainWindow::_OpenLoginWindow(const BMessage& onSuccessMessage) 108704c9d578SStephan Aßmus { 108804c9d578SStephan Aßmus UserLoginWindow* window = new UserLoginWindow(this, 108904c9d578SStephan Aßmus BRect(0, 0, 500, 400), fModel); 10901bbda92dSStephan Aßmus 10911bbda92dSStephan Aßmus if (onSuccessMessage.what != 0) 10921bbda92dSStephan Aßmus window->SetOnSuccessMessage(BMessenger(this), onSuccessMessage); 10931bbda92dSStephan Aßmus 109404c9d578SStephan Aßmus window->Show(); 109504c9d578SStephan Aßmus } 109604c9d578SStephan Aßmus 10978f03a0f9SStephan Aßmus 10988f03a0f9SStephan Aßmus void 109910cd325cSAndrew Lindesay MainWindow::_StartUserVerify() 110010cd325cSAndrew Lindesay { 110110cd325cSAndrew Lindesay if (!fModel.Nickname().IsEmpty()) { 110210cd325cSAndrew Lindesay _AddProcessCoordinator( 110310cd325cSAndrew Lindesay ProcessCoordinatorFactory::CreateUserDetailVerifierCoordinator( 110410cd325cSAndrew Lindesay this, 110510cd325cSAndrew Lindesay // UserDetailVerifierListener 110610cd325cSAndrew Lindesay this, 110710cd325cSAndrew Lindesay // ProcessCoordinatorListener 110810cd325cSAndrew Lindesay &fModel) ); 110910cd325cSAndrew Lindesay } 111010cd325cSAndrew Lindesay } 111110cd325cSAndrew Lindesay 111210cd325cSAndrew Lindesay 111310cd325cSAndrew Lindesay void 11148f03a0f9SStephan Aßmus MainWindow::_UpdateAuthorization() 11158f03a0f9SStephan Aßmus { 1116d2d4866dSAndrew Lindesay BString nickname(fModel.Nickname()); 1117d2d4866dSAndrew Lindesay bool hasUser = !nickname.IsEmpty(); 1118e0a26dceSStephan Aßmus 11196d519fd1SStephan Aßmus if (fLogOutItem != NULL) 1120e0a26dceSStephan Aßmus fLogOutItem->SetEnabled(hasUser); 1121d2d4866dSAndrew Lindesay if (fUsersUserUsageConditionsMenuItem != NULL) 1122d2d4866dSAndrew Lindesay fUsersUserUsageConditionsMenuItem->SetEnabled(hasUser); 1123e0a26dceSStephan Aßmus if (fLogInItem != NULL) { 1124e0a26dceSStephan Aßmus if (hasUser) 1125e0a26dceSStephan Aßmus fLogInItem->SetLabel(B_TRANSLATE("Switch account" B_UTF8_ELLIPSIS)); 1126e0a26dceSStephan Aßmus else 1127e0a26dceSStephan Aßmus fLogInItem->SetLabel(B_TRANSLATE("Log in" B_UTF8_ELLIPSIS)); 1128e0a26dceSStephan Aßmus } 1129e0a26dceSStephan Aßmus 1130e0a26dceSStephan Aßmus if (fUserMenu != NULL) { 1131e0a26dceSStephan Aßmus BString label; 1132d2d4866dSAndrew Lindesay if (hasUser) { 1133e0a26dceSStephan Aßmus label = B_TRANSLATE("Logged in as %User%"); 1134d2d4866dSAndrew Lindesay label.ReplaceAll("%User%", nickname); 1135d2d4866dSAndrew Lindesay } else { 1136d2d4866dSAndrew Lindesay label = B_TRANSLATE("Not logged in"); 1137e0a26dceSStephan Aßmus } 1138e0a26dceSStephan Aßmus fUserMenu->Superitem()->SetLabel(label); 1139e0a26dceSStephan Aßmus } 11408f03a0f9SStephan Aßmus } 11411bbda92dSStephan Aßmus 11421bbda92dSStephan Aßmus 11431bbda92dSStephan Aßmus void 1144b965ce70SHumdinger MainWindow::_UpdateAvailableRepositories() 1145b965ce70SHumdinger { 1146b965ce70SHumdinger fRepositoryMenu->RemoveItems(0, fRepositoryMenu->CountItems(), true); 1147b965ce70SHumdinger 1148b965ce70SHumdinger fRepositoryMenu->AddItem(new BMenuItem(B_TRANSLATE("All repositories"), 1149b965ce70SHumdinger new BMessage(MSG_DEPOT_SELECTED))); 1150b965ce70SHumdinger 1151b965ce70SHumdinger fRepositoryMenu->AddItem(new BSeparatorItem()); 1152b965ce70SHumdinger 1153b965ce70SHumdinger bool foundSelectedDepot = false; 115405880d13SAndrew Lindesay std::vector<DepotInfoRef> depots = _CreateSnapshotOfDepots(); 115505880d13SAndrew Lindesay std::vector<DepotInfoRef>::iterator it; 1156d13c3d89SAndrew Lindesay 115705880d13SAndrew Lindesay for (it = depots.begin(); it != depots.end(); it++) { 115805880d13SAndrew Lindesay DepotInfoRef depot = *it; 115905880d13SAndrew Lindesay 116005880d13SAndrew Lindesay if (depot->Name().Length() != 0) { 1161b965ce70SHumdinger BMessage* message = new BMessage(MSG_DEPOT_SELECTED); 116205880d13SAndrew Lindesay message->AddString("name", depot->Name()); 116305880d13SAndrew Lindesay BMenuItem* item = new(std::nothrow) BMenuItem(depot->Name(), message); 116405880d13SAndrew Lindesay 116505880d13SAndrew Lindesay if (item == NULL) 116605880d13SAndrew Lindesay HDFATAL("memory exhaustion"); 116705880d13SAndrew Lindesay 1168b965ce70SHumdinger fRepositoryMenu->AddItem(item); 1169b965ce70SHumdinger 117005880d13SAndrew Lindesay if (depot->Name() == fModel.Depot()) { 1171b965ce70SHumdinger item->SetMarked(true); 1172b965ce70SHumdinger foundSelectedDepot = true; 1173b965ce70SHumdinger } 1174b965ce70SHumdinger } 1175d13c3d89SAndrew Lindesay } 1176b965ce70SHumdinger 1177b965ce70SHumdinger if (!foundSelectedDepot) 1178b965ce70SHumdinger fRepositoryMenu->ItemAt(0)->SetMarked(true); 1179b965ce70SHumdinger } 1180b965ce70SHumdinger 1181b965ce70SHumdinger 1182a9edb9bfSAndrew Lindesay bool 1183a9edb9bfSAndrew Lindesay MainWindow::_SelectedPackageHasWebAppRepositoryCode() 1184a9edb9bfSAndrew Lindesay { 1185a9edb9bfSAndrew Lindesay const PackageInfoRef& package = fPackageInfoView->Package(); 11866ab878c0SAndrew Lindesay const BString depotName = package->DepotName(); 1187a9edb9bfSAndrew Lindesay 11886ab878c0SAndrew Lindesay if (depotName.IsEmpty()) { 1189fa5c8097SAndrew Lindesay HDDEBUG("the package [%s] has no depot name", package->Name().String()); 11906ab878c0SAndrew Lindesay } else { 11916ab878c0SAndrew Lindesay const DepotInfo* depot = fModel.DepotForName(depotName); 1192a9edb9bfSAndrew Lindesay 11936ab878c0SAndrew Lindesay if (depot == NULL) { 1194f96d1f4dSAndrew Lindesay HDINFO("the depot [%s] was not able to be found", 1195fa5c8097SAndrew Lindesay depotName.String()); 11966ab878c0SAndrew Lindesay } else { 11976ab878c0SAndrew Lindesay BString repositoryCode = depot->WebAppRepositoryCode(); 1198a9edb9bfSAndrew Lindesay 11996ab878c0SAndrew Lindesay if (repositoryCode.IsEmpty()) { 1200f96d1f4dSAndrew Lindesay HDINFO("the depot [%s] has no web app repository code", 1201fa5c8097SAndrew Lindesay depotName.String()); 1202fa5c8097SAndrew Lindesay } else 12036ab878c0SAndrew Lindesay return true; 12046ab878c0SAndrew Lindesay } 12056ab878c0SAndrew Lindesay } 12066ab878c0SAndrew Lindesay 12076ab878c0SAndrew Lindesay return false; 1208a9edb9bfSAndrew Lindesay } 1209a9edb9bfSAndrew Lindesay 1210a9edb9bfSAndrew Lindesay 1211b965ce70SHumdinger void 12121bbda92dSStephan Aßmus MainWindow::_RatePackage() 12131bbda92dSStephan Aßmus { 1214a9edb9bfSAndrew Lindesay if (!_SelectedPackageHasWebAppRepositoryCode()) { 1215a9edb9bfSAndrew Lindesay BAlert* alert = new(std::nothrow) BAlert( 1216cbadcae1SHumdinger B_TRANSLATE("Rating not possible"), 1217cbadcae1SHumdinger B_TRANSLATE("This package doesn't seem to be on the HaikuDepot " 1218cbadcae1SHumdinger "Server, so it's not possible to create a new rating " 1219cbadcae1SHumdinger "or edit an existing rating."), 1220a9edb9bfSAndrew Lindesay B_TRANSLATE("OK")); 1221a9edb9bfSAndrew Lindesay alert->Go(); 1222a9edb9bfSAndrew Lindesay return; 1223a9edb9bfSAndrew Lindesay } 1224a9edb9bfSAndrew Lindesay 1225d2d4866dSAndrew Lindesay if (fModel.Nickname().IsEmpty()) { 12261bbda92dSStephan Aßmus BAlert* alert = new(std::nothrow) BAlert( 12271bbda92dSStephan Aßmus B_TRANSLATE("Not logged in"), 12281bbda92dSStephan Aßmus B_TRANSLATE("You need to be logged into an account before you " 12291bbda92dSStephan Aßmus "can rate packages."), 12301bbda92dSStephan Aßmus B_TRANSLATE("Cancel"), 12311bbda92dSStephan Aßmus B_TRANSLATE("Login or Create account")); 12321bbda92dSStephan Aßmus 12331bbda92dSStephan Aßmus if (alert == NULL) 12341bbda92dSStephan Aßmus return; 12351bbda92dSStephan Aßmus 12361bbda92dSStephan Aßmus int32 choice = alert->Go(); 12371bbda92dSStephan Aßmus if (choice == 1) 12381bbda92dSStephan Aßmus _OpenLoginWindow(BMessage(MSG_RATE_PACKAGE)); 12391bbda92dSStephan Aßmus return; 12401bbda92dSStephan Aßmus } 12411bbda92dSStephan Aßmus 12421bbda92dSStephan Aßmus // TODO: Allow only one RatePackageWindow 12431bbda92dSStephan Aßmus // TODO: Mechanism for remembering the window frame 12441bbda92dSStephan Aßmus RatePackageWindow* window = new RatePackageWindow(this, 12451bbda92dSStephan Aßmus BRect(0, 0, 500, 400), fModel); 12461bbda92dSStephan Aßmus window->SetPackage(fPackageInfoView->Package()); 12471bbda92dSStephan Aßmus window->Show(); 12481bbda92dSStephan Aßmus } 1249d5ef985eSStephan Aßmus 1250d5ef985eSStephan Aßmus 1251d5ef985eSStephan Aßmus void 1252d5ef985eSStephan Aßmus MainWindow::_ShowScreenshot() 1253d5ef985eSStephan Aßmus { 1254d5ef985eSStephan Aßmus // TODO: Mechanism for remembering the window frame 1255d5ef985eSStephan Aßmus if (fScreenshotWindow == NULL) 1256d5ef985eSStephan Aßmus fScreenshotWindow = new ScreenshotWindow(this, BRect(0, 0, 500, 400)); 1257d5ef985eSStephan Aßmus 1258d5ef985eSStephan Aßmus if (fScreenshotWindow->LockWithTimeout(1000) != B_OK) 1259d5ef985eSStephan Aßmus return; 1260d5ef985eSStephan Aßmus 1261d5ef985eSStephan Aßmus fScreenshotWindow->SetPackage(fPackageInfoView->Package()); 1262d5ef985eSStephan Aßmus 1263d5ef985eSStephan Aßmus if (fScreenshotWindow->IsHidden()) 1264d5ef985eSStephan Aßmus fScreenshotWindow->Show(); 1265d5ef985eSStephan Aßmus else 1266d5ef985eSStephan Aßmus fScreenshotWindow->Activate(); 1267d5ef985eSStephan Aßmus 1268d5ef985eSStephan Aßmus fScreenshotWindow->Unlock(); 1269d5ef985eSStephan Aßmus } 127001339a54SAndrew Lindesay 127101339a54SAndrew Lindesay 127201339a54SAndrew Lindesay void 1273d2d4866dSAndrew Lindesay MainWindow::_ViewUserUsageConditions( 1274d2d4866dSAndrew Lindesay UserUsageConditionsSelectionMode mode) 127501339a54SAndrew Lindesay { 127601339a54SAndrew Lindesay UserUsageConditionsWindow* window = new UserUsageConditionsWindow( 1277d2d4866dSAndrew Lindesay fModel, mode); 127801339a54SAndrew Lindesay window->Show(); 127901339a54SAndrew Lindesay } 128010cd325cSAndrew Lindesay 128110cd325cSAndrew Lindesay 128210cd325cSAndrew Lindesay void 128310cd325cSAndrew Lindesay MainWindow::UserCredentialsFailed() 128410cd325cSAndrew Lindesay { 128510cd325cSAndrew Lindesay BString message = B_TRANSLATE("The password previously " 128610cd325cSAndrew Lindesay "supplied for the user [%Nickname%] is not currently " 128710cd325cSAndrew Lindesay "valid. The user will be logged-out of this application " 128810cd325cSAndrew Lindesay "and you should login again with your updated password."); 128910cd325cSAndrew Lindesay message.ReplaceAll("%Nickname%", fModel.Nickname()); 129010cd325cSAndrew Lindesay 129110cd325cSAndrew Lindesay AppUtils::NotifySimpleError(B_TRANSLATE("Login issue"), 129210cd325cSAndrew Lindesay message); 129310cd325cSAndrew Lindesay 129410cd325cSAndrew Lindesay { 129510cd325cSAndrew Lindesay AutoLocker<BLocker> locker(fModel.Lock()); 129610cd325cSAndrew Lindesay fModel.SetNickname(""); 129710cd325cSAndrew Lindesay } 129810cd325cSAndrew Lindesay } 129910cd325cSAndrew Lindesay 130010cd325cSAndrew Lindesay 130110cd325cSAndrew Lindesay /*! \brief This method is invoked from the UserDetailVerifierProcess on a 130210cd325cSAndrew Lindesay background thread. For this reason it lodges a message into itself 130310cd325cSAndrew Lindesay which can then be handled on the main thread. 130410cd325cSAndrew Lindesay */ 130510cd325cSAndrew Lindesay 130610cd325cSAndrew Lindesay void 130710cd325cSAndrew Lindesay MainWindow::UserUsageConditionsNotLatest(const UserDetail& userDetail) 130810cd325cSAndrew Lindesay { 130910cd325cSAndrew Lindesay BMessage message(MSG_USER_USAGE_CONDITIONS_NOT_LATEST); 131010cd325cSAndrew Lindesay BMessage detailsMessage; 131110cd325cSAndrew Lindesay if (userDetail.Archive(&detailsMessage, true) != B_OK 131210cd325cSAndrew Lindesay || message.AddMessage("userDetail", &detailsMessage) != B_OK) { 1313fa5c8097SAndrew Lindesay HDERROR("unable to archive the user detail into a message"); 131410cd325cSAndrew Lindesay } 131510cd325cSAndrew Lindesay else 131610cd325cSAndrew Lindesay BMessenger(this).SendMessage(&message); 131710cd325cSAndrew Lindesay } 131810cd325cSAndrew Lindesay 131910cd325cSAndrew Lindesay 132010cd325cSAndrew Lindesay void 132110cd325cSAndrew Lindesay MainWindow::_HandleUserUsageConditionsNotLatest( 132210cd325cSAndrew Lindesay const UserDetail& userDetail) 132310cd325cSAndrew Lindesay { 132410cd325cSAndrew Lindesay ToLatestUserUsageConditionsWindow* window = 132510cd325cSAndrew Lindesay new ToLatestUserUsageConditionsWindow(this, fModel, userDetail); 132610cd325cSAndrew Lindesay window->Show(); 132710cd325cSAndrew Lindesay } 132810cd325cSAndrew Lindesay 132910cd325cSAndrew Lindesay 133010cd325cSAndrew Lindesay void 133110cd325cSAndrew Lindesay MainWindow::_AddProcessCoordinator(ProcessCoordinator* item) 133210cd325cSAndrew Lindesay { 133310cd325cSAndrew Lindesay AutoLocker<BLocker> lock(&fCoordinatorLock); 133410cd325cSAndrew Lindesay 1335779ab335SX512 if (!fCoordinator.IsSet()) { 133610cd325cSAndrew Lindesay if (acquire_sem(fCoordinatorRunningSem) != B_OK) 133710cd325cSAndrew Lindesay debugger("unable to acquire the process coordinator sem"); 1338f96d1f4dSAndrew Lindesay HDINFO("adding and starting a process coordinator [%s]", 1339fa5c8097SAndrew Lindesay item->Name().String()); 1340f95ec23eSAndrew Lindesay fCoordinator = BReference<ProcessCoordinator>(item); 134110cd325cSAndrew Lindesay fCoordinator->Start(); 134210cd325cSAndrew Lindesay } 134310cd325cSAndrew Lindesay else { 1344f96d1f4dSAndrew Lindesay HDINFO("adding process coordinator [%s] to the queue", 134510cd325cSAndrew Lindesay item->Name().String()); 134610cd325cSAndrew Lindesay fCoordinatorQueue.push(item); 134710cd325cSAndrew Lindesay } 134810cd325cSAndrew Lindesay } 134910cd325cSAndrew Lindesay 135010cd325cSAndrew Lindesay 135110cd325cSAndrew Lindesay void 135210cd325cSAndrew Lindesay MainWindow::_SpinUntilProcessCoordinatorComplete() 135310cd325cSAndrew Lindesay { 135410cd325cSAndrew Lindesay while (true) { 135510cd325cSAndrew Lindesay if (acquire_sem(fCoordinatorRunningSem) != B_OK) 135610cd325cSAndrew Lindesay debugger("unable to acquire the process coordinator sem"); 135710cd325cSAndrew Lindesay if (release_sem(fCoordinatorRunningSem) != B_OK) 135810cd325cSAndrew Lindesay debugger("unable to release the process coordinator sem"); 135910cd325cSAndrew Lindesay { 136010cd325cSAndrew Lindesay AutoLocker<BLocker> lock(&fCoordinatorLock); 1361779ab335SX512 if (!fCoordinator.IsSet()) 136210cd325cSAndrew Lindesay return; 136310cd325cSAndrew Lindesay } 136410cd325cSAndrew Lindesay } 136510cd325cSAndrew Lindesay } 136610cd325cSAndrew Lindesay 136710cd325cSAndrew Lindesay 136810cd325cSAndrew Lindesay void 136910cd325cSAndrew Lindesay MainWindow::_StopProcessCoordinators() 137010cd325cSAndrew Lindesay { 1371fa5c8097SAndrew Lindesay HDINFO("will stop all process coordinators"); 137210cd325cSAndrew Lindesay 137310cd325cSAndrew Lindesay { 137410cd325cSAndrew Lindesay AutoLocker<BLocker> lock(&fCoordinatorLock); 137510cd325cSAndrew Lindesay 137610cd325cSAndrew Lindesay while (!fCoordinatorQueue.empty()) { 1377f96d1f4dSAndrew Lindesay BReference<ProcessCoordinator> processCoordinator 1378f96d1f4dSAndrew Lindesay = fCoordinatorQueue.front(); 1379f96d1f4dSAndrew Lindesay HDINFO("will drop queued process coordinator [%s]", 1380fa5c8097SAndrew Lindesay processCoordinator->Name().String()); 138110cd325cSAndrew Lindesay fCoordinatorQueue.pop(); 138210cd325cSAndrew Lindesay } 138310cd325cSAndrew Lindesay 1384779ab335SX512 if (fCoordinator.IsSet()) { 138510cd325cSAndrew Lindesay fCoordinator->Stop(); 138610cd325cSAndrew Lindesay } 138710cd325cSAndrew Lindesay } 138810cd325cSAndrew Lindesay 1389fa5c8097SAndrew Lindesay HDINFO("will wait until the process coordinator has stopped"); 139010cd325cSAndrew Lindesay 139110cd325cSAndrew Lindesay _SpinUntilProcessCoordinatorComplete(); 139210cd325cSAndrew Lindesay 1393fa5c8097SAndrew Lindesay HDINFO("did stop all process coordinators"); 139410cd325cSAndrew Lindesay } 139510cd325cSAndrew Lindesay 139610cd325cSAndrew Lindesay 139710cd325cSAndrew Lindesay /*! This method is called when there is some change in the bulk load process 139810cd325cSAndrew Lindesay or other process coordinator. 139910cd325cSAndrew Lindesay A change may mean that a new process has started / stopped etc... or it 140010cd325cSAndrew Lindesay may mean that the entire coordinator has finished. 140110cd325cSAndrew Lindesay */ 140210cd325cSAndrew Lindesay 140310cd325cSAndrew Lindesay void 140410cd325cSAndrew Lindesay MainWindow::CoordinatorChanged(ProcessCoordinatorState& coordinatorState) 140510cd325cSAndrew Lindesay { 140610cd325cSAndrew Lindesay AutoLocker<BLocker> lock(&fCoordinatorLock); 140710cd325cSAndrew Lindesay 1408f95ec23eSAndrew Lindesay if (fCoordinator.Get() == coordinatorState.Coordinator()) { 140910cd325cSAndrew Lindesay if (!coordinatorState.IsRunning()) { 141010cd325cSAndrew Lindesay if (release_sem(fCoordinatorRunningSem) != B_OK) 141110cd325cSAndrew Lindesay debugger("unable to release the process coordinator sem"); 1412f96d1f4dSAndrew Lindesay HDINFO("process coordinator [%s] did complete", 1413fa5c8097SAndrew Lindesay fCoordinator->Name().String()); 141410cd325cSAndrew Lindesay // complete the last one that just finished 141510cd325cSAndrew Lindesay BMessage* message = fCoordinator->Message(); 141610cd325cSAndrew Lindesay 141710cd325cSAndrew Lindesay if (message != NULL) { 141810cd325cSAndrew Lindesay BMessenger messenger(this); 141910cd325cSAndrew Lindesay message->AddInt64(KEY_ERROR_STATUS, 142010cd325cSAndrew Lindesay (int64) fCoordinator->ErrorStatus()); 142110cd325cSAndrew Lindesay messenger.SendMessage(message); 142210cd325cSAndrew Lindesay } 142310cd325cSAndrew Lindesay 1424f95ec23eSAndrew Lindesay fCoordinator = BReference<ProcessCoordinator>(NULL); 1425f95ec23eSAndrew Lindesay // will delete the old process coordinator if it is not used 1426f95ec23eSAndrew Lindesay // elsewhere. 142710cd325cSAndrew Lindesay 142810cd325cSAndrew Lindesay // now schedule the next one. 142910cd325cSAndrew Lindesay if (!fCoordinatorQueue.empty()) { 143010cd325cSAndrew Lindesay if (acquire_sem(fCoordinatorRunningSem) != B_OK) 143110cd325cSAndrew Lindesay debugger("unable to acquire the process coordinator sem"); 143210cd325cSAndrew Lindesay fCoordinator = fCoordinatorQueue.front(); 1433f96d1f4dSAndrew Lindesay HDINFO("starting next process coordinator [%s]", 143410cd325cSAndrew Lindesay fCoordinator->Name().String()); 143510cd325cSAndrew Lindesay fCoordinatorQueue.pop(); 143610cd325cSAndrew Lindesay fCoordinator->Start(); 143710cd325cSAndrew Lindesay } 143810cd325cSAndrew Lindesay else { 143910cd325cSAndrew Lindesay _NotifyWorkStatusClear(); 144010cd325cSAndrew Lindesay } 144110cd325cSAndrew Lindesay } 144210cd325cSAndrew Lindesay else { 144310cd325cSAndrew Lindesay _NotifyWorkStatusChange(coordinatorState.Message(), 144410cd325cSAndrew Lindesay coordinatorState.Progress()); 144510cd325cSAndrew Lindesay // show the progress to the user. 144610cd325cSAndrew Lindesay } 1447fa5c8097SAndrew Lindesay } else 1448fa5c8097SAndrew Lindesay HDINFO("! unknown process coordinator changed"); 144910cd325cSAndrew Lindesay } 1450ccf707d0SAndrew Lindesay 1451ccf707d0SAndrew Lindesay 1452ccf707d0SAndrew Lindesay static package_list_view_mode 1453ccf707d0SAndrew Lindesay main_window_tab_to_package_list_view_mode(int32 tab) 1454ccf707d0SAndrew Lindesay { 1455ccf707d0SAndrew Lindesay if (tab == TAB_PROMINENT_PACKAGES) 1456ccf707d0SAndrew Lindesay return PROMINENT; 1457ccf707d0SAndrew Lindesay return ALL; 1458ccf707d0SAndrew Lindesay } 1459ccf707d0SAndrew Lindesay 1460ccf707d0SAndrew Lindesay 1461ccf707d0SAndrew Lindesay void 1462ccf707d0SAndrew Lindesay MainWindow::_HandleChangePackageListViewMode() 1463ccf707d0SAndrew Lindesay { 1464ccf707d0SAndrew Lindesay package_list_view_mode tabMode = main_window_tab_to_package_list_view_mode( 1465ccf707d0SAndrew Lindesay fListTabs->Selection()); 1466ccf707d0SAndrew Lindesay package_list_view_mode modelMode = fModel.PackageListViewMode(); 1467ccf707d0SAndrew Lindesay 1468ccf707d0SAndrew Lindesay if (tabMode != modelMode) { 1469ccf707d0SAndrew Lindesay BAutolock locker(fModel.Lock()); 1470ccf707d0SAndrew Lindesay fModel.SetPackageListViewMode(tabMode); 1471ccf707d0SAndrew Lindesay } 1472ccf707d0SAndrew Lindesay } 147305880d13SAndrew Lindesay 147405880d13SAndrew Lindesay 147505880d13SAndrew Lindesay std::vector<DepotInfoRef> 147605880d13SAndrew Lindesay MainWindow::_CreateSnapshotOfDepots() 147705880d13SAndrew Lindesay { 147805880d13SAndrew Lindesay std::vector<DepotInfoRef> result; 147905880d13SAndrew Lindesay BAutolock locker(fModel.Lock()); 148005880d13SAndrew Lindesay int32 countDepots = fModel.CountDepots(); 148105880d13SAndrew Lindesay for(int32 i = 0; i < countDepots; i++) 148205880d13SAndrew Lindesay result.push_back(fModel.DepotAtIndex(i)); 148305880d13SAndrew Lindesay return result; 148405880d13SAndrew Lindesay } 1485