KiCad PCB EDA Suite
Loading...
Searching...
No Matches
dialog_pcm.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// kicad_curl_easy.h **must be** included before any wxWidgets header to avoid conflicts
22// at least on Windows/msys2
24
25#include "bitmaps.h"
27#include "dialog_pcm.h"
28#include <eda_base_frame.h>
29#include "grid_tricks.h"
30#include "ki_exception.h"
31#include "pcm_task_manager.h"
32#include "pgm_base.h"
35#include "thread"
36#include "widgets/wx_grid.h"
37
38#include <fstream>
39#include <kiplatform/ui.h>
40#include <launch_ext.h>
41#include <sstream>
42#include <wx/filedlg.h>
43#include <wx/msgdlg.h>
44
45
46#define GRID_CELL_MARGIN 4
47
48// Notes: These strings are static, so wxGetTranslation must be called to display the
49// transalted text
50static std::vector<std::pair<PCM_PACKAGE_TYPE, wxString>> PACKAGE_TYPE_LIST = {
51 { PT_PLUGIN, _( "Plugins (%d)" ) },
52 { PT_FAB, _( "Fabrication plugins (%d)" ) },
53 { PT_LIBRARY, _( "Libraries (%d)" ) },
54 { PT_DATASOURCE, _( "Data sources (%d)" ) },
55 { PT_COLORTHEME, _( "Color themes (%d)" ) },
56};
57
58
59DIALOG_PCM::DIALOG_PCM( EDA_BASE_FRAME* parent, std::shared_ptr<PLUGIN_CONTENT_MANAGER> pcm ) :
60 DIALOG_PCM_BASE( parent ),
61 m_parentFrame( parent ),
62 m_pcm( pcm )
63{
64 // correct the min size from wxfb with fromdip
65 SetMinSize( FromDIP( GetMinSize() ) );
66
67 SetDoubleBuffered( true );
68
70
71 m_pcm->SetDialogWindow( this );
72 m_pcm->StopBackgroundUpdate();
73
74 m_gridPendingActions->PushEventHandler( new GRID_TRICKS( m_gridPendingActions ) );
75
77 m_panelPending->Layout();
78
79 m_actionCallback = [this]( const PACKAGE_VIEW_DATA& aData, PCM_PACKAGE_ACTION aAction,
80 const wxString& aVersion )
81 {
82 if( aAction == PPA_UPDATE && m_pcm->IsPackagePinned( aData.package.identifier ) )
83 {
84 if( wxMessageBox( wxString::Format( _( "Are you sure you want to update pinned package "
85 "from version %s to %s?" ),
86 aData.current_version, aVersion ),
87 _( "Confirm update" ), wxICON_QUESTION | wxYES_NO, this )
88 == wxNO )
89 {
90 return;
91 }
92 }
93
94 m_gridPendingActions->Freeze();
95
96 PCM_PACKAGE_STATE new_state;
97
98 m_gridPendingActions->AppendRows();
99 int row = m_gridPendingActions->GetNumberRows() - 1;
100
101 m_gridPendingActions->SetCellValue( row, PENDING_COL_NAME, aData.package.name );
103
104 switch( aAction )
105 {
106 default:
107 case PPA_INSTALL:
108 m_gridPendingActions->SetCellValue( row, PENDING_COL_ACTION, _( "Install" ) );
109 m_gridPendingActions->SetCellValue( row, PENDING_COL_VERSION, aVersion );
110 new_state = PPS_PENDING_INSTALL;
111 break;
112
113 case PPA_UPDATE:
114 m_gridPendingActions->SetCellValue( row, PENDING_COL_ACTION, _( "Update" ) );
115 m_gridPendingActions->SetCellValue( row, PENDING_COL_VERSION,
116 wxString::Format( wxT( "%s \u279C %s" ),
117 aData.current_version,
118 aVersion ) );
119 new_state = PPS_PENDING_UPDATE;
120 break;
121
122 case PPA_UNINSTALL:
123 m_gridPendingActions->SetCellValue( row, PENDING_COL_ACTION, _( "Uninstall" ) );
124 m_gridPendingActions->SetCellValue( row, PENDING_COL_VERSION,
125 m_pcm->GetInstalledPackageVersion( aData.package.identifier ) );
126 new_state = PPS_PENDING_UNINSTALL;
127 break;
128 }
129
130 m_pendingActions.emplace_back( aAction, aData.repository_id, aData.package, aVersion );
131
132 m_gridPendingActions->Thaw();
133
135
136 updatePackageState( aData.package.identifier, new_state );
137 };
138
140 [this]( const wxString& aPackageId, const PCM_PACKAGE_STATE aState, const bool aPinned )
141 {
142 m_pcm->SetPinned( aPackageId, aPinned );
143
144 updatePackageState( aPackageId, aState );
145 };
146
148 m_panelInstalledHolder->GetSizer()->Add( m_installedPanel, 1, wxEXPAND );
149 m_panelInstalledHolder->Layout();
150
151 for( const std::pair<PCM_PACKAGE_TYPE, wxString>& entry : PACKAGE_TYPE_LIST )
152 {
155 wxString label = wxGetTranslation( entry.second );
156 m_contentNotebook->AddPage( panel, wxString::Format( label, 0 ) );
157 m_repositoryContentPanels.insert( { entry.first, panel } );
158 }
159
160 m_dialogNotebook->SetPageText( 0, wxString::Format( _( "Repository (%d)" ), 0 ) );
161
164
165 m_dialogNotebook->SetSelection( 0 );
166
167 SetupStandardButtons( { { wxID_OK, _( "Close" ) },
168 { wxID_APPLY, _( "Apply Pending Changes" ) },
169 { wxID_CANCEL, _( "Discard Pending Changes" ) } } );
170
171 Bind( wxEVT_CLOSE_WINDOW, &DIALOG_PCM::OnCloseWindow, this );
172 m_sdbSizer1Cancel->Bind( wxEVT_UPDATE_UI, &DIALOG_PCM::OnUpdateEventButtons, this );
173 m_sdbSizer1Apply->Bind( wxEVT_UPDATE_UI, &DIALOG_PCM::OnUpdateEventButtons, this );
174
175 // Has to be called after DIALOG_SHIM reads cached values
176 CallAfter(
177 [this]()
178 {
180 } );
181
182 for( int col = 0; col < m_gridPendingActions->GetNumberCols(); col++ )
183 {
184 const wxString& heading = m_gridPendingActions->GetColLabelValue( col );
185 int headingWidth = GetTextExtent( heading ).x + 2 * GRID_CELL_MARGIN;
186
187 // Set the minimal width to the column label size.
188 m_gridPendingActions->SetColMinimalWidth( col, headingWidth );
189 }
190
191 // fix sizers now widgets are set.
193}
194
195
197{
198 Unbind( wxEVT_CLOSE_WINDOW, &DIALOG_PCM::OnCloseWindow, this );
199 m_sdbSizer1Cancel->Unbind( wxEVT_UPDATE_UI, &DIALOG_PCM::OnUpdateEventButtons, this );
200 m_sdbSizer1Apply->Unbind( wxEVT_UPDATE_UI, &DIALOG_PCM::OnUpdateEventButtons, this );
201
202 m_pcm->SaveInstalledPackages();
203 m_pcm->SetDialogWindow( nullptr );
204 m_pcm->RunBackgroundUpdate();
205
206 m_gridPendingActions->PopEventHandler( true );
207}
208
209
211{
212 for( size_t i = 0; i < PACKAGE_TYPE_LIST.size(); ++i )
213 {
214 if( PACKAGE_TYPE_LIST[i].first == aType )
215 {
216 m_contentNotebook->SetSelection( i );
217 break;
218 }
219 }
220}
221
222
223void DIALOG_PCM::OnUpdateEventButtons( wxUpdateUIEvent& event )
224{
225 event.Enable( !m_pendingActions.empty() );
226}
227
228
229void DIALOG_PCM::OnCloseClicked( wxCommandEvent& event )
230{
231 if( m_pendingActions.size() == 0
232 || wxMessageBox( _( "Are you sure you want to close the package manager "
233 "and discard pending changes?" ),
234 _( "Plugin and Content Manager" ), wxICON_QUESTION | wxYES_NO, this )
235 == wxYES )
236 {
237 EndModal( wxID_OK );
238 }
239}
240
241
242void DIALOG_PCM::OnCloseWindow( wxCloseEvent& aEvent )
243{
244 wxCommandEvent dummy;
245
247}
248
249
250void DIALOG_PCM::OnManageRepositoriesClicked( wxCommandEvent& event )
251{
253
254 std::vector<std::pair<wxString, wxString>> dialog_data;
255 std::vector<std::tuple<wxString, wxString, wxString>> repo_list = m_pcm->GetRepositoryList();
256
257 for( const auto& [id, url, name] : repo_list )
258 dialog_data.push_back( std::make_pair( url, name ) );
259
260 dialog->SetData( dialog_data );
261
262 if( dialog->ShowModal() == wxID_SAVE )
263 {
264 dialog_data = dialog->GetData();
265 m_pcm->SetRepositoryList( dialog_data );
266
267 if( KICAD_SETTINGS* cfg = GetAppSettings<KICAD_SETTINGS>( "kicad" ) )
268 cfg->m_PcmRepositories = std::move( dialog_data );
269
272 }
273
274 dialog->Destroy();
275}
276
277
279{
280 std::vector<std::tuple<wxString, wxString, wxString>> repositories = m_pcm->GetRepositoryList();
282
283 m_choiceRepository->Clear();
284
285 for( const auto& [id, url, name] : repositories )
286 m_choiceRepository->Append( url, new wxStringClientData( id ) );
287
288 if( repositories.size() > 1 )
289 m_choiceRepository->Append( _( "-- All repositories --" ), new wxStringClientData( "ALL_REPOSITORIES" ) );
290
291 if( repositories.size() > 0 )
292 {
293 int idx = 0;
294
295 if( cfg && !cfg->m_PcmLastSelectedRepoId.IsEmpty() )
296 {
297 if( cfg->m_PcmLastSelectedRepoId == "ALL_REPOSITORIES" && repositories.size() > 1 )
298 {
299 idx = repositories.size();
300 }
301 else
302 {
303 auto it = std::find_if( repositories.begin(), repositories.end(),
304 [&cfg]( const auto& repo )
305 {
306 return std::get<0>( repo ) == cfg->m_PcmLastSelectedRepoId;
307 } );
308
309 if( it != repositories.end() )
310 idx = std::distance( repositories.begin(), it );
311 }
312 }
313
314 m_choiceRepository->SetSelection( idx );
315 wxStringClientData* data = static_cast<wxStringClientData*>( m_choiceRepository->GetClientObject( idx ) );
316 m_selectedRepositoryId = data->GetData();
318 }
319 else
320 {
322 }
323
324 if( cfg )
326}
327
328
329void DIALOG_PCM::OnRefreshClicked( wxCommandEvent& event )
330{
331 m_pcm->DiscardRepositoryCache( m_selectedRepositoryId );
334}
335
336
337void DIALOG_PCM::OnInstallFromFileClicked( wxCommandEvent& event )
338{
339 wxFileDialog open_file_dialog( this, _( "Install Package" ), wxEmptyString, wxEmptyString,
340 wxT( "Zip files (*.zip)|*.zip" ), wxFD_OPEN | wxFD_FILE_MUST_EXIST );
341
342 KIPLATFORM::UI::AllowNetworkFileSystems( &open_file_dialog );
343
344 if( open_file_dialog.ShowModal() == wxID_CANCEL )
345 return;
346
347 PCM_TASK_MANAGER task_manager( m_pcm );
348 task_manager.InstallFromFile( this, open_file_dialog.GetPath() );
349
350 m_changed_package_types.merge( task_manager.GetChangedPackageTypes() );
351
353
354 if( !m_selectedRepositoryId.IsEmpty() )
356}
357
358
359void DIALOG_PCM::OnRepositoryChoice( wxCommandEvent& event )
360{
361 wxStringClientData* data = static_cast<wxStringClientData*>(
362 m_choiceRepository->GetClientObject( m_choiceRepository->GetSelection() ) );
363
364 m_selectedRepositoryId = data->GetData();
365
368
369 if( KICAD_SETTINGS* cfg = GetAppSettings<KICAD_SETTINGS>( "kicad" ) )
370 cfg->m_PcmLastSelectedRepoId = m_selectedRepositoryId;
371}
372
373
374void DIALOG_PCM::setRepositoryData( const wxString& aRepositoryId )
375{
376 if( aRepositoryId == "ALL_REPOSITORIES" )
377 {
379 return;
380 }
381
382 m_dialogNotebook->Freeze();
383
384 for( const auto& [packageType, packagesView] : m_repositoryContentPanels )
385 packagesView->ClearData();
386
387 std::unordered_map<wxString, PCM_PACKAGE> packagesMap;
388 std::unordered_map<wxString, wxString> repoIds;
389 std::unordered_map<wxString, wxString> repoNames;
390
391 if( m_pcm->CacheRepository( aRepositoryId ) )
392 {
393 m_packageBitmaps = m_pcm->GetRepositoryPackageBitmaps( aRepositoryId );
394 wxString repoName = m_choiceRepository->GetStringSelection();
395
396 for( const PCM_PACKAGE& pkg : m_pcm->GetRepositoryPackages( aRepositoryId ) )
397 {
398 if( pkg.type == PT_INVALID )
399 continue;
400
401 packagesMap[pkg.identifier] = pkg;
402 repoIds[pkg.identifier] = aRepositoryId;
403 repoNames[pkg.identifier] = repoName;
404 }
405 }
406
407 renderPackageGrids( packagesMap, repoIds, repoNames );
408
409 m_dialogNotebook->Thaw();
410}
411
413{
414 m_dialogNotebook->Freeze();
415
416 for( const auto& [packageType, packagesView] : m_repositoryContentPanels )
417 packagesView->ClearData();
418
419 std::unordered_map<wxString, PCM_PACKAGE> bestPackages;
420 std::unordered_map<wxString, wxString> bestRepositoryId;
421 std::unordered_map<wxString, wxString> bestRepositoryName;
422
423 m_packageBitmaps.clear();
424
425 for( const auto& [repo_id, repo_url, repo_name] : m_pcm->GetRepositoryList() )
426 {
427 if( !m_pcm->CacheRepository( repo_id ) )
428 continue;
429
430 std::unordered_map<wxString, wxBitmap> repo_bitmaps = m_pcm->GetRepositoryPackageBitmaps( repo_id );
431 const std::vector<PCM_PACKAGE> packages = m_pcm->GetRepositoryPackages( repo_id );
432
433 for( const PCM_PACKAGE& pkg : packages )
434 {
435 if( pkg.type == PT_INVALID )
436 continue;
437
438 bool isBetter = false;
439 auto it = bestPackages.find( pkg.identifier );
440
441 if( it == bestPackages.end() )
442 {
443 isBetter = true;
444 }
445 else
446 {
447 const PCM_PACKAGE& best = it->second;
448 if( !pkg.versions.empty() && !best.versions.empty() )
449 {
450 if( pkg.versions[0].parsed_version > best.versions[0].parsed_version )
451 isBetter = true;
452 }
453 }
454
455 if( isBetter )
456 {
457 bestPackages[pkg.identifier] = pkg;
458 bestRepositoryId[pkg.identifier] = repo_id;
459 bestRepositoryName[pkg.identifier] = repo_name;
460
461 if( repo_bitmaps.count( pkg.identifier ) > 0 )
462 m_packageBitmaps[pkg.identifier] = repo_bitmaps.at( pkg.identifier );
463 }
464 }
465 }
466
467 renderPackageGrids( bestPackages, bestRepositoryId, bestRepositoryName );
468
469 m_dialogNotebook->Thaw();
470}
471
472
473void DIALOG_PCM::renderPackageGrids( const std::unordered_map<wxString, PCM_PACKAGE>& aPackages,
474 const std::unordered_map<wxString, wxString>& aPackageRepoIds,
475 const std::unordered_map<wxString, wxString>& aPackageRepoNames )
476{
477 std::unordered_map<PCM_PACKAGE_TYPE, std::vector<PACKAGE_VIEW_DATA>> data;
478 int totalPackages = 0;
479
480 for( const auto& [pkg_id, best_pkg] : aPackages )
481 {
482 wxString repo_id = aPackageRepoIds.at( pkg_id );
483 wxString repo_name = aPackageRepoNames.at( pkg_id );
484
485 PACKAGE_VIEW_DATA package_data( best_pkg );
486
487 if( m_packageBitmaps.count( package_data.package.identifier ) > 0 )
488 package_data.bitmap = &m_packageBitmaps.at( package_data.package.identifier );
489 else
490 package_data.bitmap = &m_defaultBitmap;
491
492 package_data.state = m_pcm->GetPackageState( repo_id, pkg_id );
493
494 if( package_data.state == PPS_INSTALLED || package_data.state == PPS_UPDATE_AVAILABLE )
495 {
496 package_data.current_version = m_pcm->GetInstalledPackageVersion( pkg_id );
497 package_data.pinned = m_pcm->IsPackagePinned( pkg_id );
498 package_data.swig_warning = m_pcm->UsesSWIGRuntime( best_pkg, package_data.current_version );
499 }
500 else if( !best_pkg.versions.empty() )
501 {
502 package_data.swig_warning = m_pcm->UsesSWIGRuntime( best_pkg, best_pkg.versions[0].version );
503 }
504
505 if( package_data.state == PPS_UPDATE_AVAILABLE )
506 package_data.update_version = m_pcm->GetPackageUpdateVersion( best_pkg );
507
508 for( const PENDING_ACTION& action : m_pendingActions )
509 {
510 if( action.package.identifier != pkg_id )
511 continue;
512
513 switch( action.action )
514 {
515 case PPA_INSTALL: package_data.state = PPS_PENDING_INSTALL; break;
516 case PPA_UPDATE: package_data.state = PPS_PENDING_UPDATE; break;
517 case PPA_UNINSTALL: package_data.state = PPS_PENDING_UNINSTALL; break;
518 }
519
520 break;
521 }
522
523 package_data.repository_id = repo_id;
524 package_data.repository_name = repo_name;
525
526 // Fabrication plugins are displayed in a different tab although they are still plugins
527 PCM_PACKAGE_TYPE type = best_pkg.category == PC_FAB ? PT_FAB : best_pkg.type;
528 data[type].emplace_back( package_data );
529 totalPackages++;
530 }
531
532 for( size_t i = 0; i < PACKAGE_TYPE_LIST.size(); i++ )
533 {
534 PCM_PACKAGE_TYPE type = PACKAGE_TYPE_LIST[i].first;
535 const wxString& label = PACKAGE_TYPE_LIST[i].second;
536 m_repositoryContentPanels[type]->SetData( data[type] );
537 m_contentNotebook->SetPageText( i, wxString::Format( wxGetTranslation( label ), (int) data[type].size() ) );
538 }
539
540 m_dialogNotebook->SetPageText( 0, wxString::Format( _( "Repository (%d)" ), totalPackages ) );
541}
542
543
545{
546 m_gridPendingActions->ClearSelection();
547 m_gridPendingActions->SelectRow( event.GetRow() );
548}
549
550
552{
553 m_dialogNotebook->SetPageText( 2, wxString::Format( _( "Pending (%d)" ),
554 (int) m_pendingActions.size() ) );
555
556 for( int col = 0; col < m_gridPendingActions->GetNumberCols(); col++ )
557 {
558 // Set the width to see the full contents
559 m_gridPendingActions->SetColSize( col, m_gridPendingActions->GetVisibleWidth( col ) );
560 }
561}
562
563
565{
566 m_installedPanel->ClearData();
567
568 // This rewrites stale repository ids and refreshes package metadata, so it has to run
569 // before the entries are copied into the view data
570 m_pcm->ResolveInstalledPackageRepositories();
571
572 const std::vector<PCM_INSTALLATION_ENTRY> installed = m_pcm->GetInstalledPackages();
573 std::vector<PACKAGE_VIEW_DATA> package_list;
574
575 m_installedBitmaps = m_pcm->GetInstalledPackageBitmaps();
576
577 for( const PCM_INSTALLATION_ENTRY& entry : installed )
578 {
579 PACKAGE_VIEW_DATA package_data( entry );
580
581 if( m_installedBitmaps.count( package_data.package.identifier ) > 0 )
582 package_data.bitmap = &m_installedBitmaps.at( package_data.package.identifier );
583 else
584 package_data.bitmap = &m_defaultBitmap;
585
586 package_data.state = m_pcm->GetPackageState( entry.repository_id,
587 entry.package.identifier );
588
589 package_data.swig_warning = m_pcm->UsesSWIGRuntime( entry.package, entry.current_version );
590
591 if( package_data.state == PPS_UPDATE_AVAILABLE )
592 package_data.update_version = m_pcm->GetPackageUpdateVersion( entry.package );
593
594 package_list.emplace_back( package_data );
595 }
596
597 m_installedPanel->SetData( package_list );
598
599 m_dialogNotebook->SetPageText( 1, wxString::Format( _( "Installed (%d)" ),
600 (int) package_list.size() ) );
601}
602
603
604void DIALOG_PCM::OnApplyChangesClicked( wxCommandEvent& event )
605{
606 if( m_pendingActions.size() == 0 )
607 return;
608
609 m_sdbSizer1OK->Disable();
610 m_sdbSizer1Apply->Disable();
611 m_sdbSizer1Cancel->Disable();
612
613 PCM_TASK_MANAGER task_manager( m_pcm );
614
615 for( const PENDING_ACTION& action : m_pendingActions )
616 {
617 if( action.action == PPA_UNINSTALL )
618 {
619 task_manager.Uninstall( action.package );
620 }
621 else
622 {
623 bool isUpdate = action.action == PPA_UPDATE;
624 task_manager.DownloadAndInstall( action.package, action.version, action.repository_id,
625 isUpdate );
626 }
627 }
628
629 task_manager.RunQueue( this );
630
631 m_changed_package_types.merge( task_manager.GetChangedPackageTypes() );
632
633 m_sdbSizer1OK->Enable();
634 m_sdbSizer1Apply->Enable();
635 m_sdbSizer1Cancel->Enable();
636
638 wxCommandEvent dummy;
640
641 if( !m_selectedRepositoryId.IsEmpty() )
643}
644
645
646void DIALOG_PCM::OnDiscardChangesClicked( wxCommandEvent& event )
647{
648 m_gridPendingActions->Freeze();
649
650 for( int i = m_pendingActions.size() - 1; i >= 0; i-- )
651 discardAction( i );
652
654 m_gridPendingActions->Thaw();
655}
656
657
658void DIALOG_PCM::OnDiscardActionClicked( wxCommandEvent& event )
659{
660 wxArrayInt rows = m_gridPendingActions->GetSelectedRows();
661
662 std::sort( rows.begin(), rows.end(),
663 []( const int& a, const int& b )
664 {
665 return a > b;
666 } );
667
668 m_gridPendingActions->Freeze();
669
670 for( int row : rows )
671 discardAction( row );
672
674 m_gridPendingActions->Thaw();
675}
676
677
679{
680 m_gridPendingActions->DeleteRows( aIndex );
681
682 PENDING_ACTION action = m_pendingActions[aIndex];
683
684 PCM_PACKAGE_STATE state = m_pcm->GetPackageState( action.repository_id,
685 action.package.identifier );
686
687 updatePackageState( action.package.identifier, state );
688
689 m_pendingActions.erase( m_pendingActions.begin() + aIndex );
690}
691
692
693void DIALOG_PCM::updatePackageState( const wxString& aPackageId, const PCM_PACKAGE_STATE aState )
694{
695 bool pinned = m_pcm->IsPackagePinned( aPackageId );
696
697 m_installedPanel->SetPackageState( aPackageId, aState, pinned );
698
699 for( const auto& [ packageType, packagesView ] : m_repositoryContentPanels )
700 packagesView->SetPackageState( aPackageId, aState, pinned );
701}
702
703
704void DIALOG_PCM::OnOpenPackageDirClicked( wxCommandEvent& event )
705{
706 LaunchExternal( m_pcm->Get3rdPartyPath() );
707}
const char * name
wxBitmap KiBitmap(BITMAPS aBitmap, int aHeightTag)
Construct a wxBitmap from an image identifier Returns the image from the active theme if the image ha...
Definition bitmap.cpp:100
wxBitmapBundle KiBitmapBundle(BITMAPS aBitmap, int aMinHeight)
Definition bitmap.cpp:106
Implementing DIALOG_MANAGE_REPOSITORIES_BASE.
std::vector< std::pair< wxString, wxString > > GetData()
void SetData(const std::vector< std::pair< wxString, wxString > > &aData)
wxChoice * m_choiceRepository
wxNotebook * m_contentNotebook
WX_GRID * m_gridPendingActions
wxButton * m_sdbSizer1OK
wxButton * m_sdbSizer1Cancel
wxBitmapButton * m_discardActionButton
DIALOG_PCM_BASE(wxWindow *parent, wxWindowID id=wxID_ANY, const wxString &title=_("Plugin And Content Manager"), const wxPoint &pos=wxDefaultPosition, const wxSize &size=wxSize(-1,-1), long style=wxDEFAULT_DIALOG_STYLE|wxRESIZE_BORDER)
wxNotebook * m_dialogNotebook
wxButton * m_sdbSizer1Apply
wxPanel * m_panelInstalledHolder
wxPanel * m_panelPending
ActionCallback m_actionCallback
Definition dialog_pcm.h:131
void OnDiscardChangesClicked(wxCommandEvent &event) override
Switches to another repository.
std::unordered_map< wxString, wxBitmap > m_installedBitmaps
Definition dialog_pcm.h:137
std::unordered_map< wxString, wxBitmap > m_packageBitmaps
Definition dialog_pcm.h:136
void OnManageRepositoriesClicked(wxCommandEvent &event) override
Discards current repo cache, fetches it anew and displays.
void updatePackageState(const wxString &aPackageId, const PCM_PACKAGE_STATE aState)
Discards specified pending action.
void OnApplyChangesClicked(wxCommandEvent &event) override
Discards all pending changes.
void OnDiscardActionClicked(wxCommandEvent &event) override
Handles modification of the buttons' status.
void OnUpdateEventButtons(wxUpdateUIEvent &event)
Returns types of packages that were installed/uninstalled.
std::unordered_map< PCM_PACKAGE_TYPE, PANEL_PACKAGES_VIEW * > m_repositoryContentPanels
Definition dialog_pcm.h:134
void OnOpenPackageDirClicked(wxCommandEvent &event) override
Enqueues current pending actions in PCM_TASK_MANAGER and runs the queue.
PinCallback m_pinCallback
Definition dialog_pcm.h:132
void renderPackageGrids(const std::unordered_map< wxString, PCM_PACKAGE > &aPackages, const std::unordered_map< wxString, wxString > &aPackageRepoIds, const std::unordered_map< wxString, wxString > &aPackageRepoNames)
Shared logic to render a given set of packages to the UI notebooks.
std::unordered_set< PCM_PACKAGE_TYPE > m_changed_package_types
Definition dialog_pcm.h:139
void SetActivePackageType(PCM_PACKAGE_TYPE aType)
EDA_BASE_FRAME * m_parentFrame
Definition dialog_pcm.h:129
void setRepositoryDataMulti()
Aggregates and deduplicates packages from all configured repositories.
DIALOG_PCM(EDA_BASE_FRAME *parent, std::shared_ptr< PLUGIN_CONTENT_MANAGER > pcm)
Constructor.
void updatePendingActionsTab()
Gets installed packages list from PCM and displays it on installed tab.
std::vector< PENDING_ACTION > m_pendingActions
Definition dialog_pcm.h:155
void setRepositoryListFromPcm()
Updates pending actions tab caption and content-fits the grid.
void OnInstallFromFileClicked(wxCommandEvent &event) override
Opens local directory where packages are installed in file manager.
@ PENDING_COL_REPOSITORY
Definition dialog_pcm.h:162
@ PENDING_COL_VERSION
Definition dialog_pcm.h:161
@ PENDING_COL_ACTION
Definition dialog_pcm.h:159
void OnCloseWindow(wxCloseEvent &aEvent)
Opens repository management dialog, saves changes to PCM.
std::shared_ptr< PLUGIN_CONTENT_MANAGER > m_pcm
Definition dialog_pcm.h:130
void OnRepositoryChoice(wxCommandEvent &event) override
Selects the whole row in the grid if a cell is clicked.
wxString m_selectedRepositoryId
Definition dialog_pcm.h:135
PANEL_PACKAGES_VIEW * m_installedPanel
Definition dialog_pcm.h:133
void setInstalledPackages()
Reflects new state of the package in all panels where it is displayed.
void OnPendingActionsCellClicked(wxGridEvent &event) override
Discards selected pending actions.
void setRepositoryData(const wxString &aRepositoryId)
Gets package data from PCM and displays it on repository tab.
void discardAction(int aIndex)
wxBitmap m_defaultBitmap
Definition dialog_pcm.h:138
void OnRefreshClicked(wxCommandEvent &event) override
Opens file selection dialog and installs selected package archive.
void OnCloseClicked(wxCommandEvent &event) override
void SetupStandardButtons(std::map< int, wxString > aLabels={})
void finishDialogSettings()
In all dialogs, we must call the same functions to fix minimal dlg size, the default position and per...
int ShowModal() override
The base frame for deriving all KiCad main window classes.
Add mouse and command handling (such as cut, copy, and paste) to a WX_GRID instance.
Definition grid_tricks.h:57
wxString m_PcmLastSelectedRepoId
Helper class that handles package (un)installation.
std::unordered_set< PCM_PACKAGE_TYPE > & GetChangedPackageTypes()
PCM_TASK_MANAGER::STATUS DownloadAndInstall(const PCM_PACKAGE &aPackage, const wxString &aVersion, const wxString &aRepositoryId, const bool isUpdate)
Enqueue package download and installation.
void RunQueue(wxWindow *aParent)
Run queue of pending actions.
PCM_TASK_MANAGER::STATUS Uninstall(const PCM_PACKAGE &aPackage)
Enqueue package uninstallation.
PCM_TASK_MANAGER::STATUS InstallFromFile(wxWindow *aParent, const wxString &aFilePath)
Installs package from an archive file on disk.
#define GRID_CELL_MARGIN
static std::vector< std::pair< PCM_PACKAGE_TYPE, wxString > > PACKAGE_TYPE_LIST
#define _(s)
Base window classes and related definitions.
bool LaunchExternal(const wxString &aPath)
Launches the given file or folder in the host OS.
void AllowNetworkFileSystems(wxDialog *aDialog)
Configure a file dialog to show network and virtual file systems.
Definition wxgtk/ui.cpp:521
PCM_PACKAGE_STATE
Definition pcm.h:58
@ PPS_INSTALLED
Definition pcm.h:61
@ PPS_PENDING_UPDATE
Definition pcm.h:65
@ PPS_UPDATE_AVAILABLE
Definition pcm.h:64
@ PPS_PENDING_UNINSTALL
Definition pcm.h:63
@ PPS_PENDING_INSTALL
Definition pcm.h:62
PCM_PACKAGE_ACTION
Definition pcm.h:71
@ PPA_UNINSTALL
Definition pcm.h:73
@ PPA_UPDATE
Definition pcm.h:74
@ PPA_INSTALL
Definition pcm.h:72
@ PC_FAB
Definition pcm_data.h:56
PCM_PACKAGE_TYPE
< Supported package types
Definition pcm_data.h:42
@ PT_DATASOURCE
Definition pcm_data.h:47
@ PT_COLORTHEME
Definition pcm_data.h:48
@ PT_INVALID
Definition pcm_data.h:43
@ PT_PLUGIN
Definition pcm_data.h:44
@ PT_LIBRARY
Definition pcm_data.h:46
@ PT_FAB
Definition pcm_data.h:45
see class PGM_BASE
T * GetAppSettings(const char *aFilename)
std::vector< FAB_LAYER_COLOR > dummy
< Collection of data relevant to the package display panelCallback for (un)install button
wxString update_version
wxString current_version
const PCM_PACKAGE package
wxString repository_name
PCM_PACKAGE_STATE state
Definition pcm_data.h:159
Repository reference to a resource.
Definition pcm_data.h:114
wxString identifier
Definition pcm_data.h:118
wxString name
Definition pcm_data.h:115
std::vector< PACKAGE_VERSION > versions
Definition pcm_data.h:127