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#define ALL_REPOSITORIES wxT( "ALL_REPOSITORIES" )
49
50// Notes: These strings are static, so wxGetTranslation must be called to display the
51// transalted text
52static std::vector<std::pair<PCM_PACKAGE_TYPE, wxString>> PACKAGE_TYPE_LIST = {
53 { PT_PLUGIN, _( "Plugins (%d)" ) },
54 { PT_FAB, _( "Fabrication plugins (%d)" ) },
55 { PT_LIBRARY, _( "Libraries (%d)" ) },
56 { PT_DATASOURCE, _( "Data sources (%d)" ) },
57 { PT_COLORTHEME, _( "Color themes (%d)" ) },
58};
59
60
61DIALOG_PCM::DIALOG_PCM( EDA_BASE_FRAME* parent, std::shared_ptr<PLUGIN_CONTENT_MANAGER> pcm ) :
62 DIALOG_PCM_BASE( parent ),
63 m_parentFrame( parent ),
64 m_pcm( pcm )
65{
66 // correct the min size from wxfb with fromdip
67 SetMinSize( FromDIP( GetMinSize() ) );
68
69 SetDoubleBuffered( true );
70
72
73 m_pcm->SetDialogWindow( this );
74 m_pcm->StopBackgroundUpdate();
75
76 m_gridPendingActions->PushEventHandler( new GRID_TRICKS( m_gridPendingActions ) );
77
79 m_panelPending->Layout();
80
81 m_actionCallback = [this]( const PACKAGE_VIEW_DATA& aData, PCM_PACKAGE_ACTION aAction,
82 const wxString& aVersion )
83 {
84 if( aAction == PPA_UPDATE && m_pcm->IsPackagePinned( aData.package.identifier ) )
85 {
86 if( wxMessageBox( wxString::Format( _( "Are you sure you want to update pinned package "
87 "from version %s to %s?" ),
88 aData.current_version, aVersion ),
89 _( "Confirm update" ), wxICON_QUESTION | wxYES_NO, this )
90 == wxNO )
91 {
92 return;
93 }
94 }
95
96 m_gridPendingActions->Freeze();
97
98 PCM_PACKAGE_STATE new_state;
99
100 m_gridPendingActions->AppendRows();
101 int row = m_gridPendingActions->GetNumberRows() - 1;
102
103 m_gridPendingActions->SetCellValue( row, PENDING_COL_NAME, aData.package.name );
105
106 switch( aAction )
107 {
108 default:
109 case PPA_INSTALL:
110 m_gridPendingActions->SetCellValue( row, PENDING_COL_ACTION, _( "Install" ) );
111 m_gridPendingActions->SetCellValue( row, PENDING_COL_VERSION, aVersion );
112 new_state = PPS_PENDING_INSTALL;
113 break;
114
115 case PPA_UPDATE:
116 m_gridPendingActions->SetCellValue( row, PENDING_COL_ACTION, _( "Update" ) );
117 m_gridPendingActions->SetCellValue( row, PENDING_COL_VERSION,
118 wxString::Format( wxT( "%s \u279C %s" ),
119 aData.current_version,
120 aVersion ) );
121 new_state = PPS_PENDING_UPDATE;
122 break;
123
124 case PPA_UNINSTALL:
125 m_gridPendingActions->SetCellValue( row, PENDING_COL_ACTION, _( "Uninstall" ) );
126 m_gridPendingActions->SetCellValue( row, PENDING_COL_VERSION,
127 m_pcm->GetInstalledPackageVersion( aData.package.identifier ) );
128 new_state = PPS_PENDING_UNINSTALL;
129 break;
130 }
131
132 m_pendingActions.emplace_back( aAction, aData.repository_id, aData.package, aVersion );
133
134 m_gridPendingActions->Thaw();
135
137
138 updatePackageState( aData.package.identifier, new_state );
139 };
140
142 [this]( const wxString& aPackageId, const PCM_PACKAGE_STATE aState, const bool aPinned )
143 {
144 m_pcm->SetPinned( aPackageId, aPinned );
145
146 updatePackageState( aPackageId, aState );
147 };
148
150 m_panelInstalledHolder->GetSizer()->Add( m_installedPanel, 1, wxEXPAND );
151 m_panelInstalledHolder->Layout();
152
153 for( const std::pair<PCM_PACKAGE_TYPE, wxString>& entry : PACKAGE_TYPE_LIST )
154 {
157 wxString label = wxGetTranslation( entry.second );
158 m_contentNotebook->AddPage( panel, wxString::Format( label, 0 ) );
159 m_repositoryContentPanels.insert( { entry.first, panel } );
160 }
161
162 m_dialogNotebook->SetPageText( 0, wxString::Format( _( "Repository (%d)" ), 0 ) );
163
166
167 m_dialogNotebook->SetSelection( 0 );
168
169 SetupStandardButtons( { { wxID_OK, _( "Close" ) },
170 { wxID_APPLY, _( "Apply Pending Changes" ) },
171 { wxID_CANCEL, _( "Discard Pending Changes" ) } } );
172
173 Bind( wxEVT_CLOSE_WINDOW, &DIALOG_PCM::OnCloseWindow, this );
174 m_sdbSizer1Cancel->Bind( wxEVT_UPDATE_UI, &DIALOG_PCM::OnUpdateEventButtons, this );
175 m_sdbSizer1Apply->Bind( wxEVT_UPDATE_UI, &DIALOG_PCM::OnUpdateEventButtons, this );
176
177 // Has to be called after DIALOG_SHIM reads cached values
178 CallAfter(
179 [this]()
180 {
182 } );
183
184 for( int col = 0; col < m_gridPendingActions->GetNumberCols(); col++ )
185 {
186 const wxString& heading = m_gridPendingActions->GetColLabelValue( col );
187 int headingWidth = GetTextExtent( heading ).x + 2 * GRID_CELL_MARGIN;
188
189 // Set the minimal width to the column label size.
190 m_gridPendingActions->SetColMinimalWidth( col, headingWidth );
191 }
192
193 // fix sizers now widgets are set.
195}
196
197
199{
200 Unbind( wxEVT_CLOSE_WINDOW, &DIALOG_PCM::OnCloseWindow, this );
201 m_sdbSizer1Cancel->Unbind( wxEVT_UPDATE_UI, &DIALOG_PCM::OnUpdateEventButtons, this );
202 m_sdbSizer1Apply->Unbind( wxEVT_UPDATE_UI, &DIALOG_PCM::OnUpdateEventButtons, this );
203
204 m_pcm->SaveInstalledPackages();
205 m_pcm->SetDialogWindow( nullptr );
206 m_pcm->RunBackgroundUpdate();
207
208 m_gridPendingActions->PopEventHandler( true );
209}
210
211
213{
214 for( size_t i = 0; i < PACKAGE_TYPE_LIST.size(); ++i )
215 {
216 if( PACKAGE_TYPE_LIST[i].first == aType )
217 {
218 m_contentNotebook->SetSelection( i );
219 break;
220 }
221 }
222}
223
224
225void DIALOG_PCM::OnUpdateEventButtons( wxUpdateUIEvent& event )
226{
227 event.Enable( !m_pendingActions.empty() );
228}
229
230
231void DIALOG_PCM::OnCloseClicked( wxCommandEvent& event )
232{
233 if( m_pendingActions.size() == 0
234 || wxMessageBox( _( "Are you sure you want to close the package manager and discard pending changes?" ),
235 _( "Plugin and Content Manager" ), wxICON_QUESTION | wxYES_NO, this )
236 == wxYES )
237 {
238 EndModal( wxID_OK );
239 }
240}
241
242
243void DIALOG_PCM::OnCloseWindow( wxCloseEvent& aEvent )
244{
245 wxCommandEvent dummy;
246
248}
249
250
251void DIALOG_PCM::OnManageRepositoriesClicked( wxCommandEvent& event )
252{
254
255 std::vector<std::pair<wxString, wxString>> dialog_data;
256 std::vector<std::tuple<wxString, wxString, wxString>> repo_list = m_pcm->GetRepositoryList();
257
258 for( const auto& [id, url, name] : repo_list )
259 dialog_data.push_back( std::make_pair( url, name ) );
260
261 dialog->SetData( dialog_data );
262
263 if( dialog->ShowModal() == wxID_SAVE )
264 {
265 dialog_data = dialog->GetData();
266 m_pcm->SetRepositoryList( dialog_data );
267
268 if( KICAD_SETTINGS* cfg = GetAppSettings<KICAD_SETTINGS>( "kicad" ) )
269 cfg->m_PcmRepositories = std::move( dialog_data );
270
273 }
274
275 dialog->Destroy();
276}
277
278
280{
281 std::vector<std::tuple<wxString, wxString, wxString>> repositories = m_pcm->GetRepositoryList();
283
284 m_choiceRepository->Clear();
285
286 for( const auto& [id, url, name] : repositories )
287 m_choiceRepository->Append( url, new wxStringClientData( id ) );
288
289 if( repositories.size() > 1 )
290 m_choiceRepository->Append( _( "-- All repositories --" ), new wxStringClientData( ALL_REPOSITORIES ) );
291
292 if( repositories.size() > 0 )
293 {
294 int idx = 0;
295
296 if( cfg && !cfg->m_PcmLastSelectedRepoId.IsEmpty() )
297 {
298 if( cfg->m_PcmLastSelectedRepoId == ALL_REPOSITORIES && repositories.size() > 1 )
299 {
300 idx = (int) repositories.size();
301 }
302 else
303 {
304 auto it = std::find_if( repositories.begin(), repositories.end(),
305 [&cfg]( const auto& repo )
306 {
307 return std::get<0>( repo ) == cfg->m_PcmLastSelectedRepoId;
308 } );
309
310 if( it != repositories.end() )
311 idx = (int) std::distance( repositories.begin(), it );
312 }
313 }
314
315 m_choiceRepository->SetSelection( idx );
316 wxStringClientData* data = static_cast<wxStringClientData*>( m_choiceRepository->GetClientObject( idx ) );
317 m_selectedRepositoryId = data->GetData();
318
321 else
323 }
324 else
325 {
327 }
328
329 if( cfg )
331}
332
333
334void DIALOG_PCM::OnRefreshClicked( wxCommandEvent& event )
335{
337 {
338 m_pcm->DiscardAllRepositoryCaches();
340 }
341 else
342 {
343 m_pcm->DiscardRepositoryCache( m_selectedRepositoryId );
345 }
346
348}
349
350
351void DIALOG_PCM::OnInstallFromFileClicked( wxCommandEvent& event )
352{
353 wxFileDialog open_file_dialog( this, _( "Install Package" ), wxEmptyString, wxEmptyString,
354 wxT( "Zip files (*.zip)|*.zip" ), wxFD_OPEN | wxFD_FILE_MUST_EXIST );
355
356 KIPLATFORM::UI::AllowNetworkFileSystems( &open_file_dialog );
357
358 if( open_file_dialog.ShowModal() == wxID_CANCEL )
359 return;
360
361 PCM_TASK_MANAGER task_manager( m_pcm );
362 task_manager.InstallFromFile( this, open_file_dialog.GetPath() );
363
364 m_changed_package_types.merge( task_manager.GetChangedPackageTypes() );
365
367
370 else if( !m_selectedRepositoryId.IsEmpty() )
372}
373
374
375void DIALOG_PCM::OnRepositoryChoice( wxCommandEvent& event )
376{
377 wxStringClientData* data = static_cast<wxStringClientData*>(
378 m_choiceRepository->GetClientObject( m_choiceRepository->GetSelection() ) );
379
380 m_selectedRepositoryId = data->GetData();
381
384 else
386
388
389 if( KICAD_SETTINGS* cfg = GetAppSettings<KICAD_SETTINGS>( "kicad" ) )
390 cfg->m_PcmLastSelectedRepoId = m_selectedRepositoryId;
391}
392
393
394void DIALOG_PCM::setRepositoryData( const wxString& aRepositoryId )
395{
396 wxCHECK2_MSG( aRepositoryId != ALL_REPOSITORIES, return, wxT( "should have been handled higher up" ) );
397
398 m_dialogNotebook->Freeze();
399
400 for( const auto& [packageType, packagesView] : m_repositoryContentPanels )
401 packagesView->ClearData();
402
403 std::unordered_map<wxString, PCM_PACKAGE> packagesMap;
404 std::unordered_map<wxString, wxString> repoIds;
405 std::unordered_map<wxString, wxString> repoNames;
406
407 if( m_pcm->CacheRepository( aRepositoryId ) )
408 {
409 m_packageBitmaps = m_pcm->GetRepositoryPackageBitmaps( aRepositoryId );
410 wxString repoName = m_choiceRepository->GetStringSelection();
411
412 for( const PCM_PACKAGE& pkg : m_pcm->GetRepositoryPackages( aRepositoryId ) )
413 {
414 if( pkg.type == PT_INVALID )
415 continue;
416
417 packagesMap[pkg.identifier] = pkg;
418 repoIds[pkg.identifier] = aRepositoryId;
419 repoNames[pkg.identifier] = repoName;
420 }
421 }
422
423 renderPackageGrids( packagesMap, repoIds, repoNames );
424
425 m_dialogNotebook->Thaw();
426}
427
429{
430 m_dialogNotebook->Freeze();
431
432 for( const auto& [packageType, packagesView] : m_repositoryContentPanels )
433 packagesView->ClearData();
434
435 std::unordered_map<wxString, PCM_PACKAGE> bestPackages;
436 std::unordered_map<wxString, wxString> bestRepositoryId;
437 std::unordered_map<wxString, wxString> bestRepositoryName;
438
439 m_packageBitmaps.clear();
440
441 for( const auto& [repo_id, repo_url, repo_name] : m_pcm->GetRepositoryList() )
442 {
443 if( !m_pcm->CacheRepository( repo_id ) )
444 continue;
445
446 std::unordered_map<wxString, wxBitmap> repo_bitmaps = m_pcm->GetRepositoryPackageBitmaps( repo_id );
447 const std::vector<PCM_PACKAGE> packages = m_pcm->GetRepositoryPackages( repo_id );
448
449 for( const PCM_PACKAGE& pkg : packages )
450 {
451 if( pkg.type == PT_INVALID )
452 continue;
453
454 bool isBetter = false;
455 auto it = bestPackages.find( pkg.identifier );
456
457 if( it == bestPackages.end() )
458 {
459 isBetter = true;
460 }
461 else
462 {
463 const PCM_PACKAGE& best = it->second;
464 if( !pkg.versions.empty() && !best.versions.empty() )
465 {
466 if( pkg.versions[0].parsed_version > best.versions[0].parsed_version )
467 isBetter = true;
468 }
469 }
470
471 if( isBetter )
472 {
473 bestPackages[pkg.identifier] = pkg;
474 bestRepositoryId[pkg.identifier] = repo_id;
475 bestRepositoryName[pkg.identifier] = repo_name;
476
477 if( repo_bitmaps.count( pkg.identifier ) > 0 )
478 m_packageBitmaps[pkg.identifier] = repo_bitmaps.at( pkg.identifier );
479 }
480 }
481 }
482
483 renderPackageGrids( bestPackages, bestRepositoryId, bestRepositoryName );
484
485 m_dialogNotebook->Thaw();
486}
487
488
489void DIALOG_PCM::renderPackageGrids( const std::unordered_map<wxString, PCM_PACKAGE>& aPackages,
490 const std::unordered_map<wxString, wxString>& aPackageRepoIds,
491 const std::unordered_map<wxString, wxString>& aPackageRepoNames )
492{
493 std::unordered_map<PCM_PACKAGE_TYPE, std::vector<PACKAGE_VIEW_DATA>> data;
494 int totalPackages = 0;
495
496 for( const auto& [pkg_id, best_pkg] : aPackages )
497 {
498 const wxString& repo_id = aPackageRepoIds.at( pkg_id );
499 const wxString& repo_name = aPackageRepoNames.at( pkg_id );
500
501 PACKAGE_VIEW_DATA package_data( best_pkg );
502
503 if( m_packageBitmaps.count( package_data.package.identifier ) > 0 )
504 package_data.bitmap = &m_packageBitmaps.at( package_data.package.identifier );
505 else
506 package_data.bitmap = &m_defaultBitmap;
507
508 package_data.state = m_pcm->GetPackageState( repo_id, pkg_id );
509
510 if( package_data.state == PPS_INSTALLED || package_data.state == PPS_UPDATE_AVAILABLE )
511 {
512 package_data.current_version = m_pcm->GetInstalledPackageVersion( pkg_id );
513 package_data.pinned = m_pcm->IsPackagePinned( pkg_id );
514 package_data.swig_warning = m_pcm->UsesSWIGRuntime( best_pkg, package_data.current_version );
515 }
516 else if( !best_pkg.versions.empty() )
517 {
518 package_data.swig_warning = m_pcm->UsesSWIGRuntime( best_pkg, best_pkg.versions[0].version );
519 }
520
521 if( package_data.state == PPS_UPDATE_AVAILABLE )
522 package_data.update_version = m_pcm->GetPackageUpdateVersion( best_pkg );
523
524 for( const PENDING_ACTION& action : m_pendingActions )
525 {
526 if( action.package.identifier != pkg_id )
527 continue;
528
529 switch( action.action )
530 {
531 case PPA_INSTALL: package_data.state = PPS_PENDING_INSTALL; break;
532 case PPA_UPDATE: package_data.state = PPS_PENDING_UPDATE; break;
533 case PPA_UNINSTALL: package_data.state = PPS_PENDING_UNINSTALL; break;
534 }
535
536 break;
537 }
538
539 package_data.repository_id = repo_id;
540 package_data.repository_name = repo_name;
541
542 // Fabrication plugins are displayed in a different tab although they are still plugins
543 PCM_PACKAGE_TYPE type = best_pkg.category == PC_FAB ? PT_FAB : best_pkg.type;
544 data[type].emplace_back( package_data );
545 totalPackages++;
546 }
547
548 for( size_t i = 0; i < PACKAGE_TYPE_LIST.size(); i++ )
549 {
550 PCM_PACKAGE_TYPE type = PACKAGE_TYPE_LIST[i].first;
551 const wxString& label = PACKAGE_TYPE_LIST[i].second;
552 m_repositoryContentPanels[type]->SetData( data[type] );
553 m_contentNotebook->SetPageText( i, wxString::Format( wxGetTranslation( label ), (int) data[type].size() ) );
554 }
555
556 m_dialogNotebook->SetPageText( 0, wxString::Format( _( "Repository (%d)" ), totalPackages ) );
557}
558
559
561{
562 m_gridPendingActions->ClearSelection();
563 m_gridPendingActions->SelectRow( event.GetRow() );
564}
565
566
568{
569 m_dialogNotebook->SetPageText( 2, wxString::Format( _( "Pending (%d)" ),
570 (int) m_pendingActions.size() ) );
571
572 for( int col = 0; col < m_gridPendingActions->GetNumberCols(); col++ )
573 {
574 // Set the width to see the full contents
575 m_gridPendingActions->SetColSize( col, m_gridPendingActions->GetVisibleWidth( col ) );
576 }
577}
578
579
581{
582 m_installedPanel->ClearData();
583
584 // This rewrites stale repository ids and refreshes package metadata, so it has to run
585 // before the entries are copied into the view data
586 m_pcm->ResolveInstalledPackageRepositories();
587
588 const std::vector<PCM_INSTALLATION_ENTRY> installed = m_pcm->GetInstalledPackages();
589 std::vector<PACKAGE_VIEW_DATA> package_list;
590
591 m_installedBitmaps = m_pcm->GetInstalledPackageBitmaps();
592
593 for( const PCM_INSTALLATION_ENTRY& entry : installed )
594 {
595 PACKAGE_VIEW_DATA package_data( entry );
596
597 if( m_installedBitmaps.count( package_data.package.identifier ) > 0 )
598 package_data.bitmap = &m_installedBitmaps.at( package_data.package.identifier );
599 else
600 package_data.bitmap = &m_defaultBitmap;
601
602 package_data.state = m_pcm->GetPackageState( entry.repository_id,
603 entry.package.identifier );
604
605 package_data.swig_warning = m_pcm->UsesSWIGRuntime( entry.package, entry.current_version );
606
607 if( package_data.state == PPS_UPDATE_AVAILABLE )
608 package_data.update_version = m_pcm->GetPackageUpdateVersion( entry.package );
609
610 package_list.emplace_back( package_data );
611 }
612
613 m_installedPanel->SetData( package_list );
614
615 m_dialogNotebook->SetPageText( 1, wxString::Format( _( "Installed (%d)" ),
616 (int) package_list.size() ) );
617}
618
619
620void DIALOG_PCM::OnApplyChangesClicked( wxCommandEvent& event )
621{
622 if( m_pendingActions.size() == 0 )
623 return;
624
625 m_sdbSizer1OK->Disable();
626 m_sdbSizer1Apply->Disable();
627 m_sdbSizer1Cancel->Disable();
628
629 PCM_TASK_MANAGER task_manager( m_pcm );
630
631 for( const PENDING_ACTION& action : m_pendingActions )
632 {
633 if( action.action == PPA_UNINSTALL )
634 {
635 task_manager.Uninstall( action.package );
636 }
637 else
638 {
639 bool isUpdate = action.action == PPA_UPDATE;
640 task_manager.DownloadAndInstall( action.package, action.version, action.repository_id, isUpdate );
641 }
642 }
643
644 task_manager.RunQueue( this );
645
646 m_changed_package_types.merge( task_manager.GetChangedPackageTypes() );
647
648 m_sdbSizer1OK->Enable();
649 m_sdbSizer1Apply->Enable();
650 m_sdbSizer1Cancel->Enable();
651
653 wxCommandEvent dummy;
655
658 else if( !m_selectedRepositoryId.IsEmpty() )
660}
661
662
663void DIALOG_PCM::OnDiscardChangesClicked( wxCommandEvent& event )
664{
665 m_gridPendingActions->Freeze();
666
667 for( int i = (int) m_pendingActions.size() - 1; i >= 0; i-- )
668 discardAction( i );
669
671 m_gridPendingActions->Thaw();
672}
673
674
675void DIALOG_PCM::OnDiscardActionClicked( wxCommandEvent& event )
676{
677 wxArrayInt rows = m_gridPendingActions->GetSelectedRows();
678
679 std::sort( rows.begin(), rows.end(),
680 []( const int& a, const int& b )
681 {
682 return a > b;
683 } );
684
685 m_gridPendingActions->Freeze();
686
687 for( int row : rows )
688 discardAction( row );
689
691 m_gridPendingActions->Thaw();
692}
693
694
696{
697 m_gridPendingActions->DeleteRows( aIndex );
698
699 PENDING_ACTION action = m_pendingActions[aIndex];
700
701 PCM_PACKAGE_STATE state = m_pcm->GetPackageState( action.repository_id,
702 action.package.identifier );
703
704 updatePackageState( action.package.identifier, state );
705
706 m_pendingActions.erase( m_pendingActions.begin() + aIndex );
707}
708
709
710void DIALOG_PCM::updatePackageState( const wxString& aPackageId, const PCM_PACKAGE_STATE aState )
711{
712 bool pinned = m_pcm->IsPackagePinned( aPackageId );
713
714 m_installedPanel->SetPackageState( aPackageId, aState, pinned );
715
716 for( const auto& [ packageType, packagesView ] : m_repositoryContentPanels )
717 packagesView->SetPackageState( aPackageId, aState, pinned );
718}
719
720
721void DIALOG_PCM::OnOpenPackageDirClicked( wxCommandEvent& event )
722{
723 LaunchExternal( m_pcm->Get3rdPartyPath() );
724}
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
Discards all pending changes.
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
Opens repository management dialog, saves changes to PCM.
void updatePackageState(const wxString &aPackageId, const PCM_PACKAGE_STATE aState)
Reflects new state of the package in all panels where it is displayed.
void OnApplyChangesClicked(wxCommandEvent &event) override
Enqueues current pending actions in PCM_TASK_MANAGER and runs the queue.
void OnDiscardActionClicked(wxCommandEvent &event) override
Discards selected pending actions.
void OnUpdateEventButtons(wxUpdateUIEvent &event)
Handles modification of the buttons' status.
std::unordered_map< PCM_PACKAGE_TYPE, PANEL_PACKAGES_VIEW * > m_repositoryContentPanels
Definition dialog_pcm.h:134
void OnOpenPackageDirClicked(wxCommandEvent &event) override
Opens local directory where packages are installed in file manager.
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()
Updates pending actions tab caption and content-fits the grid.
std::vector< PENDING_ACTION > m_pendingActions
Definition dialog_pcm.h:155
void setRepositoryListFromPcm()
Sets repository choice list values.
void OnInstallFromFileClicked(wxCommandEvent &event) override
Opens file selection dialog and installs selected package archive.
@ 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)
std::shared_ptr< PLUGIN_CONTENT_MANAGER > m_pcm
Definition dialog_pcm.h:130
void OnRepositoryChoice(wxCommandEvent &event) override
Switches to another repository.
wxString m_selectedRepositoryId
Definition dialog_pcm.h:135
PANEL_PACKAGES_VIEW * m_installedPanel
Definition dialog_pcm.h:133
void setInstalledPackages()
Gets installed packages list from PCM and displays it on installed tab.
void OnPendingActionsCellClicked(wxGridEvent &event) override
Selects the whole row in the grid if a cell is clicked.
void setRepositoryData(const wxString &aRepositoryId)
Gets package data from PCM and displays it on repository tab.
void discardAction(int aIndex)
Discards specified pending action.
wxBitmap m_defaultBitmap
Definition dialog_pcm.h:138
void OnRefreshClicked(wxCommandEvent &event) override
Discards current repo cache, fetches it anew and displays.
void OnCloseClicked(wxCommandEvent &event) override
Closes the window, asks user confirmation if there are pending actions.
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
#define ALL_REPOSITORIES
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:533
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_UPDATE_AVAILABLE
Definition pcm.h:65
@ PPS_PENDING_UNINSTALL
Definition pcm.h:64
@ PPS_PENDING_INSTALL
Definition pcm.h:63
PCM_PACKAGE_ACTION
Package actions.
Definition pcm.h:72
@ PPA_UNINSTALL
Definition pcm.h:74
@ PPA_UPDATE
Definition pcm.h:75
@ PPA_INSTALL
Definition pcm.h:73
@ 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 panel.
wxString update_version
wxString current_version
const PCM_PACKAGE package
wxString repository_name
PCM_PACKAGE_STATE state
Package installation entry.
Definition pcm_data.h:159
Package metadata.
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