KiCad PCB EDA Suite
Loading...
Searching...
No Matches
dialog_template_selector.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) 2012 Brian Sidebotham <[email protected]>
5 * Copyright The KiCad Developers, see AUTHORS.txt for contributors.
6 *
7 * This program is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU General Public License
9 * as published by the Free Software Foundation; either version 2
10 * of the License, or (at your option) any later version.
11 *
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU 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, you may find one here:
19 * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
20 * or you may search the http://www.gnu.org website for the version 2 license,
21 * or you may write to the Free Software Foundation, Inc.,
22 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
23 */
24
26#include <bitmaps.h>
28#include <widgets/ui_common.h>
29#include <algorithm>
30#include <wx_filename.h>
31#include <wx/dir.h>
32#include <wx/dirdlg.h>
33#include <wx/settings.h>
34#include <wx/bitmap.h>
35#include <wx/image.h>
36#include <wx/math.h>
37#include <wx/menu.h>
38#include <wx/textdlg.h>
39#include <wx/textfile.h>
40#include <confirm.h>
43
44// Welcome / fallback HTML now provided by template_default_html.h
45
47 const wxString& aPath ) :
49{
50 m_parent = aParent;
51 m_templatesPath = aPath;
52 m_isUserTemplates = false;
53}
54
55
57{
58 m_SizerChoice->Add( aTemplateWidget );
59 Layout();
60}
61
62
63// Sort the widgets alphabetically, leaving Default at the top
65{
66 std::vector<TEMPLATE_WIDGET*> sortedList;
67 TEMPLATE_WIDGET* default_temp = nullptr;
68 size_t count = m_SizerChoice->GetItemCount();
69
70 if( count <= 1 )
71 return;
72
73 for( size_t idx = 0; idx < count; idx++ )
74 {
75 wxSizerItem* item = m_SizerChoice->GetItem( idx );
76 if( item && item->IsWindow() )
77 {
78 TEMPLATE_WIDGET* temp = static_cast<TEMPLATE_WIDGET*>( item->GetWindow() );
79
80 const wxString title = *temp->GetTemplate()->GetTitle();
81
82 if( default_temp == nullptr && title.CmpNoCase( "default" ) == 0 )
83 default_temp = temp;
84 else
85 sortedList.push_back( temp );
86 }
87 }
88
89 std::sort(
90 sortedList.begin(), sortedList.end(),
91 []( TEMPLATE_WIDGET* aWidgetA, TEMPLATE_WIDGET* aWidgetB ) -> bool
92 {
93 const wxString* a = aWidgetA->GetTemplate()->GetTitle();
94 const wxString* b = aWidgetB->GetTemplate()->GetTitle();
95
96 return ( *a ).CmpNoCase( *b ) < 0;
97 });
98
99 m_SizerChoice->Clear( false );
100
101 if( default_temp != nullptr )
102 m_SizerChoice->Add( default_temp );
103
104 for (TEMPLATE_WIDGET* temp : sortedList)
105 {
106 m_SizerChoice->Add( temp );
107 }
108
109 Layout();
110}
111
112
114 TEMPLATE_WIDGET_BASE( aParent )
115{
116 m_parent = aParent;
117 m_dialog = aDialog;
118 m_isUserTemplate = false;
119
120 // wxWidgets_3.xx way of doing the same...
121 // Bind(wxEVT_LEFT_DOWN, &TEMPLATE_WIDGET::OnMouse, this );
122
123 m_bitmapIcon->Connect( wxEVT_LEFT_DOWN, wxMouseEventHandler( TEMPLATE_WIDGET::OnMouse ),
124 nullptr, this );
125 m_staticTitle->Connect( wxEVT_LEFT_DOWN, wxMouseEventHandler( TEMPLATE_WIDGET::OnMouse ),
126 nullptr, this );
127
128 // Add right-click handler
129 m_bitmapIcon->Connect( wxEVT_RIGHT_DOWN, wxMouseEventHandler( TEMPLATE_WIDGET::onRightClick ),
130 nullptr, this );
131 m_staticTitle->Connect( wxEVT_RIGHT_DOWN, wxMouseEventHandler( TEMPLATE_WIDGET::onRightClick ),
132 nullptr, this );
133 Connect( wxEVT_RIGHT_DOWN, wxMouseEventHandler( TEMPLATE_WIDGET::onRightClick ),
134 nullptr, this );
135
136 // Add double-click handler to activate the template (like OK button)
137 m_bitmapIcon->Connect( wxEVT_LEFT_DCLICK, wxMouseEventHandler( TEMPLATE_WIDGET::OnDoubleClick ),
138 nullptr, this );
139 m_staticTitle->Connect( wxEVT_LEFT_DCLICK, wxMouseEventHandler( TEMPLATE_WIDGET::OnDoubleClick ),
140 nullptr, this );
141 Connect( wxEVT_LEFT_DCLICK, wxMouseEventHandler( TEMPLATE_WIDGET::OnDoubleClick ),
142 nullptr, this );
143
144 // We're not selected until we're clicked
145 Unselect();
146
147 // Start with template being NULL
148 m_currTemplate = nullptr;
149}
150
151
153{
154 m_dialog->SetWidget( this );
155 SetBackgroundColour( wxSystemSettings::GetColour( wxSYS_COLOUR_HIGHLIGHT ) );
156 m_staticTitle->SetForegroundColour( wxSystemSettings::GetColour( wxSYS_COLOUR_HIGHLIGHTTEXT ) );
157 m_selected = true;
158 Refresh();
159}
160
161
163{
164 SetBackgroundColour( wxSystemSettings::GetColour( wxSYS_COLOUR_BTNFACE ) );
165 m_staticTitle->SetForegroundColour( wxSystemSettings::GetColour( wxSYS_COLOUR_BTNTEXT ) );
166 m_selected = false;
167 Refresh();
168}
169
170
172{
173 m_currTemplate = aTemplate;
174 m_staticTitle->SetFont( KIUI::GetInfoFont( this ) );
175 m_staticTitle->SetLabel( *aTemplate->GetTitle() );
176 m_staticTitle->Wrap( 100 );
177 wxBitmap* icon = aTemplate->GetIcon();
178
179 if( icon && icon->IsOk() )
180 {
181 wxSize maxSize = m_bitmapIcon->GetSize();
182
183 if( icon->GetWidth() > maxSize.x || icon->GetHeight() > maxSize.y )
184 {
185 double scale = std::min( (double) maxSize.x / icon->GetWidth(),
186 (double) maxSize.y / icon->GetHeight() );
187 wxImage image = icon->ConvertToImage();
188 int w = wxRound( icon->GetWidth() * scale );
189 int h = wxRound( icon->GetHeight() * scale );
190 image.Rescale( w, h, wxIMAGE_QUALITY_HIGH );
191 m_bitmapIcon->SetBitmap( wxBitmap( image ) );
192 }
193 else
194 {
195 m_bitmapIcon->SetBitmap( *icon );
196 }
197 }
198 else
200}
201
202
203void TEMPLATE_WIDGET::OnMouse( wxMouseEvent& event )
204{
205 // Toggle selection here
206 Select();
207 event.Skip();
208}
209
210
211void TEMPLATE_WIDGET::OnDoubleClick( wxMouseEvent& event )
212{
213 // Double-click acts like pressing OK button
214 Select();
215 m_dialog->EndModal( wxID_OK );
216 event.Skip();
217}
218
219
220void TEMPLATE_WIDGET::onRightClick( wxMouseEvent& event )
221{
222 // Only show context menu for user templates
224 {
225 event.Skip();
226 return;
227 }
228
229 wxMenu menu;
230 menu.Append( wxID_EDIT, _( "Edit Template" ) );
231 menu.Append( wxID_COPY, _( "Duplicate Template" ) );
232
233 menu.Bind( wxEVT_COMMAND_MENU_SELECTED,
234 [this]( wxCommandEvent& evt )
235 {
236 if( evt.GetId() == wxID_EDIT )
237 onEditTemplate( evt );
238 else if( evt.GetId() == wxID_COPY )
239 onDuplicateTemplate( evt );
240 } );
241
242 PopupMenu( &menu );
243}
244
245
246void TEMPLATE_WIDGET::onEditTemplate( wxCommandEvent& event )
247{
248 if( !m_currTemplate )
249 return;
250
251 // Get the template's base path
252 wxFileName templatePath = m_currTemplate->GetHtmlFile();
253 templatePath.RemoveLastDir(); // Remove "meta" dir
254
255 // Find a .kicad_pro file in the template directory
256 wxDir dir( templatePath.GetPath() );
257
258 if( !dir.IsOpened() )
259 {
261 _( "Could not open template directory." ) );
262 return;
263 }
264
265 wxString filename;
266 bool found = dir.GetFirst( &filename, "*.kicad_pro", wxDIR_FILES );
267
268 if( !found )
269 {
271 _( "No project file found in template directory." ) );
272 return;
273 }
274
275 wxFileName projectFile( templatePath.GetPath(), filename );
276
277 // Store the project path in the dialog so the caller can handle it
278 m_dialog->SetProjectToEdit( projectFile.GetFullPath() );
279
280 // Close with wxID_APPLY to indicate we want to edit, not create
281 m_dialog->EndModal( wxID_APPLY );
282}
283
284
285
286void TEMPLATE_WIDGET::onDuplicateTemplate( wxCommandEvent& event )
287{
288 if( !m_currTemplate )
289 return;
290
291 // Get the template's base path
292 wxFileName templatePath = m_currTemplate->GetHtmlFile();
293 templatePath.RemoveLastDir(); // Remove "meta" dir
294 wxString srcTemplatePath = templatePath.GetPath();
295 wxString srcTemplateName = m_currTemplate->GetPrjDirName();
296
297 // Ask for new template name
298 wxTextEntryDialog nameDlg( m_dialog,
299 _( "Enter name for the new template:" ),
300 _( "Duplicate Template" ),
301 srcTemplateName + _( "_copy" ) );
302
303 if( nameDlg.ShowModal() != wxID_OK )
304 return;
305
306 wxString newTemplateName = nameDlg.GetValue();
307
308 if( newTemplateName.IsEmpty() )
309 {
310 DisplayErrorMessage( m_dialog, _( "Template name cannot be empty." ) );
311 return;
312 }
313
314 // Get the user templates directory from the dialog
315 wxString userTemplatesPath = m_dialog->GetUserTemplatesPath();
316
317 if( userTemplatesPath.IsEmpty() )
318 {
319 DisplayErrorMessage( m_dialog, _( "Could not find user templates directory." ) );
320 return;
321 }
322
323 // Create destination directory in user templates folder
324 wxFileName destPath( userTemplatesPath, wxEmptyString );
325 destPath.AppendDir( newTemplateName );
326 wxString newTemplatePath = destPath.GetPath();
327
328 if( destPath.DirExists() )
329 {
331 wxString::Format( _( "Directory '%s' already exists." ),
332 newTemplatePath ) );
333 return;
334 }
335
336 if( !destPath.Mkdir( wxS_DIR_DEFAULT, wxPATH_MKDIR_FULL ) )
337 {
339 wxString::Format( _( "Could not create directory '%s'." ),
340 newTemplatePath ) );
341 return;
342 }
343
344 // Use shared traverser to copy all files with proper renaming
345 // Pass nullptr for frame to enable simple copy mode (no KIFACE handling)
346 wxDir sourceDir( srcTemplatePath );
347
348 if( !sourceDir.IsOpened() )
349 {
350 DisplayErrorMessage( m_dialog, _( "Could not open source template directory." ) );
351 return;
352 }
353
354 PROJECT_TREE_TRAVERSER traverser( nullptr, srcTemplatePath, srcTemplateName,
355 newTemplatePath, newTemplateName );
356
357 sourceDir.Traverse( traverser );
358
359 if( !traverser.GetErrors().empty() )
360 {
361 DisplayErrorMessage( m_dialog, traverser.GetErrors() );
362 return;
363 }
364
365 // Update the title in meta/info.html if it exists
366 wxFileName metaHtmlFile( newTemplatePath, "info.html" );
367 metaHtmlFile.AppendDir( "meta" );
368
369 if( metaHtmlFile.FileExists() )
370 {
371 wxTextFile htmlFile( metaHtmlFile.GetFullPath() );
372
373 if( htmlFile.Open() )
374 {
375 bool modified = false;
376
377 for( size_t i = 0; i < htmlFile.GetLineCount(); i++ )
378 {
379 wxString line = htmlFile.GetLine( i );
380
381 // Update the title tag - replace content between <title> and </title>
382 if( line.Contains( wxT( "<title>" ) ) && line.Contains( wxT( "</title>" ) ) )
383 {
384 int titleStart = line.Find( wxT( "<title>" ) );
385 int titleEnd = line.Find( wxT( "</title>" ) );
386
387 if( titleStart != wxNOT_FOUND && titleEnd != wxNOT_FOUND && titleEnd > titleStart )
388 {
389 wxString before = line.Left( titleStart + 7 ); // Include "<title>"
390 wxString after = line.Mid( titleEnd ); // Include "</title>" onwards
391 line = before + newTemplateName + after;
392 htmlFile[i] = line;
393 modified = true;
394 }
395 }
396 }
397
398 if( modified )
399 htmlFile.Write();
400
401 htmlFile.Close();
402 }
403 }
404
405 DisplayInfoMessage( m_dialog, wxString::Format( _( "Template duplicated successfully to '%s'." ),
406 newTemplatePath ) );
407
408 // Refresh the widget list to show the new template
409 m_dialog->replaceCurrentPage();
410}
411
412
413
414void DIALOG_TEMPLATE_SELECTOR::OnPageChange( wxNotebookEvent& event )
415{
416 int newPage = event.GetSelection();
417 int oldPage = event.GetOldSelection();
418
419 // Move webview panel from old page to new page
420 if( oldPage != wxNOT_FOUND && (unsigned)oldPage < m_panels.size() )
421 {
422 // Detach webview from old panel
423 m_panels[oldPage]->m_SizerBase->Detach( m_webviewPanel );
424 m_panels[oldPage]->Layout();
425 }
426
427 if( newPage != wxNOT_FOUND && (unsigned)newPage < m_panels.size() )
428 {
429 // Reparent the webview to the new panel
430 m_webviewPanel->Reparent( m_panels[newPage] );
431
432 // Attach webview to new panel
433 m_panels[newPage]->m_SizerBase->Add( m_webviewPanel, 1, wxEXPAND | wxALL, 5 );
434 m_panels[newPage]->Layout();
435
436 // Update template path
437 m_tcTemplatePath->SetValue( m_panels[newPage]->GetPath() );
438
439 // Reset to welcome page when switching tabs if no template selected
440 m_webviewPanel->SetPage( GetWelcomeHtml() );
441 }
442
443 event.Skip();
444}
445
446
447DIALOG_TEMPLATE_SELECTOR::DIALOG_TEMPLATE_SELECTOR( wxWindow* aParent, const wxPoint& aPos, const wxSize& aSize,
448 std::vector<std::pair<wxString, wxFileName>> aTitleDirList,
449 const wxFileName& aDefaultTemplate ) :
450 DIALOG_TEMPLATE_SELECTOR_BASE( aParent, wxID_ANY, _( "Project Template Selector" ), aPos, aSize )
451{
454
455 m_webviewPanel->BindLoadedEvent();
456
457 m_selectedWidget = nullptr;
458 m_defaultTemplatePath = aDefaultTemplate;
459 m_defaultWidget = nullptr;
460
461 for( auto& [title, pathFname] : aTitleDirList )
462 {
463 pathFname.Normalize( FN_NORMALIZE_FLAGS | wxPATH_NORM_ENV_VARS );
464 wxString path = pathFname.GetFullPath(); // caller ensures this ends with file separator.
465
467
468 // Mark the first panel as "User Templates" if the title matches
469 if( title == _( "User Templates" ) )
470 tpanel->SetIsUserTemplates( true );
471
472 m_panels.push_back( tpanel );
473
474 m_notebook->AddPage( tpanel, title );
475
476 if( m_notebook->GetPageCount() == 1 )
477 m_tcTemplatePath->SetValue( path );
478
479 buildPageContent( path, m_notebook->GetPageCount() - 1 );
480 }
481
482 // Move webview panel from dialog to first template selection panel
483 if( !m_panels.empty() )
484 {
485 // Find the sizer containing the webview and detach it
486 wxSizer* parentSizer = m_webviewPanel->GetContainingSizer();
487
488 if( parentSizer )
489 {
490 parentSizer->Detach( m_webviewPanel );
491 }
492
493 // Reparent the webview to the first panel
494 m_webviewPanel->Reparent( m_panels[0] );
495
496 // Add webview to first panel
497 m_panels[0]->m_SizerBase->Add( m_webviewPanel, 1, wxEXPAND | wxALL, 5 );
498 m_panels[0]->Layout();
499 }
500
501 if( m_defaultWidget )
502 m_defaultWidget->Select();
503
504 // Set welcome HTML after dialog is fully constructed
505 CallAfter(
506 [this]()
507 {
508 #if defined (_WIN32)
509 wxSafeYield();
510 m_tcTemplatePath->SelectNone();
511 #endif
512
513 if( m_selectedWidget )
514 {
515 wxFileName htmlFile = m_selectedWidget->GetTemplate()->GetHtmlFile();
516
517 if( htmlFile.FileExists() && htmlFile.IsFileReadable() && htmlFile.GetSize() > 100 /* Basic HTML */ )
518 m_webviewPanel->LoadURL( wxFileName::FileNameToURL( htmlFile ) );
519 else
520 m_webviewPanel->SetPage( GetWelcomeHtml() );
521 }
522 else
523 {
524 m_webviewPanel->SetPage( GetWelcomeHtml() );
525 }
526 } );
527
528 // When all widgets have the size fixed, call finishDialogSettings to update sizers
529 finishDialogSettings();
530}
531
532
534{
535 if( m_selectedWidget != nullptr )
536 m_selectedWidget->Unselect();
537
538 m_selectedWidget = aWidget;
539 wxFileName htmlFile = aWidget->GetTemplate()->GetHtmlFile();
540
541 if( htmlFile.FileExists() && htmlFile.IsFileReadable() )
542 m_webviewPanel->LoadURL( wxFileName::FileNameToURL( htmlFile ) );
543 else
544 m_webviewPanel->SetPage( GetTemplateInfoHtml( *aWidget->GetTemplate()->GetTitle() ) );
545}
546
547
549{
550 TEMPLATE_WIDGET* w = new TEMPLATE_WIDGET( m_panels[aPage]->m_scrolledWindow, this );
551 w->SetTemplate( aTemplate );
552 w->SetIsUserTemplate( m_panels[aPage]->IsUserTemplates() );
553 m_panels[aPage]->AddTemplateWidget( w );
554 m_allWidgets.push_back( w );
555
556 wxFileName base = aTemplate->GetHtmlFile();
557 base.RemoveLastDir();
558
560 m_defaultWidget = w;
561
562 wxString dirName = base.GetDirs().IsEmpty() ? wxString() : base.GetDirs().back();
563
564 if( dirName.CmpNoCase( "default" ) == 0 )
565 {
566 // Prefer a directory literally named 'default'
567 m_defaultWidget = w;
568 }
569}
570
571
576
581
582
584{
585 // Find the first panel marked as user templates
586 for( const TEMPLATE_SELECTION_PANEL* panel : m_panels )
587 {
588 if( panel->IsUserTemplates() )
589 return panel->GetPath();
590 }
591
592 // If no user templates panel found, return empty string
593 return wxEmptyString;
594}
595
596
597void DIALOG_TEMPLATE_SELECTOR::buildPageContent( const wxString& aPath, int aPage )
598{
599 // Track initial template count to detect if any templates were added
600 size_t initialTemplateCount = m_panels[aPage]->m_SizerChoice->GetItemCount();
601
602 // Get a list of files under the template path to include as choices...
603 wxDir dir;
604
605 if( dir.Open( aPath ) )
606 {
607 if( dir.HasSubDirs( "meta" ) )
608 {
609 AddTemplate( aPage, new PROJECT_TEMPLATE( aPath ) );
610 }
611 else
612 {
613 wxString sub_name;
614 wxArrayString subdirs;
615
616 bool cont = dir.GetFirst( &sub_name, wxEmptyString, wxDIR_DIRS );
617
618 while( cont )
619 {
620 subdirs.Add( wxString( sub_name ) );
621 cont = dir.GetNext( &sub_name );
622 }
623
624 if( !subdirs.IsEmpty() )
625 subdirs.Sort();
626
627 for( const wxString& dir_name : subdirs )
628 {
629 wxDir sub_dir;
630 wxString sub_full = aPath + dir_name;
631
632 if( sub_dir.Open( sub_full ) )
633 AddTemplate( aPage, new PROJECT_TEMPLATE( sub_full ) );
634 }
635 }
636 }
637
638 m_panels[aPage]->SortAlphabetically();
639
640 // Check if any templates were added; if not, display "No templates found" message
641 size_t finalTemplateCount = m_panels[aPage]->m_SizerChoice->GetItemCount();
642
643 if( finalTemplateCount == initialTemplateCount )
644 {
645 // No templates found in this directory - show message in webview
646 if( (unsigned)aPage < m_panels.size() )
647 {
648 // Get the panel's webview if it exists (it may not be directly accessible)
649 // Instead, we'll set the message on the main webview if it's associated with this panel
650 if( m_selectedWidget == nullptr && aPage == m_notebook->GetSelection() )
651 {
653 }
654 }
655 }
656
657 Layout();
658}
659
660
661
663{
664 wxFileName fn;
665 fn.AssignDir( m_tcTemplatePath->GetValue() );
666 fn.Normalize( FN_NORMALIZE_FLAGS | wxPATH_NORM_ENV_VARS );
667 wxString currPath = fn.GetFullPath();
668
669 wxDirDialog dirDialog( this, _( "Select Templates Directory" ), currPath,
670 wxDD_DEFAULT_STYLE | wxDD_DIR_MUST_EXIST );
671
672 if( dirDialog.ShowModal() != wxID_OK )
673 return;
674
675 wxFileName dirName = wxFileName::DirName( dirDialog.GetPath() );
676
677 m_tcTemplatePath->SetValue( dirName.GetFullPath() );
678
679 // Rebuild the page from the new templates path:
681}
682
683
684void DIALOG_TEMPLATE_SELECTOR::onReload( wxCommandEvent& event )
685{
686 int page = m_notebook->GetSelection();
687
688 if( page < 0 )
689 return; // Should not happen
690
691 wxString currPath = m_tcTemplatePath->GetValue();
692
693 wxFileName fn;
694 fn.AssignDir( m_tcTemplatePath->GetValue() );
695 fn.Normalize( FN_NORMALIZE_FLAGS | wxPATH_NORM_ENV_VARS );
696 currPath = fn.GetFullPath();
697 m_tcTemplatePath->SetValue( currPath );
698
700}
701
702
704{
705 // Rebuild the page from the new templates path:
706 int page = m_notebook->GetSelection();
707
708 if( page < 0 )
709 return; // Should not happen
710
711 wxString title = m_notebook->GetPageText( page );
712 wxString currPath = m_tcTemplatePath->GetValue();
713
714 // Save the user template flag before deleting
715 bool wasUserTemplates = false;
716
717 if( (unsigned)page < m_panels.size() )
718 wasUserTemplates = m_panels[page]->IsUserTemplates();
719
720 // Block all events to the notebook and its children
721 wxEventBlocker blocker( m_notebook );
722
723 // Detach webview from current panel before deleting it
724 if( (unsigned)page < m_panels.size() )
725 {
726 m_panels[page]->m_SizerBase->Detach( m_webviewPanel );
727 m_webviewPanel->Reparent( this ); // Reparent to dialog
728 m_webviewPanel->Hide(); // Hide webview panel temporarily
729 }
730
731 m_notebook->DeletePage( page );
732
734 tpanel->SetIsUserTemplates( wasUserTemplates ); // Restore the flag
735 m_panels[page] = tpanel;
736 m_notebook->InsertPage( page, tpanel, title, true );
737
738 // Reparent and add webview back to the new panel
739 m_webviewPanel->Reparent( tpanel );
740 m_webviewPanel->Show();
741 tpanel->m_SizerBase->Add( m_webviewPanel, 1, wxEXPAND | wxALL, 5 );
742
743 buildPageContent( m_tcTemplatePath->GetValue(), page );
744
745 m_selectedWidget = nullptr;
746 // Reset to welcome page after rebuilding
747 m_webviewPanel->SetPage( GetWelcomeHtml() );
748
749 Layout();
750}
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:104
wxBitmapBundle KiBitmapBundle(BITMAPS aBitmap, int aMinHeight)
Definition bitmap.cpp:110
DIALOG_TEMPLATE_SELECTOR_BASE(wxWindow *parent, wxWindowID id=wxID_ANY, const wxString &title=_("Project Template Selector"), const wxPoint &pos=wxDefaultPosition, const wxSize &size=wxSize(513, 523), long style=wxDEFAULT_DIALOG_STYLE|wxRESIZE_BORDER)
void AddTemplate(int aPage, PROJECT_TEMPLATE *aTemplate)
void OnPageChange(wxNotebookEvent &event) override
void onReload(wxCommandEvent &event) override
DIALOG_TEMPLATE_SELECTOR(wxWindow *aParent, const wxPoint &aPos, const wxSize &aSize, std::vector< std::pair< wxString, wxFileName > > aTitleDirList, const wxFileName &aDefaultTemplate)
void onDirectoryBrowseClicked(wxCommandEvent &event) override
void replaceCurrentPage()
Refresh the current page to show updated template list.
std::vector< TEMPLATE_WIDGET * > m_allWidgets
void SetWidget(TEMPLATE_WIDGET *aWidget)
void buildPageContent(const wxString &aPath, int aPage)
wxString GetUserTemplatesPath() const
Get the path to the user templates directory (first panel marked as user templates)
std::vector< TEMPLATE_SELECTION_PANEL * > m_panels
A class which provides project template functionality.
wxBitmap * GetIcon()
Get the 64px^2 icon for the project template.
wxFileName GetHtmlFile()
Get the full Html filename for the project template.
wxString * GetTitle()
Get the title of the project (extracted from the html title tag)
Traverser class to duplicate/copy project or template files with proper renaming.
TEMPLATE_SELECTION_PANEL_BASE(wxWindow *parent, wxWindowID id=wxID_ANY, const wxPoint &pos=wxDefaultPosition, const wxSize &size=wxSize(-1,-1), long style=wxTAB_TRAVERSAL|wxBORDER_NONE, const wxString &name=wxEmptyString)
TEMPLATE_SELECTION_PANEL(wxNotebookPage *aParent, const wxString &aPath)
wxString m_templatesPath
the path to access to the folder containing the templates (which are also folders)
void AddTemplateWidget(TEMPLATE_WIDGET *aTemplateWidget)
bool m_isUserTemplates
true if this panel contains user templates
void SetIsUserTemplates(bool aIsUser)
Set whether templates in this panel are user templates (can be edited/duplicated)
TEMPLATE_WIDGET_BASE(wxWindow *parent, wxWindowID id=wxID_ANY, const wxPoint &pos=wxDefaultPosition, const wxSize &size=wxSize(-1,-1), long style=wxTAB_TRAVERSAL, const wxString &name=wxEmptyString)
void SetIsUserTemplate(bool aIsUser)
Set whether this template widget represents a user template.
PROJECT_TEMPLATE * GetTemplate()
void OnMouse(wxMouseEvent &event)
void SetTemplate(PROJECT_TEMPLATE *aTemplate)
Set the project template for this widget, which will determine the icon and title associated with thi...
DIALOG_TEMPLATE_SELECTOR * m_dialog
void onEditTemplate(wxCommandEvent &event)
void OnDoubleClick(wxMouseEvent &event)
void onDuplicateTemplate(wxCommandEvent &event)
void onRightClick(wxMouseEvent &event)
TEMPLATE_WIDGET(wxWindow *aParent, DIALOG_TEMPLATE_SELECTOR *aDialog)
PROJECT_TEMPLATE * m_currTemplate
void DisplayInfoMessage(wxWindow *aParent, const wxString &aMessage, const wxString &aExtraInfo)
Display an informational message box with aMessage.
Definition confirm.cpp:230
void DisplayErrorMessage(wxWindow *aParent, const wxString &aText, const wxString &aExtraInfo)
Display an error message with aMessage.
Definition confirm.cpp:202
This file is part of the common library.
#define _(s)
KICOMMON_API wxFont GetInfoFont(wxWindow *aWindow)
void Refresh()
Update the board display after modifying it by a python script (note: it is automatically called by a...
const int scale
wxString GetWelcomeHtml()
wxString GetNoTemplatesHtml()
wxString GetTemplateInfoHtml(const wxString &aTemplateName)
std::string path
Functions to provide common constants and other functions to assist in making a consistent UI.
#define FN_NORMALIZE_FLAGS
Default flags to pass to wxFileName::Normalize().
Definition wx_filename.h:39