KiCad PCB EDA Suite
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 <brian.sidebotham@gmail.com>
5  * Copyright (C) 1992-2021 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>
27 #include <wx/dir.h>
28 #include <wx/dirdlg.h>
29 #include <wx/settings.h>
30 
31 
33  const wxString& aPath ) :
35 {
36  m_parent = aParent;
37  m_templatesPath = aPath;
38  m_minHeight = 0;
39 }
40 
41 
43 {
44  m_SizerChoice->Add( aTemplateWidget );
45  int height = aTemplateWidget->GetBestSize().GetHeight();
46  m_minHeight = std::max( m_minHeight, height );
47 }
48 
49 
51  TEMPLATE_WIDGET_BASE( aParent )
52 {
53  m_parent = aParent;
54  m_dialog = aDialog;
55 
56  // wxWidgets_3.xx way of doing the same...
57  // Bind(wxEVT_LEFT_DOWN, &TEMPLATE_WIDGET::OnMouse, this );
58 
59  m_bitmapIcon->Connect( wxEVT_LEFT_DOWN, wxMouseEventHandler( TEMPLATE_WIDGET::OnMouse ),
60  nullptr, this );
61  m_staticTitle->Connect( wxEVT_LEFT_DOWN, wxMouseEventHandler( TEMPLATE_WIDGET::OnMouse ),
62  nullptr, this );
63 
64  // We're not selected until we're clicked
65  Unselect();
66 
67  // Start with template being NULL
68  m_currTemplate = nullptr;
69 }
70 
71 
73 {
74  m_dialog->SetWidget( this );
75  SetBackgroundColour( wxSystemSettings::GetColour( wxSYS_COLOUR_BTNHIGHLIGHT ) );
76  m_selected = true;
77  Refresh();
78 }
79 
80 
82 {
83  SetBackgroundColour( wxSystemSettings::GetColour( wxSYS_COLOUR_BTNFACE ) );
84  m_selected = false;
85  Refresh();
86 }
87 
88 
90 {
91  m_currTemplate = aTemplate;
92  m_staticTitle->SetLabel( *aTemplate->GetTitle() );
93  m_staticTitle->Wrap( 100 );
94  m_bitmapIcon->SetBitmap( *aTemplate->GetIcon() );
95 }
96 
97 
98 void TEMPLATE_WIDGET::OnMouse( wxMouseEvent& event )
99 {
100  // Toggle selection here
101  Select();
102  event.Skip();
103 }
104 
105 
107 {
108  // Ensure all panels have the full available width:
109  for( size_t i = 0; i < m_notebook->GetPageCount(); i++ )
110  {
111  // Gives a little margin for panel horizontal size, especially to show the
112  // full scroll bars of wxScrolledWindow
113  // Fix me if a better way exists
114  const int h_margin = 10;
115 
116  int max_width = m_notebook->GetClientSize().GetWidth() - h_margin;
117  m_panels[i]->SetSize( max_width, -1);
118  }
119 
120  Refresh();
121 
122  event.Skip();
123 }
124 
125 
126 void DIALOG_TEMPLATE_SELECTOR::OnPageChange( wxNotebookEvent& event )
127 {
128  int page = event.GetSelection();
129 
130  if( page != wxNOT_FOUND && (unsigned)page < m_panels.size() )
131  m_tcTemplatePath->SetValue( m_panels[page]->GetPath() );
132 
133  event.Skip();
134 }
135 
136 
139 {
142 
143  m_htmlWin->SetPage( _( "<h1>Template Selector</h1>" ) );
144  m_notebook->Connect( wxEVT_SIZE,
145  wxSizeEventHandler( DIALOG_TEMPLATE_SELECTOR::onNotebookResize ),
146  nullptr, this );
147  m_selectedWidget = nullptr;
148 }
149 
150 
152 {
153  if( m_selectedWidget != nullptr )
155 
156  m_selectedWidget = aWidget;
158 }
159 
160 
162 {
163  TEMPLATE_WIDGET* w = new TEMPLATE_WIDGET( m_panels[aPage]->m_scrolledWindow, this );
164  w->SetTemplate( aTemplate );
165  m_panels[aPage]->AddTemplateWidget( w );
166 
167  m_notebook->Refresh();
168 }
169 
170 
172 {
173  return m_selectedWidget? m_selectedWidget->GetTemplate() : nullptr;
174 }
175 
176 
177 void DIALOG_TEMPLATE_SELECTOR::AddTemplatesPage( const wxString& aTitle, wxFileName& aPath )
178 {
179  wxNotebookPage* newPage = new wxNotebookPage( m_notebook, wxID_ANY );
180 
181  aPath.Normalize();
182  wxString path = aPath.GetFullPath(); // caller ensures this ends with file separator.
183 
184  TEMPLATE_SELECTION_PANEL* tpanel = new TEMPLATE_SELECTION_PANEL( newPage, path );
185  m_panels.push_back( tpanel );
186 
187  m_notebook->AddPage( newPage, aTitle );
188 
189  if( m_notebook->GetPageCount() == 1 )
190  m_tcTemplatePath->SetValue( path );
191 
192  buildPageContent( path, m_notebook->GetPageCount() - 1 );
193 
194  // Ensure m_notebook has a minimal height to show the template widgets:
195  // and add a margin for scroll bars and decorations
196  // FIX ME: find a better way to allow space for these items: the value works on MSW
197  // but is too big on GTK. But I did not find a better way (JPC)
198  const int margin = 50;
199  int min_height = tpanel->GetMinHeight() + margin;
200 
201  if( m_notebook->GetMinClientSize().GetHeight() < min_height )
202  m_notebook->SetMinClientSize( wxSize( -1, min_height ) );
203 }
204 
205 
206 void DIALOG_TEMPLATE_SELECTOR::buildPageContent( const wxString& aPath, int aPage )
207 {
208  // Get a list of files under the template path to include as choices...
209  wxDir dir;
210 
211  if( dir.Open( aPath ) )
212  {
213  if( dir.HasSubDirs( "meta" ) )
214  {
215  AddTemplate( aPage, new PROJECT_TEMPLATE( aPath ) );
216  }
217  else
218  {
219  wxDir sub_dir;
220  wxString sub_name;
221 
222  bool cont = dir.GetFirst( &sub_name, wxEmptyString, wxDIR_DIRS );
223 
224  while( cont )
225  {
226  wxString sub_full = aPath + sub_name;
227 
228  if( sub_dir.Open( sub_full ) )
229  AddTemplate( aPage, new PROJECT_TEMPLATE( sub_full ) );
230 
231  cont = dir.GetNext( &sub_name );
232  }
233  }
234  }
235 }
236 
237 
239 {
240  wxFileName fn;
241  fn.AssignDir( m_tcTemplatePath->GetValue() );
242  fn.Normalize();
243  wxString currPath = fn.GetFullPath();
244 
245  wxDirDialog dirDialog( this, _( "Select Templates Directory" ), currPath,
246  wxDD_DEFAULT_STYLE | wxDD_DIR_MUST_EXIST );
247 
248  if( dirDialog.ShowModal() != wxID_OK )
249  return;
250 
251  wxFileName dirName = wxFileName::DirName( dirDialog.GetPath() );
252 
253  m_tcTemplatePath->SetValue( dirName.GetFullPath() );
254 
255  // Rebuild the page from the new templates path:
257 }
258 
259 
260 void DIALOG_TEMPLATE_SELECTOR::onReload( wxCommandEvent& event )
261 {
262  int page = m_notebook->GetSelection();
263 
264  if( page < 0 )
265  return; // Should not happen
266 
267  wxString currPath = m_tcTemplatePath->GetValue();
268 
269  wxFileName fn;
270  fn.AssignDir( m_tcTemplatePath->GetValue() );
271  fn.Normalize();
272  currPath = fn.GetFullPath();
273  m_tcTemplatePath->SetValue( currPath );
274 
276 }
277 
278 
280 {
281  // Rebuild the page from the new templates path:
282  int page = m_notebook->GetSelection();
283 
284  if( page < 0 )
285  return; // Should not happen
286 
287  wxString title = m_notebook->GetPageText( page );
288  wxString currPath = m_tcTemplatePath->GetValue();
289 
290  m_notebook->DeletePage( page );
291 
292  wxNotebookPage* newPage = new wxNotebookPage( m_notebook, wxID_ANY );
293  TEMPLATE_SELECTION_PANEL* tpanel = new TEMPLATE_SELECTION_PANEL( newPage, currPath );
294  m_panels[page] = tpanel;
295  m_notebook->InsertPage( page, newPage, title, true );
296 
297  buildPageContent( m_tcTemplatePath->GetValue(), page );
298 
299  m_selectedWidget = nullptr;
300 }
301 
302 
303 void DIALOG_TEMPLATE_SELECTOR::OnHtmlLinkActivated( wxHtmlLinkEvent& event )
304 {
305  wxString url = event.GetLinkInfo().GetHref();
306  wxLaunchDefaultBrowser( url );
307 }
TEMPLATE_WIDGET(wxWindow *aParent, DIALOG_TEMPLATE_SELECTOR *aDialog)
void buildPageContent(const wxString &aPath, int aPage)
void OnPageChange(wxNotebookEvent &event) override
PROJECT_TEMPLATE * GetSelectedTemplate()
void onNotebookResize(wxSizeEvent &event)
wxFileName GetHtmlFile()
Get the full Html filename for the project template.
void OnHtmlLinkActivated(wxHtmlLinkEvent &event) override
DIALOG_TEMPLATE_SELECTOR(wxWindow *aParent)
void onDirectoryBrowseClicked(wxCommandEvent &event) override
A class which provides project template functionality.
std::vector< TEMPLATE_SELECTION_PANEL * > m_panels
PROJECT_TEMPLATE * GetTemplate()
void Refresh()
Update the board display after modifying it by a python script (note: it is automatically called by a...
void AddTemplate(int aPage, PROJECT_TEMPLATE *aTemplate)
bool SetPage(const wxString &aSource) override
Definition: html_window.cpp:38
#define _(s)
int m_minHeight
minimal height to show templates (this is the height of the biggest template widget)
wxString * GetTitle()
Get the title of the project (extracted from the html title tag)
Class DIALOG_TEMPLATE_SELECTOR_BASE.
DIALOG_TEMPLATE_SELECTOR * m_dialog
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:105
void SetHtml(const wxFileName &aFilename)
Class TEMPLATE_WIDGET_BASE.
void AddTemplateWidget(TEMPLATE_WIDGET *aTemplateWidget)
Class TEMPLATE_SELECTION_PANEL_BASE.
PROJECT_TEMPLATE * m_currTemplate
TEMPLATE_SELECTION_PANEL(wxNotebookPage *aParent, const wxString &aPath)
void SetTemplate(PROJECT_TEMPLATE *aTemplate)
Set the project template for this widget, which will determine the icon and title associated with thi...
void SetWidget(TEMPLATE_WIDGET *aWidget)
void AddTemplatesPage(const wxString &aTitle, wxFileName &aPath)
Add a new page with aTitle, populated with templates from aPath.
wxString m_templatesPath
the path to access to the folder containing the templates (which are also folders)
void OnMouse(wxMouseEvent &event)
void onReload(wxCommandEvent &event) override
wxBitmap * GetIcon()
Get the 64px^2 icon for the project template.