15bf2b6ebSBrian Hill /* 25bf2b6ebSBrian Hill * Copyright 2017 Haiku Inc. All rights reserved. 35bf2b6ebSBrian Hill * Distributed under the terms of the MIT License. 45bf2b6ebSBrian Hill * 55bf2b6ebSBrian Hill * Authors: 65bf2b6ebSBrian Hill * Brian Hill 75bf2b6ebSBrian Hill */ 85bf2b6ebSBrian Hill 95bf2b6ebSBrian Hill 105bf2b6ebSBrian Hill #include "RepositoriesView.h" 115bf2b6ebSBrian Hill 125bf2b6ebSBrian Hill #include <stdlib.h> 135bf2b6ebSBrian Hill #include <Alert.h> 145bf2b6ebSBrian Hill #include <Button.h> 155bf2b6ebSBrian Hill #include <Catalog.h> 165bf2b6ebSBrian Hill #include <ColumnTypes.h> 175bf2b6ebSBrian Hill #include <LayoutBuilder.h> 185bf2b6ebSBrian Hill #include <MessageRunner.h> 195bf2b6ebSBrian Hill #include <ScrollBar.h> 205bf2b6ebSBrian Hill #include <SeparatorView.h> 21856ecc7bSBrian Hill #include <Url.h> 225bf2b6ebSBrian Hill #include <package/PackageRoster.h> 235bf2b6ebSBrian Hill #include <package/RepositoryConfig.h> 245bf2b6ebSBrian Hill 255bf2b6ebSBrian Hill #include "constants.h" 265bf2b6ebSBrian Hill 275bf2b6ebSBrian Hill #undef B_TRANSLATION_CONTEXT 285bf2b6ebSBrian Hill #define B_TRANSLATION_CONTEXT "RepositoriesView" 295bf2b6ebSBrian Hill 305bf2b6ebSBrian Hill 315bf2b6ebSBrian Hill static const BString kTitleEnabled = 3269478e07SBrian Hill B_TRANSLATE_COMMENT("Status", "Column title"); 335bf2b6ebSBrian Hill static const BString kTitleName = B_TRANSLATE_COMMENT("Name", "Column title"); 345bf2b6ebSBrian Hill static const BString kTitleUrl = B_TRANSLATE_COMMENT("URL", "Column title"); 355bf2b6ebSBrian Hill static const BString kLabelRemove = 365bf2b6ebSBrian Hill B_TRANSLATE_COMMENT("Remove", "Button label"); 375bf2b6ebSBrian Hill static const BString kLabelRemoveAll = 385bf2b6ebSBrian Hill B_TRANSLATE_COMMENT("Remove All", "Button label"); 395bf2b6ebSBrian Hill static const BString kLabelEnable = 405bf2b6ebSBrian Hill B_TRANSLATE_COMMENT("Enable", "Button label"); 415bf2b6ebSBrian Hill static const BString kLabelEnableAll = 425bf2b6ebSBrian Hill B_TRANSLATE_COMMENT("Enable All", "Button label"); 435bf2b6ebSBrian Hill static const BString kLabelDisable = 445bf2b6ebSBrian Hill B_TRANSLATE_COMMENT("Disable", "Button label"); 455bf2b6ebSBrian Hill static const BString kLabelDisableAll = 465bf2b6ebSBrian Hill B_TRANSLATE_COMMENT("Disable All", "Button label"); 475bf2b6ebSBrian Hill static const BString kStatusViewText = 485bf2b6ebSBrian Hill B_TRANSLATE_COMMENT("Changes pending:", "Status view text"); 495bf2b6ebSBrian Hill static const BString kStatusCompletedText = 505bf2b6ebSBrian Hill B_TRANSLATE_COMMENT("Changes completed", "Status view text"); 515bf2b6ebSBrian Hill 525bf2b6ebSBrian Hill 535bf2b6ebSBrian Hill RepositoriesListView::RepositoriesListView(const char* name) 545bf2b6ebSBrian Hill : 555bf2b6ebSBrian Hill BColumnListView(name, B_NAVIGABLE, B_PLAIN_BORDER) 565bf2b6ebSBrian Hill { 575bf2b6ebSBrian Hill } 585bf2b6ebSBrian Hill 595bf2b6ebSBrian Hill 605bf2b6ebSBrian Hill void 615bf2b6ebSBrian Hill RepositoriesListView::KeyDown(const char* bytes, int32 numBytes) 625bf2b6ebSBrian Hill { 635bf2b6ebSBrian Hill switch (bytes[0]) { 645bf2b6ebSBrian Hill case B_DELETE: 655bf2b6ebSBrian Hill Window()->PostMessage(DELETE_KEY_PRESSED); 665bf2b6ebSBrian Hill break; 675bf2b6ebSBrian Hill 685bf2b6ebSBrian Hill default: 695bf2b6ebSBrian Hill BColumnListView::KeyDown(bytes, numBytes); 705bf2b6ebSBrian Hill } 715bf2b6ebSBrian Hill } 725bf2b6ebSBrian Hill 735bf2b6ebSBrian Hill 745bf2b6ebSBrian Hill RepositoriesView::RepositoriesView() 755bf2b6ebSBrian Hill : 765bf2b6ebSBrian Hill BGroupView("RepositoriesView"), 775bf2b6ebSBrian Hill fTaskLooper(NULL), 785bf2b6ebSBrian Hill fShowCompletedStatus(false), 795bf2b6ebSBrian Hill fRunningTaskCount(0), 805bf2b6ebSBrian Hill fLastCompletedTimerId(0) 815bf2b6ebSBrian Hill { 825bf2b6ebSBrian Hill // Column list view with 3 columns 835bf2b6ebSBrian Hill fListView = new RepositoriesListView("list"); 845bf2b6ebSBrian Hill fListView->SetSelectionMessage(new BMessage(LIST_SELECTION_CHANGED)); 855bf2b6ebSBrian Hill float col0width = be_plain_font->StringWidth(kTitleEnabled) + 15; 865bf2b6ebSBrian Hill float col1width = be_plain_font->StringWidth(kTitleName) + 15; 875bf2b6ebSBrian Hill float col2width = be_plain_font->StringWidth(kTitleUrl) + 15; 885bf2b6ebSBrian Hill fListView->AddColumn(new BStringColumn(kTitleEnabled, col0width, col0width, 8969478e07SBrian Hill 2 * col0width, B_TRUNCATE_END), kEnabledColumn); 905bf2b6ebSBrian Hill fListView->AddColumn(new BStringColumn(kTitleName, 90, col1width, 300, 915bf2b6ebSBrian Hill B_TRUNCATE_END), kNameColumn); 925bf2b6ebSBrian Hill fListView->AddColumn(new BStringColumn(kTitleUrl, 500, col2width, 5000, 935bf2b6ebSBrian Hill B_TRUNCATE_END), kUrlColumn); 945bf2b6ebSBrian Hill fListView->SetInvocationMessage(new BMessage(ITEM_INVOKED)); 955bf2b6ebSBrian Hill 965bf2b6ebSBrian Hill // Repository list status view 975bf2b6ebSBrian Hill fStatusContainerView = new BView("status", B_SUPPORTS_LAYOUT); 985bf2b6ebSBrian Hill BString templateText(kStatusViewText); 995bf2b6ebSBrian Hill templateText.Append(" 88"); 1005bf2b6ebSBrian Hill // Simulate a status text with two digit queue count 1015bf2b6ebSBrian Hill fListStatusView = new BStringView("status", templateText); 1025bf2b6ebSBrian Hill 1035bf2b6ebSBrian Hill // Set a smaller fixed font size and slightly lighten text color 1045bf2b6ebSBrian Hill BFont font(be_plain_font); 1055bf2b6ebSBrian Hill font.SetSize(10.0f); 1065bf2b6ebSBrian Hill fListStatusView->SetFont(&font, B_FONT_SIZE); 1075bf2b6ebSBrian Hill fListStatusView->SetHighUIColor(fListStatusView->HighUIColor(), .9f); 1085bf2b6ebSBrian Hill 1095bf2b6ebSBrian Hill // Set appropriate explicit view sizes 1101aacfd69SAugustin Cavalier float viewWidth = std::max(fListStatusView->StringWidth(templateText), 1115bf2b6ebSBrian Hill fListStatusView->StringWidth(kStatusCompletedText)); 1125bf2b6ebSBrian Hill BSize statusViewSize(viewWidth + 3, B_H_SCROLL_BAR_HEIGHT - 2); 1135bf2b6ebSBrian Hill fListStatusView->SetExplicitSize(statusViewSize); 1145bf2b6ebSBrian Hill statusViewSize.height += 1; 1155bf2b6ebSBrian Hill fStatusContainerView->SetExplicitSize(statusViewSize); 1165bf2b6ebSBrian Hill BLayoutBuilder::Group<>(fStatusContainerView, B_HORIZONTAL, 0) 1175bf2b6ebSBrian Hill .Add(new BSeparatorView(B_VERTICAL)) 1185bf2b6ebSBrian Hill .AddGroup(B_VERTICAL, 0) 1195bf2b6ebSBrian Hill .AddGlue() 1205bf2b6ebSBrian Hill .AddGroup(B_HORIZONTAL, 0) 1215bf2b6ebSBrian Hill .SetInsets(2, 0, 0, 0) 1225bf2b6ebSBrian Hill .Add(fListStatusView) 1235bf2b6ebSBrian Hill .AddGlue() 1245bf2b6ebSBrian Hill .End() 1255bf2b6ebSBrian Hill .Add(new BSeparatorView(B_HORIZONTAL)) 1265bf2b6ebSBrian Hill .End() 1275bf2b6ebSBrian Hill .End(); 1285bf2b6ebSBrian Hill fListView->AddStatusView(fStatusContainerView); 1295bf2b6ebSBrian Hill 1305bf2b6ebSBrian Hill // Standard buttons 1315bf2b6ebSBrian Hill fEnableButton = new BButton(kLabelEnable, 1325bf2b6ebSBrian Hill new BMessage(ENABLE_BUTTON_PRESSED)); 1335bf2b6ebSBrian Hill fDisableButton = new BButton(kLabelDisable, 1345bf2b6ebSBrian Hill new BMessage(DISABLE_BUTTON_PRESSED)); 1355bf2b6ebSBrian Hill 1365bf2b6ebSBrian Hill // Create buttons with fixed size 1375bf2b6ebSBrian Hill font_height fontHeight; 1385bf2b6ebSBrian Hill GetFontHeight(&fontHeight); 1395bf2b6ebSBrian Hill int16 buttonHeight = int16(fontHeight.ascent + fontHeight.descent + 12); 1405bf2b6ebSBrian Hill // button size determined by font size 1415bf2b6ebSBrian Hill BSize btnSize(buttonHeight, buttonHeight); 1425bf2b6ebSBrian Hill 1435bf2b6ebSBrian Hill fAddButton = new BButton("plus", "+", new BMessage(ADD_REPO_WINDOW)); 1445bf2b6ebSBrian Hill fAddButton->SetExplicitSize(btnSize); 1455bf2b6ebSBrian Hill fRemoveButton = new BButton("minus", "-", new BMessage(REMOVE_REPOS)); 1465bf2b6ebSBrian Hill fRemoveButton->SetExplicitSize(btnSize); 1475bf2b6ebSBrian Hill 1485bf2b6ebSBrian Hill // Layout 1495bf2b6ebSBrian Hill int16 buttonSpacing = 1; 1505bf2b6ebSBrian Hill BLayoutBuilder::Group<>(this, B_VERTICAL, 0) 1515bf2b6ebSBrian Hill .SetInsets(B_USE_WINDOW_SPACING) 1525bf2b6ebSBrian Hill .AddGroup(B_HORIZONTAL, 0, 0.0) 1535f020e71SAnirudh M .Add(new BStringView("instruction", B_TRANSLATE_COMMENT("Enable" 1545f020e71SAnirudh M " repositories to use with package management:", 1555bf2b6ebSBrian Hill "Label text")), 0.0) 1565bf2b6ebSBrian Hill .AddGlue() 1575bf2b6ebSBrian Hill .End() 1585bf2b6ebSBrian Hill .AddStrut(B_USE_DEFAULT_SPACING) 1595bf2b6ebSBrian Hill .Add(fListView, 1) 1605bf2b6ebSBrian Hill .AddGroup(B_HORIZONTAL, 0, 0.0) 1615bf2b6ebSBrian Hill // Add and Remove buttons 1625bf2b6ebSBrian Hill .AddGroup(B_VERTICAL, 0, 0.0) 1635bf2b6ebSBrian Hill .AddGroup(B_HORIZONTAL, 0, 0.0) 1645bf2b6ebSBrian Hill .Add(new BSeparatorView(B_VERTICAL)) 1655bf2b6ebSBrian Hill .AddGroup(B_VERTICAL, 0, 0.0) 1665bf2b6ebSBrian Hill .AddGroup(B_HORIZONTAL, buttonSpacing, 0.0) 1675bf2b6ebSBrian Hill .SetInsets(buttonSpacing) 1685bf2b6ebSBrian Hill .Add(fAddButton) 1695bf2b6ebSBrian Hill .Add(fRemoveButton) 1705bf2b6ebSBrian Hill .End() 1715bf2b6ebSBrian Hill .Add(new BSeparatorView(B_HORIZONTAL)) 1725bf2b6ebSBrian Hill .End() 1735bf2b6ebSBrian Hill .Add(new BSeparatorView(B_VERTICAL)) 1745bf2b6ebSBrian Hill .End() 1755bf2b6ebSBrian Hill .AddGlue() 1765bf2b6ebSBrian Hill .End() 1775bf2b6ebSBrian Hill // Enable and Disable buttons 1785bf2b6ebSBrian Hill .AddGroup(B_HORIZONTAL) 1795bf2b6ebSBrian Hill .SetInsets(B_USE_DEFAULT_SPACING, B_USE_DEFAULT_SPACING, 1805bf2b6ebSBrian Hill B_USE_DEFAULT_SPACING, 0) 1815bf2b6ebSBrian Hill .AddGlue() 1825bf2b6ebSBrian Hill .Add(fEnableButton) 1835bf2b6ebSBrian Hill .Add(fDisableButton) 1845bf2b6ebSBrian Hill .End() 1855bf2b6ebSBrian Hill .End() 1865bf2b6ebSBrian Hill .End(); 1875bf2b6ebSBrian Hill } 1885bf2b6ebSBrian Hill 1895bf2b6ebSBrian Hill 1905bf2b6ebSBrian Hill RepositoriesView::~RepositoriesView() 1915bf2b6ebSBrian Hill { 1925bf2b6ebSBrian Hill if (fTaskLooper) { 1935bf2b6ebSBrian Hill fTaskLooper->Lock(); 1945bf2b6ebSBrian Hill fTaskLooper->Quit(); 1955bf2b6ebSBrian Hill } 1965bf2b6ebSBrian Hill _EmptyList(); 1975bf2b6ebSBrian Hill } 1985bf2b6ebSBrian Hill 1995bf2b6ebSBrian Hill 2005bf2b6ebSBrian Hill void 2015bf2b6ebSBrian Hill RepositoriesView::AllAttached() 2025bf2b6ebSBrian Hill { 2035bf2b6ebSBrian Hill BView::AllAttached(); 2045bf2b6ebSBrian Hill fRemoveButton->SetTarget(this); 2055bf2b6ebSBrian Hill fEnableButton->SetTarget(this); 2065bf2b6ebSBrian Hill fDisableButton->SetTarget(this); 2075bf2b6ebSBrian Hill fListView->SetTarget(this); 2085bf2b6ebSBrian Hill fRemoveButton->SetEnabled(false); 2095bf2b6ebSBrian Hill fEnableButton->SetEnabled(false); 2105bf2b6ebSBrian Hill fDisableButton->SetEnabled(false); 2115bf2b6ebSBrian Hill _UpdateStatusView(); 2125bf2b6ebSBrian Hill _InitList(); 2135bf2b6ebSBrian Hill } 2145bf2b6ebSBrian Hill 2155bf2b6ebSBrian Hill 2165bf2b6ebSBrian Hill void 2175bf2b6ebSBrian Hill RepositoriesView::AttachedToWindow() 2185bf2b6ebSBrian Hill { 2195bf2b6ebSBrian Hill fTaskLooper = new TaskLooper(BMessenger(this)); 2205bf2b6ebSBrian Hill } 2215bf2b6ebSBrian Hill 2225bf2b6ebSBrian Hill 2235bf2b6ebSBrian Hill void 2245bf2b6ebSBrian Hill RepositoriesView::MessageReceived(BMessage* message) 2255bf2b6ebSBrian Hill { 2265bf2b6ebSBrian Hill switch (message->what) 2275bf2b6ebSBrian Hill { 228856ecc7bSBrian Hill case REMOVE_REPOS: 229856ecc7bSBrian Hill { 2305bf2b6ebSBrian Hill RepoRow* rowItem = dynamic_cast<RepoRow*>(fListView->CurrentSelection()); 2315bf2b6ebSBrian Hill if (!rowItem || !fRemoveButton->IsEnabled()) 2325bf2b6ebSBrian Hill break; 2335bf2b6ebSBrian Hill 2345bf2b6ebSBrian Hill BString text; 2355bf2b6ebSBrian Hill // More than one selected row 2365bf2b6ebSBrian Hill if (fListView->CurrentSelection(rowItem)) { 2375bf2b6ebSBrian Hill text.SetTo(B_TRANSLATE_COMMENT("Remove these repositories?", 2385bf2b6ebSBrian Hill "Removal alert confirmation message")); 2395bf2b6ebSBrian Hill text.Append("\n"); 2405bf2b6ebSBrian Hill } 2415bf2b6ebSBrian Hill // Only one selected row 2425bf2b6ebSBrian Hill else { 2435bf2b6ebSBrian Hill text.SetTo(B_TRANSLATE_COMMENT("Remove this repository?", 2445bf2b6ebSBrian Hill "Removal alert confirmation message")); 2455bf2b6ebSBrian Hill text.Append("\n"); 2465bf2b6ebSBrian Hill } 2475bf2b6ebSBrian Hill float minWidth = 0; 2485bf2b6ebSBrian Hill while (rowItem) { 2495bf2b6ebSBrian Hill BString repoText; 2505bf2b6ebSBrian Hill repoText.Append("\n").Append(rowItem->Name()) 2515bf2b6ebSBrian Hill .Append(" (").Append(rowItem->Url()).Append(")"); 2521aacfd69SAugustin Cavalier minWidth = std::max(minWidth, StringWidth(repoText.String())); 2535bf2b6ebSBrian Hill text.Append(repoText); 2545bf2b6ebSBrian Hill rowItem = dynamic_cast<RepoRow*>(fListView->CurrentSelection(rowItem)); 2555bf2b6ebSBrian Hill } 2561aacfd69SAugustin Cavalier minWidth = std::min(minWidth, Frame().Width()); 2575bf2b6ebSBrian Hill // Ensure alert window isn't much larger than the main window 2585bf2b6ebSBrian Hill BAlert* alert = new BAlert("confirm", text, kRemoveLabel, 2595bf2b6ebSBrian Hill kCancelLabel, NULL, B_WIDTH_AS_USUAL, B_WARNING_ALERT); 2605bf2b6ebSBrian Hill alert->TextView()->SetExplicitMinSize(BSize(minWidth, B_SIZE_UNSET)); 2615bf2b6ebSBrian Hill alert->SetFlags(alert->Flags() | B_CLOSE_ON_ESCAPE); 2625bf2b6ebSBrian Hill int32 answer = alert->Go(); 2635bf2b6ebSBrian Hill // User presses Cancel button 2645bf2b6ebSBrian Hill if (answer) 2655bf2b6ebSBrian Hill break; 2665bf2b6ebSBrian Hill 2675bf2b6ebSBrian Hill rowItem = dynamic_cast<RepoRow*>(fListView->CurrentSelection()); 2685bf2b6ebSBrian Hill while (rowItem) { 2695bf2b6ebSBrian Hill RepoRow* oldRow = rowItem; 2705bf2b6ebSBrian Hill rowItem = dynamic_cast<RepoRow*>(fListView->CurrentSelection(rowItem)); 2715bf2b6ebSBrian Hill fListView->RemoveRow(oldRow); 2725bf2b6ebSBrian Hill delete oldRow; 2735bf2b6ebSBrian Hill } 2745bf2b6ebSBrian Hill _SaveList(); 2755bf2b6ebSBrian Hill break; 2765bf2b6ebSBrian Hill } 277856ecc7bSBrian Hill 2785bf2b6ebSBrian Hill case LIST_SELECTION_CHANGED: 2795bf2b6ebSBrian Hill _UpdateButtons(); 2805bf2b6ebSBrian Hill break; 2815bf2b6ebSBrian Hill 282856ecc7bSBrian Hill case ITEM_INVOKED: 283856ecc7bSBrian Hill { 2845bf2b6ebSBrian Hill // Simulates pressing whichever is the enabled button 2855bf2b6ebSBrian Hill if (fEnableButton->IsEnabled()) { 2865bf2b6ebSBrian Hill BMessage invokeMessage(ENABLE_BUTTON_PRESSED); 2875bf2b6ebSBrian Hill MessageReceived(&invokeMessage); 2885bf2b6ebSBrian Hill } else if (fDisableButton->IsEnabled()) { 2895bf2b6ebSBrian Hill BMessage invokeMessage(DISABLE_BUTTON_PRESSED); 2905bf2b6ebSBrian Hill MessageReceived(&invokeMessage); 2915bf2b6ebSBrian Hill } 2925bf2b6ebSBrian Hill break; 2935bf2b6ebSBrian Hill } 294856ecc7bSBrian Hill 295856ecc7bSBrian Hill case ENABLE_BUTTON_PRESSED: 296856ecc7bSBrian Hill { 2975bf2b6ebSBrian Hill BStringList names; 2985bf2b6ebSBrian Hill bool paramsOK = true; 2995bf2b6ebSBrian Hill // Check if there are multiple selections of the same repository, 3005bf2b6ebSBrian Hill // pkgman won't like that 3015bf2b6ebSBrian Hill RepoRow* rowItem = dynamic_cast<RepoRow*>(fListView->CurrentSelection()); 3025bf2b6ebSBrian Hill while (rowItem) { 3035bf2b6ebSBrian Hill if (names.HasString(rowItem->Name()) 3045bf2b6ebSBrian Hill && kNewRepoDefaultName.Compare(rowItem->Name()) != 0) { 3055bf2b6ebSBrian Hill (new BAlert("duplicate", 3065bf2b6ebSBrian Hill B_TRANSLATE_COMMENT("Only one URL for each repository can " 3075bf2b6ebSBrian Hill "be enabled. Please change your selections.", 3085bf2b6ebSBrian Hill "Error message"), 3095bf2b6ebSBrian Hill kOKLabel, NULL, NULL, 3105bf2b6ebSBrian Hill B_WIDTH_AS_USUAL, B_STOP_ALERT))->Go(NULL); 3115bf2b6ebSBrian Hill paramsOK = false; 3125bf2b6ebSBrian Hill break; 3135bf2b6ebSBrian Hill } else 3145bf2b6ebSBrian Hill names.Add(rowItem->Name()); 3155bf2b6ebSBrian Hill rowItem = dynamic_cast<RepoRow*>(fListView->CurrentSelection(rowItem)); 3165bf2b6ebSBrian Hill } 3175bf2b6ebSBrian Hill if (paramsOK) { 3185bf2b6ebSBrian Hill _AddSelectedRowsToQueue(); 3195bf2b6ebSBrian Hill _UpdateButtons(); 3205bf2b6ebSBrian Hill } 3215bf2b6ebSBrian Hill break; 3225bf2b6ebSBrian Hill } 323856ecc7bSBrian Hill 3245bf2b6ebSBrian Hill case DISABLE_BUTTON_PRESSED: 3255bf2b6ebSBrian Hill _AddSelectedRowsToQueue(); 3265bf2b6ebSBrian Hill _UpdateButtons(); 3275bf2b6ebSBrian Hill break; 3285bf2b6ebSBrian Hill 329856ecc7bSBrian Hill case TASK_STARTED: 330856ecc7bSBrian Hill { 3315bf2b6ebSBrian Hill int16 count; 3325bf2b6ebSBrian Hill status_t result1 = message->FindInt16(key_count, &count); 3335bf2b6ebSBrian Hill RepoRow* rowItem; 3345bf2b6ebSBrian Hill status_t result2 = message->FindPointer(key_rowptr, (void**)&rowItem); 3355bf2b6ebSBrian Hill if (result1 == B_OK && result2 == B_OK) 3365bf2b6ebSBrian Hill _TaskStarted(rowItem, count); 3375bf2b6ebSBrian Hill break; 3385bf2b6ebSBrian Hill } 339856ecc7bSBrian Hill 340856ecc7bSBrian Hill case TASK_COMPLETED_WITH_ERRORS: 341856ecc7bSBrian Hill { 3425bf2b6ebSBrian Hill BString errorDetails; 3435bf2b6ebSBrian Hill status_t result = message->FindString(key_details, &errorDetails); 3445bf2b6ebSBrian Hill if (result == B_OK) { 3455bf2b6ebSBrian Hill (new BAlert("error", errorDetails, kOKLabel, NULL, NULL, 3465bf2b6ebSBrian Hill B_WIDTH_AS_USUAL, B_STOP_ALERT))->Go(NULL); 3475bf2b6ebSBrian Hill } 3485bf2b6ebSBrian Hill BString repoName = message->GetString(key_name, 3495bf2b6ebSBrian Hill kNewRepoDefaultName.String()); 3505bf2b6ebSBrian Hill int16 count; 3515bf2b6ebSBrian Hill status_t result1 = message->FindInt16(key_count, &count); 3525bf2b6ebSBrian Hill RepoRow* rowItem; 3535bf2b6ebSBrian Hill status_t result2 = message->FindPointer(key_rowptr, (void**)&rowItem); 3545bf2b6ebSBrian Hill if (result1 == B_OK && result2 == B_OK) { 3555bf2b6ebSBrian Hill _TaskCompleted(rowItem, count, repoName); 3565bf2b6ebSBrian Hill // Refresh the enabled status of each row since it is unsure what 3575bf2b6ebSBrian Hill // caused the error 3585bf2b6ebSBrian Hill _RefreshList(); 3595bf2b6ebSBrian Hill } 3605bf2b6ebSBrian Hill _UpdateButtons(); 3615bf2b6ebSBrian Hill break; 3625bf2b6ebSBrian Hill } 363856ecc7bSBrian Hill 364856ecc7bSBrian Hill case TASK_COMPLETED: 365856ecc7bSBrian Hill { 3665bf2b6ebSBrian Hill BString repoName = message->GetString(key_name, 3675bf2b6ebSBrian Hill kNewRepoDefaultName.String()); 3685bf2b6ebSBrian Hill int16 count; 3695bf2b6ebSBrian Hill status_t result1 = message->FindInt16(key_count, &count); 3705bf2b6ebSBrian Hill RepoRow* rowItem; 3715bf2b6ebSBrian Hill status_t result2 = message->FindPointer(key_rowptr, (void**)&rowItem); 3725bf2b6ebSBrian Hill if (result1 == B_OK && result2 == B_OK) { 3735bf2b6ebSBrian Hill _TaskCompleted(rowItem, count, repoName); 3745bf2b6ebSBrian Hill // If the completed row has siblings then enabling this row may 3755bf2b6ebSBrian Hill // have disabled one of the other siblings, do full refresh. 3765bf2b6ebSBrian Hill if (rowItem->HasSiblings() && rowItem->IsEnabled()) 3775bf2b6ebSBrian Hill _RefreshList(); 3785bf2b6ebSBrian Hill } 3795bf2b6ebSBrian Hill _UpdateButtons(); 3805bf2b6ebSBrian Hill break; 3815bf2b6ebSBrian Hill } 382856ecc7bSBrian Hill 383856ecc7bSBrian Hill case TASK_CANCELED: 384856ecc7bSBrian Hill { 3855bf2b6ebSBrian Hill int16 count; 3865bf2b6ebSBrian Hill status_t result1 = message->FindInt16(key_count, &count); 3875bf2b6ebSBrian Hill RepoRow* rowItem; 3885bf2b6ebSBrian Hill status_t result2 = message->FindPointer(key_rowptr, (void**)&rowItem); 3895bf2b6ebSBrian Hill if (result1 == B_OK && result2 == B_OK) 3905bf2b6ebSBrian Hill _TaskCanceled(rowItem, count); 3915bf2b6ebSBrian Hill // Refresh the enabled status of each row since it is unsure what 3925bf2b6ebSBrian Hill // caused the cancelation 3935bf2b6ebSBrian Hill _RefreshList(); 3945bf2b6ebSBrian Hill _UpdateButtons(); 3955bf2b6ebSBrian Hill break; 3965bf2b6ebSBrian Hill } 397856ecc7bSBrian Hill 3985bf2b6ebSBrian Hill case UPDATE_LIST: 3995bf2b6ebSBrian Hill _RefreshList(); 4005bf2b6ebSBrian Hill _UpdateButtons(); 4015bf2b6ebSBrian Hill break; 4025bf2b6ebSBrian Hill 403856ecc7bSBrian Hill case STATUS_VIEW_COMPLETED_TIMEOUT: 404856ecc7bSBrian Hill { 4055bf2b6ebSBrian Hill int32 timerID; 4065bf2b6ebSBrian Hill status_t result = message->FindInt32(key_ID, &timerID); 4075bf2b6ebSBrian Hill if (result == B_OK && timerID == fLastCompletedTimerId) 4085bf2b6ebSBrian Hill _UpdateStatusView(); 4095bf2b6ebSBrian Hill break; 4105bf2b6ebSBrian Hill } 411856ecc7bSBrian Hill 4125bf2b6ebSBrian Hill default: 4135bf2b6ebSBrian Hill BView::MessageReceived(message); 4145bf2b6ebSBrian Hill } 4155bf2b6ebSBrian Hill } 4165bf2b6ebSBrian Hill 4175bf2b6ebSBrian Hill 4185bf2b6ebSBrian Hill void 4195bf2b6ebSBrian Hill RepositoriesView::_AddSelectedRowsToQueue() 4205bf2b6ebSBrian Hill { 4215bf2b6ebSBrian Hill RepoRow* rowItem = dynamic_cast<RepoRow*>(fListView->CurrentSelection()); 4225bf2b6ebSBrian Hill while (rowItem) { 4235bf2b6ebSBrian Hill rowItem->SetTaskState(STATE_IN_QUEUE_WAITING); 4245bf2b6ebSBrian Hill BMessage taskMessage(DO_TASK); 4255bf2b6ebSBrian Hill taskMessage.AddPointer(key_rowptr, rowItem); 4265bf2b6ebSBrian Hill fTaskLooper->PostMessage(&taskMessage); 4275bf2b6ebSBrian Hill rowItem = dynamic_cast<RepoRow*>(fListView->CurrentSelection(rowItem)); 4285bf2b6ebSBrian Hill } 4295bf2b6ebSBrian Hill } 4305bf2b6ebSBrian Hill 4315bf2b6ebSBrian Hill 4325bf2b6ebSBrian Hill void 4335bf2b6ebSBrian Hill RepositoriesView::_TaskStarted(RepoRow* rowItem, int16 count) 4345bf2b6ebSBrian Hill { 4355bf2b6ebSBrian Hill fRunningTaskCount = count; 4365bf2b6ebSBrian Hill rowItem->SetTaskState(STATE_IN_QUEUE_RUNNING); 4375bf2b6ebSBrian Hill // Only present a status count if there is more than one task in queue 4385bf2b6ebSBrian Hill if (count > 1) { 4395bf2b6ebSBrian Hill _UpdateStatusView(); 4405bf2b6ebSBrian Hill fShowCompletedStatus = true; 4415bf2b6ebSBrian Hill } 4425bf2b6ebSBrian Hill } 4435bf2b6ebSBrian Hill 4445bf2b6ebSBrian Hill 4455bf2b6ebSBrian Hill void 4465bf2b6ebSBrian Hill RepositoriesView::_TaskCompleted(RepoRow* rowItem, int16 count, BString& newName) 4475bf2b6ebSBrian Hill { 4485bf2b6ebSBrian Hill fRunningTaskCount = count; 4495bf2b6ebSBrian Hill _ShowCompletedStatusIfDone(); 4505bf2b6ebSBrian Hill 4515bf2b6ebSBrian Hill // Update row state and values 4525bf2b6ebSBrian Hill rowItem->SetTaskState(STATE_NOT_IN_QUEUE); 4535bf2b6ebSBrian Hill if (kNewRepoDefaultName.Compare(rowItem->Name()) == 0 454856ecc7bSBrian Hill && newName.Compare("") != 0) { 4555bf2b6ebSBrian Hill rowItem->SetName(newName.String()); 456*3e967b3fSBrian Hill _SaveList(); 457856ecc7bSBrian Hill } 4585bf2b6ebSBrian Hill _UpdateFromRepoConfig(rowItem); 4595bf2b6ebSBrian Hill } 4605bf2b6ebSBrian Hill 4615bf2b6ebSBrian Hill 4625bf2b6ebSBrian Hill void 4635bf2b6ebSBrian Hill RepositoriesView::_TaskCanceled(RepoRow* rowItem, int16 count) 4645bf2b6ebSBrian Hill { 4655bf2b6ebSBrian Hill fRunningTaskCount = count; 4665bf2b6ebSBrian Hill _ShowCompletedStatusIfDone(); 4675bf2b6ebSBrian Hill 4685bf2b6ebSBrian Hill // Update row state and values 4695bf2b6ebSBrian Hill rowItem->SetTaskState(STATE_NOT_IN_QUEUE); 4705bf2b6ebSBrian Hill _UpdateFromRepoConfig(rowItem); 4715bf2b6ebSBrian Hill } 4725bf2b6ebSBrian Hill 4735bf2b6ebSBrian Hill 4745bf2b6ebSBrian Hill void 4755bf2b6ebSBrian Hill RepositoriesView::_ShowCompletedStatusIfDone() 4765bf2b6ebSBrian Hill { 4775bf2b6ebSBrian Hill // If this is the last task show completed status text for 3 seconds 4785bf2b6ebSBrian Hill if (fRunningTaskCount == 0 && fShowCompletedStatus) { 4795bf2b6ebSBrian Hill fListStatusView->SetText(kStatusCompletedText); 4805bf2b6ebSBrian Hill fLastCompletedTimerId = rand(); 4815bf2b6ebSBrian Hill BMessage timerMessage(STATUS_VIEW_COMPLETED_TIMEOUT); 4825bf2b6ebSBrian Hill timerMessage.AddInt32(key_ID, fLastCompletedTimerId); 4835bf2b6ebSBrian Hill new BMessageRunner(this, &timerMessage, 3000000, 1); 4845bf2b6ebSBrian Hill fShowCompletedStatus = false; 4855bf2b6ebSBrian Hill } else 4865bf2b6ebSBrian Hill _UpdateStatusView(); 4875bf2b6ebSBrian Hill } 4885bf2b6ebSBrian Hill 4895bf2b6ebSBrian Hill 4905bf2b6ebSBrian Hill void 4915bf2b6ebSBrian Hill RepositoriesView::_UpdateFromRepoConfig(RepoRow* rowItem) 4925bf2b6ebSBrian Hill { 4935bf2b6ebSBrian Hill BPackageKit::BPackageRoster pRoster; 4945bf2b6ebSBrian Hill BPackageKit::BRepositoryConfig repoConfig; 4955bf2b6ebSBrian Hill BString repoName(rowItem->Name()); 4965bf2b6ebSBrian Hill status_t result = pRoster.GetRepositoryConfig(repoName, &repoConfig); 4975bf2b6ebSBrian Hill // Repo name was found and the URL matches 4985bf2b6ebSBrian Hill if (result == B_OK && repoConfig.BaseURL() == rowItem->Url()) 4995bf2b6ebSBrian Hill rowItem->SetEnabled(true); 5005bf2b6ebSBrian Hill else 5015bf2b6ebSBrian Hill rowItem->SetEnabled(false); 5025bf2b6ebSBrian Hill } 5035bf2b6ebSBrian Hill 5045bf2b6ebSBrian Hill 5055bf2b6ebSBrian Hill void 5065bf2b6ebSBrian Hill RepositoriesView::AddManualRepository(BString url) 5075bf2b6ebSBrian Hill { 508856ecc7bSBrian Hill BUrl newRepoUrl(url); 509856ecc7bSBrian Hill if (!newRepoUrl.IsValid()) 510856ecc7bSBrian Hill return; 511856ecc7bSBrian Hill 5125bf2b6ebSBrian Hill BString name(kNewRepoDefaultName); 5135bf2b6ebSBrian Hill int32 index; 5145bf2b6ebSBrian Hill int32 listCount = fListView->CountRows(); 5155bf2b6ebSBrian Hill for (index = 0; index < listCount; index++) { 5165bf2b6ebSBrian Hill RepoRow* repoItem = dynamic_cast<RepoRow*>(fListView->RowAt(index)); 517856ecc7bSBrian Hill BUrl rowRepoUrl(repoItem->Url()); 5185bf2b6ebSBrian Hill // Find an already existing URL 519856ecc7bSBrian Hill if (newRepoUrl == rowRepoUrl) { 5205bf2b6ebSBrian Hill (new BAlert("duplicate", 5215bf2b6ebSBrian Hill B_TRANSLATE_COMMENT("This repository URL already exists.", 5225bf2b6ebSBrian Hill "Error message"), 5235bf2b6ebSBrian Hill kOKLabel))->Go(NULL); 5245bf2b6ebSBrian Hill return; 5255bf2b6ebSBrian Hill } 526856ecc7bSBrian Hill } 5275bf2b6ebSBrian Hill RepoRow* newRepo = _AddRepo(name, url, false); 5285bf2b6ebSBrian Hill _FindSiblings(); 5295bf2b6ebSBrian Hill fListView->DeselectAll(); 5305bf2b6ebSBrian Hill fListView->AddToSelection(newRepo); 5315bf2b6ebSBrian Hill _UpdateButtons(); 5325bf2b6ebSBrian Hill _SaveList(); 533*3e967b3fSBrian Hill if (fEnableButton->IsEnabled()) 534*3e967b3fSBrian Hill fEnableButton->Invoke(); 5355bf2b6ebSBrian Hill } 5365bf2b6ebSBrian Hill 5375bf2b6ebSBrian Hill 5385bf2b6ebSBrian Hill status_t 5395bf2b6ebSBrian Hill RepositoriesView::_EmptyList() 5405bf2b6ebSBrian Hill { 541856ecc7bSBrian Hill BRow* row = fListView->RowAt((int32)0, NULL); 542856ecc7bSBrian Hill while (row != NULL) { 5435bf2b6ebSBrian Hill fListView->RemoveRow(row); 5445bf2b6ebSBrian Hill delete row; 545856ecc7bSBrian Hill row = fListView->RowAt((int32)0, NULL); 5465bf2b6ebSBrian Hill } 5475bf2b6ebSBrian Hill return B_OK; 5485bf2b6ebSBrian Hill } 5495bf2b6ebSBrian Hill 5505bf2b6ebSBrian Hill 5515bf2b6ebSBrian Hill void 5525bf2b6ebSBrian Hill RepositoriesView::_InitList() 5535bf2b6ebSBrian Hill { 5545bf2b6ebSBrian Hill // Get list of known repositories from the settings file 5555bf2b6ebSBrian Hill int32 index, repoCount; 5565bf2b6ebSBrian Hill BStringList nameList, urlList; 5575bf2b6ebSBrian Hill status_t result = fSettings.GetRepositories(repoCount, nameList, urlList); 5585bf2b6ebSBrian Hill if (result == B_OK) { 5595bf2b6ebSBrian Hill BString name, url; 5605bf2b6ebSBrian Hill for (index = 0; index < repoCount; index++) { 5615bf2b6ebSBrian Hill name = nameList.StringAt(index); 5625bf2b6ebSBrian Hill url = urlList.StringAt(index); 5635bf2b6ebSBrian Hill _AddRepo(name, url, false); 5645bf2b6ebSBrian Hill } 5655bf2b6ebSBrian Hill } 5665bf2b6ebSBrian Hill _UpdateListFromRoster(); 5675bf2b6ebSBrian Hill fListView->SetSortColumn(fListView->ColumnAt(kUrlColumn), false, true); 5685bf2b6ebSBrian Hill fListView->ResizeAllColumnsToPreferred(); 5695bf2b6ebSBrian Hill } 5705bf2b6ebSBrian Hill 5715bf2b6ebSBrian Hill 5725bf2b6ebSBrian Hill void 5735bf2b6ebSBrian Hill RepositoriesView::_RefreshList() 5745bf2b6ebSBrian Hill { 5755bf2b6ebSBrian Hill // Clear enabled status on all rows 5765bf2b6ebSBrian Hill int32 index, listCount = fListView->CountRows(); 5775bf2b6ebSBrian Hill for (index = 0; index < listCount; index++) { 5785bf2b6ebSBrian Hill RepoRow* repoItem = dynamic_cast<RepoRow*>(fListView->RowAt(index)); 5795bf2b6ebSBrian Hill if (repoItem->TaskState() == STATE_NOT_IN_QUEUE) 5805bf2b6ebSBrian Hill repoItem->SetEnabled(false); 5815bf2b6ebSBrian Hill } 5825bf2b6ebSBrian Hill // Get current list of enabled repositories 5835bf2b6ebSBrian Hill _UpdateListFromRoster(); 5845bf2b6ebSBrian Hill } 5855bf2b6ebSBrian Hill 5865bf2b6ebSBrian Hill 5875bf2b6ebSBrian Hill void 5885bf2b6ebSBrian Hill RepositoriesView::_UpdateListFromRoster() 5895bf2b6ebSBrian Hill { 5905bf2b6ebSBrian Hill // Get list of currently enabled repositories 5915bf2b6ebSBrian Hill BStringList repositoryNames; 5925bf2b6ebSBrian Hill BPackageKit::BPackageRoster pRoster; 5935bf2b6ebSBrian Hill status_t result = pRoster.GetRepositoryNames(repositoryNames); 5945bf2b6ebSBrian Hill if (result != B_OK) { 5955bf2b6ebSBrian Hill (new BAlert("error", 5965bf2b6ebSBrian Hill B_TRANSLATE_COMMENT("Repositories could not retrieve the names of " 5975bf2b6ebSBrian Hill "the currently enabled repositories.", "Alert error message"), 5985bf2b6ebSBrian Hill kOKLabel, NULL, NULL, B_WIDTH_AS_USUAL, B_WARNING_ALERT))->Go(NULL); 5995bf2b6ebSBrian Hill return; 6005bf2b6ebSBrian Hill } 6015bf2b6ebSBrian Hill BPackageKit::BRepositoryConfig repoConfig; 6025bf2b6ebSBrian Hill int16 index, count = repositoryNames.CountStrings(); 6035bf2b6ebSBrian Hill for (index = 0; index < count; index++) { 6045bf2b6ebSBrian Hill const BString& repoName = repositoryNames.StringAt(index); 6055bf2b6ebSBrian Hill result = pRoster.GetRepositoryConfig(repoName, &repoConfig); 6065bf2b6ebSBrian Hill if (result == B_OK) 6075bf2b6ebSBrian Hill _AddRepo(repoName, repoConfig.BaseURL(), true); 6085bf2b6ebSBrian Hill else { 6095bf2b6ebSBrian Hill BString text(B_TRANSLATE_COMMENT("Error getting repository" 6105bf2b6ebSBrian Hill " configuration for %name%.", "Alert error message, " 6115bf2b6ebSBrian Hill "do not translate %name%")); 6125bf2b6ebSBrian Hill text.ReplaceFirst("%name%", repoName); 6135bf2b6ebSBrian Hill (new BAlert("error", text, kOKLabel))->Go(NULL); 6145bf2b6ebSBrian Hill } 6155bf2b6ebSBrian Hill } 6165bf2b6ebSBrian Hill _FindSiblings(); 6175bf2b6ebSBrian Hill _SaveList(); 6185bf2b6ebSBrian Hill } 6195bf2b6ebSBrian Hill 6205bf2b6ebSBrian Hill 6215bf2b6ebSBrian Hill void 6225bf2b6ebSBrian Hill RepositoriesView::_SaveList() 6235bf2b6ebSBrian Hill { 6245bf2b6ebSBrian Hill BStringList nameList, urlList; 6255bf2b6ebSBrian Hill int32 index; 6265bf2b6ebSBrian Hill int32 listCount = fListView->CountRows(); 6275bf2b6ebSBrian Hill for (index = 0; index < listCount; index++) { 6285bf2b6ebSBrian Hill RepoRow* repoItem = dynamic_cast<RepoRow*>(fListView->RowAt(index)); 6295bf2b6ebSBrian Hill nameList.Add(repoItem->Name()); 6305bf2b6ebSBrian Hill urlList.Add(repoItem->Url()); 6315bf2b6ebSBrian Hill } 6325bf2b6ebSBrian Hill fSettings.SetRepositories(nameList, urlList); 6335bf2b6ebSBrian Hill } 6345bf2b6ebSBrian Hill 6355bf2b6ebSBrian Hill 6365bf2b6ebSBrian Hill RepoRow* 6375bf2b6ebSBrian Hill RepositoriesView::_AddRepo(BString name, BString url, bool enabled) 6385bf2b6ebSBrian Hill { 639856ecc7bSBrian Hill // URL must be valid 640856ecc7bSBrian Hill BUrl repoUrl(url); 641856ecc7bSBrian Hill if (!repoUrl.IsValid()) 6425bf2b6ebSBrian Hill return NULL; 6435bf2b6ebSBrian Hill int32 index; 6445bf2b6ebSBrian Hill int32 listCount = fListView->CountRows(); 6455bf2b6ebSBrian Hill // Find if the repo already exists in list 6465bf2b6ebSBrian Hill for (index = 0; index < listCount; index++) { 6475bf2b6ebSBrian Hill RepoRow* repoItem = dynamic_cast<RepoRow*>(fListView->RowAt(index)); 648856ecc7bSBrian Hill BUrl itemUrl(repoItem->Url()); 649856ecc7bSBrian Hill if (repoUrl == itemUrl) { 6505bf2b6ebSBrian Hill // update name and enabled values 651856ecc7bSBrian Hill if (name != repoItem->Name()) 6525bf2b6ebSBrian Hill repoItem->SetName(name.String()); 6535bf2b6ebSBrian Hill repoItem->SetEnabled(enabled); 654856ecc7bSBrian Hill return repoItem; 6555bf2b6ebSBrian Hill } 6565bf2b6ebSBrian Hill } 657856ecc7bSBrian Hill RepoRow* addedRow = new RepoRow(name, url, enabled); 6585bf2b6ebSBrian Hill fListView->AddRow(addedRow); 6595bf2b6ebSBrian Hill return addedRow; 6605bf2b6ebSBrian Hill } 6615bf2b6ebSBrian Hill 6625bf2b6ebSBrian Hill 6635bf2b6ebSBrian Hill void 6645bf2b6ebSBrian Hill RepositoriesView::_FindSiblings() 6655bf2b6ebSBrian Hill { 6665bf2b6ebSBrian Hill BStringList namesFound, namesWithSiblings; 6675bf2b6ebSBrian Hill int32 index, listCount = fListView->CountRows(); 6685bf2b6ebSBrian Hill // Find repository names that are duplicated 6695bf2b6ebSBrian Hill for (index = 0; index < listCount; index++) { 6705bf2b6ebSBrian Hill RepoRow* repoItem = dynamic_cast<RepoRow*>(fListView->RowAt(index)); 6715bf2b6ebSBrian Hill BString name = repoItem->Name(); 6725bf2b6ebSBrian Hill // Ignore newly added repos since we don't know the real name yet 6735bf2b6ebSBrian Hill if (name.Compare(kNewRepoDefaultName)==0) 6745bf2b6ebSBrian Hill continue; 6755bf2b6ebSBrian Hill // First time a name is found- no sibling (yet) 6765bf2b6ebSBrian Hill if (!namesFound.HasString(name)) 6775bf2b6ebSBrian Hill namesFound.Add(name); 6785bf2b6ebSBrian Hill // Name was already found once so this name has 2 or more siblings 6795bf2b6ebSBrian Hill else if (!namesWithSiblings.HasString(name)) 6805bf2b6ebSBrian Hill namesWithSiblings.Add(name); 6815bf2b6ebSBrian Hill } 6825bf2b6ebSBrian Hill // Set sibling values for each row 6835bf2b6ebSBrian Hill for (index = 0; index < listCount; index++) { 6845bf2b6ebSBrian Hill RepoRow* repoItem = dynamic_cast<RepoRow*>(fListView->RowAt(index)); 6855bf2b6ebSBrian Hill BString name = repoItem->Name(); 6865bf2b6ebSBrian Hill repoItem->SetHasSiblings(namesWithSiblings.HasString(name)); 6875bf2b6ebSBrian Hill } 6885bf2b6ebSBrian Hill } 6895bf2b6ebSBrian Hill 6905bf2b6ebSBrian Hill 6915bf2b6ebSBrian Hill void 6925bf2b6ebSBrian Hill RepositoriesView::_UpdateButtons() 6935bf2b6ebSBrian Hill { 6945bf2b6ebSBrian Hill RepoRow* rowItem = dynamic_cast<RepoRow*>(fListView->CurrentSelection()); 6955bf2b6ebSBrian Hill // At least one row is selected 6965bf2b6ebSBrian Hill if (rowItem) { 697856ecc7bSBrian Hill bool someAreEnabled = false; 698856ecc7bSBrian Hill bool someAreDisabled = false; 699856ecc7bSBrian Hill bool someAreInQueue = false; 7005bf2b6ebSBrian Hill int32 selectedCount = 0; 7015bf2b6ebSBrian Hill RepoRow* rowItem = dynamic_cast<RepoRow*>(fListView->CurrentSelection()); 7025bf2b6ebSBrian Hill while (rowItem) { 7035bf2b6ebSBrian Hill selectedCount++; 7045bf2b6ebSBrian Hill uint32 taskState = rowItem->TaskState(); 7055bf2b6ebSBrian Hill if ( taskState == STATE_IN_QUEUE_WAITING 706856ecc7bSBrian Hill || taskState == STATE_IN_QUEUE_RUNNING) { 7075bf2b6ebSBrian Hill someAreInQueue = true; 708856ecc7bSBrian Hill } 7095bf2b6ebSBrian Hill if (rowItem->IsEnabled()) 7105bf2b6ebSBrian Hill someAreEnabled = true; 7115bf2b6ebSBrian Hill else 7125bf2b6ebSBrian Hill someAreDisabled = true; 7135bf2b6ebSBrian Hill rowItem = dynamic_cast<RepoRow*>(fListView->CurrentSelection(rowItem)); 7145bf2b6ebSBrian Hill } 7155bf2b6ebSBrian Hill // Change button labels depending on which rows are selected 7165bf2b6ebSBrian Hill if (selectedCount > 1) { 7175bf2b6ebSBrian Hill fEnableButton->SetLabel(kLabelEnableAll); 7185bf2b6ebSBrian Hill fDisableButton->SetLabel(kLabelDisableAll); 7195bf2b6ebSBrian Hill } else { 7205bf2b6ebSBrian Hill fEnableButton->SetLabel(kLabelEnable); 7215bf2b6ebSBrian Hill fDisableButton->SetLabel(kLabelDisable); 7225bf2b6ebSBrian Hill } 7235bf2b6ebSBrian Hill // Set which buttons should be enabled 7245bf2b6ebSBrian Hill fRemoveButton->SetEnabled(!someAreEnabled && !someAreInQueue); 7255bf2b6ebSBrian Hill if ((someAreEnabled && someAreDisabled) || someAreInQueue) { 7265bf2b6ebSBrian Hill // there are a mix of enabled and disabled repositories selected 7275bf2b6ebSBrian Hill fEnableButton->SetEnabled(false); 7285bf2b6ebSBrian Hill fDisableButton->SetEnabled(false); 7295bf2b6ebSBrian Hill } else { 7305bf2b6ebSBrian Hill fEnableButton->SetEnabled(someAreDisabled); 7315bf2b6ebSBrian Hill fDisableButton->SetEnabled(someAreEnabled); 7325bf2b6ebSBrian Hill } 7335bf2b6ebSBrian Hill 7345bf2b6ebSBrian Hill } else { 7355bf2b6ebSBrian Hill // No selected rows 7365bf2b6ebSBrian Hill fEnableButton->SetLabel(kLabelEnable); 7375bf2b6ebSBrian Hill fDisableButton->SetLabel(kLabelDisable); 7385bf2b6ebSBrian Hill fEnableButton->SetEnabled(false); 7395bf2b6ebSBrian Hill fDisableButton->SetEnabled(false); 7405bf2b6ebSBrian Hill fRemoveButton->SetEnabled(false); 7415bf2b6ebSBrian Hill } 7425bf2b6ebSBrian Hill } 7435bf2b6ebSBrian Hill 7445bf2b6ebSBrian Hill 7455bf2b6ebSBrian Hill void 7465bf2b6ebSBrian Hill RepositoriesView::_UpdateStatusView() 7475bf2b6ebSBrian Hill { 7485bf2b6ebSBrian Hill if (fRunningTaskCount) { 7495bf2b6ebSBrian Hill BString text(kStatusViewText); 7505bf2b6ebSBrian Hill text.Append(" "); 7515bf2b6ebSBrian Hill text << fRunningTaskCount; 7525bf2b6ebSBrian Hill fListStatusView->SetText(text); 7535bf2b6ebSBrian Hill } else 7545bf2b6ebSBrian Hill fListStatusView->SetText(""); 7555bf2b6ebSBrian Hill } 756