2020-10-26 03:54:36 -07:00
|
|
|
/*
|
|
|
|
* This program source code file is part of KiCad, a free EDA CAD application.
|
|
|
|
*
|
|
|
|
* Copyright (C) 2021 Andrew Lutsenko, anlutsenko at gmail dot com
|
2025-01-01 13:30:11 -08:00
|
|
|
* Copyright The KiCad Developers, see AUTHORS.txt for contributors.
|
2020-10-26 03:54:36 -07:00
|
|
|
*
|
|
|
|
* This program is free software: you can redistribute it and/or modify it
|
|
|
|
* under the terms of the GNU General Public License as published by the
|
|
|
|
* Free Software Foundation, either version 3 of the License, or (at your
|
|
|
|
* option) any later version.
|
|
|
|
*
|
|
|
|
* This program is distributed in the hope that it will be useful, but
|
|
|
|
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
|
|
* General Public License for more details.
|
|
|
|
*
|
|
|
|
* You should have received a copy of the GNU General Public License along
|
|
|
|
* with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
|
|
*/
|
|
|
|
|
|
|
|
#include "panel_packages_view.h"
|
2021-11-11 23:41:31 +00:00
|
|
|
#include <grid_tricks.h>
|
2023-09-11 19:09:55 -04:00
|
|
|
#include <widgets/html_window.h>
|
2021-11-11 23:41:31 +00:00
|
|
|
#include <pgm_base.h>
|
2022-10-23 22:07:22 +03:00
|
|
|
#include <kiplatform/ui.h>
|
2021-11-14 13:10:24 +00:00
|
|
|
#include <settings/common_settings.h>
|
2022-08-18 20:41:43 +00:00
|
|
|
#include <settings/kicad_settings.h>
|
2022-08-28 04:40:06 -07:00
|
|
|
#include <settings/settings_manager.h>
|
2021-11-11 23:41:31 +00:00
|
|
|
#include <string_utils.h>
|
2022-06-30 21:09:25 -07:00
|
|
|
#include <widgets/wx_panel.h>
|
|
|
|
#include <widgets/wx_splitter_window.h>
|
2020-10-26 03:54:36 -07:00
|
|
|
|
|
|
|
#include <cmath>
|
|
|
|
#include <fstream>
|
|
|
|
#include <wx/filedlg.h>
|
|
|
|
#include <wx/font.h>
|
|
|
|
#include <wx/tokenzr.h>
|
|
|
|
|
|
|
|
|
|
|
|
#define GRID_CELL_MARGIN 4
|
|
|
|
|
|
|
|
|
|
|
|
std::unordered_map<PCM_PACKAGE_VERSION_STATUS, wxString> PANEL_PACKAGES_VIEW::STATUS_ENUM_TO_STR = {
|
2023-01-16 19:07:41 -05:00
|
|
|
{ PVS_INVALID, wxS( "invalid" ) },
|
|
|
|
{ PVS_STABLE, wxS( "stable" ) },
|
|
|
|
{ PVS_TESTING, wxS( "testing" ) },
|
|
|
|
{ PVS_DEVELOPMENT, wxS( "development" ) },
|
|
|
|
{ PVS_DEPRECATED, wxS( "deprecated" ) }
|
2020-10-26 03:54:36 -07:00
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
PANEL_PACKAGES_VIEW::PANEL_PACKAGES_VIEW( wxWindow* parent,
|
2022-08-28 04:40:06 -07:00
|
|
|
std::shared_ptr<PLUGIN_CONTENT_MANAGER> aPcm,
|
|
|
|
const ActionCallback& aActionCallback,
|
|
|
|
const PinCallback& aPinCallback ) :
|
2020-10-26 03:54:36 -07:00
|
|
|
PANEL_PACKAGES_VIEW_BASE( parent ),
|
2022-09-03 19:54:12 +02:00
|
|
|
m_actionCallback( aActionCallback ),
|
|
|
|
m_pinCallback( aPinCallback ),
|
|
|
|
m_pcm( aPcm )
|
2020-10-26 03:54:36 -07:00
|
|
|
{
|
2021-11-12 01:14:36 +00:00
|
|
|
// Replace wxFormBuilder's sash initializer with one which will respect m_initialSashPos.
|
|
|
|
m_splitter1->Disconnect( wxEVT_IDLE,
|
|
|
|
wxIdleEventHandler( PANEL_PACKAGES_VIEW_BASE::m_splitter1OnIdle ),
|
|
|
|
NULL, this );
|
|
|
|
m_splitter1->Connect( wxEVT_IDLE, wxIdleEventHandler( PANEL_PACKAGES_VIEW::SetSashOnIdle ),
|
|
|
|
NULL, this );
|
|
|
|
|
2024-01-17 22:52:01 -05:00
|
|
|
m_splitter1->SetPaneMinimums( FromDIP( 350 ), FromDIP( 450 ) );
|
2021-11-12 01:14:36 +00:00
|
|
|
|
2021-11-10 11:15:07 +00:00
|
|
|
#ifdef __WXGTK__
|
|
|
|
// wxSearchCtrl vertical height is not calculated correctly on some GTK setups
|
|
|
|
// See https://gitlab.com/kicad/code/kicad/-/issues/9019
|
|
|
|
m_searchCtrl->SetMinSize( wxSize( -1, GetTextExtent( wxT( "qb" ) ).y + 10 ) );
|
|
|
|
#endif
|
|
|
|
|
|
|
|
m_searchCtrl->Bind( wxEVT_TEXT, &PANEL_PACKAGES_VIEW::OnSearchTextChanged, this );
|
|
|
|
m_searchCtrl->SetDescriptiveText( _( "Filter" ) );
|
|
|
|
|
2021-11-14 15:01:00 +00:00
|
|
|
m_panelList->SetBorders( false, true, false, false );
|
2021-11-10 11:15:07 +00:00
|
|
|
|
2020-10-26 03:54:36 -07:00
|
|
|
m_gridVersions->PushEventHandler( new GRID_TRICKS( m_gridVersions ) );
|
|
|
|
|
|
|
|
for( int col = 0; col < m_gridVersions->GetNumberCols(); col++ )
|
|
|
|
{
|
|
|
|
const wxString& heading = m_gridVersions->GetColLabelValue( col );
|
|
|
|
int headingWidth = GetTextExtent( heading ).x + 2 * GRID_CELL_MARGIN;
|
|
|
|
|
|
|
|
// Set the minimal width to the column label size.
|
|
|
|
m_gridVersions->SetColMinimalWidth( col, headingWidth );
|
2022-08-18 17:56:36 +01:00
|
|
|
m_gridVersions->SetColSize( col, m_gridVersions->GetVisibleWidth( col ) );
|
2020-10-26 03:54:36 -07:00
|
|
|
}
|
|
|
|
|
2021-11-13 04:10:37 +01:00
|
|
|
// Most likely should be changed to wxGridSelectNone once WxWidgets>=3.1.5 is mandatory.
|
|
|
|
m_gridVersions->SetSelectionMode( WX_GRID::wxGridSelectRows );
|
|
|
|
|
2021-11-14 13:10:24 +00:00
|
|
|
wxColor background = wxStaticText::GetClassDefaultAttributes().colBg;
|
|
|
|
m_panelList->SetBackgroundColour( background );
|
|
|
|
m_packageListWindow->SetBackgroundColour( background );
|
|
|
|
m_infoScrollWindow->SetBackgroundColour( background );
|
2021-11-12 00:39:47 +00:00
|
|
|
m_infoScrollWindow->EnableScrolling( false, true );
|
2020-10-26 03:54:36 -07:00
|
|
|
|
|
|
|
ClearData();
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
PANEL_PACKAGES_VIEW::~PANEL_PACKAGES_VIEW()
|
|
|
|
{
|
2023-10-01 22:03:42 -04:00
|
|
|
m_splitter1->Disconnect( wxEVT_IDLE, wxIdleEventHandler( PANEL_PACKAGES_VIEW::SetSashOnIdle ),
|
2024-02-02 12:47:34 -05:00
|
|
|
NULL, this );
|
2023-10-01 22:03:42 -04:00
|
|
|
|
2021-11-14 13:10:24 +00:00
|
|
|
COMMON_SETTINGS* cfg = Pgm().GetCommonSettings();
|
|
|
|
cfg->m_PackageManager.sash_pos = m_splitter1->GetSashPosition();
|
|
|
|
|
2020-10-26 03:54:36 -07:00
|
|
|
m_gridVersions->PopEventHandler( true );
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void PANEL_PACKAGES_VIEW::ClearData()
|
|
|
|
{
|
|
|
|
unsetPackageDetails();
|
|
|
|
|
|
|
|
m_currentSelected = nullptr;
|
2022-08-18 20:41:43 +00:00
|
|
|
m_updateablePackages.clear();
|
2020-10-26 03:54:36 -07:00
|
|
|
m_packagePanels.clear();
|
|
|
|
m_packageInitialOrder.clear();
|
|
|
|
m_packageListWindow->GetSizer()->Clear( true ); // Delete panels
|
|
|
|
m_packageListWindow->GetSizer()->FitInside( m_packageListWindow );
|
|
|
|
m_packageListWindow->Layout();
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2022-08-28 04:40:06 -07:00
|
|
|
void PANEL_PACKAGES_VIEW::SetData( const std::vector<PACKAGE_VIEW_DATA>& aPackageData )
|
2020-10-26 03:54:36 -07:00
|
|
|
{
|
|
|
|
ClearData();
|
|
|
|
|
|
|
|
for( const PACKAGE_VIEW_DATA& data : aPackageData )
|
|
|
|
{
|
2022-10-23 12:03:55 +01:00
|
|
|
PANEL_PACKAGE* package_panel = new PANEL_PACKAGE( m_packageListWindow, m_actionCallback,
|
|
|
|
m_pinCallback, data );
|
2020-10-26 03:54:36 -07:00
|
|
|
|
|
|
|
package_panel->SetSelectCallback(
|
2022-10-23 12:03:55 +01:00
|
|
|
[package_panel, this] ()
|
2020-10-26 03:54:36 -07:00
|
|
|
{
|
|
|
|
if( m_currentSelected && m_currentSelected != package_panel )
|
|
|
|
m_currentSelected->SetSelected( false );
|
|
|
|
|
|
|
|
package_panel->SetSelected( true );
|
|
|
|
m_currentSelected = package_panel;
|
|
|
|
setPackageDetails( package_panel->GetPackageData() );
|
|
|
|
|
|
|
|
Layout();
|
|
|
|
} );
|
|
|
|
|
|
|
|
m_packagePanels.insert( { data.package.identifier, package_panel } );
|
|
|
|
m_packageInitialOrder.push_back( data.package.identifier );
|
2022-08-18 20:41:43 +00:00
|
|
|
|
2022-08-28 04:40:06 -07:00
|
|
|
if( data.state == PPS_UPDATE_AVAILABLE && !data.pinned )
|
2022-08-18 20:41:43 +00:00
|
|
|
m_updateablePackages.insert( data.package.identifier );
|
2020-10-26 03:54:36 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
updatePackageList();
|
2022-08-18 20:41:43 +00:00
|
|
|
updateCommonState();
|
2020-10-26 03:54:36 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void PANEL_PACKAGES_VIEW::setPackageDetails( const PACKAGE_VIEW_DATA& aPackageData )
|
|
|
|
{
|
|
|
|
const PCM_PACKAGE& package = aPackageData.package;
|
|
|
|
|
|
|
|
// Details
|
2021-11-11 23:41:31 +00:00
|
|
|
wxString details;
|
2021-11-10 11:15:07 +00:00
|
|
|
|
2022-10-23 12:03:55 +01:00
|
|
|
details << wxT( "<h5>" ) + package.name + wxT( "</h5>" );
|
2020-10-26 03:54:36 -07:00
|
|
|
|
2022-10-23 12:03:55 +01:00
|
|
|
auto format_desc =
|
|
|
|
[]( const wxString& text ) -> wxString
|
2021-11-12 00:39:47 +00:00
|
|
|
{
|
2022-10-23 12:03:55 +01:00
|
|
|
wxString result;
|
|
|
|
bool inURL = false;
|
|
|
|
wxString url;
|
2021-11-12 00:39:47 +00:00
|
|
|
|
2022-10-23 12:03:55 +01:00
|
|
|
for( unsigned i = 0; i < text.length(); ++i )
|
2021-11-12 00:39:47 +00:00
|
|
|
{
|
2022-10-23 12:03:55 +01:00
|
|
|
wxUniChar c = text[i];
|
|
|
|
|
|
|
|
if( inURL )
|
|
|
|
{
|
2023-01-04 12:56:18 -08:00
|
|
|
if( c == ' ' || c == '\n')
|
2022-10-23 12:03:55 +01:00
|
|
|
{
|
|
|
|
result += wxString::Format( wxT( "<a href='%s'>%s</a>" ), url, url );
|
|
|
|
inURL = false;
|
|
|
|
|
2023-01-04 12:56:18 -08:00
|
|
|
if( c == '\n' )
|
|
|
|
result += wxT( "</p><p>" );
|
|
|
|
else
|
|
|
|
result += c;
|
2022-10-23 12:03:55 +01:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
url += c;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else if( text.Mid( i, 5 ) == wxT( "http:" )
|
|
|
|
|| text.Mid( i, 6 ) == wxT( "https:" ) )
|
|
|
|
{
|
|
|
|
url = c;
|
|
|
|
inURL = true;
|
|
|
|
}
|
|
|
|
else if( c == '\n' )
|
|
|
|
{
|
|
|
|
result += wxT( "</p><p>" );
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
result += c;
|
|
|
|
}
|
2021-11-12 00:39:47 +00:00
|
|
|
}
|
|
|
|
|
2023-01-04 12:56:18 -08:00
|
|
|
if( inURL )
|
|
|
|
result += wxString::Format( wxT( "<a href='%s'>%s</a>" ), url, url );
|
|
|
|
|
2022-10-23 12:03:55 +01:00
|
|
|
return result;
|
|
|
|
};
|
2021-11-12 00:39:47 +00:00
|
|
|
|
2021-11-11 23:41:31 +00:00
|
|
|
wxString desc = package.description_full;
|
2022-10-23 12:03:55 +01:00
|
|
|
details << wxT( "<p>" ) + format_desc( desc ) + wxT( "</p>" );
|
2020-10-26 03:54:36 -07:00
|
|
|
|
2022-10-23 12:03:55 +01:00
|
|
|
details << wxT( "<p><b>" ) + _( "Metadata" ) + wxT( "</b></p>" );
|
|
|
|
details << wxT( "<ul>" );
|
|
|
|
details << wxT( "<li>" ) + _( "Package identifier: " ) + package.identifier + wxT( "</li>" );
|
|
|
|
details << wxT( "<li>" ) + _( "License: " ) + package.license + wxT( "</li>" );
|
2020-10-26 03:54:36 -07:00
|
|
|
|
|
|
|
if( package.tags.size() > 0 )
|
|
|
|
{
|
|
|
|
wxString tags_str;
|
|
|
|
|
2021-11-10 11:15:07 +00:00
|
|
|
for( const std::string& tag : package.tags )
|
2020-10-26 03:54:36 -07:00
|
|
|
{
|
|
|
|
if( !tags_str.IsEmpty() )
|
|
|
|
tags_str += ", ";
|
|
|
|
|
|
|
|
tags_str += tag;
|
|
|
|
}
|
|
|
|
|
2022-10-23 12:03:55 +01:00
|
|
|
details << wxT( "<li>" ) + _( "Tags: " ) + tags_str + wxT( "</li>" );
|
2020-10-26 03:54:36 -07:00
|
|
|
}
|
|
|
|
|
2022-10-23 12:03:55 +01:00
|
|
|
auto format_entry =
|
|
|
|
[]( const std::pair<const std::string, wxString>& entry ) -> wxString
|
|
|
|
{
|
|
|
|
wxString name = entry.first;
|
|
|
|
wxString url = EscapeHTML( entry.second );
|
2021-11-12 00:39:47 +00:00
|
|
|
|
2022-10-23 12:03:55 +01:00
|
|
|
if( name == wxT( "email" ) )
|
|
|
|
return wxString::Format( wxT( "<a href='mailto:%s'>%s</a>" ), url, url );
|
|
|
|
else if( url.StartsWith( wxT( "http:" ) ) || url.StartsWith( wxT( "https:" ) ) )
|
|
|
|
return wxString::Format( wxT( "<a href='%s'>%s</a>" ), url, url );
|
|
|
|
else
|
|
|
|
return entry.second;
|
|
|
|
};
|
2021-11-11 23:41:31 +00:00
|
|
|
|
2022-10-23 12:03:55 +01:00
|
|
|
auto write_contact =
|
|
|
|
[&]( const wxString& type, const PCM_CONTACT& contact )
|
|
|
|
{
|
|
|
|
details << wxT( "<li>" ) + type + wxT( ": " ) + contact.name + wxT( "<ul>" );
|
2020-10-26 03:54:36 -07:00
|
|
|
|
2022-10-23 12:03:55 +01:00
|
|
|
for( const std::pair<const std::string, wxString>& entry : contact.contact )
|
|
|
|
{
|
|
|
|
details << wxT( "<li>" );
|
2024-03-20 21:52:19 -04:00
|
|
|
details << entry.first << wxT( ": " ) + format_entry( entry );
|
2022-10-23 12:03:55 +01:00
|
|
|
details << wxT( "</li>" );
|
|
|
|
}
|
2020-10-26 03:54:36 -07:00
|
|
|
|
2022-10-23 12:03:55 +01:00
|
|
|
details << wxT( "</ul>" );
|
|
|
|
};
|
2020-10-26 03:54:36 -07:00
|
|
|
|
|
|
|
write_contact( _( "Author" ), package.author );
|
|
|
|
|
|
|
|
if( package.maintainer )
|
2022-08-30 13:58:43 -07:00
|
|
|
write_contact( _( "Maintainer" ), *package.maintainer );
|
2020-10-26 03:54:36 -07:00
|
|
|
|
|
|
|
if( package.resources.size() > 0 )
|
|
|
|
{
|
2022-10-23 12:03:55 +01:00
|
|
|
details << wxT( "<li>" ) + _( "Resources" ) + wxT( "<ul>" );
|
2020-10-26 03:54:36 -07:00
|
|
|
|
2021-11-10 11:15:07 +00:00
|
|
|
for( const std::pair<const std::string, wxString>& entry : package.resources )
|
2022-10-23 12:03:55 +01:00
|
|
|
{
|
|
|
|
details << wxT( "<li>" );
|
2024-03-20 21:52:19 -04:00
|
|
|
details << entry.first << wxT( ": " );
|
2022-10-23 12:03:55 +01:00
|
|
|
details << format_entry( entry ) + wxT( "</li>" );
|
|
|
|
}
|
2020-10-26 03:54:36 -07:00
|
|
|
|
2022-10-23 12:03:55 +01:00
|
|
|
details << wxT( "</ul>" );
|
2020-10-26 03:54:36 -07:00
|
|
|
}
|
|
|
|
|
2022-10-23 12:03:55 +01:00
|
|
|
details << wxT( "</ul>" );
|
2021-11-11 23:41:31 +00:00
|
|
|
|
|
|
|
m_infoText->SetPage( details );
|
2020-10-26 03:54:36 -07:00
|
|
|
|
2021-11-11 11:33:28 +00:00
|
|
|
wxSizeEvent dummy;
|
|
|
|
OnSizeInfoBox( dummy );
|
2021-11-10 11:15:07 +00:00
|
|
|
|
2020-10-26 03:54:36 -07:00
|
|
|
// Versions table
|
|
|
|
m_gridVersions->Freeze();
|
|
|
|
|
|
|
|
if( m_gridVersions->GetNumberRows() != 0 )
|
|
|
|
m_gridVersions->DeleteRows( 0, m_gridVersions->GetNumberRows() );
|
|
|
|
|
|
|
|
int row = 0;
|
|
|
|
wxString current_version;
|
|
|
|
|
2022-06-30 21:09:25 -07:00
|
|
|
if( aPackageData.state == PPS_INSTALLED || aPackageData.state == PPS_UPDATE_AVAILABLE )
|
2020-10-26 03:54:36 -07:00
|
|
|
current_version = m_pcm->GetInstalledPackageVersion( package.identifier );
|
|
|
|
|
|
|
|
wxFont bold_font = m_gridVersions->GetDefaultCellFont().Bold();
|
|
|
|
|
|
|
|
for( const PACKAGE_VERSION& version : package.versions )
|
|
|
|
{
|
|
|
|
if( !version.compatible && !m_showAllVersions->IsChecked() )
|
|
|
|
continue;
|
|
|
|
|
|
|
|
m_gridVersions->InsertRows( row );
|
|
|
|
|
|
|
|
m_gridVersions->SetCellValue( row, COL_VERSION, version.version );
|
|
|
|
m_gridVersions->SetCellValue( row, COL_DOWNLOAD_SIZE,
|
|
|
|
toHumanReadableSize( version.download_size ) );
|
|
|
|
m_gridVersions->SetCellValue( row, COL_INSTALL_SIZE,
|
|
|
|
toHumanReadableSize( version.install_size ) );
|
|
|
|
m_gridVersions->SetCellValue( row, COL_COMPATIBILITY,
|
|
|
|
version.compatible ? wxT( "\u2714" ) : wxEmptyString );
|
|
|
|
m_gridVersions->SetCellValue( row, COL_STATUS, STATUS_ENUM_TO_STR.at( version.status ) );
|
|
|
|
|
|
|
|
m_gridVersions->SetCellAlignment( row, COL_COMPATIBILITY, wxALIGN_CENTER, wxALIGN_CENTER );
|
|
|
|
|
|
|
|
if( current_version == version.version )
|
|
|
|
{
|
|
|
|
for( int col = 0; col < m_gridVersions->GetNumberCols(); col++ )
|
|
|
|
m_gridVersions->SetCellFont( row, col, bold_font );
|
|
|
|
}
|
|
|
|
|
|
|
|
row++;
|
|
|
|
}
|
|
|
|
|
|
|
|
for( int col = 0; col < m_gridVersions->GetNumberCols(); col++ )
|
|
|
|
{
|
|
|
|
// Set the width to see the full contents
|
2022-08-18 17:56:36 +01:00
|
|
|
m_gridVersions->SetColSize( col, m_gridVersions->GetVisibleWidth( col ) );
|
2020-10-26 03:54:36 -07:00
|
|
|
}
|
|
|
|
|
2022-06-30 21:09:25 -07:00
|
|
|
// Autoselect preferred or installed version
|
2021-11-13 04:10:37 +01:00
|
|
|
if( m_gridVersions->GetNumberRows() >= 1 )
|
2021-11-13 18:55:41 +01:00
|
|
|
{
|
2022-06-30 21:09:25 -07:00
|
|
|
wxString version = m_currentSelected->GetPackageData().current_version;
|
|
|
|
|
|
|
|
if( version.IsEmpty() )
|
|
|
|
version = m_currentSelected->GetPreferredVersion();
|
2021-11-13 18:55:41 +01:00
|
|
|
|
|
|
|
if( !version.IsEmpty() )
|
|
|
|
{
|
|
|
|
for( int i = 0; i < m_gridVersions->GetNumberRows(); i++ )
|
|
|
|
{
|
|
|
|
if( m_gridVersions->GetCellValue( i, COL_VERSION ) == version )
|
|
|
|
{
|
|
|
|
m_gridVersions->SelectRow( i );
|
2022-06-30 21:09:25 -07:00
|
|
|
m_gridVersions->SetGridCursor( i, COL_VERSION );
|
2021-11-13 18:55:41 +01:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
// Fall back to first row.
|
|
|
|
m_gridVersions->SelectRow( 0 );
|
|
|
|
}
|
|
|
|
}
|
2021-11-13 04:10:37 +01:00
|
|
|
|
2020-10-26 03:54:36 -07:00
|
|
|
m_gridVersions->Thaw();
|
|
|
|
|
2021-11-13 03:42:26 +01:00
|
|
|
updateDetailsButtons();
|
2021-11-10 11:15:07 +00:00
|
|
|
|
2021-11-11 23:41:31 +00:00
|
|
|
m_infoText->Show( true );
|
2021-11-10 11:15:07 +00:00
|
|
|
m_sizerVersions->Show( true );
|
|
|
|
m_sizerVersions->Layout();
|
|
|
|
|
2021-11-11 13:56:53 +00:00
|
|
|
wxSize size = m_infoScrollWindow->GetTargetWindow()->GetBestVirtualSize();
|
|
|
|
m_infoScrollWindow->SetVirtualSize( size );
|
2020-10-26 03:54:36 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void PANEL_PACKAGES_VIEW::unsetPackageDetails()
|
|
|
|
{
|
2021-11-11 23:41:31 +00:00
|
|
|
m_infoText->SetPage( wxEmptyString );
|
|
|
|
m_infoText->Show( false );
|
2021-11-10 11:15:07 +00:00
|
|
|
m_sizerVersions->Show( false );
|
|
|
|
|
2021-11-11 13:56:53 +00:00
|
|
|
wxSize size = m_infoScrollWindow->GetTargetWindow()->GetBestVirtualSize();
|
|
|
|
m_infoScrollWindow->SetVirtualSize( size );
|
2020-10-26 03:54:36 -07:00
|
|
|
|
2021-11-10 11:15:07 +00:00
|
|
|
// Clean up grid just so we don't keep stale info around (it's already been hidden).
|
2020-10-26 03:54:36 -07:00
|
|
|
m_gridVersions->Freeze();
|
|
|
|
|
|
|
|
if( m_gridVersions->GetNumberRows() > 0 )
|
|
|
|
m_gridVersions->DeleteRows( 0, m_gridVersions->GetNumberRows() );
|
|
|
|
|
|
|
|
m_gridVersions->Thaw();
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2022-08-25 15:50:47 -07:00
|
|
|
wxString PANEL_PACKAGES_VIEW::toHumanReadableSize( const std::optional<uint64_t> size ) const
|
2020-10-26 03:54:36 -07:00
|
|
|
{
|
|
|
|
if( !size )
|
2022-10-23 12:03:55 +01:00
|
|
|
return wxT( "-" );
|
2020-10-26 03:54:36 -07:00
|
|
|
|
2022-08-30 13:58:43 -07:00
|
|
|
uint64_t b = *size;
|
2020-10-26 03:54:36 -07:00
|
|
|
|
|
|
|
if( b >= 1024 * 1024 )
|
2022-10-23 12:03:55 +01:00
|
|
|
return wxString::Format( wxT( "%.1f MB" ), b / 1000.0 / 1000.0 );
|
2020-10-26 03:54:36 -07:00
|
|
|
|
|
|
|
if( b >= 1024 )
|
2022-10-23 12:03:55 +01:00
|
|
|
return wxString::Format( wxT( "%lld kB" ), b / 1000 );
|
2020-10-26 03:54:36 -07:00
|
|
|
|
2022-10-23 12:03:55 +01:00
|
|
|
return wxString::Format( wxT( "%lld B" ), b );
|
2020-10-26 03:54:36 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2021-11-13 03:42:26 +01:00
|
|
|
bool PANEL_PACKAGES_VIEW::canDownload() const
|
|
|
|
{
|
|
|
|
if( !m_currentSelected )
|
|
|
|
return false;
|
|
|
|
|
|
|
|
return m_gridVersions->GetNumberRows() == 1 || m_gridVersions->GetSelectedRows().size() == 1;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2022-06-30 21:09:25 -07:00
|
|
|
bool PANEL_PACKAGES_VIEW::canRunAction() const
|
2021-11-13 03:42:26 +01:00
|
|
|
{
|
|
|
|
if( !m_currentSelected )
|
|
|
|
return false;
|
|
|
|
|
|
|
|
const PACKAGE_VIEW_DATA& packageData = m_currentSelected->GetPackageData();
|
|
|
|
|
2022-06-30 21:09:25 -07:00
|
|
|
switch( packageData.state )
|
|
|
|
{
|
|
|
|
case PPS_PENDING_INSTALL:
|
|
|
|
case PPS_PENDING_UNINSTALL:
|
|
|
|
case PPS_PENDING_UPDATE: return false;
|
|
|
|
default: break;
|
|
|
|
}
|
2021-11-13 03:42:26 +01:00
|
|
|
|
|
|
|
return m_gridVersions->GetNumberRows() == 1 || m_gridVersions->GetSelectedRows().size() == 1;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2020-10-26 03:54:36 -07:00
|
|
|
void PANEL_PACKAGES_VIEW::SetPackageState( const wxString& aPackageId,
|
2022-08-28 04:40:06 -07:00
|
|
|
const PCM_PACKAGE_STATE aState, const bool aPinned )
|
2020-10-26 03:54:36 -07:00
|
|
|
{
|
|
|
|
auto it = m_packagePanels.find( aPackageId );
|
|
|
|
|
|
|
|
if( it != m_packagePanels.end() )
|
|
|
|
{
|
2022-08-28 04:40:06 -07:00
|
|
|
it->second->SetState( aState, aPinned );
|
2020-10-26 03:54:36 -07:00
|
|
|
|
|
|
|
if( m_currentSelected && m_currentSelected == it->second )
|
|
|
|
{
|
|
|
|
wxMouseEvent dummy;
|
|
|
|
m_currentSelected->OnClick( dummy );
|
|
|
|
}
|
2022-08-18 20:41:43 +00:00
|
|
|
|
2022-08-28 04:40:06 -07:00
|
|
|
if( aState == PPS_UPDATE_AVAILABLE && !aPinned )
|
2022-08-18 20:41:43 +00:00
|
|
|
{
|
|
|
|
m_updateablePackages.insert( aPackageId );
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
m_updateablePackages.erase( aPackageId );
|
|
|
|
}
|
|
|
|
|
|
|
|
updateCommonState();
|
2020-10-26 03:54:36 -07:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void PANEL_PACKAGES_VIEW::OnVersionsCellClicked( wxGridEvent& event )
|
|
|
|
{
|
|
|
|
m_gridVersions->ClearSelection();
|
|
|
|
m_gridVersions->SelectRow( event.GetRow() );
|
2021-11-13 03:42:26 +01:00
|
|
|
|
|
|
|
updateDetailsButtons();
|
2020-10-26 03:54:36 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void PANEL_PACKAGES_VIEW::OnDownloadVersionClicked( wxCommandEvent& event )
|
|
|
|
{
|
2021-11-13 03:42:26 +01:00
|
|
|
if( !canDownload() )
|
2020-10-26 03:54:36 -07:00
|
|
|
{
|
|
|
|
wxBell();
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2021-11-13 03:42:26 +01:00
|
|
|
if( m_gridVersions->GetNumberRows() == 1 )
|
|
|
|
m_gridVersions->SelectRow( 0 );
|
|
|
|
|
|
|
|
const wxArrayInt selectedRows = m_gridVersions->GetSelectedRows();
|
|
|
|
|
2021-11-12 14:06:06 +01:00
|
|
|
wxString version = m_gridVersions->GetCellValue( selectedRows[0], COL_VERSION );
|
2020-10-26 03:54:36 -07:00
|
|
|
const PCM_PACKAGE& package = m_currentSelected->GetPackageData().package;
|
|
|
|
|
|
|
|
auto ver_it = std::find_if( package.versions.begin(), package.versions.end(),
|
|
|
|
[&]( const PACKAGE_VERSION& ver )
|
|
|
|
{
|
|
|
|
return ver.version == version;
|
|
|
|
} );
|
|
|
|
|
|
|
|
wxASSERT_MSG( ver_it != package.versions.end(), "Could not find package version" );
|
|
|
|
|
|
|
|
if( !ver_it->download_url )
|
|
|
|
{
|
|
|
|
wxMessageBox( _( "Package download url is not specified" ),
|
2024-02-02 12:47:34 -05:00
|
|
|
_( "Error downloading package" ), wxICON_INFORMATION | wxOK,
|
|
|
|
wxGetTopLevelParent( this ) );
|
2020-10-26 03:54:36 -07:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2022-08-30 13:58:43 -07:00
|
|
|
const wxString& url = *ver_it->download_url;
|
2020-10-26 03:54:36 -07:00
|
|
|
|
|
|
|
SETTINGS_MANAGER& mgr = Pgm().GetSettingsManager();
|
2024-12-08 21:46:47 +00:00
|
|
|
KICAD_SETTINGS* cfg = mgr.GetAppSettings<KICAD_SETTINGS>( "kicad" );
|
2020-10-26 03:54:36 -07:00
|
|
|
|
2024-02-02 09:20:36 -05:00
|
|
|
wxWindow* topLevelParent = wxGetTopLevelParent( this );
|
2024-12-08 21:46:47 +00:00
|
|
|
wxFileDialog dialog( topLevelParent, _( "Save Package" ), cfg->m_PcmLastDownloadDir,
|
2022-10-23 12:03:55 +01:00
|
|
|
wxString::Format( wxT( "%s_v%s.zip" ), package.identifier, version ),
|
|
|
|
wxT( "ZIP files (*.zip)|*.zip" ), wxFD_SAVE | wxFD_OVERWRITE_PROMPT );
|
2020-10-26 03:54:36 -07:00
|
|
|
|
|
|
|
if( dialog.ShowModal() == wxID_CANCEL )
|
|
|
|
return;
|
|
|
|
|
|
|
|
wxString path = dialog.GetPath();
|
2024-12-08 21:46:47 +00:00
|
|
|
cfg->m_PcmLastDownloadDir = wxPathOnly( path );
|
2020-10-26 03:54:36 -07:00
|
|
|
|
|
|
|
std::ofstream output( path.ToUTF8(), std::ios_base::binary );
|
|
|
|
|
2025-06-01 12:43:31 +01:00
|
|
|
WX_PROGRESS_REPORTER reporter( this, _( "Download Package" ), 1, PR_CAN_ABORT );
|
2021-11-24 21:34:41 -08:00
|
|
|
|
2025-06-01 12:43:31 +01:00
|
|
|
bool success = m_pcm->DownloadToStream( url, &output, &reporter, 0 );
|
2020-10-26 03:54:36 -07:00
|
|
|
|
|
|
|
output.close();
|
|
|
|
|
|
|
|
if( success )
|
|
|
|
{
|
|
|
|
if( ver_it->download_sha256 )
|
|
|
|
{
|
|
|
|
std::ifstream stream( path.ToUTF8(), std::ios_base::binary );
|
|
|
|
|
2022-08-30 13:58:43 -07:00
|
|
|
bool matches = m_pcm->VerifyHash( stream, *ver_it->download_sha256 );
|
2020-10-26 03:54:36 -07:00
|
|
|
|
|
|
|
stream.close();
|
|
|
|
|
|
|
|
if( !matches
|
|
|
|
&& wxMessageBox(
|
|
|
|
_( "Integrity of the downloaded package could not be verified, hash "
|
|
|
|
"does not match. Are you sure you want to keep this file?" ),
|
2024-02-02 12:47:34 -05:00
|
|
|
_( "Keep downloaded file" ), wxICON_EXCLAMATION | wxYES_NO,
|
|
|
|
wxGetTopLevelParent( this ) )
|
2020-10-26 03:54:36 -07:00
|
|
|
== wxNO )
|
|
|
|
{
|
|
|
|
wxRemoveFile( path );
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
if( wxFileExists( path ) )
|
|
|
|
wxRemoveFile( path );
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2022-06-30 21:09:25 -07:00
|
|
|
void PANEL_PACKAGES_VIEW::OnVersionActionClicked( wxCommandEvent& event )
|
2020-10-26 03:54:36 -07:00
|
|
|
{
|
2022-06-30 21:09:25 -07:00
|
|
|
if( !canRunAction() )
|
2020-10-26 03:54:36 -07:00
|
|
|
{
|
|
|
|
wxBell();
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2022-06-30 21:09:25 -07:00
|
|
|
PCM_PACKAGE_ACTION action = getAction();
|
|
|
|
|
|
|
|
if( action == PPA_UNINSTALL )
|
|
|
|
{
|
|
|
|
m_actionCallback( m_currentSelected->GetPackageData(), PPA_UNINSTALL,
|
|
|
|
m_currentSelected->GetPackageData().current_version );
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2021-11-13 03:42:26 +01:00
|
|
|
if( m_gridVersions->GetNumberRows() == 1 )
|
|
|
|
m_gridVersions->SelectRow( 0 );
|
|
|
|
|
|
|
|
const wxArrayInt selectedRows = m_gridVersions->GetSelectedRows();
|
|
|
|
|
2021-11-12 14:06:06 +01:00
|
|
|
wxString version = m_gridVersions->GetCellValue( selectedRows[0], COL_VERSION );
|
2020-10-26 03:54:36 -07:00
|
|
|
const PCM_PACKAGE& package = m_currentSelected->GetPackageData().package;
|
|
|
|
|
|
|
|
auto ver_it = std::find_if( package.versions.begin(), package.versions.end(),
|
|
|
|
[&]( const PACKAGE_VERSION& ver )
|
|
|
|
{
|
|
|
|
return ver.version == version;
|
|
|
|
} );
|
|
|
|
|
2022-07-07 12:38:34 +02:00
|
|
|
wxCHECK_RET( ver_it != package.versions.end(), "Could not find package version" );
|
2020-10-26 03:54:36 -07:00
|
|
|
|
|
|
|
if( !ver_it->compatible
|
2023-11-12 20:45:19 +00:00
|
|
|
&& wxMessageBox( _( "This package version is incompatible with your KiCad version or "
|
2020-10-26 03:54:36 -07:00
|
|
|
"platform. Are you sure you want to install it anyway?" ),
|
2024-02-02 12:47:34 -05:00
|
|
|
_( "Install package" ), wxICON_EXCLAMATION | wxYES_NO,
|
|
|
|
wxGetTopLevelParent( this ) )
|
2020-10-26 03:54:36 -07:00
|
|
|
== wxNO )
|
|
|
|
{
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2022-06-30 21:09:25 -07:00
|
|
|
m_actionCallback( m_currentSelected->GetPackageData(), action, version );
|
2020-10-26 03:54:36 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void PANEL_PACKAGES_VIEW::OnShowAllVersionsClicked( wxCommandEvent& event )
|
|
|
|
{
|
|
|
|
if( m_currentSelected )
|
|
|
|
{
|
|
|
|
wxMouseEvent dummy;
|
|
|
|
m_currentSelected->OnClick( dummy );
|
|
|
|
}
|
2021-11-13 03:42:26 +01:00
|
|
|
|
|
|
|
updateDetailsButtons();
|
2020-10-26 03:54:36 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void PANEL_PACKAGES_VIEW::OnSearchTextChanged( wxCommandEvent& event )
|
|
|
|
{
|
|
|
|
unsetPackageDetails();
|
|
|
|
|
|
|
|
if( m_currentSelected )
|
|
|
|
m_currentSelected->SetSelected( false );
|
|
|
|
|
|
|
|
m_currentSelected = nullptr;
|
|
|
|
|
|
|
|
updatePackageList();
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void PANEL_PACKAGES_VIEW::updatePackageList()
|
|
|
|
{
|
|
|
|
// Sort by descending rank, ascending index
|
|
|
|
std::vector<std::pair<int, int>> package_ranks;
|
|
|
|
|
|
|
|
const wxString search_term = m_searchCtrl->GetValue().Trim();
|
|
|
|
|
|
|
|
for( size_t index = 0; index < m_packageInitialOrder.size(); index++ )
|
|
|
|
{
|
|
|
|
int rank = 1;
|
|
|
|
const PCM_PACKAGE& pkg =
|
|
|
|
m_packagePanels[m_packageInitialOrder[index]]->GetPackageData().package;
|
|
|
|
|
|
|
|
if( search_term.size() > 2 )
|
|
|
|
rank = m_pcm->GetPackageSearchRank( pkg, search_term );
|
|
|
|
|
|
|
|
// Packages with no versions are delisted and should not be shown
|
|
|
|
if( pkg.versions.size() == 0 )
|
|
|
|
rank = 0;
|
|
|
|
|
|
|
|
package_ranks.emplace_back( rank, index );
|
|
|
|
}
|
|
|
|
|
|
|
|
std::sort( package_ranks.begin(), package_ranks.end(),
|
|
|
|
[]( const std::pair<int, int>& a, const std::pair<int, int>& b )
|
|
|
|
{
|
|
|
|
return a.first > b.first || ( a.first == b.first && a.second < b.second );
|
|
|
|
} );
|
|
|
|
|
|
|
|
// Rearrange panels, hide ones with 0 rank
|
|
|
|
wxSizer* sizer = m_packageListWindow->GetSizer();
|
|
|
|
sizer->Clear( false ); // Don't delete panels
|
|
|
|
|
2021-11-11 13:56:53 +00:00
|
|
|
for( const std::pair<int, int>& pair : package_ranks )
|
2020-10-26 03:54:36 -07:00
|
|
|
{
|
|
|
|
PANEL_PACKAGE* panel = m_packagePanels[m_packageInitialOrder[pair.second]];
|
|
|
|
|
|
|
|
if( pair.first > 0 )
|
|
|
|
{
|
|
|
|
sizer->Add( panel, 0, wxEXPAND );
|
|
|
|
panel->Show();
|
2024-12-31 13:07:26 +00:00
|
|
|
|
|
|
|
if( !m_currentSelected )
|
|
|
|
{
|
|
|
|
wxMouseEvent dummy;
|
|
|
|
panel->OnClick( dummy );
|
|
|
|
}
|
2020-10-26 03:54:36 -07:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
panel->Hide();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2021-11-13 11:21:00 +00:00
|
|
|
m_packageListWindow->FitInside();
|
2020-10-26 03:54:36 -07:00
|
|
|
m_packageListWindow->SetScrollRate( 0, 15 );
|
2021-11-14 16:27:24 -08:00
|
|
|
m_packageListWindow->SendSizeEvent( wxSEND_EVENT_POST );
|
2020-10-26 03:54:36 -07:00
|
|
|
}
|
2021-11-11 11:33:28 +00:00
|
|
|
|
|
|
|
|
2021-11-13 03:42:26 +01:00
|
|
|
void PANEL_PACKAGES_VIEW::updateDetailsButtons()
|
|
|
|
{
|
|
|
|
m_buttonDownload->Enable( canDownload() );
|
2022-06-30 21:09:25 -07:00
|
|
|
|
|
|
|
if( canRunAction() )
|
|
|
|
{
|
|
|
|
m_buttonAction->Enable();
|
|
|
|
|
|
|
|
PCM_PACKAGE_ACTION action = getAction();
|
|
|
|
|
|
|
|
switch( action )
|
|
|
|
{
|
|
|
|
case PPA_INSTALL: m_buttonAction->SetLabel( _( "Install" ) ); break;
|
|
|
|
case PPA_UNINSTALL: m_buttonAction->SetLabel( _( "Uninstall" ) ); break;
|
|
|
|
case PPA_UPDATE: m_buttonAction->SetLabel( _( "Update" ) ); break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
m_buttonAction->Disable();
|
|
|
|
m_buttonAction->SetLabel( _( "Pending" ) );
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
PCM_PACKAGE_ACTION PANEL_PACKAGES_VIEW::getAction() const
|
|
|
|
{
|
|
|
|
wxASSERT_MSG( m_gridVersions->GetNumberRows() == 1
|
|
|
|
|| m_gridVersions->GetSelectedRows().size() == 1,
|
2022-10-23 12:03:55 +01:00
|
|
|
wxT( "getAction() called with ambiguous version selection" ) );
|
2022-06-30 21:09:25 -07:00
|
|
|
|
|
|
|
int selected_row = 0;
|
|
|
|
|
|
|
|
if( m_gridVersions->GetSelectedRows().size() == 1 )
|
|
|
|
selected_row = m_gridVersions->GetSelectedRows()[0];
|
|
|
|
|
|
|
|
wxString version = m_gridVersions->GetCellValue( selected_row, COL_VERSION );
|
|
|
|
const PACKAGE_VIEW_DATA& package = m_currentSelected->GetPackageData();
|
|
|
|
|
|
|
|
switch( package.state )
|
|
|
|
{
|
|
|
|
case PPS_AVAILABLE:
|
|
|
|
case PPS_UNAVAILABLE:
|
|
|
|
return PPA_INSTALL; // Only action for not installed package is to install it
|
|
|
|
case PPS_INSTALLED:
|
|
|
|
case PPS_UPDATE_AVAILABLE:
|
|
|
|
if( version == package.current_version )
|
|
|
|
return PPA_UNINSTALL;
|
|
|
|
else
|
|
|
|
return PPA_UPDATE;
|
|
|
|
default:
|
|
|
|
return PPA_INSTALL; // For pending states return value does not matter as button will be disabled
|
|
|
|
}
|
2021-11-13 03:42:26 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2021-11-11 23:41:31 +00:00
|
|
|
void PANEL_PACKAGES_VIEW::OnSizeInfoBox( wxSizeEvent& aEvent )
|
2021-11-11 11:33:28 +00:00
|
|
|
{
|
2022-10-23 22:07:22 +03:00
|
|
|
wxSize infoSize = KIPLATFORM::UI::GetUnobscuredSize( m_infoText->GetParent() );
|
|
|
|
infoSize.x -= 10;
|
2021-11-11 11:33:28 +00:00
|
|
|
m_infoText->SetMinSize( infoSize );
|
|
|
|
m_infoText->SetMaxSize( infoSize );
|
|
|
|
m_infoText->SetSize( infoSize );
|
2021-11-11 23:41:31 +00:00
|
|
|
m_infoText->Layout();
|
2021-11-11 11:33:28 +00:00
|
|
|
|
2021-11-12 00:39:47 +00:00
|
|
|
infoSize.y = m_infoText->GetInternalRepresentation()->GetHeight() + 12;
|
2021-11-11 11:33:28 +00:00
|
|
|
m_infoText->SetMinSize( infoSize );
|
|
|
|
m_infoText->SetMaxSize( infoSize );
|
|
|
|
m_infoText->SetSize( infoSize );
|
|
|
|
m_infoText->Layout();
|
2021-11-18 10:57:52 +01:00
|
|
|
|
|
|
|
Refresh();
|
2021-11-11 23:41:31 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void PANEL_PACKAGES_VIEW::OnURLClicked( wxHtmlLinkEvent& aEvent )
|
|
|
|
{
|
|
|
|
const wxHtmlLinkInfo& info = aEvent.GetLinkInfo();
|
|
|
|
::wxLaunchDefaultBrowser( info.GetHref() );
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void PANEL_PACKAGES_VIEW::OnInfoMouseWheel( wxMouseEvent& event )
|
|
|
|
{
|
|
|
|
// Transfer scrolling from the info window to its parent scroll window
|
|
|
|
m_infoScrollWindow->HandleOnMouseWheel( event );
|
2021-11-12 01:14:36 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void PANEL_PACKAGES_VIEW::SetSashOnIdle( wxIdleEvent& aEvent )
|
|
|
|
{
|
2021-11-14 13:10:24 +00:00
|
|
|
COMMON_SETTINGS* cfg = Pgm().GetCommonSettings();
|
|
|
|
m_splitter1->SetSashPosition( cfg->m_PackageManager.sash_pos );
|
|
|
|
|
|
|
|
m_packageListWindow->FitInside();
|
|
|
|
|
2022-06-30 21:09:25 -07:00
|
|
|
m_splitter1->Disconnect( wxEVT_IDLE, wxIdleEventHandler( PANEL_PACKAGES_VIEW::SetSashOnIdle ),
|
2021-11-12 01:14:36 +00:00
|
|
|
NULL, this );
|
|
|
|
}
|
2022-08-18 20:41:43 +00:00
|
|
|
|
|
|
|
|
|
|
|
void PANEL_PACKAGES_VIEW::updateCommonState()
|
|
|
|
{
|
|
|
|
m_buttonUpdateAll->Enable( m_updateablePackages.size() > 0 );
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void PANEL_PACKAGES_VIEW::OnUpdateAllClicked( wxCommandEvent& event )
|
|
|
|
{
|
|
|
|
// The map will be modified by the callback so we copy the list here
|
|
|
|
std::vector<wxString> packages;
|
|
|
|
|
|
|
|
std::copy( m_updateablePackages.begin(), m_updateablePackages.end(),
|
|
|
|
std::back_inserter( packages ) );
|
|
|
|
|
|
|
|
for( const wxString& pkg_id : packages )
|
|
|
|
{
|
|
|
|
auto it = m_packagePanels.find( pkg_id );
|
|
|
|
|
|
|
|
if( it != m_packagePanels.end() )
|
|
|
|
{
|
|
|
|
const PACKAGE_VIEW_DATA& data = it->second->GetPackageData();
|
|
|
|
|
|
|
|
m_actionCallback( data, PPA_UPDATE, data.update_version );
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|