KiCad PCB EDA Suite
Loading...
Searching...
No Matches
panel_jobs.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) 2024 Mark Roszko <[email protected]>
5 * Copyright (C) 2024 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 along
18 * with this program. If not, see <http://www.gnu.org/licenses/>.
19 */
20
21#include "panel_jobs.h"
22#include <wx/aui/auibook.h>
23#include <jobs/jobset.h>
24#include <jobs/job_registry.h>
25#include <eda_list_dialog.h>
27#include <wx/checkbox.h>
28#include <wx/menu.h>
29#include <bitmaps.h>
30#include <i18n_utility.h>
31#include <jobs_runner.h>
35#include <kicad_manager_frame.h>
36#include <vector>
37
38#include <wx/dirdlg.h>
39#include <wx/filedlg.h>
42
43#include <confirm.h>
44
47
48
50{
51 wxString name;
54 wxString fileWildcard;
55};
56
57
58static std::map<JOBSET_OUTPUT_TYPE, JOB_TYPE_INFO> jobTypeInfos = {
60 { _HKI( "Folder" ), BITMAPS::small_folder, true, "" } },
62 { _HKI( "Archive" ), BITMAPS::zip, false, FILEEXT::ZipFileWildcard() } },
63};
64
65
67{
68public:
69 DIALOG_JOB_OUTPUT( wxWindow* aParent, JOBSET* aJobsFile, JOBSET_OUTPUT* aOutput ) :
70 DIALOG_JOB_OUTPUT_BASE( aParent ), m_jobsFile( aJobsFile ), m_output( aOutput )
71 {
72 SetAffirmativeId( wxID_SAVE );
73
74 // prevent someone from failing to add the type info in the future
75 wxASSERT( jobTypeInfos.contains( m_output->m_type ) );
76
77 SetTitle( wxString::Format( _( "%s Output Options" ), jobTypeInfos[m_output->m_type].name ) );
78
79 if( m_output->m_type != JOBSET_OUTPUT_TYPE::ARCHIVE )
80 {
81 m_textArchiveFormat->Hide();
83 }
84
86 m_buttonOutputPath->SetBitmap( KiBitmapBundle( BITMAPS::small_folder ) );
87 }
88
89
90 virtual void onOutputPathBrowseClicked(wxCommandEvent& event) override
91 {
92 bool isFolder = false;
93 wxString fileWildcard = "";
94 isFolder = jobTypeInfos[m_output->m_type].outputPathIsFolder;
95 fileWildcard = jobTypeInfos[m_output->m_type].fileWildcard;
96
97 if( isFolder )
98 {
99 wxFileName fn;
100 fn.AssignDir( m_textCtrlOutputPath->GetValue() );
101 fn.Normalize( FN_NORMALIZE_FLAGS | wxPATH_NORM_ENV_VARS );
102 wxString currPath = fn.GetFullPath();
103
104 wxDirDialog dirDialog( this, _( "Select output directory" ), currPath,
105 wxDD_DEFAULT_STYLE | wxDD_DIR_MUST_EXIST );
106
107 if( dirDialog.ShowModal() != wxID_OK )
108 return;
109
110 wxFileName dirName = wxFileName::DirName( dirDialog.GetPath() );
111
112 m_textCtrlOutputPath->SetValue( dirName.GetFullPath() );
113 }
114 else
115 {
116 wxFileName fname( m_textCtrlOutputPath->GetValue() );
117
118 wxFileDialog dlg( this, _( "Select output path" ), fname.GetPath(), fname.GetFullName(),
119 fileWildcard,
120 wxFD_OVERWRITE_PROMPT | wxFD_SAVE );
121
122 if( dlg.ShowModal() != wxID_OK )
123 {
124 return;
125 }
126
127 m_textCtrlOutputPath->SetValue( dlg.GetPath() );
128 }
129
130 }
131
133 {
134 wxString outputPath = m_textCtrlOutputPath->GetValue().Trim().Trim( false );
135 if( outputPath == wxEmptyString )
136 {
137 DisplayErrorMessage( this, _( "Output path cannot be empty" ) );
138 return false;
139 }
140
141 wxArrayInt selectedItems;
142 m_listBoxOnly->GetSelections( selectedItems );
143
144 // Update the only job map
145 m_output->m_only.clear();
146 for( int i : selectedItems )
147 {
148 if( m_onlyMap.contains( i ) )
149 {
150 m_output->m_only.emplace_back( m_onlyMap[i] );
151 }
152 }
153
154 m_output->m_outputHandler->SetOutputPath( outputPath );
155
156 if( m_output->m_type == JOBSET_OUTPUT_TYPE::ARCHIVE )
157 {
158 JOBS_OUTPUT_ARCHIVE* archive =
160
162 }
163
164
165 return true;
166 }
167
168
169 bool TransferDataToWindow() override
170 {
171 wxArrayString arrayStr;
172 std::vector<int> selectedList;
173
174 std::vector<JOBSET_JOB> jobs = m_jobsFile->GetJobs();
175 int i = 0;
176 for( JOBSET_JOB& job : jobs )
177 {
178 arrayStr.Add( job.m_job->GetDescription() );
179
180 auto it = std::find_if( m_output->m_only.begin(), m_output->m_only.end(),
181 [&]( const wxString& only )
182 {
183 if( only == job.m_id )
184 return true;
185
186 return false;
187 } );
188
189 if( it != m_output->m_only.end() )
190 {
191 selectedList.emplace_back( i );
192 }
193
194 m_onlyMap.emplace( i, job.m_id );
195 i++;
196 }
197
198 if( arrayStr.size() != 0 )
199 {
200 m_listBoxOnly->InsertItems( arrayStr, 0 );
201
202 for( int idx : selectedList )
203 {
204 m_listBoxOnly->SetSelection( idx );
205 }
206 }
207
208 m_choiceArchiveformat->AppendString( _( "Zip" ) );
209 m_choiceArchiveformat->SetSelection( 0 );
210
211 return true;
212 }
213
214
215private:
218 std::map<int, wxString> m_onlyMap;
219};
220
221
223{
224public:
225 DIALOG_OUTPUT_RUN_RESULTS( wxWindow* aParent,
226 JOBSET* aJobsFile,
227 JOBSET_OUTPUT* aOutput ) :
229 {
231
232 int jobBmpColId = m_jobList->AppendColumn( wxT( "" ) );
233 int jobNoColId = m_jobList->AppendColumn( _( "No." ) );
234 int jobDescColId = m_jobList->AppendColumn( _( "Job Description" ) );
235 m_jobList->SetColumnWidth( jobBmpColId, wxLIST_AUTOSIZE_USEHEADER );
236 m_jobList->SetColumnWidth( jobNoColId, wxLIST_AUTOSIZE_USEHEADER );
237 m_jobList->SetColumnWidth( jobDescColId, wxLIST_AUTOSIZE_USEHEADER );
238
239 wxImageList* imageList = new wxImageList( 16, 16, true, 3 );
240 imageList->Add( KiBitmapBundle( BITMAPS::ercerr ).GetBitmap( wxSize( 16, 16 ) ) );
241 imageList->Add( KiBitmapBundle( BITMAPS::checked_ok ).GetBitmap( wxSize( 16, 16 ) ) );
242 m_jobList->SetImageList( imageList, wxIMAGE_LIST_SMALL );
243
244 int num = 1;
245 for( auto& job : aJobsFile->GetJobsForOutput( aOutput ) )
246 {
247 int imageIdx = -1;
248 if( aOutput->m_lastRunSuccessMap.contains( job.m_id ) )
249 {
250 if( aOutput->m_lastRunSuccessMap[job.m_id].value() )
251 {
252 imageIdx = 1;
253 }
254 else
255 {
256 imageIdx = 0;
257 }
258 }
259
260 long itemIndex = m_jobList->InsertItem( m_jobList->GetItemCount(), imageIdx );
261
262 m_jobList->SetItem( itemIndex, jobNoColId, wxString::Format( "%d", num++ ) );
263 m_jobList->SetItem( itemIndex, jobDescColId, job.m_job->GetDescription() );
264 }
265 }
266
267};
268
269
271{
272public:
273 PANEL_JOB_OUTPUT( wxWindow* aParent, PANEL_JOBS* aPanelParent, KICAD_MANAGER_FRAME* aFrame,
274 JOBSET* aFile, JOBSET_OUTPUT* aOutput ) :
275 PANEL_JOB_OUTPUT_BASE( aParent ),
276 m_jobsFile( aFile ),
277 m_output( aOutput ),
278 m_frame( aFrame ),
279 m_panelParent( aPanelParent )
280 {
281 m_buttonOutputRun->SetBitmap( KiBitmapBundle( BITMAPS::sim_run ) );
282 m_buttonOutputOptions->SetBitmap( KiBitmapBundle( BITMAPS::preference ) );
283
284 m_buttonOutputOptions->Connect( wxEVT_MENU,
285 wxCommandEventHandler( PANEL_JOB_OUTPUT::onMenu ), nullptr, this );
286
287 if( jobTypeInfos.contains( aOutput->m_type ) )
288 {
289 JOB_TYPE_INFO& jobTypeInfo = jobTypeInfos[aOutput->m_type];
290 m_textOutputType->SetLabel( wxGetTranslation( jobTypeInfo.name ) );
291 m_bitmapOutputType->SetBitmap( KiBitmapBundle( jobTypeInfo.bitmap ) );
292 }
293 }
294
295
297 {
298 m_buttonOutputOptions->Disconnect(
299 wxEVT_MENU, wxCommandEventHandler( PANEL_JOB_OUTPUT::onMenu ), nullptr, this );
300 }
301
303 {
304 if( m_output->m_lastRunSuccess.has_value() )
305 {
306 if( m_output->m_lastRunSuccess.value() )
307 {
308 m_statusBitmap->SetBitmap( KiBitmapBundle( BITMAPS::checked_ok ) );
309 m_statusBitmap->Show();
310 m_statusBitmap->SetToolTip( _( "Last run successful" ) );
311 }
312 else
313 {
314 m_statusBitmap->SetBitmap( KiBitmapBundle( BITMAPS::ercerr ) );
315 m_statusBitmap->Show();
316 m_statusBitmap->SetToolTip( _( "Last run failed" ) );
317 }
318 }
319 else
320 {
321 m_statusBitmap->Hide();
322 }
323 }
324
325
326 virtual void OnOutputRunClick( wxCommandEvent& event ) override
327 {
328 CallAfter(
329 [this]()
330 {
333
334 wxFileName fn = project.GetProjectFullName();
335 wxSetWorkingDirectory( fn.GetPath() );
336
337 JOBS_RUNNER jobRunner( &( m_frame->Kiway() ), m_jobsFile );
338
339 WX_PROGRESS_REPORTER* progressReporter =
340 new WX_PROGRESS_REPORTER( m_frame, _( "Running jobs" ), 1 );
341
342 jobRunner.RunJobsForOutput( m_output );
343 UpdateStatus();
344
345 delete progressReporter;
346 } );
347 }
348
349 virtual void OnLastStatusClick(wxMouseEvent& event) override
350 {
352 dialog.ShowModal();
353 }
354
355 virtual void OnOutputOptionsClick( wxCommandEvent& event ) override
356 {
357 wxMenu menu;
358 menu.Append( wxID_EDIT, _( "Edit..." ) );
359 menu.Append( wxID_DELETE, _( "Delete" ) );
360
361 if( m_output->m_lastRunSuccess.has_value() )
362 {
363 menu.AppendSeparator();
364 menu.Append( wxID_VIEW_DETAILS, _( "View last run results..." ) );
365 }
366
367 m_buttonOutputOptions->PopupMenu( &menu );
368 }
369
370
371private:
372 void onMenu( wxCommandEvent& aEvent )
373 {
374 switch( aEvent.GetId() )
375 {
376 case wxID_EDIT:
377 {
379
380 dialog.ShowModal();
381 }
382 break;
383
384 case wxID_DELETE:
386 break;
387
388 case wxID_VIEW_DETAILS:
389 {
391 dialog.ShowModal();
392 }
393 break;
394
395 default:
396 wxFAIL_MSG( wxT( "Unknown ID in context menu event" ) );
397 }
398 }
399
404};
405
406
407PANEL_JOBS::PANEL_JOBS( wxAuiNotebook* aParent, KICAD_MANAGER_FRAME* aFrame,
408 std::unique_ptr<JOBSET> aJobsFile ) :
409 PANEL_JOBS_BASE( aParent ),
410 m_parentBook( aParent ),
411 m_frame( aFrame ),
412 m_jobsFile( std::move( aJobsFile ) )
413{
414 int jobNoColId = m_jobList->AppendColumn( _( "No." ) );
415 int jobDescColId = m_jobList->AppendColumn( _( "Job Description" ) );
416 m_jobList->SetColumnWidth( jobNoColId, wxLIST_AUTOSIZE_USEHEADER );
417 m_jobList->SetColumnWidth( jobDescColId, wxLIST_AUTOSIZE_USEHEADER );
418
419 m_buttonAddJob->SetBitmap( KiBitmapBundle( BITMAPS::small_plus ) );
420 m_buttonUp->SetBitmap( KiBitmapBundle( BITMAPS::small_up ) );
421 m_buttonDown->SetBitmap( KiBitmapBundle( BITMAPS::small_down ) );
422 m_buttonOutputAdd->SetBitmap( KiBitmapBundle( BITMAPS::small_plus ) );
423
424 m_jobList->Connect( wxEVT_MENU, wxCommandEventHandler( PANEL_JOBS::onJobListMenu ),
425 nullptr, this );
426
429
430 m_buttonRunAllOutputs->Enable( !m_jobsFile->GetOutputs().empty() );
431}
432
433
435{
436 m_jobList->Disconnect( wxEVT_MENU, wxCommandEventHandler( PANEL_JOBS::onJobListMenu ),
437 nullptr, this );
438}
439
440
442{
443 auto it = m_outputPanelMap.find( aOutput );
444 if( it != m_outputPanelMap.end() )
445 {
446 PANEL_JOB_OUTPUT* panel = m_outputPanelMap[aOutput];
447 m_outputListSizer->Detach( panel );
448 panel->Destroy();
449
450 m_outputPanelMap.erase( it );
451
452 // ensure the window contents get shifted as needed
453 m_outputList->Layout();
454 Layout();
455 }
456
457 m_jobsFile->RemoveOutput( aOutput );
458
459 m_buttonRunAllOutputs->Enable( !m_jobsFile->GetOutputs().empty() );
460}
461
462
464{
465 m_jobList->DeleteAllItems();
466
467 int num = 1;
468 for( auto& job : m_jobsFile->GetJobs() )
469 {
470 long itemIndex =
471 m_jobList->InsertItem( m_jobList->GetItemCount(), wxString::Format( "%d", num++ ) );
472 m_jobList->SetItem( itemIndex, 1, job.m_job->GetDescription() );
473 }
474
475 updateTitle();
476}
477
478
480{
481 wxString tabName = m_jobsFile->GetFullName();
482 if( m_jobsFile->GetDirty() )
483 {
484 tabName = wxS( "*" ) + tabName;
485 }
486 int pageIdx = m_parentBook->FindPage( this );
487 m_parentBook->SetPageText( pageIdx, tabName );
488}
489
490
492{
493 PANEL_JOB_OUTPUT* outputPanel =
494 new PANEL_JOB_OUTPUT( m_outputList, this, m_frame, m_jobsFile.get(), aOutput );
495 m_outputListSizer->Add( outputPanel, 0, wxEXPAND | wxALL, 5 );
496
497 m_outputPanelMap[aOutput] = outputPanel;
498
499 m_outputList->Layout();
500}
501
502
504{
505 Freeze();
506 m_outputPanelMap.clear();
507
508 for( auto& job : m_jobsFile->GetOutputs() )
509 {
510 addJobOutputPanel( &job );
511 }
512
513 // ensure the window contents get shifted as needed
514 Layout();
515 Thaw();
516}
517
518
520{
521 JOBSET_JOB& job = m_jobsFile->GetJobs()[aItemIndex];
522
524
525 if( iface < KIWAY::KIWAY_FACE_COUNT )
526 {
528
529 m_frame->Kiway().ProcessJobConfigDialog( iface, job.m_job.get(), m_frame );
530 }
531 else
532 {
533 // special jobs
534 if( job.m_job->GetType() == "special_execute" )
535 {
536 JOB_SPECIAL_EXECUTE* specialJob = static_cast<JOB_SPECIAL_EXECUTE*>( job.m_job.get() );
537
538 DIALOG_SPECIAL_EXECUTE dialog( m_frame, specialJob );
539 dialog.ShowModal();
540 }
541 }
542}
543
544
545void PANEL_JOBS::OnJobListDoubleClicked( wxListEvent& aEvent )
546{
547 long item = aEvent.GetIndex();
548
550}
551
552
553void PANEL_JOBS::OnJobListItemRightClick( wxListEvent& event )
554{
555 wxMenu menu;
556 menu.Append( wxID_EDIT, _( "Edit..." ) );
557 menu.Append( wxID_DELETE, _( "Delete" ) );
558
559 m_jobList->PopupMenu( &menu, event.GetPoint() );
560}
561
562
563void PANEL_JOBS::onJobListMenu( wxCommandEvent& aEvent )
564{
565 switch( aEvent.GetId() )
566 {
567 case wxID_EDIT:
568 {
569 long item = m_jobList->GetNextItem( -1, wxLIST_NEXT_ALL, wxLIST_STATE_SELECTED );
570
571 if( item == -1 )
572 return;
573
575 }
576 break;
577
578 case wxID_DELETE:
579 {
580 long item = m_jobList->GetNextItem( -1, wxLIST_NEXT_ALL, wxLIST_STATE_SELECTED );
581
582 if( item == -1 )
583 return;
584
585 m_jobsFile->RemoveJob( item );
587 break;
588 }
589
590 default: wxFAIL_MSG( wxT( "Unknown ID in context menu event" ) );
591 }
592}
593
594
595void PANEL_JOBS::OnSaveButtonClick( wxCommandEvent& aEvent )
596{
597 m_jobsFile->SaveToFile();
598 updateTitle();
599}
600
601
602void PANEL_JOBS::OnAddJobClick( wxCommandEvent& aEvent )
603{
604 wxArrayString headers;
605 std::vector<wxArrayString> items;
606
607 headers.Add( _( "Job Types" ) );
608
610
611 for( const std::pair<const wxString, JOB_REGISTRY_ENTRY>& entry : jobMap )
612 {
613 wxArrayString item;
614 item.Add( wxGetTranslation( entry.second.title ) );
615 items.emplace_back( item );
616 }
617
618 EDA_LIST_DIALOG dlg( this, _( "Add New Job" ), headers, items );
619 dlg.SetListLabel( _( "Select job type:" ) );
620
621 if( dlg.ShowModal() == wxID_OK )
622 {
623 wxString selectedString = dlg.GetTextSelection();
624
625 wxString jobKey;
626 if( !selectedString.IsEmpty() )
627 {
628 for( const std::pair<const wxString, JOB_REGISTRY_ENTRY>& entry : jobMap )
629 {
630 if( wxGetTranslation( entry.second.title ) == selectedString )
631 {
632 jobKey = entry.first;
633 break;
634 }
635 }
636 }
637
638 if( !jobKey.IsEmpty() )
639 {
640 JOB* job = JOB_REGISTRY::CreateInstance<JOB>( jobKey );
641 m_jobsFile->AddNewJob( jobKey, job );
642
644 }
645 }
646}
647
648
649void PANEL_JOBS::OnAddOutputClick( wxCommandEvent& aEvent )
650{
651 wxArrayString headers;
652 std::vector<wxArrayString> items;
653
654 headers.Add( _( "Job Types" ) );
655
656 for( const std::pair<const JOBSET_OUTPUT_TYPE, JOB_TYPE_INFO>& jobType : jobTypeInfos )
657 {
658 wxArrayString item;
659 item.Add( wxGetTranslation( jobType.second.name ) );
660 items.emplace_back( item );
661 }
662
663 EDA_LIST_DIALOG dlg( this, _( "Add New Output" ), headers, items );
664 dlg.SetListLabel( _( "Select output type:" ) );
665 dlg.HideFilter();
666
667 if( dlg.ShowModal() == wxID_OK )
668 {
669 wxString selectedString = dlg.GetTextSelection();
670
671 for( const std::pair<const JOBSET_OUTPUT_TYPE, JOB_TYPE_INFO>& jobType : jobTypeInfos )
672 {
673 if( wxGetTranslation( jobType.second.name ) == selectedString )
674 {
675 JOBSET_OUTPUT* output = m_jobsFile->AddNewJobOutput( jobType.first );
676
677 DIALOG_JOB_OUTPUT dialog( m_frame, m_jobsFile.get(), output );
678 if (dialog.ShowModal() == wxID_SAVE)
679 {
680 Freeze();
681 addJobOutputPanel( output );
682 m_buttonRunAllOutputs->Enable( !m_jobsFile->GetOutputs().empty() );
683 Thaw();
684 }
685 else
686 {
687 // canceled
688 m_jobsFile->RemoveOutput( output );
689 }
690 }
691 }
692 }
693}
694
695
697{
698 if( m_jobsFile->GetDirty() )
699 {
700 wxFileName fileName = m_jobsFile->GetFullFilename();
701 wxString msg = _( "Save changes to '%s' before closing?" );
702
703 if( !HandleUnsavedChanges( this, wxString::Format( msg, fileName.GetFullName() ),
704 [&]() -> bool
705 {
706 return m_jobsFile->SaveToFile();
707 } ) )
708 {
709 return false;
710 }
711 }
712
713 return true;
714}
715
716
718{
720 KIWAY_PLAYER* frame = m_frame->Kiway().Player( FRAME_PCB_EDITOR, false );
721
722 if( !frame )
723 {
724 frame = m_frame->Kiway().Player( FRAME_PCB_EDITOR, true );
725
726 // frame can be null if Cvpcb cannot be run. No need to show a warning
727 // Kiway() generates the error messages
728 if( !frame )
729 return;
730
731 wxFileName boardfn = project.GetProjectFullName();
732 boardfn.SetExt( FILEEXT::PcbFileExtension );
733
734 // Prevent our window from being closed during the open process
735 wxEventBlocker blocker( this );
736
737 frame->OpenProjectFiles( std::vector<wxString>( 1, boardfn.GetFullPath() ) );
738 }
739
740 frame = m_frame->Kiway().Player( FRAME_SCH, false );
741
742 if( !frame )
743 {
744 frame = m_frame->Kiway().Player( FRAME_SCH, true );
745
746 // frame can be null if Cvpcb cannot be run. No need to show a warning
747 // Kiway() generates the error messages
748 if( !frame )
749 return;
750
751 wxFileName schFn = project.GetProjectFullName();
753
754 wxEventBlocker blocker( this );
755
756 frame->OpenProjectFiles( std::vector<wxString>( 1, schFn.GetFullPath() ) );
757 }
758}
759
760
762{
763 return m_jobsFile->GetFullFilename();
764}
765
766
767void PANEL_JOBS::OnJobButtonUp( wxCommandEvent& aEvent )
768{
769 long item = m_jobList->GetNextItem( -1, wxLIST_NEXT_ALL, wxLIST_STATE_SELECTED );
770
771 if( item == -1 )
772 return;
773
774 if( item == 0 )
775 return;
776
777 m_jobsFile->MoveJobUp( item );
778
780
781 m_jobList->SetItemState( item - 1, wxLIST_STATE_SELECTED, wxLIST_STATE_SELECTED );
782}
783
784
785void PANEL_JOBS::OnJobButtonDown( wxCommandEvent& aEvent )
786{
787 long item = m_jobList->GetNextItem( -1, wxLIST_NEXT_ALL, wxLIST_STATE_SELECTED );
788
789 if( item == -1 )
790 return;
791
792 if( item == m_jobList->GetItemCount() - 1 )
793 return;
794
795 m_jobsFile->MoveJobDown( item );
796
798
799 m_jobList->SetItemState( item + 1, wxLIST_STATE_SELECTED, wxLIST_STATE_SELECTED );
800}
801
802void PANEL_JOBS::OnRunAllJobsClick( wxCommandEvent& event )
803{
804 // sanity
805 if( m_jobsFile->GetOutputs().empty() )
806 {
807 DisplayError( this, _( "No outputs defined" ) );
808 return;
809 }
810
811 CallAfter(
812 [this]()
813 {
816
817 wxFileName fn = project.GetProjectFullName();
818 wxSetWorkingDirectory( fn.GetPath() );
819
820 JOBS_RUNNER jobRunner( &( m_frame->Kiway() ), m_jobsFile.get() );
821
822 WX_PROGRESS_REPORTER* progressReporter =
823 new WX_PROGRESS_REPORTER( m_frame, _( "Running jobs" ), 1 );
824
825 jobRunner.RunJobsAllOutputs();
826
827 for( auto& output : m_jobsFile->GetOutputs() )
828 {
829 PANEL_JOB_OUTPUT* panel = m_outputPanelMap[&output];
830 panel->UpdateStatus();
831 }
832
833 delete progressReporter;
834 } );
835}
wxBitmapBundle KiBitmapBundle(BITMAPS aBitmap)
Definition: bitmap.cpp:110
BITMAPS
A list of all bitmap identifiers.
Definition: bitmaps_list.h:33
@ small_folder
Class DIALOG_JOB_OUTPUT_BASE.
wxStaticText * m_textArchiveFormat
STD_BITMAP_BUTTON * m_buttonOutputPath
wxChoice * m_choiceArchiveformat
wxTextCtrl * m_textCtrlOutputPath
bool TransferDataFromWindow() override
Definition: panel_jobs.cpp:132
JOBSET_OUTPUT * m_output
Definition: panel_jobs.cpp:217
DIALOG_JOB_OUTPUT(wxWindow *aParent, JOBSET *aJobsFile, JOBSET_OUTPUT *aOutput)
Definition: panel_jobs.cpp:69
bool TransferDataToWindow() override
Definition: panel_jobs.cpp:169
std::map< int, wxString > m_onlyMap
Definition: panel_jobs.cpp:218
virtual void onOutputPathBrowseClicked(wxCommandEvent &event) override
Definition: panel_jobs.cpp:90
Class DIALOG_OUTPUT_RUN_RESULTS_BASE.
DIALOG_OUTPUT_RUN_RESULTS(wxWindow *aParent, JOBSET *aJobsFile, JOBSET_OUTPUT *aOutput)
Definition: panel_jobs.cpp:225
int ShowModal() override
A dialog which shows:
wxString GetTextSelection(int aColumn=0)
Return the selected text from aColumn in the wxListCtrl in the dialog.
void SetListLabel(const wxString &aLabel)
Definition: jobset.h:72
std::vector< JOBSET_JOB > GetJobsForOutput(JOBSET_OUTPUT *aOutput)
Definition: jobset.cpp:234
std::vector< JOBSET_JOB > & GetJobs()
Definition: jobset.h:78
void SetFormat(FORMAT format)
wxString GetOutputPath() const
Definition: jobs_output.h:51
void SetOutputPath(const wxString &aPath)
Definition: jobs_output.h:50
bool RunJobsForOutput(JOBSET_OUTPUT *aOutput, bool aBail=false)
Definition: jobs_runner.cpp:91
bool RunJobsAllOutputs(bool aBail=false)
Definition: jobs_runner.cpp:46
static const REGISTRY_MAP_T & GetRegistry()
Definition: job_registry.h:55
std::unordered_map< wxString, JOB_REGISTRY_ENTRY > REGISTRY_MAP_T
Definition: job_registry.h:37
static KIWAY::FACE_T GetKifaceType(const wxString &aName)
An simple container class that lets us dispatch output jobs to kifaces.
Definition: job.h:79
The main KiCad project manager frame.
KIWAY & Kiway() const
Return a reference to the KIWAY that this object has an opportunity to participate in.
Definition: kiway_holder.h:55
A wxFrame capable of the OpenProjectFiles function, meaning it can load a portion of a KiCad project.
Definition: kiway_player.h:65
virtual bool OpenProjectFiles(const std::vector< wxString > &aFileList, int aCtl=0)
Open a project or set of files given by aFileList.
Definition: kiway_player.h:113
bool ProcessJobConfigDialog(KIWAY::FACE_T aFace, JOB *aJob, wxWindow *aWindow)
Definition: kiway.cpp:717
virtual KIWAY_PLAYER * Player(FRAME_T aFrameType, bool doCreate=true, wxTopLevelWindow *aParent=nullptr)
Return the KIWAY_PLAYER* given a FRAME_T.
Definition: kiway.cpp:406
FACE_T
Known KIFACE implementations.
Definition: kiway.h:290
@ KIWAY_FACE_COUNT
Definition: kiway.h:300
virtual PROJECT & Prj() const
Return the PROJECT associated with this KIWAY.
Definition: kiway.cpp:196
Class PANEL_JOBS_BASE.
wxBitmapButton * m_buttonUp
wxBitmapButton * m_buttonAddJob
wxButton * m_buttonRunAllOutputs
wxBoxSizer * m_outputListSizer
wxBitmapButton * m_buttonOutputAdd
wxListCtrl * m_jobList
wxScrolledWindow * m_outputList
wxBitmapButton * m_buttonDown
wxString GetFilePath() const
Definition: panel_jobs.cpp:761
virtual void OnAddOutputClick(wxCommandEvent &aEvent) override
Definition: panel_jobs.cpp:649
virtual void OnJobListItemRightClick(wxListEvent &event) override
Definition: panel_jobs.cpp:553
std::unique_ptr< JOBSET > m_jobsFile
Definition: panel_jobs.h:68
void openJobOptionsForListItem(size_t aItemIndex)
Definition: panel_jobs.cpp:519
std::unordered_map< JOBSET_OUTPUT *, PANEL_JOB_OUTPUT * > m_outputPanelMap
Definition: panel_jobs.h:70
wxAuiNotebook * m_parentBook
Definition: panel_jobs.h:66
PANEL_JOBS(wxAuiNotebook *aParent, KICAD_MANAGER_FRAME *aFrame, std::unique_ptr< JOBSET > aJobsFile)
Definition: panel_jobs.cpp:407
virtual void OnAddJobClick(wxCommandEvent &aEvent) override
Definition: panel_jobs.cpp:602
void rebuildJobList()
Definition: panel_jobs.cpp:463
void RemoveOutput(JOBSET_OUTPUT *aOutput)
Definition: panel_jobs.cpp:441
void addJobOutputPanel(JOBSET_OUTPUT *aOutput)
Definition: panel_jobs.cpp:491
void updateTitle()
Definition: panel_jobs.cpp:479
void onJobListMenu(wxCommandEvent &aEvent)
Definition: panel_jobs.cpp:563
virtual void OnJobButtonUp(wxCommandEvent &aEvent) override
Definition: panel_jobs.cpp:767
void buildOutputList()
Definition: panel_jobs.cpp:503
virtual void OnJobButtonDown(wxCommandEvent &aEvent) override
Definition: panel_jobs.cpp:785
virtual void OnRunAllJobsClick(wxCommandEvent &event) override
Definition: panel_jobs.cpp:802
bool GetCanClose() override
Definition: panel_jobs.cpp:696
void EnsurePcbSchFramesOpen()
Definition: panel_jobs.cpp:717
virtual void OnSaveButtonClick(wxCommandEvent &aEvent) override
Definition: panel_jobs.cpp:595
KICAD_MANAGER_FRAME * m_frame
Definition: panel_jobs.h:67
virtual void OnJobListDoubleClicked(wxListEvent &aEvent) override
Definition: panel_jobs.cpp:545
Class PANEL_JOB_OUTPUT_BASE.
wxBitmapButton * m_buttonOutputRun
wxStaticBitmap * m_statusBitmap
wxStaticBitmap * m_bitmapOutputType
wxBitmapButton * m_buttonOutputOptions
wxStaticText * m_textOutputType
virtual void OnLastStatusClick(wxMouseEvent &event) override
Definition: panel_jobs.cpp:349
JOBSET_OUTPUT * m_output
Definition: panel_jobs.cpp:401
virtual void OnOutputRunClick(wxCommandEvent &event) override
Definition: panel_jobs.cpp:326
KICAD_MANAGER_FRAME * m_frame
Definition: panel_jobs.cpp:402
void onMenu(wxCommandEvent &aEvent)
Definition: panel_jobs.cpp:372
PANEL_JOBS * m_panelParent
Definition: panel_jobs.cpp:403
JOBSET * m_jobsFile
Definition: panel_jobs.cpp:400
virtual void OnOutputOptionsClick(wxCommandEvent &event) override
Definition: panel_jobs.cpp:355
PANEL_JOB_OUTPUT(wxWindow *aParent, PANEL_JOBS *aPanelParent, KICAD_MANAGER_FRAME *aFrame, JOBSET *aFile, JOBSET_OUTPUT *aOutput)
Definition: panel_jobs.cpp:273
Container for project specific data.
Definition: project.h:64
void SetBitmap(const wxBitmapBundle &aBmp)
Multi-thread safe progress reporter dialog, intended for use of tasks that parallel reporting back of...
void DisplayError(wxWindow *aParent, const wxString &aText, int aDisplayTime)
Display an error or warning message box with aMessage.
Definition: confirm.cpp:170
bool HandleUnsavedChanges(wxWindow *aParent, const wxString &aMessage, const std::function< bool()> &aSaveFunction)
Display a dialog with Save, Cancel and Discard Changes buttons.
Definition: confirm.cpp:130
void DisplayErrorMessage(wxWindow *aParent, const wxString &aText, const wxString &aExtraInfo)
Display an error message with aMessage.
Definition: confirm.cpp:195
This file is part of the common library.
#define _HKI(x)
#define _(s)
@ FRAME_PCB_EDITOR
Definition: frame_type.h:42
@ FRAME_SCH
Definition: frame_type.h:34
static const std::string KiCadSchematicFileExtension
static wxString ZipFileWildcard()
Some functions to handle hotkeys in KiCad.
PROJECT & Prj()
Definition: kicad.cpp:597
STL namespace.
static std::map< JOBSET_OUTPUT_TYPE, JOB_TYPE_INFO > jobTypeInfos
Definition: panel_jobs.cpp:58
std::shared_ptr< JOB > m_job
Definition: jobset.h:39
wxString m_type
Definition: jobset.h:38
std::vector< wxString > m_only
Transient property, not stored for now.
Definition: jobset.h:61
JOBS_OUTPUT_HANDLER * m_outputHandler
Definition: jobset.h:60
std::unordered_map< wxString, std::optional< bool > > m_lastRunSuccessMap
Definition: jobset.h:65
std::optional< bool > m_lastRunSuccess
Definition: jobset.h:64
JOBSET_OUTPUT_TYPE m_type
Definition: jobset.h:59
wxString name
Definition: panel_jobs.cpp:51
bool outputPathIsFolder
Definition: panel_jobs.cpp:53
wxString fileWildcard
Definition: panel_jobs.cpp:54
BITMAPS bitmap
Definition: panel_jobs.cpp:52
Definition of file extensions used in Kicad.
#define FN_NORMALIZE_FLAGS
Default flags to pass to wxFileName::Normalize().
Definition: wx_filename.h:39