KiCad PCB EDA Suite
Loading...
Searching...
No Matches
panel_package.cpp
Go to the documentation of this file.
1/*
2 * This program source code file is part of KiCad, a free EDA CAD application.
3 *
4 * Copyright (C) 2021 Andrew Lutsenko, anlutsenko at gmail dot com
5 * Copyright The KiCad Developers, see AUTHORS.txt for contributors.
6 *
7 * This program is free software: you can redistribute it and/or modify it
8 * under the terms of the GNU General Public License as published by the
9 * Free Software Foundation, either version 3 of the License, or (at your
10 * option) any later version.
11 *
12 * This program is distributed in the hope that it will be useful, but
13 * WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with this program. If not, see <https://www.gnu.org/licenses/>.
19 */
20
21#include <math/util.h>
22#include <wx/dcclient.h>
23
24#include "panel_package.h"
25
28
29PANEL_PACKAGE::PANEL_PACKAGE( wxWindow* parent, const ActionCallback& aCallback,
30 const PinCallback& aPinCallback, const PACKAGE_VIEW_DATA& aData ) :
31 PANEL_PACKAGE_BASE( parent ),
32 m_actionCallback( aCallback ),
33 m_pinCallback( aPinCallback ),
34 m_data( aData )
35{
36 // correct the min size from wxfb with fromdip
37 SetMinSize( FromDIP( GetMinSize() ) );
38
39 // Propagate clicks on static elements to the panel handler.
40 m_name->Connect( wxEVT_LEFT_DOWN, wxMouseEventHandler( PANEL_PACKAGE::OnClick ), NULL, this );
41 m_desc->Connect( wxEVT_LEFT_DOWN, wxMouseEventHandler( PANEL_PACKAGE::OnClick ), NULL, this );
42 m_bitmap->Connect( wxEVT_LEFT_DOWN, wxMouseEventHandler( PANEL_PACKAGE::OnClick ), NULL, this );
43
44 wxColour bgColor = wxSystemSettings::GetColour( wxSYS_COLOUR_FRAMEBK );
45 m_desc->SetBackgroundColour( bgColor );
46 m_name->SetBackgroundColour( bgColor );
47 m_bitmap->SetBackgroundColour( bgColor );
48
49 m_name->SetFont( m_name->GetFont().Bold() );
50
51 m_name->SetLabelText( m_data.package.name );
52 m_bitmap->SetBitmap( *m_data.bitmap );
53
54 // Set min width to 0 otherwise wxStaticLabel really doesn't want to shrink on resize
55 m_desc->SetMinSize( wxSize( 0, -1 ) );
56
57 m_minHeight = GetMinHeight();
58
59 double descLineHeight = m_desc->GetTextExtent( wxT( "X" ) ).GetHeight() * 1.2 /* leading */;
60 m_desc->SetLabelText( m_data.package.description );
61
62#if wxCHECK_VERSION( 3, 3, 2 )
63 m_desc->SetWindowStyle( wxST_WRAP );
64#else
65 m_desc->Wrap( m_descSizer->GetSize().GetWidth() );
66#endif
67
68 descLineHeight = wxSplit( m_desc->GetLabel(), '\n' ).size() * descLineHeight;
69
70 int nameLineHeight = m_name->GetTextExtent( wxT( "X" ) ).GetHeight();
71 wxSize minSize = GetMinSize();
72 minSize.y = std::max( nameLineHeight + KiROUND( descLineHeight ) + FromDIP( 15 ), m_minHeight );
73 SetMinSize( minSize );
74
75 m_splitButton->SetLabel( _( "Update" ) );
76 m_splitButton->Bind( wxEVT_BUTTON, &PANEL_PACKAGE::OnButtonClicked, this );
77
78 wxMenu* splitMenu = m_splitButton->GetSplitButtonMenu();
80 splitMenu->Append( wxID_ANY, _( "Pin package" ),
81 _( "Pinned packages don't affect available update notification and "
82 "will not be updated with 'Update All' button." ),
83 wxITEM_CHECK );
84 splitMenu->Bind( wxEVT_COMMAND_MENU_SELECTED, &PANEL_PACKAGE::OnPinVersionClick, this,
85 m_pinVersionMenuItem->GetId() );
86
87 m_actionMenuItem = splitMenu->Append( wxID_ANY, _( "Uninstall" ) );
88
90 m_warningIcon->SetToolTip( _( "Warning: This plugin only supports the legacy Python API "
91 "and will not run in this KiCad version." ) );
92 m_warningIcon->Show( m_data.swig_warning );
93
94 SetState( m_data.state, m_data.pinned );
95}
96
97
98void PANEL_PACKAGE::OnSize( wxSizeEvent& event )
99{
100 Layout();
101
102 double descLineHeight = m_desc->GetTextExtent( wxT( "X" ) ).GetHeight() * 1.2 /* leading */;
103
104#if !wxCHECK_VERSION( 3, 3, 2 )
105 m_desc->SetLabelText( m_data.package.description );
106 m_desc->Wrap( m_descSizer->GetSize().GetWidth() );
107#endif
108
109 descLineHeight = wxSplit( m_desc->GetLabel(), '\n' ).size() * descLineHeight;
110
111 int nameLineHeight = m_name->GetTextExtent( wxT( "X" ) ).GetHeight();
112 wxSize minSize = GetMinSize();
113 minSize.y = std::max( nameLineHeight + KiROUND( descLineHeight ) + 15, m_minHeight );
114 SetMinSize( minSize );
115}
116
117
118void PANEL_PACKAGE::SetState( PCM_PACKAGE_STATE aState, bool aPinned )
119{
120 m_data.state = aState;
121 m_data.pinned = aPinned;
122 m_splitButton->GetSplitButtonMenu()->Check( m_pinVersionMenuItem->GetId(), aPinned );
123
124 switch( aState )
125 {
127 m_splitButton->Hide();
128 m_button->Show();
129 m_button->SetLabel( _( "Install" ) );
130 m_button->Enable();
131 break;
133 m_splitButton->Hide();
134 m_button->Show();
135 m_button->SetLabel( _( "Install" ) );
136 m_button->Disable();
137 break;
139 m_button->Hide();
140 m_splitButton->Show();
141
142 m_splitButton->SetLabel( _( "Uninstall" ) );
143 m_splitButton->Bind( wxEVT_BUTTON, &PANEL_PACKAGE::OnButtonClicked, this );
144
145 m_actionMenuItem->SetItemLabel( _( "Update" ) );
146 m_splitButton->GetSplitButtonMenu()->Enable( m_actionMenuItem->GetId(), false );
147
148 break;
150 m_splitButton->Hide();
151 m_button->Show();
152 m_button->SetLabel( _( "Install Pending" ) );
153 m_button->Disable();
154 break;
156 m_splitButton->Hide();
157 m_button->Show();
158 m_button->SetLabel( _( "Uninstall Pending" ) );
159 m_button->Disable();
160 break;
162 m_button->Hide();
163 m_splitButton->Show();
164
165 if( aPinned )
166 {
167 m_splitButton->SetLabel( _( "Uninstall" ) );
168 m_splitButton->Bind( wxEVT_BUTTON, &PANEL_PACKAGE::OnUninstallClick, this );
169
170 m_actionMenuItem->SetItemLabel( _( "Update" ) );
171 m_splitButton->GetSplitButtonMenu()->Enable( m_actionMenuItem->GetId(), true );
172 m_splitButton->GetSplitButtonMenu()->Bind( wxEVT_COMMAND_MENU_SELECTED,
174 m_actionMenuItem->GetId() );
175 }
176 else
177 {
178 m_splitButton->SetLabel( _( "Update" ) );
179 m_splitButton->Bind( wxEVT_BUTTON, &PANEL_PACKAGE::OnButtonClicked, this );
180
181 m_actionMenuItem->SetItemLabel( _( "Uninstall" ) );
182 m_splitButton->GetSplitButtonMenu()->Enable( m_actionMenuItem->GetId(), true );
183 m_splitButton->GetSplitButtonMenu()->Bind( wxEVT_COMMAND_MENU_SELECTED,
185 m_actionMenuItem->GetId() );
186 }
187 break;
189 m_splitButton->Hide();
190 m_button->Show();
191 m_button->SetLabel( _( "Update Pending" ) );
192 m_button->Disable();
193 break;
194 }
195
196 // Relayout to change button size to fit the label.
197 Layout();
198}
199
200
201void PANEL_PACKAGE::OnButtonClicked( wxCommandEvent& event )
202{
203 if( m_data.state == PPS_AVAILABLE )
204 {
205 wxString version = GetPreferredVersion();
206
207 if( version.IsEmpty() )
208 return;
209
211 }
212 else if( m_data.state == PPS_UPDATE_AVAILABLE )
213 {
214 m_actionCallback( m_data, PPA_UPDATE, m_data.update_version );
215 }
216 else
217 {
218 m_actionCallback( m_data, PPA_UNINSTALL, m_data.current_version );
219 }
220}
221
222
223void PANEL_PACKAGE::OnPinVersionClick( wxCommandEvent& event )
224{
225 m_data.pinned = event.IsChecked();
226
227 m_pinCallback( m_data.package.identifier, m_data.state, m_data.pinned );
228}
229
230
231void PANEL_PACKAGE::OnUninstallClick( wxCommandEvent& event )
232{
233 if( m_data.state == PPS_UPDATE_AVAILABLE )
234 {
235 m_actionCallback( m_data, PPA_UNINSTALL, m_data.current_version );
236 }
237 else
238 {
239 // Clicking uninstall menu item of the split button should not be possible
240 // for any state other than UPDATE_AVAILABLE
241 wxLogError( wxT( "Uninstall clicked in unexpected state" ) );
242 }
243}
244
245
246void PANEL_PACKAGE::SetSelectCallback( const std::function<void()>& aCallback )
247{
248 m_selectCallback = aCallback;
249}
250
251
252void PANEL_PACKAGE::OnClick( wxMouseEvent& event )
253{
255}
256
257
258void PANEL_PACKAGE::OnPaint( wxPaintEvent& event )
259{
260 wxRect rect( wxPoint( 1, 1 ), GetClientSize() - wxSize( 1, 1 ) );
261 wxPaintDC dc( this );
262 dc.SetBrush( wxSystemSettings::GetColour( wxSYS_COLOUR_FRAMEBK ) );
263 dc.SetPen( wxPen( wxSystemSettings::GetColour( wxSYS_COLOUR_ACTIVEBORDER ), 1 ) );
264
265 if( m_selected )
266 {
267 rect.Deflate( 1 );
268 dc.SetPen( wxPen( wxSystemSettings::GetColour( wxSYS_COLOUR_HOTLIGHT ), 3 ) );
269 }
270
271 dc.DrawRectangle( rect );
272}
273
274
275void PANEL_PACKAGE::SetSelected( bool aSelected )
276{
277 m_selected = aSelected;
278 Refresh();
279}
280
281
283{
284 // Versions are already presorted in descending order
285
286 // Find last stable compatible version
287 auto ver_it = std::find_if( m_data.package.versions.begin(), m_data.package.versions.end(),
288 []( const PACKAGE_VERSION& ver )
289 {
290 return ver.compatible && ver.status == PVS_STABLE;
291 } );
292
293 // If not found then find any compatible version
294 if( ver_it == m_data.package.versions.end() )
295 {
296 ver_it = std::find_if( m_data.package.versions.begin(), m_data.package.versions.end(),
297 []( const PACKAGE_VERSION& ver )
298 {
299 return ver.compatible;
300 } );
301 }
302
303 if( ver_it == m_data.package.versions.end() )
304 return wxEmptyString; // Shouldn't happen
305
306 return ver_it->version;
307}
wxBitmapBundle KiBitmapBundle(BITMAPS aBitmap, int aMinHeight)
Definition bitmap.cpp:106
constexpr BOX2I KiROUND(const BOX2D &aBoxD)
Definition box2.h:982
wxStaticBitmap * m_bitmap
PANEL_PACKAGE_BASE(wxWindow *parent, wxWindowID id=wxID_ANY, const wxPoint &pos=wxDefaultPosition, const wxSize &size=wxSize(-1,-1), long style=wxBORDER_NONE|wxTAB_TRAVERSAL, const wxString &name=wxEmptyString)
SPLIT_BUTTON * m_splitButton
wxStaticBitmap * m_warningIcon
void OnClick(wxMouseEvent &event) override
Called when anywhere on the panel is clicked (except install button)
void OnUninstallClick(wxCommandEvent &event)
wxMenuItem * m_actionMenuItem
void OnPinVersionClick(wxCommandEvent &event)
void OnPaint(wxPaintEvent &event) override
void SetSelected(bool aSelected)
Marks panel as selected.
void OnButtonClicked(wxCommandEvent &event) override
const ActionCallback & m_actionCallback
const PinCallback & m_pinCallback
wxMenuItem * m_pinVersionMenuItem
PACKAGE_VIEW_DATA m_data
void SetState(PCM_PACKAGE_STATE aState, bool aPinned)
Changes state of the (un)install button.
PANEL_PACKAGE(wxWindow *parent, const ActionCallback &aCallback, const PinCallback &aPinCallback, const PACKAGE_VIEW_DATA &aData)
void OnSize(wxSizeEvent &event) override
std::function< void()> m_selectCallback
void SetSelectCallback(const std::function< void()> &aCallback)
Sets callback for OnClick action.
wxString GetPreferredVersion() const
Get preferred version. If criteria are not met, return wxEmptyString.
const int minSize
Push and Shove router track width and via size dialog.
#define _(s)
std::function< void(const wxString &aPackageId, const PCM_PACKAGE_STATE aState, const bool aPinned)> PinCallback
std::function< void(const PACKAGE_VIEW_DATA &aData, PCM_PACKAGE_ACTION aAction, const wxString &aVersion)> ActionCallback
Callback for (un)install button.
PCM_PACKAGE_STATE
Package states Package is available if it is not installed and there is a compatible version Package ...
Definition pcm.h:59
@ PPS_INSTALLED
Definition pcm.h:62
@ PPS_PENDING_UPDATE
Definition pcm.h:66
@ PPS_UNAVAILABLE
Definition pcm.h:61
@ PPS_UPDATE_AVAILABLE
Definition pcm.h:65
@ PPS_PENDING_UNINSTALL
Definition pcm.h:64
@ PPS_PENDING_INSTALL
Definition pcm.h:63
@ PPS_AVAILABLE
Definition pcm.h:60
@ PPA_UNINSTALL
Definition pcm.h:74
@ PPA_UPDATE
Definition pcm.h:75
@ PPA_INSTALL
Definition pcm.h:73
Package version metadata.
Definition pcm_data.h:92
Collection of data relevant to the package display panel.