Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Manager] Gray out projects in project wizard that are already attached #5862

Draft
wants to merge 2 commits into
base: master
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
131 changes: 85 additions & 46 deletions clientgui/ProjectInfoPage.cpp
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
// This file is part of BOINC.
// https://boinc.berkeley.edu
// Copyright (C) 2022 University of California
// Copyright (C) 2024 University of California
//
// BOINC is free software; you can redistribute it and/or modify it
// under the terms of the GNU Lesser General Public License
Expand Down Expand Up @@ -209,7 +209,7 @@ bool CProjectInfoPage::Create( CBOINCBaseWizard* parent )

void CProjectInfoPage::CreateControls()
{
////@begin CProjectInfoPage content construction
////@begin CProjectInfoPage content construction
#ifdef __WXMAC__
const int descriptionWidth = 350;
#else
Expand Down Expand Up @@ -256,10 +256,32 @@ void CProjectInfoPage::CreateControls()
// so we don't need to worry about duplicate entries here.
// Get the project list
m_apl = new ALL_PROJECTS_LIST;
pDoc->rpc.get_all_projects_list(*m_apl);
for (unsigned int i=0; i<m_apl->projects.size(); i++) {
wxString strGeneralArea = wxGetTranslation(wxString(m_apl->projects[i]->general_area.c_str(), wxConvUTF8));
aCategories.Add(strGeneralArea);
std::string tempstring;
if (pDoc) {
pDoc->rpc.get_all_projects_list(*m_apl);

for (unsigned int i = 0; i < m_apl->projects.size(); i++) {
wxString strGeneralArea = wxGetTranslation(wxString(m_apl->projects[i]->general_area.c_str(), wxConvUTF8));
aCategories.Add(strGeneralArea);
tempstring = m_apl->projects[i]->url;
// Canonicalize/trim/store the URLs of all projects. This will be used later on for the wxListBox
// to visually indicate any projects that are currently attached, as well as checking for when a
// project or manual URL is selected.
//
canonicalize_master_url(tempstring);
TrimURL(tempstring);
m_pTrimmedURL.push_back(tempstring);
}
// Take all projects that the Client is already attached to and create an array of their
// canonicalized and trimmed URLs. This will be used for comparing against the master list of projects
// to visually indicate which projectes have already been attached.
//
for (unsigned int i = 0; i < pDoc->GetProjectCount(); i++) {
tempstring = pDoc->project(i)->master_url;
canonicalize_master_url(tempstring);
TrimURL(tempstring);
m_pTrimmedURL_attached.push_back(tempstring);
}
}
m_pProjectCategoriesCtrl = new wxComboBox( itemWizardPage23, ID_CATEGORIES, wxT(""), wxDefaultPosition, wxDefaultSize, aCategories, wxCB_READONLY
#ifndef __WXMAC__ // wxCB_SORT is not available in wxCocoa 3.0
Expand All @@ -277,7 +299,7 @@ void CProjectInfoPage::CreateControls()
itemBoxSizer7->Add(itemFlexGridSizer11, 0, wxGROW|wxALL, 0);

wxArrayString m_pProjectsCtrlStrings;
m_pProjectsCtrl = new wxListBox( itemWizardPage23, ID_PROJECTS, wxDefaultPosition, wxSize(-1, 175), m_pProjectsCtrlStrings, wxLB_SINGLE|wxLB_SORT );
m_pProjectsCtrl = new wxListBox( itemWizardPage23, ID_PROJECTS, wxDefaultPosition, wxSize(-1, 175), m_pProjectsCtrlStrings, wxLB_SINGLE|wxLB_SORT|wxLB_OWNERDRAW );
itemFlexGridSizer11->Add(m_pProjectsCtrl, 0, wxGROW|wxALIGN_CENTER_VERTICAL|wxLEFT|wxRIGHT, 0);

m_pProjectDetailsStaticCtrl = new wxStaticBox(itemWizardPage23, wxID_ANY, _("Project details"));
Expand Down Expand Up @@ -514,13 +536,26 @@ void CProjectInfoPage::OnProjectCategorySelected( wxCommandEvent& WXUNUSED(event

m_pProjectsCtrl->Clear();

int lastproject = -1;
// Populate the list box with the list of project names that belong to either the specific
// category or all of them.
for (unsigned int i=0; i<m_Projects.size(); i++) {
//
for (unsigned int i=0; i<m_Projects.size(); i++) { // cycle through all projects
if ((m_pProjectCategoriesCtrl->GetValue() == _("All")) ||
(m_pProjectCategoriesCtrl->GetValue() == m_Projects[i]->m_strGeneralArea)
) {
m_pProjectsCtrl->Append(m_Projects[i]->m_strName, m_Projects[i]);
lastproject = m_pProjectsCtrl->GetCount() - 1;
// Since this project was added to the wxListBox, check to see if the project has already been attached.
// If it has, grey out the text for a visual indicator that the project has been added.
//
for (unsigned int j = 0; j < m_pTrimmedURL_attached.size(); j++) { // cycle through all attached projects
if (m_pTrimmedURL[i] == m_pTrimmedURL_attached[j]) {
// Color 117,117,117 has a 4.6:1 contract ratio that passes accessibility
m_pProjectsCtrl->GetItem(lastproject)->SetTextColour(wxColour(117,117,117));
break;
}
}
}
}

Expand Down Expand Up @@ -706,27 +741,27 @@ void CProjectInfoPage::OnPageChanged( wxWizardExEvent& event ) {

if (strProjectPlanClass.Find(_T("cuda")) != wxNOT_FOUND) {
pProjectInfo->m_bProjectSupportsCUDA = true;
if (!pDoc->state.host_info.coprocs.have_nvidia()) continue;
if (!pDoc->state.host_info.coprocs.have_nvidia()) continue;
}

if (strProjectPlanClass.Find(_T("nvidia")) != wxNOT_FOUND) {
pProjectInfo->m_bProjectSupportsCUDA = true;
if (!pDoc->state.host_info.coprocs.have_nvidia()) continue;
if (!pDoc->state.host_info.coprocs.have_nvidia()) continue;
}

if (strProjectPlanClass.Find(_T("ati")) != wxNOT_FOUND) {
pProjectInfo->m_bProjectSupportsCAL = true;
if (!pDoc->state.host_info.coprocs.have_ati()) continue;
if (!pDoc->state.host_info.coprocs.have_ati()) continue;
}

if (strProjectPlanClass.Find(_T("amd")) != wxNOT_FOUND) {
pProjectInfo->m_bProjectSupportsCAL = true;
if (!pDoc->state.host_info.coprocs.have_ati()) continue;
if (!pDoc->state.host_info.coprocs.have_ati()) continue;
}

if (strProjectPlanClass.Find(_T("intel_gpu")) != wxNOT_FOUND) {
pProjectInfo->m_bProjectSupportsIntelGPU = true;
if (!pDoc->state.host_info.coprocs.have_intel_gpu()) continue;
if (!pDoc->state.host_info.coprocs.have_intel_gpu()) continue;
}

if (strProjectPlanClass.Find(_T("vbox")) != wxNOT_FOUND) {
Expand All @@ -739,11 +774,11 @@ void CProjectInfoPage::OnPageChanged( wxWizardExEvent& event ) {
}
}

// If project doesn't export its platforms, assume we're supported
//
if (aProjectPlatforms.size() == 0) {
pProjectInfo->m_bSupportedPlatformFound = true;
}
// If project doesn't export its platforms, assume we're supported
//
if (aProjectPlatforms.size() == 0) {
pProjectInfo->m_bSupportedPlatformFound = true;
}
}


Expand Down Expand Up @@ -816,38 +851,16 @@ void CProjectInfoPage::OnPageChanging( wxWizardExEvent& event ) {
const std::string http = "http://";
const std::string https = "https://";

std::string new_project_url = (const char*)m_strProjectURL.mb_str();
canonicalize_master_url(new_project_url);
// remove http(s):// at the beginning of project address
// there is no reason to connect to secure address project
// if we're already connected to the non-secure address
// or vice versa
// also clear last '/' character if present
size_t pos = new_project_url.find(http);
if (pos != std::string::npos) {
new_project_url.erase(pos, http.length());
}
else if ((pos = new_project_url.find(https)) != std::string::npos) {
new_project_url.erase(pos, https.length());
}
if (new_project_url.length() >= 1 && new_project_url[new_project_url.length() - 1] == '/') {
new_project_url.erase(new_project_url.length() - 1, 1);
}
for (int i = 0; i < pDoc->GetProjectCount(); ++i) {
PROJECT* project = pDoc->project(i);
std::string new_project_url = (const char*)m_strProjectURL.mb_str();
canonicalize_master_url(new_project_url);
TrimURL(new_project_url);
for (int i = 0; i < pDoc->GetProjectCount(); ++i) {
PROJECT* project = pDoc->project(i);
if (project) {
std::string project_url = project->master_url;

canonicalize_master_url(project_url);

if ((pos = project_url.find(http)) != std::string::npos) {
project_url.erase(pos, http.length());
} else if ((pos = project_url.find(https)) != std::string::npos) {
project_url.erase(pos, https.length());
}
if (project_url.length() >= 1 && project_url[project_url.length() - 1] == '/') {
project_url.erase(project_url.length() - 1, 1);
}
TrimURL(project_url);

if (project_url == new_project_url) {
bAlreadyAttached = true;
Expand Down Expand Up @@ -914,3 +927,29 @@ void CProjectInfoPage::RefreshPage() {
wxCommandEvent evtEvent(wxEVT_COMMAND_COMBOBOX_SELECTED, ID_CATEGORIES);
ProcessEvent(evtEvent);
}


// Function to "trim" the URL of the http(s) prefix and the last slash.
// Prior to running this function, the string should be canonicalized using
// the canonicalize_master_url function.
//
void CProjectInfoPage::TrimURL(std::string& purl) {
const std::string http = "http://";
const std::string https = "https://";
// Remove http(s):// at the beginning of project address
// there is no reason to connect to secure address project
// if we're already connected to the non-secure address
// or vice versa
// also clear last '/' character if present
//
size_t pos = purl.find(http);
if (pos != std::string::npos) {
purl.erase(pos, http.length());
}
else if ((pos = purl.find(https)) != std::string::npos) {
purl.erase(pos, https.length());
}
if (purl.length() >= 1 && purl[purl.length() - 1] == '/') {
purl.erase(purl.length() - 1, 1);
}
}
6 changes: 5 additions & 1 deletion clientgui/ProjectInfoPage.h
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
// This file is part of BOINC.
// https://boinc.berkeley.edu
// Copyright (C) 2018 University of California
// Copyright (C) 2024 University of California
//
// BOINC is free software; you can redistribute it and/or modify it
// under the terms of the GNU Lesser General Public License
Expand Down Expand Up @@ -91,6 +91,8 @@ class CProjectInfoPage: public wxWizardPageEx

void RefreshPage();

void TrimURL(std::string& purl);

////@begin CProjectInfoPage member variables
wxStaticText* m_pTitleStaticCtrl;
wxStaticText* m_pDescriptionStaticCtrl;
Expand Down Expand Up @@ -127,6 +129,8 @@ class CProjectInfoPage: public wxWizardPageEx
std::vector<CProjectInfo*> m_Projects;
bool m_bProjectSupported;
bool m_bProjectListPopulated;
std::vector<std::string> m_pTrimmedURL;
std::vector<std::string> m_pTrimmedURL_attached;
};

#endif
Loading