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
|
2022-10-23 12:03:55 +01:00
|
|
|
* Copyright (C) 1992-2022 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/>.
|
|
|
|
*/
|
|
|
|
|
2021-11-12 15:30:46 +00:00
|
|
|
#include <math/util.h>
|
2022-06-30 21:09:25 -07:00
|
|
|
#include <wx/dcclient.h>
|
2020-10-26 03:54:36 -07:00
|
|
|
|
|
|
|
#include "panel_package.h"
|
|
|
|
|
|
|
|
PANEL_PACKAGE::PANEL_PACKAGE( wxWindow* parent, const ActionCallback& aCallback,
|
2022-08-28 04:40:06 -07:00
|
|
|
const PinCallback& aPinCallback, const PACKAGE_VIEW_DATA& aData ) :
|
2020-10-26 03:54:36 -07:00
|
|
|
PANEL_PACKAGE_BASE( parent ),
|
2022-10-23 12:03:55 +01:00
|
|
|
m_actionCallback( aCallback ),
|
|
|
|
m_pinCallback( aPinCallback ),
|
|
|
|
m_data( aData )
|
2020-10-26 03:54:36 -07:00
|
|
|
{
|
|
|
|
// Propagate clicks on static elements to the panel handler.
|
|
|
|
m_name->Connect( wxEVT_LEFT_DOWN, wxMouseEventHandler( PANEL_PACKAGE::OnClick ), NULL, this );
|
|
|
|
m_desc->Connect( wxEVT_LEFT_DOWN, wxMouseEventHandler( PANEL_PACKAGE::OnClick ), NULL, this );
|
|
|
|
m_bitmap->Connect( wxEVT_LEFT_DOWN, wxMouseEventHandler( PANEL_PACKAGE::OnClick ), NULL, this );
|
|
|
|
|
|
|
|
wxColour bgColor = wxSystemSettings::GetColour( wxSYS_COLOUR_FRAMEBK );
|
|
|
|
m_desc->SetBackgroundColour( bgColor );
|
|
|
|
m_name->SetBackgroundColour( bgColor );
|
|
|
|
m_bitmap->SetBackgroundColour( bgColor );
|
|
|
|
|
2021-09-12 12:17:22 +01:00
|
|
|
m_name->SetFont( m_name->GetFont().Bold() );
|
|
|
|
|
2023-05-22 11:18:39 -07:00
|
|
|
m_name->SetLabelText( m_data.package.name );
|
2020-10-26 03:54:36 -07:00
|
|
|
m_bitmap->SetBitmap( *m_data.bitmap );
|
|
|
|
|
|
|
|
// Set min width to 0 otherwise wxStaticLabel really doesn't want to shrink on resize
|
|
|
|
m_desc->SetMinSize( wxSize( 0, -1 ) );
|
|
|
|
|
2021-11-12 15:30:46 +00:00
|
|
|
m_minHeight = GetMinHeight();
|
2020-10-26 03:54:36 -07:00
|
|
|
|
2022-10-23 12:03:55 +01:00
|
|
|
double descLineHeight = m_desc->GetTextExtent( wxT( "X" ) ).GetHeight() * 1.2 /* leading */;
|
2023-05-22 11:18:39 -07:00
|
|
|
m_desc->SetLabelText( m_data.package.description );
|
2021-11-12 15:30:46 +00:00
|
|
|
descLineHeight = wxSplit( m_desc->GetLabel(), '\n' ).size() * descLineHeight;
|
|
|
|
|
2022-10-23 12:03:55 +01:00
|
|
|
int nameLineHeight = m_name->GetTextExtent( wxT( "X" ) ).GetHeight();
|
2021-11-12 15:30:46 +00:00
|
|
|
wxSize minSize = GetMinSize();
|
|
|
|
minSize.y = std::max( nameLineHeight + KiROUND( descLineHeight ) + 15, m_minHeight );
|
|
|
|
SetMinSize( minSize );
|
|
|
|
|
2022-06-30 21:09:25 -07:00
|
|
|
m_splitButton->SetLabel( _( "Update" ) );
|
|
|
|
m_splitButton->Bind( wxEVT_BUTTON, &PANEL_PACKAGE::OnButtonClicked, this );
|
|
|
|
|
2022-08-28 04:40:06 -07:00
|
|
|
wxMenu* splitMenu = m_splitButton->GetSplitButtonMenu();
|
|
|
|
m_pinVersionMenuItem =
|
|
|
|
splitMenu->Append( wxID_ANY, _( "Pin package" ),
|
|
|
|
_( "Pinned packages don't affect available update notification and "
|
2022-10-23 12:03:55 +01:00
|
|
|
"will not be updated with 'Update All' button." ),
|
2022-08-28 04:40:06 -07:00
|
|
|
wxITEM_CHECK );
|
|
|
|
splitMenu->Bind( wxEVT_COMMAND_MENU_SELECTED, &PANEL_PACKAGE::OnPinVersionClick, this,
|
|
|
|
m_pinVersionMenuItem->GetId() );
|
2022-06-30 21:09:25 -07:00
|
|
|
|
2022-08-28 04:40:06 -07:00
|
|
|
m_actionMenuItem = splitMenu->Append( wxID_ANY, _( "Uninstall" ) );
|
2022-05-17 01:39:27 +02:00
|
|
|
|
2022-08-28 04:40:06 -07:00
|
|
|
SetState( m_data.state, m_data.pinned );
|
2022-05-17 01:39:27 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void PANEL_PACKAGE::OnSize( wxSizeEvent& event )
|
2022-06-30 21:09:25 -07:00
|
|
|
{
|
2021-11-12 15:30:46 +00:00
|
|
|
Layout();
|
2020-10-26 03:54:36 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2022-08-28 04:40:06 -07:00
|
|
|
void PANEL_PACKAGE::SetState( PCM_PACKAGE_STATE aState, bool aPinned )
|
2020-10-26 03:54:36 -07:00
|
|
|
{
|
|
|
|
m_data.state = aState;
|
2022-08-28 04:40:06 -07:00
|
|
|
m_data.pinned = aPinned;
|
|
|
|
m_splitButton->GetSplitButtonMenu()->Check( m_pinVersionMenuItem->GetId(), aPinned );
|
2020-10-26 03:54:36 -07:00
|
|
|
|
|
|
|
switch( aState )
|
|
|
|
{
|
|
|
|
case PCM_PACKAGE_STATE::PPS_AVAILABLE:
|
2022-06-30 21:09:25 -07:00
|
|
|
m_splitButton->Hide();
|
|
|
|
m_button->Show();
|
2020-10-26 03:54:36 -07:00
|
|
|
m_button->SetLabel( _( "Install" ) );
|
|
|
|
m_button->Enable();
|
|
|
|
break;
|
|
|
|
case PCM_PACKAGE_STATE::PPS_UNAVAILABLE:
|
2022-06-30 21:09:25 -07:00
|
|
|
m_splitButton->Hide();
|
|
|
|
m_button->Show();
|
2020-10-26 03:54:36 -07:00
|
|
|
m_button->SetLabel( _( "Install" ) );
|
|
|
|
m_button->Disable();
|
|
|
|
break;
|
|
|
|
case PCM_PACKAGE_STATE::PPS_INSTALLED:
|
2022-08-28 04:40:06 -07:00
|
|
|
m_button->Hide();
|
|
|
|
m_splitButton->Show();
|
|
|
|
|
|
|
|
m_splitButton->SetLabel( _( "Uninstall" ) );
|
|
|
|
m_splitButton->Bind( wxEVT_BUTTON, &PANEL_PACKAGE::OnButtonClicked, this );
|
|
|
|
|
|
|
|
m_actionMenuItem->SetItemLabel( _( "Update" ) );
|
|
|
|
m_splitButton->GetSplitButtonMenu()->Enable( m_actionMenuItem->GetId(), false );
|
|
|
|
|
2020-10-26 03:54:36 -07:00
|
|
|
break;
|
|
|
|
case PCM_PACKAGE_STATE::PPS_PENDING_INSTALL:
|
2022-06-30 21:09:25 -07:00
|
|
|
m_splitButton->Hide();
|
|
|
|
m_button->Show();
|
2021-11-12 20:48:42 +00:00
|
|
|
m_button->SetLabel( _( "Install Pending" ) );
|
2020-10-26 03:54:36 -07:00
|
|
|
m_button->Disable();
|
|
|
|
break;
|
|
|
|
case PCM_PACKAGE_STATE::PPS_PENDING_UNINSTALL:
|
2022-06-30 21:09:25 -07:00
|
|
|
m_splitButton->Hide();
|
|
|
|
m_button->Show();
|
2021-11-12 20:48:42 +00:00
|
|
|
m_button->SetLabel( _( "Uninstall Pending" ) );
|
2020-10-26 03:54:36 -07:00
|
|
|
m_button->Disable();
|
|
|
|
break;
|
2022-06-30 21:09:25 -07:00
|
|
|
case PCM_PACKAGE_STATE::PPS_UPDATE_AVAILABLE:
|
|
|
|
m_button->Hide();
|
|
|
|
m_splitButton->Show();
|
2022-08-28 04:40:06 -07:00
|
|
|
|
|
|
|
if( aPinned )
|
|
|
|
{
|
|
|
|
m_splitButton->SetLabel( _( "Uninstall" ) );
|
|
|
|
m_splitButton->Bind( wxEVT_BUTTON, &PANEL_PACKAGE::OnUninstallClick, this );
|
|
|
|
|
|
|
|
m_actionMenuItem->SetItemLabel( _( "Update" ) );
|
|
|
|
m_splitButton->GetSplitButtonMenu()->Enable( m_actionMenuItem->GetId(), true );
|
|
|
|
m_splitButton->GetSplitButtonMenu()->Bind( wxEVT_COMMAND_MENU_SELECTED,
|
|
|
|
&PANEL_PACKAGE::OnButtonClicked, this,
|
|
|
|
m_actionMenuItem->GetId() );
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
m_splitButton->SetLabel( _( "Update" ) );
|
|
|
|
m_splitButton->Bind( wxEVT_BUTTON, &PANEL_PACKAGE::OnButtonClicked, this );
|
|
|
|
|
|
|
|
m_actionMenuItem->SetItemLabel( _( "Uninstall" ) );
|
|
|
|
m_splitButton->GetSplitButtonMenu()->Enable( m_actionMenuItem->GetId(), true );
|
|
|
|
m_splitButton->GetSplitButtonMenu()->Bind( wxEVT_COMMAND_MENU_SELECTED,
|
|
|
|
&PANEL_PACKAGE::OnUninstallClick, this,
|
|
|
|
m_actionMenuItem->GetId() );
|
|
|
|
}
|
2022-06-30 21:09:25 -07:00
|
|
|
break;
|
|
|
|
case PCM_PACKAGE_STATE::PPS_PENDING_UPDATE:
|
|
|
|
m_splitButton->Hide();
|
|
|
|
m_button->Show();
|
|
|
|
m_button->SetLabel( _( "Update Pending" ) );
|
|
|
|
m_button->Disable();
|
|
|
|
break;
|
2020-10-26 03:54:36 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
// Relayout to change button size to fit the label.
|
2022-06-30 21:09:25 -07:00
|
|
|
Layout();
|
2020-10-26 03:54:36 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void PANEL_PACKAGE::OnButtonClicked( wxCommandEvent& event )
|
|
|
|
{
|
|
|
|
if( m_data.state == PPS_AVAILABLE )
|
|
|
|
{
|
2021-11-13 18:55:41 +01:00
|
|
|
wxString version = GetPreferredVersion();
|
|
|
|
|
|
|
|
if( version.IsEmpty() )
|
|
|
|
return;
|
|
|
|
|
|
|
|
m_actionCallback( m_data, PPA_INSTALL, version );
|
2020-10-26 03:54:36 -07:00
|
|
|
}
|
2022-06-30 21:09:25 -07:00
|
|
|
else if( m_data.state == PPS_UPDATE_AVAILABLE )
|
|
|
|
{
|
|
|
|
m_actionCallback( m_data, PPA_UPDATE, m_data.update_version );
|
|
|
|
}
|
2020-10-26 03:54:36 -07:00
|
|
|
else
|
|
|
|
{
|
|
|
|
m_actionCallback( m_data, PPA_UNINSTALL, m_data.current_version );
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2022-08-28 04:40:06 -07:00
|
|
|
void PANEL_PACKAGE::OnPinVersionClick( wxCommandEvent& event )
|
|
|
|
{
|
|
|
|
m_data.pinned = event.IsChecked();
|
|
|
|
|
|
|
|
m_pinCallback( m_data.package.identifier, m_data.state, m_data.pinned );
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2022-06-30 21:09:25 -07:00
|
|
|
void PANEL_PACKAGE::OnUninstallClick( wxCommandEvent& event )
|
|
|
|
{
|
|
|
|
if( m_data.state == PPS_UPDATE_AVAILABLE )
|
|
|
|
{
|
|
|
|
m_actionCallback( m_data, PPA_UNINSTALL, m_data.current_version );
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
// Clicking uninstall menu item of the split button should not be possible
|
|
|
|
// for any state other than UPDATE_AVAILABLE
|
|
|
|
wxLogError( wxT( "Uninstall clicked in unexpected state" ) );
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2020-10-26 03:54:36 -07:00
|
|
|
void PANEL_PACKAGE::SetSelectCallback( const std::function<void()>& aCallback )
|
|
|
|
{
|
|
|
|
m_selectCallback = aCallback;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void PANEL_PACKAGE::OnClick( wxMouseEvent& event )
|
|
|
|
{
|
|
|
|
m_selectCallback();
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void PANEL_PACKAGE::OnPaint( wxPaintEvent& event )
|
|
|
|
{
|
2021-11-13 11:21:00 +00:00
|
|
|
wxRect rect( wxPoint( 1, 1 ), GetClientSize() - wxSize( 1, 1 ) );
|
2020-10-26 03:54:36 -07:00
|
|
|
wxPaintDC dc( this );
|
|
|
|
dc.SetBrush( wxSystemSettings::GetColour( wxSYS_COLOUR_FRAMEBK ) );
|
|
|
|
dc.SetPen( wxPen( wxSystemSettings::GetColour( wxSYS_COLOUR_ACTIVEBORDER ), 1 ) );
|
|
|
|
|
|
|
|
if( m_selected )
|
2021-11-13 11:21:00 +00:00
|
|
|
{
|
|
|
|
rect.Deflate( 1 );
|
2021-11-13 19:26:03 +00:00
|
|
|
dc.SetPen( wxPen( wxSystemSettings::GetColour( wxSYS_COLOUR_HOTLIGHT ), 3 ) );
|
2021-11-13 11:21:00 +00:00
|
|
|
}
|
2020-10-26 03:54:36 -07:00
|
|
|
|
2021-11-13 11:21:00 +00:00
|
|
|
dc.DrawRectangle( rect );
|
2020-10-26 03:54:36 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void PANEL_PACKAGE::SetSelected( bool aSelected )
|
|
|
|
{
|
|
|
|
m_selected = aSelected;
|
|
|
|
Refresh();
|
|
|
|
}
|
2021-11-13 18:55:41 +01:00
|
|
|
|
|
|
|
|
|
|
|
wxString PANEL_PACKAGE::GetPreferredVersion() const
|
|
|
|
{
|
|
|
|
// Versions are already presorted in descending order
|
|
|
|
|
|
|
|
// Find last stable compatible version
|
|
|
|
auto ver_it = std::find_if( m_data.package.versions.begin(), m_data.package.versions.end(),
|
|
|
|
[]( const PACKAGE_VERSION& ver )
|
|
|
|
{
|
|
|
|
return ver.compatible && ver.status == PVS_STABLE;
|
|
|
|
} );
|
|
|
|
|
|
|
|
// If not found then find any compatible version
|
|
|
|
if( ver_it == m_data.package.versions.end() )
|
|
|
|
{
|
|
|
|
ver_it = std::find_if( m_data.package.versions.begin(), m_data.package.versions.end(),
|
|
|
|
[]( const PACKAGE_VERSION& ver )
|
|
|
|
{
|
|
|
|
return ver.compatible;
|
|
|
|
} );
|
|
|
|
}
|
|
|
|
|
|
|
|
if( ver_it == m_data.package.versions.end() )
|
|
|
|
return wxEmptyString; // Shouldn't happen
|
|
|
|
|
|
|
|
return ver_it->version;
|
|
|
|
}
|