2012-10-14 18:57:11 +02:00
/*
* This program source code file is part of KiCad , a free EDA CAD application .
*
* Copyright ( C ) 2012 Brian Sidebotham < brian . sidebotham @ gmail . com >
2025-01-01 13:30:11 -08:00
* Copyright The KiCad Developers , see AUTHORS . txt for contributors .
2012-10-14 18:57:11 +02:00
*
* This program is free software ; you can redistribute it and / or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation ; either version 2
* of the License , or ( at your option ) any later version .
*
* This program is distributed in the hope that it will be useful ,
* but WITHOUT ANY WARRANTY ; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE . See the
* GNU General Public License for more details .
*
* You should have received a copy of the GNU General Public License
* along with this program ; if not , you may find one here :
* http : //www.gnu.org/licenses/old-licenses/gpl-2.0.html
* or you may search the http : //www.gnu.org website for the version 2 license,
* or you may write to the Free Software Foundation , Inc . ,
* 51 Franklin Street , Fifth Floor , Boston , MA 02110 - 1301 , USA
*/
# include "dialog_template_selector.h"
2021-09-26 18:38:53 +01:00
# include <bitmaps.h>
2022-12-13 20:47:28 +00:00
# include <widgets/std_bitmap_button.h>
2024-04-27 22:57:24 +03:00
# include <widgets/ui_common.h>
2022-08-14 13:36:40 -04:00
# include <wx_filename.h>
2012-10-14 18:57:11 +02:00
# include <wx/dir.h>
2020-10-18 13:31:07 +02:00
# include <wx/dirdlg.h>
2012-10-14 18:57:11 +02:00
# include <wx/settings.h>
2025-08-04 14:57:10 -07:00
static const wxString GetWelcomeHtml ( )
{
return wxString (
" <!DOCTYPE html> "
" <html lang= \" en \" > "
" <head> "
" <meta charset= \" UTF-8 \" > "
" <meta name= \" viewport \" content= \" width=device-width, initial-scale=1.0 \" > "
" <title>KiCad Project Template Selector</title> "
" <style> "
" body { font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Oxygen, Ubuntu, Cantarell, sans-serif; margin: 0; padding: 20px; background: linear-gradient(135deg, #667eea 0%, #764ba2 100%); color: #333; min-height: 100vh; box-sizing: border-box; } "
" .container { max-width: 800px; margin: 0 auto; background: rgba(255, 255, 255, 0.95); border-radius: 12px; padding: 30px; box-shadow: 0 8px 32px rgba(0, 0, 0, 0.1); backdrop-filter: blur(10px); } "
" .header { text-align: center; margin-bottom: 30px; } "
" .logo { font-size: 2.5rem; font-weight: bold; color: #4a5568; margin-bottom: 10px; text-shadow: 2px 2px 4px rgba(0, 0, 0, 0.1); } "
" .subtitle { font-size: 1.2rem; color: #666; margin-bottom: 20px; } "
2025-08-08 17:07:18 +02:00
" .welcome-card { "
# if defined( __MINGW32__ )
" background: #4299e1; " // linear-gradient does not work with webview used on MSYS2
# else
" background: linear-gradient(135deg, #4299e1, #3182ce); "
# endif
" color: white; padding: 25px; border-radius: 10px; margin-bottom: 25px; box-shadow: 0 4px 15px rgba(66, 153, 225, 0.3); } "
2025-08-04 14:57:10 -07:00
" .welcome-card h2 { margin-top: 0; font-size: 1.8rem; margin-bottom: 15px; } "
" .instructions { display: grid; grid-template-columns: repeat(auto-fit, minmax(300px, 1fr)); gap: 20px; margin-bottom: 25px; } "
" .instruction-card { background: #f7fafc; border: 2px solid #e2e8f0; border-radius: 8px; padding: 20px; transition: all 0.3s ease; position: relative; overflow: hidden; } "
" .instruction-card:hover { transform: translateY(-2px); box-shadow: 0 4px 20px rgba(0, 0, 0, 0.1); border-color: #4299e1; } "
" .instruction-card::before { content: ''; position: absolute; top: 0; left: 0; width: 4px; height: 100%; background: linear-gradient(135deg, #4299e1, #3182ce); } "
" .instruction-card h3 { color: #2d3748; margin-top: 0; margin-bottom: 10px; font-size: 1.3rem; } "
" .instruction-card p { color: #4a5568; line-height: 1.6; margin: 0; } "
" .features { background: #f0fff4; border: 2px solid #9ae6b4; border-radius: 8px; padding: 20px; margin-bottom: 25px; } "
" .features h3 { color: #22543d; margin-top: 0; margin-bottom: 15px; font-size: 1.4rem; } "
" .features ul { color: #2f855a; line-height: 1.8; margin: 0; padding-left: 20px; } "
" .features li { margin-bottom: 8px; } "
" .tips { background: #fffaf0; border: 2px solid #fbd38d; border-radius: 8px; padding: 20px; } "
" .tips h3 { color: #c05621; margin-top: 0; margin-bottom: 15px; font-size: 1.4rem; } "
" .tips p { color: #c05621; line-height: 1.6; margin: 0 0 10px 0; } "
" .highlight { background: linear-gradient(120deg, #a8edea 0%, #fed6e3 100%); padding: 2px 6px; border-radius: 4px; font-weight: 600; } "
" </style> "
" </head> "
" <body> "
" <div class= \" container \" > "
" <div class= \" header \" > "
" <div class= \" logo \" >KiCad 📑</div> "
" <div class= \" subtitle \" > " + _ ( " Project Template Selector " ) + " </div> "
" </div> "
" <div class= \" welcome-card \" > "
" <h2> " + _ ( " Welcome to Template Selection! " ) + " </h2> "
" <p> " + _ ( " Choose from a variety of pre-configured project templates to jumpstart your PCB design. Templates provide ready-to-use project structures with common components, libraries, and design rules. " ) + " </p> "
" </div> "
" <div class= \" instructions \" > "
" <div class= \" instruction-card \" > "
" <h3>→ " + _ ( " Browse Templates " ) + " </h3> "
" <p> " + _ ( " Navigate through the template tabs above to explore different categories of project templates. Each tab contains templates organized by type or complexity. " ) + " </p> "
" </div> "
" <div class= \" instruction-card \" > "
" <h3>→ " + _ ( " Select a Template " ) + " </h3> "
" <p> " + _ ( " Click on any template in the list to " ) + " <span class= \" highlight \" > " + _ ( " preview its details " ) + " </span>. " + _ ( " The template information will appear in this panel, showing descriptions, included components, and project structure. " ) + " </p> "
" </div> "
" <div class= \" instruction-card \" > "
" <h3>→ " + _ ( " Customize Path " ) + " </h3> "
" <p> " + _ ( " Use the " ) + " <span class= \" highlight \" > " + _ ( " folder path field " ) + " </span> " + _ ( " above to browse custom template directories. Click the folder icon to browse, or the refresh icon to reload templates. " ) + " </p> "
" </div> "
" <div class= \" instruction-card \" > "
" <h3>→ " + _ ( " Create Project " ) + " </h3> "
" <p> " + _ ( " Once you've found the right template, click " ) + " <span class= \" highlight \" > " + _ ( " OK " ) + " </span> " + _ ( " to create a new project based on the selected template. Your project will inherit all template settings and files. " ) + " </p> "
" </div> "
" </div> "
" <div class= \" features \" > "
" <h3> " + _ ( " What You Get with Templates " ) + " </h3> "
" <ul> "
" <li><strong> " + _ ( " Pre-configured libraries " ) + " </strong> " + _ ( " - Common components and footprints already linked " ) + " </li> "
" <li><strong> " + _ ( " Design rules " ) + " </strong> " + _ ( " - Appropriate electrical and mechanical constraints " ) + " </li> "
" <li><strong> " + _ ( " Layer stackups " ) + " </strong> " + _ ( " - Optimized for the intended application " ) + " </li> "
" <li><strong> " + _ ( " Component placement " ) + " </strong> " + _ ( " - Basic layout and routing guidelines " ) + " </li> "
" <li><strong> " + _ ( " Documentation " ) + " </strong> " + _ ( " - README files and design notes " ) + " </li> "
" <li><strong> " + _ ( " Manufacturing files " ) + " </strong> " + _ ( " - Gerber and drill file configurations " ) + " </li> "
" </ul> "
" </div> "
" <div class= \" tips \" > "
" <h3> " + _ ( " Pro Tips " ) + " </h3> "
" <p><strong> " + _ ( " Start Simple: " ) + " </strong> " + _ ( " Begin with basic templates and add more elements as you go. " ) + " </p> "
" <p><strong> " + _ ( " Customize Later: " ) + " </strong> " + _ ( " Templates are starting points - you can modify libraries, rules, and layouts after project creation. " ) + " </p> "
" <p><strong> " + _ ( " Save Your Own: " ) + " </strong> " + _ ( " Once you develop preferred settings, create a custom template for future projects. " ) + " </p> "
" </div> "
" </div> "
" </body> "
" </html> "
) ;
}
2012-10-14 18:57:11 +02:00
2015-05-16 11:20:26 +02:00
TEMPLATE_SELECTION_PANEL : : TEMPLATE_SELECTION_PANEL ( wxNotebookPage * aParent ,
2013-05-29 14:03:03 +02:00
const wxString & aPath ) :
2012-10-14 18:57:11 +02:00
TEMPLATE_SELECTION_PANEL_BASE ( aParent )
{
2015-05-16 11:20:26 +02:00
m_parent = aParent ;
2013-05-29 14:03:03 +02:00
m_templatesPath = aPath ;
2021-10-07 19:38:58 +02:00
}
void TEMPLATE_SELECTION_PANEL : : AddTemplateWidget ( TEMPLATE_WIDGET * aTemplateWidget )
{
m_SizerChoice - > Add ( aTemplateWidget ) ;
2025-01-01 12:28:20 +05:00
Layout ( ) ;
2012-10-14 18:57:11 +02:00
}
2015-05-16 11:20:26 +02:00
TEMPLATE_WIDGET : : TEMPLATE_WIDGET ( wxWindow * aParent , DIALOG_TEMPLATE_SELECTOR * aDialog ) :
2012-10-14 18:57:11 +02:00
TEMPLATE_WIDGET_BASE ( aParent )
{
2015-05-16 11:20:26 +02:00
m_parent = aParent ;
m_dialog = aDialog ;
2012-10-14 18:57:11 +02:00
2015-05-16 11:20:26 +02:00
// wxWidgets_3.xx way of doing the same...
2012-10-14 18:57:11 +02:00
// Bind(wxEVT_LEFT_DOWN, &TEMPLATE_WIDGET::OnMouse, this );
2021-09-26 22:54:30 +01:00
m_bitmapIcon - > Connect ( wxEVT_LEFT_DOWN , wxMouseEventHandler ( TEMPLATE_WIDGET : : OnMouse ) ,
nullptr , this ) ;
m_staticTitle - > Connect ( wxEVT_LEFT_DOWN , wxMouseEventHandler ( TEMPLATE_WIDGET : : OnMouse ) ,
nullptr , this ) ;
2012-10-14 18:57:11 +02:00
// We're not selected until we're clicked
Unselect ( ) ;
// Start with template being NULL
2021-07-14 15:47:32 -04:00
m_currTemplate = nullptr ;
2012-10-14 18:57:11 +02:00
}
void TEMPLATE_WIDGET : : Select ( )
{
2015-05-16 11:20:26 +02:00
m_dialog - > SetWidget ( this ) ;
2012-10-14 18:57:11 +02:00
SetBackgroundColour ( wxSystemSettings : : GetColour ( wxSYS_COLOUR_BTNHIGHLIGHT ) ) ;
2015-05-16 11:20:26 +02:00
m_selected = true ;
2012-10-14 18:57:11 +02:00
Refresh ( ) ;
}
void TEMPLATE_WIDGET : : Unselect ( )
{
SetBackgroundColour ( wxSystemSettings : : GetColour ( wxSYS_COLOUR_BTNFACE ) ) ;
2015-05-16 11:20:26 +02:00
m_selected = false ;
2012-10-14 18:57:11 +02:00
Refresh ( ) ;
}
2021-07-14 15:47:32 -04:00
void TEMPLATE_WIDGET : : SetTemplate ( PROJECT_TEMPLATE * aTemplate )
2012-10-14 18:57:11 +02:00
{
2015-05-16 11:20:26 +02:00
m_currTemplate = aTemplate ;
2022-04-18 18:30:33 +01:00
m_staticTitle - > SetFont ( KIUI : : GetInfoFont ( this ) ) ;
2025-01-01 12:28:20 +05:00
m_staticTitle - > SetLabel ( * aTemplate - > GetTitle ( ) ) ;
2021-09-26 18:38:53 +01:00
m_staticTitle - > Wrap ( 100 ) ;
2021-09-26 22:54:30 +01:00
m_bitmapIcon - > SetBitmap ( * aTemplate - > GetIcon ( ) ) ;
2012-10-14 18:57:11 +02:00
}
void TEMPLATE_WIDGET : : OnMouse ( wxMouseEvent & event )
{
2015-05-16 11:20:26 +02:00
// Toggle selection here
2012-10-14 18:57:11 +02:00
Select ( ) ;
event . Skip ( ) ;
}
2013-05-29 14:03:03 +02:00
void DIALOG_TEMPLATE_SELECTOR : : OnPageChange ( wxNotebookEvent & event )
{
2025-08-04 14:57:10 -07:00
int newPage = event . GetSelection ( ) ;
int oldPage = event . GetOldSelection ( ) ;
2013-05-29 20:00:40 +02:00
2025-08-04 14:57:10 -07:00
// Move webview panel from old page to new page
if ( oldPage ! = wxNOT_FOUND & & ( unsigned ) oldPage < m_panels . size ( ) )
{
// Detach webview from old panel
m_panels [ oldPage ] - > m_SizerBase - > Detach ( m_webviewPanel ) ;
m_panels [ oldPage ] - > Layout ( ) ;
}
if ( newPage ! = wxNOT_FOUND & & ( unsigned ) newPage < m_panels . size ( ) )
{
// Reparent the webview to the new panel
m_webviewPanel - > Reparent ( m_panels [ newPage ] ) ;
// Attach webview to new panel
m_panels [ newPage ] - > m_SizerBase - > Add ( m_webviewPanel , 1 , wxEXPAND | wxALL , 5 ) ;
m_panels [ newPage ] - > Layout ( ) ;
// Update template path
m_tcTemplatePath - > SetValue ( m_panels [ newPage ] - > GetPath ( ) ) ;
// Reset to welcome page when switching tabs if no template selected
m_webviewPanel - > SetPage ( GetWelcomeHtml ( ) ) ;
}
2019-03-03 20:12:18 +00:00
event . Skip ( ) ;
2013-05-29 14:03:03 +02:00
}
2012-10-14 18:57:11 +02:00
2024-12-31 18:19:27 +01:00
DIALOG_TEMPLATE_SELECTOR : : DIALOG_TEMPLATE_SELECTOR ( wxWindow * aParent , const wxPoint & aPos ,
2025-01-01 12:28:20 +05:00
const wxSize & aSize ,
2025-09-03 15:51:04 -07:00
std : : map < wxString , wxFileName > aTitleDirMap ,
const wxFileName & aDefaultTemplate ) :
2025-01-01 12:28:20 +05:00
DIALOG_TEMPLATE_SELECTOR_BASE ( aParent , wxID_ANY , _ ( " Project Template Selector " ) , aPos ,
aSize )
2012-10-14 18:57:11 +02:00
{
2023-10-21 14:56:19 -04:00
m_browseButton - > SetBitmap ( KiBitmapBundle ( BITMAPS : : small_folder ) ) ;
m_reloadButton - > SetBitmap ( KiBitmapBundle ( BITMAPS : : small_refresh ) ) ;
2021-09-26 18:38:53 +01:00
2021-07-14 15:47:32 -04:00
m_selectedWidget = nullptr ;
2025-09-03 15:51:04 -07:00
m_defaultTemplatePath = aDefaultTemplate ;
m_defaultWidget = nullptr ;
2024-12-09 10:10:54 +01:00
2025-01-01 12:28:20 +05:00
for ( auto & [ title , pathFname ] : aTitleDirMap )
{
pathFname . Normalize ( FN_NORMALIZE_FLAGS | wxPATH_NORM_ENV_VARS ) ;
wxString path = pathFname . GetFullPath ( ) ; // caller ensures this ends with file separator.
TEMPLATE_SELECTION_PANEL * tpanel = new TEMPLATE_SELECTION_PANEL ( m_notebook , path ) ;
m_panels . push_back ( tpanel ) ;
m_notebook - > AddPage ( tpanel , title ) ;
if ( m_notebook - > GetPageCount ( ) = = 1 )
m_tcTemplatePath - > SetValue ( path ) ;
buildPageContent ( path , m_notebook - > GetPageCount ( ) - 1 ) ;
}
2025-08-04 14:57:10 -07:00
// Move webview panel from dialog to first template selection panel
if ( ! m_panels . empty ( ) )
{
// Find the sizer containing the webview and detach it
wxSizer * parentSizer = m_webviewPanel - > GetContainingSizer ( ) ;
2025-08-08 17:07:18 +02:00
2025-08-04 14:57:10 -07:00
if ( parentSizer )
{
parentSizer - > Detach ( m_webviewPanel ) ;
}
// Reparent the webview to the first panel
m_webviewPanel - > Reparent ( m_panels [ 0 ] ) ;
// Add webview to first panel
m_panels [ 0 ] - > m_SizerBase - > Add ( m_webviewPanel , 1 , wxEXPAND | wxALL , 5 ) ;
m_panels [ 0 ] - > Layout ( ) ;
}
2025-09-03 15:51:04 -07:00
if ( m_defaultWidget )
m_defaultWidget - > Select ( ) ;
2025-08-04 14:57:10 -07:00
// Set welcome HTML after dialog is fully constructed
2025-08-08 17:07:18 +02:00
CallAfter ( [ this ] ( )
{
# if defined (_WIN32)
wxSafeYield ( ) ;
m_tcTemplatePath - > SelectNone ( ) ;
# endif
2025-09-03 15:51:04 -07:00
if ( m_selectedWidget )
{
wxFileName htmlFile = m_selectedWidget - > GetTemplate ( ) - > GetHtmlFile ( ) ;
if ( htmlFile . FileExists ( ) & & htmlFile . IsFileReadable ( ) )
m_webviewPanel - > LoadURL ( wxFileName : : FileNameToURL ( htmlFile ) ) ;
else
m_webviewPanel - > SetPage ( GetWelcomeHtml ( ) ) ;
}
else
{
m_webviewPanel - > SetPage ( GetWelcomeHtml ( ) ) ;
}
2025-08-04 14:57:10 -07:00
} ) ;
2024-12-09 10:10:54 +01:00
// When all widgets have the size fixed, call finishDialogSettings to update sizers
finishDialogSettings ( ) ;
2012-10-14 18:57:11 +02:00
}
void DIALOG_TEMPLATE_SELECTOR : : SetWidget ( TEMPLATE_WIDGET * aWidget )
{
2021-07-14 15:47:32 -04:00
if ( m_selectedWidget ! = nullptr )
2012-10-14 18:57:11 +02:00
m_selectedWidget - > Unselect ( ) ;
m_selectedWidget = aWidget ;
2025-08-04 14:57:10 -07:00
wxFileName htmlFile = aWidget - > GetTemplate ( ) - > GetHtmlFile ( ) ;
if ( htmlFile . FileExists ( ) & & htmlFile . IsFileReadable ( ) )
{
m_webviewPanel - > LoadURL ( wxFileName : : FileNameToURL ( htmlFile ) ) ;
}
else
{
// Fallback to a simple template info page if no HTML file exists
wxString templateHtml = wxString : : Format (
" <!DOCTYPE html> "
" <html><head><meta charset='UTF-8'><style> "
" body { font-family: Arial, sans-serif; margin: 20px; } "
" .template-info { background: #f0f8ff; padding: 20px; border-radius: 8px; } "
" h1 { color: #333; margin-top: 0; } "
" </style></head><body> "
" <div class='template-info'> "
" <h1>%s</h1> "
" <p>Template selected. Click OK to create a new project based on this template.</p> "
" </div></body></html> " ,
* aWidget - > GetTemplate ( ) - > GetTitle ( )
) ;
m_webviewPanel - > SetPage ( templateHtml ) ;
}
2012-10-14 18:57:11 +02:00
}
2018-03-19 12:44:00 -04:00
2012-10-14 18:57:11 +02:00
void DIALOG_TEMPLATE_SELECTOR : : AddTemplate ( int aPage , PROJECT_TEMPLATE * aTemplate )
{
2015-05-16 11:20:26 +02:00
TEMPLATE_WIDGET * w = new TEMPLATE_WIDGET ( m_panels [ aPage ] - > m_scrolledWindow , this ) ;
2012-10-14 18:57:11 +02:00
w - > SetTemplate ( aTemplate ) ;
2021-10-07 19:38:58 +02:00
m_panels [ aPage ] - > AddTemplateWidget ( w ) ;
2025-09-03 15:51:04 -07:00
wxFileName base = aTemplate - > GetHtmlFile ( ) ;
base . RemoveLastDir ( ) ;
if ( m_defaultTemplatePath . IsOk ( ) & & base = = m_defaultTemplatePath )
m_defaultWidget = w ;
2012-10-14 18:57:11 +02:00
}
2015-05-16 11:20:26 +02:00
PROJECT_TEMPLATE * DIALOG_TEMPLATE_SELECTOR : : GetSelectedTemplate ( )
{
2021-07-14 15:47:32 -04:00
return m_selectedWidget ? m_selectedWidget - > GetTemplate ( ) : nullptr ;
2015-05-16 11:20:26 +02:00
}
2018-03-19 12:44:00 -04:00
2015-05-16 11:20:26 +02:00
void DIALOG_TEMPLATE_SELECTOR : : buildPageContent ( const wxString & aPath , int aPage )
{
2012-10-14 18:57:11 +02:00
// Get a list of files under the template path to include as choices...
2025-01-01 12:28:20 +05:00
wxDir dir ;
2012-10-14 18:57:11 +02:00
2015-05-16 11:20:26 +02:00
if ( dir . Open ( aPath ) )
2012-10-14 18:57:11 +02:00
{
2018-03-19 12:44:00 -04:00
if ( dir . HasSubDirs ( " meta " ) )
2012-10-14 18:57:11 +02:00
{
2018-03-19 12:44:00 -04:00
AddTemplate ( aPage , new PROJECT_TEMPLATE ( aPath ) ) ;
}
else
{
2024-12-10 17:43:47 +00:00
wxString sub_name ;
wxArrayString subdirs ;
2018-03-19 12:44:00 -04:00
bool cont = dir . GetFirst ( & sub_name , wxEmptyString , wxDIR_DIRS ) ;
while ( cont )
2012-10-14 18:57:11 +02:00
{
2024-12-10 17:43:47 +00:00
subdirs . Add ( wxString ( sub_name ) ) ;
cont = dir . GetNext ( & sub_name ) ;
}
if ( ! subdirs . IsEmpty ( ) )
subdirs . Sort ( ) ;
for ( const wxString & dir_name : subdirs )
{
wxDir sub_dir ;
wxString sub_full = aPath + dir_name ;
2013-04-10 15:31:40 -05:00
2018-03-19 12:44:00 -04:00
if ( sub_dir . Open ( sub_full ) )
AddTemplate ( aPage , new PROJECT_TEMPLATE ( sub_full ) ) ;
}
2012-10-14 18:57:11 +02:00
}
}
2025-01-01 13:30:11 -08:00
2025-01-01 12:28:20 +05:00
Layout ( ) ;
2012-10-14 18:57:11 +02:00
}
2015-05-16 11:20:26 +02:00
void DIALOG_TEMPLATE_SELECTOR : : onDirectoryBrowseClicked ( wxCommandEvent & event )
{
wxFileName fn ;
fn . AssignDir ( m_tcTemplatePath - > GetValue ( ) ) ;
2022-08-14 13:36:40 -04:00
fn . Normalize ( FN_NORMALIZE_FLAGS | wxPATH_NORM_ENV_VARS ) ;
2015-05-16 11:20:26 +02:00
wxString currPath = fn . GetFullPath ( ) ;
2021-09-26 22:54:30 +01:00
wxDirDialog dirDialog ( this , _ ( " Select Templates Directory " ) , currPath ,
2015-05-16 11:20:26 +02:00
wxDD_DEFAULT_STYLE | wxDD_DIR_MUST_EXIST ) ;
if ( dirDialog . ShowModal ( ) ! = wxID_OK )
return ;
wxFileName dirName = wxFileName : : DirName ( dirDialog . GetPath ( ) ) ;
m_tcTemplatePath - > SetValue ( dirName . GetFullPath ( ) ) ;
// Rebuild the page from the new templates path:
replaceCurrentPage ( ) ;
}
2021-09-26 18:38:53 +01:00
void DIALOG_TEMPLATE_SELECTOR : : onReload ( wxCommandEvent & event )
2015-05-16 11:20:26 +02:00
{
int page = m_notebook - > GetSelection ( ) ;
if ( page < 0 )
return ; // Should not happen
wxString currPath = m_tcTemplatePath - > GetValue ( ) ;
wxFileName fn ;
fn . AssignDir ( m_tcTemplatePath - > GetValue ( ) ) ;
2022-08-14 13:36:40 -04:00
fn . Normalize ( FN_NORMALIZE_FLAGS | wxPATH_NORM_ENV_VARS ) ;
2015-05-16 11:20:26 +02:00
currPath = fn . GetFullPath ( ) ;
m_tcTemplatePath - > SetValue ( currPath ) ;
replaceCurrentPage ( ) ;
}
void DIALOG_TEMPLATE_SELECTOR : : replaceCurrentPage ( )
{
// Rebuild the page from the new templates path:
int page = m_notebook - > GetSelection ( ) ;
if ( page < 0 )
return ; // Should not happen
wxString title = m_notebook - > GetPageText ( page ) ;
wxString currPath = m_tcTemplatePath - > GetValue ( ) ;
2025-08-07 05:18:11 -07:00
// Block all events to the notebook and its children
wxEventBlocker blocker ( m_notebook ) ;
2025-08-04 14:57:10 -07:00
// Detach webview from current panel before deleting it
if ( ( unsigned ) page < m_panels . size ( ) )
{
m_panels [ page ] - > m_SizerBase - > Detach ( m_webviewPanel ) ;
2025-08-06 17:02:51 -07:00
m_webviewPanel - > Reparent ( this ) ; // Reparent to dialog
m_webviewPanel - > Hide ( ) ; // Hide webview panel temporarily
2025-08-04 14:57:10 -07:00
}
2015-05-16 11:20:26 +02:00
m_notebook - > DeletePage ( page ) ;
2025-01-01 12:28:20 +05:00
TEMPLATE_SELECTION_PANEL * tpanel = new TEMPLATE_SELECTION_PANEL ( m_notebook , currPath ) ;
2015-05-16 11:20:26 +02:00
m_panels [ page ] = tpanel ;
2025-01-01 12:28:20 +05:00
m_notebook - > InsertPage ( page , tpanel , title , true ) ;
2015-05-16 11:20:26 +02:00
2025-08-04 14:57:10 -07:00
// Reparent and add webview back to the new panel
m_webviewPanel - > Reparent ( tpanel ) ;
2025-08-06 17:02:51 -07:00
m_webviewPanel - > Show ( ) ;
2025-08-04 14:57:10 -07:00
tpanel - > m_SizerBase - > Add ( m_webviewPanel , 1 , wxEXPAND | wxALL , 5 ) ;
2015-05-16 11:20:26 +02:00
buildPageContent ( m_tcTemplatePath - > GetValue ( ) , page ) ;
2021-07-14 15:47:32 -04:00
m_selectedWidget = nullptr ;
2025-08-04 14:57:10 -07:00
// Reset to welcome page after rebuilding
m_webviewPanel - > SetPage ( GetWelcomeHtml ( ) ) ;
2015-07-28 15:05:47 +02:00
2025-08-04 14:57:10 -07:00
Layout ( ) ;
}