KiCad PCB EDA Suite
dialog_configure_paths.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) 2015 Wayne Stambaugh <[email protected]>
5  * Copyright (C) 2015-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 
27 #include <bitmaps.h>
28 #include <confirm.h>
29 #include <menus_helpers.h>
30 #include <validators.h>
32 #include <filename_resolver.h>
33 #include <env_vars.h>
34 #include <grid_tricks.h>
35 #include <pgm_base.h>
36 #include <widgets/wx_grid.h>
38 
39 #include <algorithm>
40 #include <wx/dirdlg.h>
41 
43 {
47 };
48 
50 {
54 };
55 
56 
58  DIALOG_CONFIGURE_PATHS_BASE( aParent ),
59  m_errorGrid( nullptr ),
60  m_errorRow( -1 ),
61  m_errorCol( -1 ),
62  m_resolver( aResolver ),
63  m_gridWidth( 0 ),
64  m_gridWidthsDirty( true ),
65  m_helpDialog( nullptr )
66 {
71  m_btnMoveUp->SetBitmap( KiBitmap( BITMAPS::small_up ) );
73 
75  m_EnvVars->AppendCols( 1 ); // for the isExternal flags
76  m_EnvVars->HideCol( TV_FLAG_COL );
77  m_EnvVars->UseNativeColHeader( true );
78 
79  wxGridCellAttr* attr = new wxGridCellAttr;
80  attr->SetEditor( new GRID_CELL_PATH_EDITOR( this, m_EnvVars, &m_curdir, wxEmptyString ) );
81  m_EnvVars->SetColAttr( TV_VALUE_COL, attr );
82 
83  attr = new wxGridCellAttr;
84  attr->SetEditor( new GRID_CELL_PATH_EDITOR( this, m_SearchPaths, &m_curdir, wxEmptyString ) );
85  m_SearchPaths->SetColAttr( TV_VALUE_COL, attr );
86 
87  // Give a bit more room for combobox editors
88  m_EnvVars->SetDefaultRowSize( m_EnvVars->GetDefaultRowSize() + 4 );
89  m_SearchPaths->SetDefaultRowSize( m_SearchPaths->GetDefaultRowSize() + 4 );
90 
91  m_EnvVars->PushEventHandler( new GRID_TRICKS( m_EnvVars ) );
92  m_SearchPaths->PushEventHandler( new GRID_TRICKS( m_SearchPaths ) );
93 
94  m_EnvVars->SetSelectionMode( wxGrid::wxGridSelectionModes::wxGridSelectRows );
95  m_SearchPaths->SetSelectionMode( wxGrid::wxGridSelectionModes::wxGridSelectRows );
96 
97  if( m_resolver )
98  {
100  m_SearchPaths->UseNativeColHeader( true );
101 
102  // prohibit these characters in the alias names: []{}()%~<>"='`;:.,&?/\|$
103  m_aliasValidator.SetStyle( wxFILTER_EXCLUDE_CHAR_LIST );
104  m_aliasValidator.SetCharExcludes( wxT( "{}[]()%~<>\"='`;:.,&?/\\|$" ) );
105  }
106  else
107  m_sb3DSearchPaths->Show( false );
108 
110  m_sdbSizerOK->SetDefault();
111 
112  // wxFormBuilder doesn't include this event...
113  m_EnvVars->Connect( wxEVT_GRID_CELL_CHANGING,
114  wxGridEventHandler( DIALOG_CONFIGURE_PATHS::OnGridCellChanging ),
115  nullptr, this );
116  m_SearchPaths->Connect( wxEVT_GRID_CELL_CHANGING,
117  wxGridEventHandler( DIALOG_CONFIGURE_PATHS::OnGridCellChanging ),
118  nullptr, this );
119 
120  GetSizer()->SetSizeHints( this );
121  Centre();
122 }
123 
124 
126 {
127  // Delete the GRID_TRICKS.
128  m_SearchPaths->PopEventHandler( true );
129  m_EnvVars->PopEventHandler( true );
130 
131  if( m_helpDialog )
132  m_helpDialog->Destroy();
133 
134  m_EnvVars->Disconnect( wxEVT_GRID_CELL_CHANGING,
135  wxGridEventHandler( DIALOG_CONFIGURE_PATHS::OnGridCellChanging ),
136  nullptr, this );
137  m_SearchPaths->Disconnect( wxEVT_GRID_CELL_CHANGING,
138  wxGridEventHandler( DIALOG_CONFIGURE_PATHS::OnGridCellChanging ),
139  nullptr, this );
140 }
141 
142 
144 {
145  if( !wxDialog::TransferDataToWindow() )
146  return false;
147 
148  // Do 3D search paths first so they get first crack at setting m_curdir
149 
150  if( m_resolver )
151  {
152  const std::list<SEARCH_PATH>* paths = m_resolver->GetPaths();
153 
154  for( auto it = paths->begin(); it != paths->end(); ++it )
155  {
156  if ( !( *it ).m_Alias.StartsWith( "${" ) && !( *it ).m_Alias.StartsWith( "$(" ) )
157  {
158  AppendSearchPath( it->m_Alias, it->m_Pathvar, it->m_Description );
159 
160  if( m_curdir.IsEmpty() )
161  m_curdir = it->m_Pathexp;
162  }
163  }
164  }
165 
166  // Environment variables
167 
168  const ENV_VAR_MAP& envVars = Pgm().GetLocalEnvVariables();
169 
170  for( auto it = envVars.begin(); it != envVars.end(); ++it )
171  {
172  const wxString& path = it->second.GetValue();
173  AppendEnvVar( it->first, path, it->second.GetDefinedExternally() );
174 
175  if( m_curdir.IsEmpty() && !path.StartsWith( "${" ) && !path.StartsWith( "$(" ) )
176  m_curdir = path;
177  }
178 
179  return true;
180 }
181 
182 
183 void DIALOG_CONFIGURE_PATHS::AppendEnvVar( const wxString& aName, const wxString& aPath,
184  bool isExternal )
185 {
186  int i = m_EnvVars->GetNumberRows();
187 
188  m_EnvVars->AppendRows( 1 );
189 
190  m_EnvVars->SetCellValue( i, TV_NAME_COL, aName );
191 
192  wxGridCellAttr* nameCellAttr = m_EnvVars->GetOrCreateCellAttr( i, TV_NAME_COL );
193  wxGridCellTextEditor* nameTextEditor = new GRID_CELL_TEXT_EDITOR();
194  nameTextEditor->SetValidator( ENV_VAR_NAME_VALIDATOR() );
195  nameCellAttr->SetEditor( nameTextEditor );
196  nameCellAttr->SetReadOnly( ENV_VAR::IsEnvVarImmutable( aName ) );
197  nameCellAttr->DecRef();
198 
199  m_EnvVars->SetCellValue( i, TV_VALUE_COL, aPath );
200 
201  wxGridCellAttr* pathCellAttr = m_EnvVars->GetOrCreateCellAttr( i, TV_VALUE_COL );
202  wxSystemColour c = isExternal ? wxSYS_COLOUR_MENU : wxSYS_COLOUR_LISTBOX;
203  pathCellAttr->SetBackgroundColour( wxSystemSettings::GetColour( c ) );
204  pathCellAttr->DecRef();
205 
206  m_EnvVars->SetCellValue( i, TV_FLAG_COL, isExternal ? wxT( "external" ) : wxEmptyString );
207 }
208 
209 
210 void DIALOG_CONFIGURE_PATHS::AppendSearchPath( const wxString& aName, const wxString& aPath,
211  const wxString& aDescription )
212 {
213  int i = m_SearchPaths->GetNumberRows();
214 
215  m_SearchPaths->AppendRows( 1 );
216 
217  m_SearchPaths->SetCellValue( i, SP_ALIAS_COL, aName );
218 
219  wxGridCellAttr* nameCellAttr = m_SearchPaths->GetOrCreateCellAttr( i, SP_ALIAS_COL );
220  wxGridCellTextEditor* nameTextEditor = new GRID_CELL_TEXT_EDITOR();
221  nameTextEditor->SetValidator( m_aliasValidator );
222  nameCellAttr->SetEditor( nameTextEditor );
223  nameCellAttr->DecRef();
224 
225  m_SearchPaths->SetCellValue( i, SP_PATH_COL, aPath );
226  m_SearchPaths->SetCellValue( i, SP_DESC_COL, aDescription );
227 }
228 
229 
231 {
233  return false;
234 
235  if( !wxDialog::TransferDataFromWindow() )
236  return false;
237 
238  // Update environment variables
239  ENV_VAR_MAP& envVarMap = Pgm().GetLocalEnvVariables();
240 
241  for( int row = 0; row < m_EnvVars->GetNumberRows(); ++row )
242  {
243  wxString name = m_EnvVars->GetCellValue( row, TV_NAME_COL );
244  wxString path = m_EnvVars->GetCellValue( row, TV_VALUE_COL );
245  bool external = !m_EnvVars->GetCellValue( row, TV_FLAG_COL ).IsEmpty();
246 
247  if( external )
248  {
249  // Don't check for consistency on external variables, just use them as-is
250  }
251  else if( name.IsEmpty() )
252  {
254  m_errorRow = row;
256  m_errorMsg = _( "Environment variable name cannot be empty." );
257  return false;
258  }
259  else if( path.IsEmpty() )
260  {
262  m_errorRow = row;
264  m_errorMsg = _( "Environment variable path cannot be empty." );
265  return false;
266  }
267 
268  if( envVarMap.count( name ) )
269  envVarMap.at( name ).SetValue( path );
270  else
271  envVarMap[ name ] = ENV_VAR_ITEM( name, path );
272  }
273 
274  // Remove deleted env vars
275  for( auto it = envVarMap.begin(); it != envVarMap.end(); )
276  {
277  bool found = false;
278 
279  for( int row = 0; row < m_EnvVars->GetNumberRows(); ++row )
280  {
281  wxString name = m_EnvVars->GetCellValue( row, TV_NAME_COL );
282 
283  if( it->first == name )
284  {
285  found = true;
286  break;
287  }
288  }
289 
290  if( found )
291  ++it;
292  else
293  it = envVarMap.erase( it );
294  }
295 
296  Pgm().SetLocalEnvVariables();
297 
298  // 3D search paths
299 
300  if( m_resolver )
301  {
302  std::vector<SEARCH_PATH> alist;
303  SEARCH_PATH alias;
304 
305  for( int row = 0; row < m_SearchPaths->GetNumberRows(); ++row )
306  {
307  alias.m_Alias = m_SearchPaths->GetCellValue( row, SP_ALIAS_COL );
308  alias.m_Pathvar = m_SearchPaths->GetCellValue( row, SP_PATH_COL );
309  alias.m_Description = m_SearchPaths->GetCellValue( row, SP_DESC_COL );
310 
311  if( alias.m_Alias.IsEmpty() )
312  {
314  m_errorRow = row;
316  m_errorMsg = _( "3D search path alias cannot be empty." );
317  return false;
318  }
319  else if( alias.m_Pathvar.IsEmpty() )
320  {
322  m_errorRow = row;
324  m_errorMsg = _( "3D search path cannot be empty." );
325  return false;
326  }
327 
328  alist.push_back( alias );
329  }
330 
331  if( !m_resolver->UpdatePathList( alist ) )
332  return false;
333  }
334 
335  return true;
336 }
337 
338 
340 {
341  wxGrid* grid = dynamic_cast<wxGrid*>( event.GetEventObject() );
342  int row = event.GetRow();
343  int col = event.GetCol();
344  wxString text = event.GetString();
345 
346  if( text.IsEmpty() )
347  {
348  if( grid == m_EnvVars )
349  {
350  if( col == TV_NAME_COL )
351  m_errorMsg = _( "Environment variable name cannot be empty." );
352  else
353  m_errorMsg = _( "Environment variable path cannot be empty." );
354  }
355  else
356  {
357  if( col == SP_ALIAS_COL )
358  m_errorMsg = _( "3D search path alias cannot be empty." );
359  else
360  m_errorMsg = _( "3D search path cannot be empty." );
361  }
362 
363  m_errorGrid = dynamic_cast<wxGrid*>( event.GetEventObject() );
364  m_errorRow = row;
365  m_errorCol = col;
366 
367  event.Veto();
368  }
369 
370  if( grid == m_EnvVars )
371  {
372  if( col == TV_VALUE_COL && m_EnvVars->GetCellValue( row, TV_FLAG_COL ).Length()
373  && !Pgm().GetCommonSettings()->m_DoNotShowAgain.env_var_overwrite_warning )
374  {
375  wxString msg1 = _( "This path was defined externally to the running process and\n"
376  "will only be temporarily overwritten." );
377  wxString msg2 = _( "The next time KiCad is launched, any paths that have already\n"
378  "been defined are honored and any settings defined in the path\n"
379  "configuration dialog are ignored. If you did not intend for\n"
380  "this behavior, either rename any conflicting entries or remove\n"
381  "the external environment variable(s) from your system." );
382  KIDIALOG dlg( this, msg1, KIDIALOG::KD_WARNING );
383  dlg.ShowDetailedText( msg2 );
384  dlg.DoNotShowCheckbox( __FILE__, __LINE__ );
385  dlg.ShowModal();
386 
387  if( dlg.DoNotShowAgain() )
388  Pgm().GetCommonSettings()->m_DoNotShowAgain.env_var_overwrite_warning = true;
389  }
390  else if( col == TV_NAME_COL && m_EnvVars->GetCellValue( row, TV_NAME_COL ) != text )
391  {
392  // This env var name is reserved and cannot be added here.
393  if( text == PROJECT_VAR_NAME )
394  {
395  wxMessageBox( wxString::Format( _( "The name %s is reserved, and cannot be used." ),
396  PROJECT_VAR_NAME ) );
397  event.Veto();
398  }
399  else // Changing name; clear external flag
400  {
401  m_EnvVars->SetCellValue( row, TV_FLAG_COL, wxEmptyString );
402  }
403  }
404  }
405 }
406 
407 
408 void DIALOG_CONFIGURE_PATHS::OnAddEnvVar( wxCommandEvent& event )
409 {
411  return;
412 
413  AppendEnvVar( wxEmptyString, wxEmptyString, false );
414 
415  m_EnvVars->MakeCellVisible( m_EnvVars->GetNumberRows() - 1, TV_NAME_COL );
416  m_EnvVars->SetGridCursor( m_EnvVars->GetNumberRows() - 1, TV_NAME_COL );
417 
418  m_EnvVars->EnableCellEditControl( true );
419  m_EnvVars->ShowCellEditControl();
420 }
421 
422 
423 void DIALOG_CONFIGURE_PATHS::OnAddSearchPath( wxCommandEvent& event )
424 {
426  return;
427 
428  AppendSearchPath( wxEmptyString, wxEmptyString, wxEmptyString);
429 
430  m_SearchPaths->MakeCellVisible( m_SearchPaths->GetNumberRows() - 1, SP_ALIAS_COL );
431  m_SearchPaths->SetGridCursor( m_SearchPaths->GetNumberRows() - 1, SP_ALIAS_COL );
432 
433  m_SearchPaths->EnableCellEditControl( true );
434  m_SearchPaths->ShowCellEditControl();
435 }
436 
437 
438 void DIALOG_CONFIGURE_PATHS::OnRemoveEnvVar( wxCommandEvent& event )
439 {
440  int curRow = m_EnvVars->GetGridCursorRow();
441 
442  if( curRow < 0 || m_EnvVars->GetNumberRows() <= curRow )
443  {
444  return;
445  }
446  else if( ENV_VAR::IsEnvVarImmutable( m_EnvVars->GetCellValue( curRow, TV_NAME_COL ) ) )
447  {
448  wxBell();
449  return;
450  }
451 
452  m_EnvVars->CommitPendingChanges( true /* silent mode; we don't care if it's valid */ );
453  m_EnvVars->DeleteRows( curRow, 1 );
454 
455  m_EnvVars->MakeCellVisible( std::max( 0, curRow-1 ), m_EnvVars->GetGridCursorCol() );
456  m_EnvVars->SetGridCursor( std::max( 0, curRow-1 ), m_EnvVars->GetGridCursorCol() );
457 }
458 
459 
460 void DIALOG_CONFIGURE_PATHS::OnDeleteSearchPath( wxCommandEvent& event )
461 {
462  wxArrayInt selectedRows = m_SearchPaths->GetSelectedRows();
463 
464  if( selectedRows.empty() && m_SearchPaths->GetGridCursorRow() >= 0 )
465  selectedRows.push_back( m_SearchPaths->GetGridCursorRow() );
466 
467  if( selectedRows.empty() )
468  return;
469 
470  m_SearchPaths->CommitPendingChanges( true /* silent mode; we don't care if it's valid */ );
471 
472  // Reverse sort so deleting a row doesn't change the indexes of the other rows.
473  selectedRows.Sort( []( int* first, int* second ) { return *second - *first; } );
474 
475  for( int row : selectedRows )
476  {
477  m_SearchPaths->DeleteRows( row, 1 );
478 
479  // if there are still rows in grid, make previous row visible
480  if( m_SearchPaths->GetNumberRows() )
481  {
482  m_SearchPaths->MakeCellVisible( std::max( 0, row-1 ),
483  m_SearchPaths->GetGridCursorCol() );
484  m_SearchPaths->SetGridCursor( std::max( 0, row-1 ),
485  m_SearchPaths->GetGridCursorCol() );
486  }
487  }
488 }
489 
490 
491 void DIALOG_CONFIGURE_PATHS::OnSearchPathMoveUp( wxCommandEvent& event )
492 {
494  return;
495 
496  int curRow = m_SearchPaths->GetGridCursorRow();
497  int prevRow = curRow - 1;
498 
499  if( curRow > 0 )
500  {
501  for( int i = 0; i < m_SearchPaths->GetNumberCols(); ++i )
502  {
503  wxString tmp = m_SearchPaths->GetCellValue( curRow, i );
504  m_SearchPaths->SetCellValue( curRow, i, m_SearchPaths->GetCellValue( prevRow, i ) );
505  m_SearchPaths->SetCellValue( prevRow, i, tmp );
506  }
507 
508  m_SearchPaths->SetGridCursor( prevRow, m_SearchPaths->GetGridCursorCol() );
509  }
510  else
511  {
512  wxBell();
513  }
514 }
515 
516 
517 void DIALOG_CONFIGURE_PATHS::OnSearchPathMoveDown( wxCommandEvent& event )
518 {
520  return;
521 
522  int curRow = m_SearchPaths->GetGridCursorRow();
523  int nextRow = curRow + 1;
524 
525  if( curRow < m_SearchPaths->GetNumberRows() - 1 )
526  {
527  for( int i = 0; i < m_SearchPaths->GetNumberCols(); ++i )
528  {
529  wxString tmp = m_SearchPaths->GetCellValue( curRow, i );
530  m_SearchPaths->SetCellValue( curRow, i, m_SearchPaths->GetCellValue( nextRow, i ) );
531  m_SearchPaths->SetCellValue( nextRow, i, tmp );
532  }
533 
534  m_SearchPaths->SetGridCursor( nextRow, m_SearchPaths->GetGridCursorCol() );
535  }
536  else
537  {
538  wxBell();
539  }
540 }
541 
542 
544 {
545  wxASSERT((int) TV_VALUE_COL == (int) SP_PATH_COL );
546 
547  if( aEvent.GetCol() == TV_VALUE_COL )
548  {
549  wxMenu menu;
550 
551  AddMenuItem( &menu, 1, _( "File Browser..." ), KiBitmap( BITMAPS::small_folder ) );
552 
553  if( GetPopupMenuSelectionFromUser( menu ) == 1 )
554  {
555  wxDirDialog dlg( nullptr, _( "Select Path" ), m_curdir,
556  wxDD_DEFAULT_STYLE | wxDD_DIR_MUST_EXIST );
557 
558  if( dlg.ShowModal() == wxID_OK )
559  {
560  wxGrid* grid = dynamic_cast<wxGrid*>( aEvent.GetEventObject() );
561  grid->SetCellValue( aEvent.GetRow(), TV_VALUE_COL, dlg.GetPath() );
562  m_curdir = dlg.GetPath();
563  }
564  }
565  }
566 }
567 
568 
569 void DIALOG_CONFIGURE_PATHS::OnUpdateUI( wxUpdateUIEvent& event )
570 {
571  if( m_gridWidthsDirty )
572  {
573  int width = m_EnvVars->GetClientRect().GetWidth();
574 
575  m_EnvVars->AutoSizeColumn( TV_NAME_COL );
576  m_EnvVars->SetColSize( TV_NAME_COL, std::max( m_EnvVars->GetColSize( TV_NAME_COL ), 120 ) );
577 
578  m_EnvVars->SetColSize( TV_VALUE_COL, width - m_EnvVars->GetColSize( TV_NAME_COL ) );
579 
580  width = m_SearchPaths->GetClientRect().GetWidth();
581 
582  m_SearchPaths->AutoSizeColumn( SP_ALIAS_COL );
583  m_SearchPaths->SetColSize( SP_ALIAS_COL,
584  std::max( m_SearchPaths->GetColSize( SP_ALIAS_COL ), 120 ) );
585 
586  m_SearchPaths->AutoSizeColumn( SP_PATH_COL );
587  m_SearchPaths->SetColSize( SP_PATH_COL,
588  std::max( m_SearchPaths->GetColSize( SP_PATH_COL ), 300 ) );
589 
590  m_SearchPaths->SetColSize( SP_DESC_COL, width -
591  ( m_SearchPaths->GetColSize( SP_ALIAS_COL ) +
592  m_SearchPaths->GetColSize( SP_PATH_COL ) ) );
593  m_gridWidth = m_EnvVars->GetSize().GetX();
594  m_gridWidthsDirty = false;
595  }
596 
597  // Handle a grid error. This is delayed to OnUpdateUI so that we can change focus
598  // even when the original validation was triggered from a killFocus event (and for
599  // dialog with notebooks, so that the corresponding notebook page can be shown in
600  // the background when triggered from an OK).
601  if( m_errorGrid )
602  {
603  // We will re-enter this routine when the error dialog is displayed, so make
604  // sure we don't keep putting up more dialogs.
605  wxGrid* grid = m_errorGrid;
606  m_errorGrid = nullptr;
607 
609 
610  grid->SetFocus();
611  grid->MakeCellVisible( m_errorRow, m_errorCol );
612  grid->SetGridCursor( m_errorRow, m_errorCol );
613 
614  grid->EnableCellEditControl( true );
615  grid->ShowCellEditControl();
616  }
617 }
618 
619 
620 void DIALOG_CONFIGURE_PATHS::OnGridSize( wxSizeEvent& event )
621 {
622  if( event.GetSize().GetX() != m_gridWidth )
623  m_gridWidthsDirty = true;
624 
625  event.Skip();
626 }
627 
628 
629 void DIALOG_CONFIGURE_PATHS::OnHelp( wxCommandEvent& event )
630 {
631  if( m_helpDialog )
632  {
634  return;
635  }
636 
637  wxString msg = _( "Enter the name and value for each environment variable. Grey entries "
638  "are names that have been defined externally at the system or user "
639  "level. Environment variables defined at the system or user level "
640  "take precedence over the ones defined in this table. This means the "
641  "values in this table are ignored." );
642  msg << "<br><br><b>";
643  msg << _( "To ensure environment variable names are valid on all platforms, the name field "
644  "will only accept upper case letters, digits, and the underscore characters." );
645  msg << "</b>";
646 
647  for( const auto& var : ENV_VAR::GetPredefinedEnvVars() )
648  {
649  msg << "<br><br><b>" << var << "</b>";
650 
651  const auto desc = ENV_VAR::LookUpEnvVarHelp( var );
652 
653  if( desc.size() > 0 )
654  msg << ": " << desc;
655 
656  }
657 
658  m_helpDialog = new HTML_MESSAGE_BOX( nullptr, _( "Environment Variable Help" ) );
659  m_helpDialog->SetDialogSizeInDU( 400, 250 );
660 
661  m_helpDialog->AddHTML_Text( msg );
663 
664  // m_helpDialog will be destroyed when closing the dialog
665 }
void OnSearchPathMoveDown(wxCommandEvent &event) override
void DoNotShowCheckbox(wxString file, int line)
Checks the 'do not show again' setting for the dialog.
Definition: confirm.cpp:55
void DisplayErrorMessage(wxWindow *aParent, const wxString &aText, const wxString &aExtraInfo)
Display an error message with aMessage.
Definition: confirm.cpp:292
Helper class to create more flexible dialogs, including 'do not show again' checkbox handling.
Definition: confirm.h:45
This file is part of the common library.
wxMenuItem * AddMenuItem(wxMenu *aMenu, int aId, const wxString &aText, const wxBitmap &aImage, wxItemKind aType=wxITEM_NORMAL)
Create and insert a menu item with an icon into aMenu.
Definition: bitmap.cpp:257
HTML_MESSAGE_BOX * m_helpDialog
void OnGridSize(wxSizeEvent &event) override
SEARCH_PATH_GRID_COLUMNS
bool IsEnvVarImmutable(const wxString &aEnvVar)
Determine if an environment variable is "predefined", i.e.
Definition: env_vars.cpp:48
KiCad uses environment variables internally for determining the base paths for libraries,...
bool UpdatePathList(const std::vector< SEARCH_PATH > &aPathList)
Clear the current path list and substitutes the given path list and update the path configuration fil...
#define PROJECT_VAR_NAME
A variable name whose value holds the current project directory.
Definition: project.h:38
Add mouse and command handling (such as cut, copy, and paste) to a WX_GRID instance.
Definition: grid_tricks.h:55
void OnGridCellChanging(wxGridEvent &event)
KIWAY Kiway & Pgm(), KFCTL_STANDALONE
The global Program "get" accessor.
Definition: single_top.cpp:106
void SetInitialFocus(wxWindow *aWindow)
Sets the window (usually a wxTextCtrl) that should be focused when the dialog is shown.
Definition: dialog_shim.h:97
This class works around a bug in wxGrid where the first keystroke doesn't get sent through the valida...
Definition: validators.h:44
wxString m_Alias
Class DIALOG_CONFIGURE_PATHS_BASE.
void AppendEnvVar(const wxString &aName, const wxString &aPath, bool isExternal)
FILENAME_RESOLVER * m_resolver
void OnUpdateUI(wxUpdateUIEvent &event) override
wxString m_Description
wxString m_Pathvar
const std::list< SEARCH_PATH > * GetPaths() const
Return a pointer to the internal path list; the items in:load.
#define _(s)
DIALOG_CONFIGURE_PATHS(wxWindow *aParent, FILENAME_RESOLVER *aResolver)
Editor for wxGrid cells that adds a file/folder browser to the grid input field.
void OnAddSearchPath(wxCommandEvent &event) override
bool CommitPendingChanges(bool aQuietMode=false)
Close any open cell edit controls.
Definition: wx_grid.cpp:190
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 OnSearchPathMoveUp(wxCommandEvent &event) override
bool DoNotShowAgain() const
Definition: confirm.cpp:63
void Format(OUTPUTFORMATTER *out, int aNestLevel, int aCtl, const CPTREE &aTree)
Output a PTREE into s-expression format via an OUTPUTFORMATTER derivative.
Definition: ptree.cpp:200
void ShowModeless()
Show a modeless version of the dialog (without an OK button).
void SetDialogSizeInDU(int aWidth, int aHeight)
Set the dialog size, using a "logical" value.
This class provides a custom wxValidator object for limiting the allowable characters when defining a...
Definition: validators.h:91
wxString LookUpEnvVarHelp(const wxString &aEnvVar)
Look up long-form help text for a given environment variable.
Definition: env_vars.cpp:108
see class PGM_BASE
Provide an extensible class to resolve 3D model paths.
std::map< wxString, ENV_VAR_ITEM > ENV_VAR_MAP
const char * name
Definition: DXF_plotter.cpp:56
void OnHelp(wxCommandEvent &event) override
void AddHTML_Text(const wxString &message)
Add HTML text (without any change) to message list.
void OnGridCellRightClick(wxGridEvent &event) override
void OnRemoveEnvVar(wxCommandEvent &event) override
const ENV_VAR_LIST & GetPredefinedEnvVars()
Get the list of pre-defined environment variables.
Definition: env_vars.cpp:60
void ClearRows()
wxWidgets recently added an ASSERT which fires if the position is greater than or equal to the number...
Definition: wx_grid.h:106
int ShowModal() override
Definition: confirm.cpp:99
void OnDeleteSearchPath(wxCommandEvent &event) override
Functions related to environment variables, including help functions.
void OnAddEnvVar(wxCommandEvent &event) override
void AppendSearchPath(const wxString &aName, const wxString &aPath, const wxString &aDesc)
Custom text control validator definitions.