KiCad PCB EDA Suite
Loading...
Searching...
No Matches
panel_sym_lib_table.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) 2017 Wayne Stambaugh <[email protected]>
5 * Copyright (C) 2021 CERN
6 * Copyright (C) 2017-2023 KiCad Developers, see AUTHORS.txt for contributors.
7 *
8 * This program is free software: you can redistribute it and/or modify it
9 * under the terms of the GNU General Public License as published by the
10 * Free Software Foundation, either version 3 of the License, or (at your
11 * option) any later version.
12 *
13 * This program is distributed in the hope that it will be useful, but
14 * WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 * General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License along
19 * with this program. If not, see <http://www.gnu.org/licenses/>.
20 */
21
22#include <set>
23#include <wx/regex.h>
24
25#include <common.h> // For ExpandEnvVarSubstitutions
27#include <project.h>
28#include <panel_sym_lib_table.h>
29#include <lib_id.h>
30#include <symbol_lib_table.h>
31#include <lib_table_lexer.h>
33#include <widgets/wx_grid.h>
34#include <confirm.h>
35#include <bitmaps.h>
36#include <lib_table_grid.h>
38#include <env_paths.h>
39#include <eeschema_id.h>
40#include <symbol_edit_frame.h>
41#include <symbol_viewer_frame.h>
42#include <sch_edit_frame.h>
43#include <kiway.h>
44#include <paths.h>
45#include <pgm_base.h>
50#include <sch_file_versions.h>
51#include <wx/filedlg.h>
52
53
54
55// clang-format off
56
61{
62 wxString m_Description;
63 wxString m_FileFilter;
65 bool m_IsFile;
66 SCH_IO_MGR::SCH_FILE_T m_Plugin;
67};
68
69
73enum {
76};
77
78
83{
84 friend class SYMBOL_GRID_TRICKS;
85
86protected:
87 LIB_TABLE_ROW* at( size_t aIndex ) override { return &m_rows.at( aIndex ); }
88
89 size_t size() const override { return m_rows.size(); }
90
92 {
93 return dynamic_cast< LIB_TABLE_ROW* >( new SYMBOL_LIB_TABLE_ROW );
94 }
95
96 LIB_TABLE_ROWS_ITER begin() override { return m_rows.begin(); }
97
99 {
100 return m_rows.insert( aIterator, aRow );
101 }
102
103 void push_back( LIB_TABLE_ROW* aRow ) override { m_rows.push_back( aRow ); }
104
106 {
107 return m_rows.erase( aFirst, aLast );
108 }
109
110public:
111 void SetValue( int aRow, int aCol, const wxString &aValue ) override
112 {
113 LIB_TABLE_GRID::SetValue( aRow, aCol, aValue );
114
115 // If setting a filepath, attempt to auto-detect the format
116 if( aCol == COL_URI )
117 {
118 SCH_IO_MGR::SCH_FILE_T pluginType = SCH_IO_MGR::GuessPluginTypeFromLibPath( aValue );
119 SetValue( aRow, COL_TYPE, SCH_IO_MGR::ShowType( pluginType ) );
120 }
121 }
122
123
125 {
126 m_rows = aTableToEdit.m_rows;
127 }
128};
129
131{
132public:
134 LIB_TABLE_GRID_TRICKS( aGrid ),
135 m_dialog( aParent )
136 {
137 }
138
139protected:
141
142 virtual void optionsEditor( int aRow ) override
143 {
145
146 if( tbl->GetNumberRows() > aRow )
147 {
148 LIB_TABLE_ROW* row = tbl->at( (size_t) aRow );
149 const wxString& options = row->GetOptions();
150 wxString result = options;
151 STRING_UTF8_MAP choices;
152
153 SCH_IO_MGR::SCH_FILE_T pi_type = SCH_IO_MGR::EnumFromStr( row->GetType() );
154 SCH_PLUGIN::SCH_PLUGIN_RELEASER pi( SCH_IO_MGR::FindPlugin( pi_type ) );
155 pi->SymbolLibOptions( &choices );
156
157 DIALOG_PLUGIN_OPTIONS dlg( m_dialog, row->GetNickName(), choices, options, &result );
158 dlg.ShowModal();
159
160 if( options != result )
161 {
162 row->SetOptions( result );
163 m_grid->Refresh();
164 }
165 }
166
167 }
168
171 virtual void paste_text( const wxString& cb_text ) override
172 {
174 size_t ndx = cb_text.find( "(sym_lib_table" );
175
176 if( ndx != std::string::npos )
177 {
178 // paste the SYMBOL_LIB_TABLE_ROWs of s-expression (sym_lib_table), starting
179 // at column 0 regardless of current cursor column.
180
181 STRING_LINE_READER slr( TO_UTF8( cb_text ), wxS( "Clipboard" ) );
182 LIB_TABLE_LEXER lexer( &slr );
183 SYMBOL_LIB_TABLE tmp_tbl;
184 bool parsed = true;
185
186 try
187 {
188 tmp_tbl.Parse( &lexer );
189 }
190 catch( PARSE_ERROR& pe )
191 {
192 DisplayError( m_dialog, pe.What() );
193 parsed = false;
194 }
195
196 if( parsed )
197 {
198 // make sure the table is big enough...
199 if( tmp_tbl.GetCount() > (unsigned) tbl->GetNumberRows() )
200 tbl->AppendRows( tmp_tbl.GetCount() - tbl->GetNumberRows() );
201
202 for( unsigned i = 0; i < tmp_tbl.GetCount(); ++i )
203 tbl->m_rows.replace( i, tmp_tbl.At( i ).clone() );
204 }
205
206 m_grid->AutoSizeColumns( false );
207 }
208 else
209 {
210 // paste spreadsheet formatted text.
211 GRID_TRICKS::paste_text( cb_text );
212
213 m_grid->AutoSizeColumns( false );
214 }
215 }
216};
217
218
220 SYMBOL_LIB_TABLE* aGlobalTable,
221 const wxString& aGlobalTablePath,
222 SYMBOL_LIB_TABLE* aProjectTable,
223 const wxString& aProjectTablePath ) :
224 PANEL_SYM_LIB_TABLE_BASE( aParent ),
225 m_globalTable( aGlobalTable ),
226 m_projectTable( aProjectTable ),
227 m_project( aProject ),
228 m_parent( aParent )
229{
230 // wxGrid only supports user owned tables if they exist past end of ~wxGrid(),
231 // so make it a grid owned table.
233
234 wxArrayString pluginChoices;
235
236 pluginChoices.Add( SCH_IO_MGR::ShowType( SCH_IO_MGR::SCH_KICAD ) );
237 pluginChoices.Add( SCH_IO_MGR::ShowType( SCH_IO_MGR::SCH_LEGACY ) );
238 pluginChoices.Add( SCH_IO_MGR::ShowType( SCH_IO_MGR::SCH_DATABASE ) );
239 pluginChoices.Add( SCH_IO_MGR::ShowType( SCH_IO_MGR::SCH_CADSTAR_ARCHIVE ) );
240
241 EESCHEMA_SETTINGS* cfg = Pgm().GetSettingsManager().GetAppSettings<EESCHEMA_SETTINGS>();
242
243 if( cfg->m_lastSymbolLibDir.IsEmpty() )
245
247
248 auto autoSizeCol =
249 [&]( WX_GRID* aGrid, int aCol )
250 {
251 int prevWidth = aGrid->GetColSize( aCol );
252
253 aGrid->AutoSizeColumn( aCol, false );
254 aGrid->SetColSize( aCol, std::max( prevWidth, aGrid->GetColSize( aCol ) ) );
255 };
256
257 auto setupGrid =
258 [&]( WX_GRID* aGrid )
259 {
260 // Give a bit more room for combobox editors
261 aGrid->SetDefaultRowSize( aGrid->GetDefaultRowSize() + 4 );
262
263 // add Cut, Copy, and Paste to wxGrids
264 aGrid->PushEventHandler( new SYMBOL_GRID_TRICKS( m_parent, aGrid ) );
265
266 aGrid->SetSelectionMode( wxGrid::wxGridSelectRows );
267
268 // Set special attributes
269 wxGridCellAttr* attr;
270
271 attr = new wxGridCellAttr;
272
273 wxString wildcards = AllSymbolLibFilesWildcard()
276 attr->SetEditor( new GRID_CELL_PATH_EDITOR( m_parent, aGrid,
277 &cfg->m_lastSymbolLibDir, wildcards,
278 true, m_project->GetProjectPath() ) );
279 aGrid->SetColAttr( COL_URI, attr );
280
281 attr = new wxGridCellAttr;
282 attr->SetEditor( new wxGridCellChoiceEditor( pluginChoices ) );
283 aGrid->SetColAttr( COL_TYPE, attr );
284
285 attr = new wxGridCellAttr;
286 attr->SetRenderer( new wxGridCellBoolRenderer() );
287 attr->SetReadOnly(); // not really; we delegate interactivity to GRID_TRICKS
288 aGrid->SetColAttr( COL_ENABLED, attr );
289
290 attr = new wxGridCellAttr;
291 attr->SetRenderer( new wxGridCellBoolRenderer() );
292 attr->SetReadOnly(); // not really; we delegate interactivity to GRID_TRICKS
293 aGrid->SetColAttr( COL_VISIBLE, attr );
294
295 // all but COL_OPTIONS, which is edited with Option Editor anyways.
296 autoSizeCol( aGrid, COL_NICKNAME );
297 autoSizeCol( aGrid, COL_TYPE );
298 autoSizeCol( aGrid, COL_URI );
299 autoSizeCol( aGrid, COL_DESCR );
300 autoSizeCol( aGrid, COL_ENABLED );
301
302 // Gives a selection to each grid, mainly for delete button. wxGrid's wake up with
303 // a currentCell which is sometimes not highlighted.
304 if( aGrid->GetNumberRows() > 0 )
305 aGrid->SelectRow( 0 );
306 };
307
308 setupGrid( m_global_grid );
309
310 if( m_projectTable )
311 {
313 setupGrid( m_project_grid );
314 }
315 else
316 {
317 m_pageNdx = 0;
318 m_notebook->DeletePage( 1 );
319 m_project_grid = nullptr;
320 }
321
322 // add Cut, Copy, and Paste to wxGrids
323 m_path_subs_grid->PushEventHandler( new GRID_TRICKS( m_path_subs_grid ) );
324
326
327 // select the last selected page
328 m_notebook->SetSelection( m_pageNdx );
330
331 m_path_subs_grid->SetColLabelValue( 0, _( "Name" ) );
332 m_path_subs_grid->SetColLabelValue( 1, _( "Value" ) );
333
334 // for ALT+A handling, we want the initial focus to be on the first selected grid.
336
337 // Configure button logos
338 m_append_button->SetBitmap( KiBitmap( BITMAPS::small_plus ) );
339 m_delete_button->SetBitmap( KiBitmap( BITMAPS::small_trash ) );
340 m_move_up_button->SetBitmap( KiBitmap( BITMAPS::small_up ) );
341 m_move_down_button->SetBitmap( KiBitmap( BITMAPS::small_down ) );
342 m_browse_button->SetBitmap( KiBitmap( BITMAPS::small_folder ) );
343}
344
345
347{
348 // Delete the GRID_TRICKS.
349 // Any additional event handlers should be popped before the window is deleted.
350 m_global_grid->PopEventHandler( true );
351
352 if( m_project_grid )
353 m_project_grid->PopEventHandler( true );
354
355 m_path_subs_grid->PopEventHandler( true );
356}
357
358
360{
361 // When the plugin type depends only of the file extension, return true.
362 // if it needs to read the actual file (taht can be not available), return false
363
364 wxFileName fn( aLibraryPath );
365 wxString ext = fn.GetExt().Lower();
366
367 // Currently, only the extension .lib is common to legacy libraries and Cadstar libraries
368 // so return false in this case
370 return false;
371
372 return true;
373}
374
375
377{
378 wxString msg;
379
380 for( SYMBOL_LIB_TABLE_GRID* model : { global_model(), project_model() } )
381 {
382 if( !model )
383 continue;
384
385 for( int r = 0; r < model->GetNumberRows(); )
386 {
387 wxString nick = model->GetValue( r, COL_NICKNAME ).Trim( false ).Trim();
388 wxString uri = model->GetValue( r, COL_URI ).Trim( false ).Trim();
389 unsigned illegalCh = 0;
390
391 if( !nick || !uri )
392 {
393 if( !nick && !uri )
394 msg = _( "A library table row nickname and path cells are empty." );
395 else if( !nick )
396 msg = _( "A library table row nickname cell is empty." );
397 else
398 msg = _( "A library table row path cell is empty." );
399
400 wxMessageDialog badCellDlg( this, msg, _( "Invalid Row Definition" ),
401 wxYES_NO | wxCENTER | wxICON_QUESTION | wxYES_DEFAULT );
402 badCellDlg.SetExtendedMessage( _( "Empty cells will result in all rows that are "
403 "invalid to be removed from the table." ) );
404 badCellDlg.SetYesNoLabels( wxMessageDialog::ButtonLabel( _( "Remove Invalid Cells" ) ),
405 wxMessageDialog::ButtonLabel( _( "Cancel Table Update" ) ) );
406
407 if( badCellDlg.ShowModal() == wxID_NO )
408 return false;
409
410 // Delete the "empty" row, where empty means missing nick or uri.
411 // This also updates the UI which could be slow, but there should only be a few
412 // rows to delete, unless the user fell asleep on the Add Row
413 // button.
414 model->DeleteRows( r, 1 );
415 }
416 else if( ( illegalCh = LIB_ID::FindIllegalLibraryNameChar( nick ) ) )
417 {
418 msg = wxString::Format( _( "Illegal character '%c' in nickname '%s'" ),
419 illegalCh,
420 nick );
421
422 // show the tabbed panel holding the grid we have flunked:
423 if( model != cur_model() )
424 m_notebook->SetSelection( model == global_model() ? 0 : 1 );
425
426 m_cur_grid->MakeCellVisible( r, 0 );
427 m_cur_grid->SetGridCursor( r, 1 );
428
429 wxMessageDialog errdlg( this, msg, _( "Library Nickname Error" ) );
430 errdlg.ShowModal();
431 return false;
432 }
433 else
434 {
435 // set the trimmed values back into the table so they get saved to disk.
436 model->SetValue( r, COL_NICKNAME, nick );
437
439 model->SetValue( r, COL_URI, uri );
440 else
441 {
442 wxString ltype = model->GetValue( r, COL_TYPE );
443 model->LIB_TABLE_GRID::SetValue( r, COL_URI, uri );
444 model->SetValue( r, COL_TYPE, ltype );
445 }
446
447 ++r; // this row was OK.
448 }
449 }
450 }
451
452 // check for duplicate nickNames, separately in each table.
453 for( SYMBOL_LIB_TABLE_GRID* model : { global_model(), project_model() } )
454 {
455 if( !model )
456 continue;
457
458 for( int r1 = 0; r1 < model->GetNumberRows() - 1; ++r1 )
459 {
460 wxString nick1 = model->GetValue( r1, COL_NICKNAME );
461
462 for( int r2=r1+1; r2 < model->GetNumberRows(); ++r2 )
463 {
464 wxString nick2 = model->GetValue( r2, COL_NICKNAME );
465
466 if( nick1 == nick2 )
467 {
468 msg = wxString::Format( _( "Multiple libraries cannot share the same "
469 "nickname ('%s')." ), nick1 );
470
471 // show the tabbed panel holding the grid we have flunked:
472 if( model != cur_model() )
473 m_notebook->SetSelection( model == global_model() ? 0 : 1 );
474
475 // go to the lower of the two rows, it is technically the duplicate:
476 m_cur_grid->MakeCellVisible( r2, 0 );
477 m_cur_grid->SetGridCursor( r2, 1 );
478
479 wxMessageDialog errdlg( this, msg, _( "Library Nickname Error" ) );
480 errdlg.ShowModal();
481
482 return false;
483 }
484 }
485 }
486 }
487
488 for( SYMBOL_LIB_TABLE* table : { global_model(), project_model() } )
489 {
490 if( !table )
491 continue;
492
493 for( unsigned int r = 0; r < table->GetCount(); ++r )
494 {
495 SYMBOL_LIB_TABLE_ROW& row = dynamic_cast<SYMBOL_LIB_TABLE_ROW&>( table->At( r ) );
496
497 if( !row.GetParent() )
498 row.SetParent( table );
499
500 if( !row.GetIsEnabled() )
501 continue;
502
503 try
504 {
505 if( row.Refresh() )
506 {
507 if( table == global_model() )
509 else
511 }
512 }
513 catch( const IO_ERROR& ioe )
514 {
515 msg.Printf( _( "Symbol library '%s' failed to load." ), row.GetNickName() );
516
517 wxMessageDialog errdlg( this, msg + wxS( "\n" ) + ioe.What(),
518 _( "Error Loading Library" ) );
519 errdlg.ShowModal();
520
521 return true;
522 }
523 }
524 }
525
526 return true;
527}
528
529
530void PANEL_SYM_LIB_TABLE::OnUpdateUI( wxUpdateUIEvent& event )
531{
532 m_pageNdx = (unsigned) std::max( 0, m_notebook->GetSelection() );
534}
535
536
538{
539 wxString wildcards = AllSymbolLibFilesWildcard()
542 + "|" + DatabaseLibFileWildcard();
543
544 EESCHEMA_SETTINGS* cfg = Pgm().GetSettingsManager().GetAppSettings<EESCHEMA_SETTINGS>();
545
546 wxString openDir = cfg->m_lastSymbolLibDir;
547
549 openDir = m_lastProjectLibDir;
550
551 wxFileDialog dlg( this, _( "Select Library" ), openDir, wxEmptyString, wildcards,
552 wxFD_OPEN | wxFD_FILE_MUST_EXIST | wxFD_MULTIPLE );
553
554 if( dlg.ShowModal() == wxID_CANCEL )
555 return;
556
558 cfg->m_lastSymbolLibDir = dlg.GetDirectory();
559 else
560 m_lastProjectLibDir = dlg.GetDirectory();
561
562 const ENV_VAR_MAP& envVars = Pgm().GetLocalEnvVariables();
563 bool addDuplicates = false;
564 bool applyToAll = false;
565 wxString warning = _( "Warning: Duplicate Nickname" );
566 wxString msg = _( "A library nicknamed '%s' already exists." );
567 wxString detailedMsg = _( "One of the nicknames will need to be changed after "
568 "adding this library." );
569
570 wxArrayString filePathsList;
571 dlg.GetPaths( filePathsList );
572
573 for( const wxString& filePath : filePathsList )
574 {
575 wxFileName fn( filePath );
576 wxString nickname = LIB_ID::FixIllegalChars( fn.GetName(), true );
577 bool doAdd = true;
578
579 if( cur_model()->ContainsNickname( nickname ) )
580 {
581 if( !applyToAll )
582 {
583 // The cancel button adds the library to the table anyway
584 addDuplicates = OKOrCancelDialog( this, warning, wxString::Format( msg, nickname ),
585 detailedMsg, _( "Skip" ), _( "Add Anyway" ),
586 &applyToAll ) == wxID_CANCEL;
587 }
588
589 doAdd = addDuplicates;
590 }
591
592 if( doAdd && m_cur_grid->AppendRows( 1 ) )
593 {
594 int last_row = m_cur_grid->GetNumberRows() - 1;
595
596 m_cur_grid->SetCellValue( last_row, COL_NICKNAME, nickname );
597
598 // attempt to auto-detect the plugin type
599 SCH_IO_MGR::SCH_FILE_T pluginType = SCH_IO_MGR::GuessPluginTypeFromLibPath( filePath );
600 m_cur_grid->SetCellValue( last_row, COL_TYPE, SCH_IO_MGR::ShowType( pluginType ) );
601
602 // try to use path normalized to an environmental variable or project path
603 wxString path = NormalizePath( filePath, &envVars, m_project->GetProjectPath() );
604
605 // Do not use the project path in the global library table. This will almost
606 // assuredly be wrong for a different project.
607 if( m_pageNdx == 0 && path.Contains( "${KIPRJMOD}" ) )
608 path = fn.GetFullPath();
609
610 m_cur_grid->SetCellValue( last_row, COL_URI, path );
611 }
612 }
613
614 if( !filePathsList.IsEmpty() )
615 {
616 m_cur_grid->MakeCellVisible( m_cur_grid->GetNumberRows() - 1, COL_ENABLED );
617 m_cur_grid->SetGridCursor( m_cur_grid->GetNumberRows() - 1, COL_NICKNAME );
618 }
619}
620
621
622void PANEL_SYM_LIB_TABLE::appendRowHandler( wxCommandEvent& event )
623{
625 return;
626
627 if( m_cur_grid->AppendRows( 1 ) )
628 {
629 int row = m_cur_grid->GetNumberRows() - 1;
630
631 // wx documentation is wrong, SetGridCursor does not make visible.
632 m_cur_grid->MakeCellVisible( row, COL_ENABLED );
633 m_cur_grid->SetGridCursor( row, COL_NICKNAME );
634 m_cur_grid->EnableCellEditControl( true );
635 m_cur_grid->ShowCellEditControl();
636 }
637}
638
639
640void PANEL_SYM_LIB_TABLE::deleteRowHandler( wxCommandEvent& event )
641{
643 return;
644
645 int curRow = m_cur_grid->GetGridCursorRow();
646 int curCol = m_cur_grid->GetGridCursorCol();
647
648 // In a wxGrid, collect rows that have a selected cell, or are selected
649 // It is not so easy: it depends on the way the selection was made.
650 // Here, we collect rows selected by clicking on a row label, and rows that contain
651 // previously-selected cells.
652 // If no candidate, just delete the row with the grid cursor.
653 wxArrayInt selectedRows = m_cur_grid->GetSelectedRows();
654 wxGridCellCoordsArray cells = m_cur_grid->GetSelectedCells();
655 wxGridCellCoordsArray blockTopLeft = m_cur_grid->GetSelectionBlockTopLeft();
656 wxGridCellCoordsArray blockBotRight = m_cur_grid->GetSelectionBlockBottomRight();
657
658 // Add all row having cell selected to list:
659 for( unsigned ii = 0; ii < cells.GetCount(); ii++ )
660 selectedRows.Add( cells[ii].GetRow() );
661
662 // Handle block selection
663 if( !blockTopLeft.IsEmpty() && !blockBotRight.IsEmpty() )
664 {
665 for( int i = blockTopLeft[0].GetRow(); i <= blockBotRight[0].GetRow(); ++i )
666 selectedRows.Add( i );
667 }
668
669 // Use the row having the grid cursor only if we have no candidate:
670 if( selectedRows.size() == 0 && m_cur_grid->GetGridCursorRow() >= 0 )
671 selectedRows.Add( m_cur_grid->GetGridCursorRow() );
672
673 if( selectedRows.size() == 0 )
674 {
675 wxBell();
676 return;
677 }
678
679 std::sort( selectedRows.begin(), selectedRows.end() );
680
681 // Remove selected rows (note: a row can be stored more than once in list)
682 int last_row = -1;
683
684 for( int ii = selectedRows.GetCount()-1; ii >= 0; ii-- )
685 {
686 int row = selectedRows[ii];
687
688 if( row != last_row )
689 {
690 last_row = row;
691 m_cur_grid->DeleteRows( row, 1 );
692 }
693 }
694
695 if( m_cur_grid->GetNumberRows() > 0 && curRow >= 0 )
696 m_cur_grid->SetGridCursor( std::min( curRow, m_cur_grid->GetNumberRows() - 1 ), curCol );
697}
698
699
700void PANEL_SYM_LIB_TABLE::moveUpHandler( wxCommandEvent& event )
701{
703 return;
704
706 int curRow = m_cur_grid->GetGridCursorRow();
707
708 // @todo: add multiple selection moves.
709 if( curRow >= 1 )
710 {
711 boost::ptr_vector< LIB_TABLE_ROW >::auto_type move_me =
712 tbl->m_rows.release( tbl->m_rows.begin() + curRow );
713
714 --curRow;
715 tbl->m_rows.insert( tbl->m_rows.begin() + curRow, move_me.release() );
716
717 if( tbl->GetView() )
718 {
719 // Update the wxGrid
720 wxGridTableMessage msg( tbl, wxGRIDTABLE_NOTIFY_ROWS_INSERTED, curRow, 0 );
721 tbl->GetView()->ProcessTableMessage( msg );
722 }
723
724 m_cur_grid->MakeCellVisible( curRow, m_cur_grid->GetGridCursorCol() );
725 m_cur_grid->SetGridCursor( curRow, m_cur_grid->GetGridCursorCol() );
726 }
727}
728
729
730void PANEL_SYM_LIB_TABLE::moveDownHandler( wxCommandEvent& event )
731{
733 return;
734
736 int curRow = m_cur_grid->GetGridCursorRow();
737
738 // @todo: add multiple selection moves.
739 if( unsigned( curRow + 1 ) < tbl->m_rows.size() )
740 {
741 boost::ptr_vector< LIB_TABLE_ROW >::auto_type move_me =
742 tbl->m_rows.release( tbl->m_rows.begin() + curRow );
743
744 ++curRow;
745 tbl->m_rows.insert( tbl->m_rows.begin() + curRow, move_me.release() );
746
747 if( tbl->GetView() )
748 {
749 // Update the wxGrid
750 wxGridTableMessage msg( tbl, wxGRIDTABLE_NOTIFY_ROWS_INSERTED, curRow - 1, 0 );
751 tbl->GetView()->ProcessTableMessage( msg );
752 }
753
754 m_cur_grid->MakeCellVisible( curRow, m_cur_grid->GetGridCursorCol() );
755 m_cur_grid->SetGridCursor( curRow, m_cur_grid->GetGridCursorCol() );
756 }
757}
758
759
761{
763 return;
764
765 wxArrayInt selectedRows = m_cur_grid->GetSelectedRows();
766
767 if( selectedRows.empty() && m_cur_grid->GetGridCursorRow() >= 0 )
768 selectedRows.push_back( m_cur_grid->GetGridCursorRow() );
769
770 wxArrayInt legacyRows;
771 wxString legacyType = SCH_IO_MGR::ShowType( SCH_IO_MGR::SCH_LEGACY );
772 wxString kicadType = SCH_IO_MGR::ShowType( SCH_IO_MGR::SCH_KICAD );
773 wxString msg;
774
775 for( int row : selectedRows )
776 {
777 if( m_cur_grid->GetCellValue( row, COL_TYPE ) == legacyType )
778 legacyRows.push_back( row );
779 }
780
781 if( legacyRows.size() <= 0 )
782 {
783 wxMessageBox( _( "Select one or more rows containing libraries in Legacy format (*.lib) "
784 "to save as current KiCad format (*.kicad_sym)." ) );
785 return;
786 }
787 else
788 {
789 if( legacyRows.size() == 1 )
790 {
791 msg.Printf( _( "Save '%s' as current KiCad format (*.kicad_sym) "
792 "and replace legacy entry in table?" ),
793 m_cur_grid->GetCellValue( legacyRows[0], COL_NICKNAME ) );
794 }
795 else
796 {
797 msg.Printf( _( "Save %d Legacy format libraries as current KiCad format (*.kicad_sym) "
798 "and replace legacy entries in table?" ),
799 (int) legacyRows.size() );
800 }
801
802 if( !IsOK( m_parent, msg ) )
803 return;
804 }
805
806 for( int row : legacyRows )
807 {
808 wxString libName = m_cur_grid->GetCellValue( row, COL_NICKNAME );
809 wxString relPath = m_cur_grid->GetCellValue( row, COL_URI );
810 wxString resolvedPath = ExpandEnvVarSubstitutions( relPath, m_project );
811 wxFileName legacyLib( resolvedPath );
812
813 if( !legacyLib.Exists() )
814 {
815 msg.Printf( _( "Library '%s' not found." ), relPath );
816 DisplayErrorMessage( this, msg );
817 continue;
818 }
819
820 wxFileName newLib( resolvedPath );
821 newLib.SetExt( "kicad_sym" );
822
823 if( newLib.Exists() )
824 {
825 msg.Printf( _( "File '%s' already exists. Do you want overwrite this file?" ),
826 newLib.GetFullPath() );
827
828 switch( wxMessageBox( msg, _( "Migrate Library" ),
829 wxYES_NO | wxCANCEL | wxICON_QUESTION, m_parent ) )
830 {
831 case wxYES: break;
832 case wxNO: continue;
833 case wxCANCEL: return;
834 }
835 }
836
837 if( convertLibrary( libName, legacyLib.GetFullPath(), newLib.GetFullPath() ) )
838 {
839 relPath = NormalizePath( newLib.GetFullPath(), &Pgm().GetLocalEnvVariables(),
840 m_project );
841
842 // Do not use the project path in the global library table. This will almost
843 // assuredly be wrong for a different project.
844 if( m_cur_grid == m_global_grid && relPath.Contains( "${KIPRJMOD}" ) )
845 relPath = newLib.GetFullPath();
846
847 m_cur_grid->SetCellValue( row, COL_URI, relPath );
848 m_cur_grid->SetCellValue( row, COL_TYPE, kicadType );
849 }
850 else
851 {
852 msg.Printf( _( "Failed to save symbol library file '%s'." ), newLib.GetFullPath() );
853 DisplayErrorMessage( this, msg );
854 }
855 }
856}
857
858
859bool PANEL_SYM_LIB_TABLE::convertLibrary( const wxString& aLibrary, const wxString& legacyFilepath,
860 const wxString& newFilepath )
861{
862 SCH_PLUGIN::SCH_PLUGIN_RELEASER legacyPI( SCH_IO_MGR::FindPlugin( SCH_IO_MGR::SCH_LEGACY ) );
863 SCH_PLUGIN::SCH_PLUGIN_RELEASER kicadPI( SCH_IO_MGR::FindPlugin( SCH_IO_MGR::SCH_KICAD ) );
864 std::vector<LIB_SYMBOL*> symbols;
865 std::vector<LIB_SYMBOL*> newSymbols;
866 std::map<LIB_SYMBOL*, LIB_SYMBOL*> symbolMap;
867
868 try
869 {
870 // Write a stub file; SaveSymbol() expects something to be there already.
871 FILE_OUTPUTFORMATTER* formatter = new FILE_OUTPUTFORMATTER( newFilepath );
872
873 formatter->Print( 0, "(kicad_symbol_lib (version %d) (generator kicad_converter))",
875
876 // This will write the file
877 delete formatter;
878
879 legacyPI->EnumerateSymbolLib( symbols, legacyFilepath );
880
881 // Copy non-aliases first so we can build a map from symbols to newSymbols
882 for( LIB_SYMBOL* symbol : symbols )
883 {
884 if( symbol->IsAlias() )
885 continue;
886
887 symbol->SetName( EscapeString( symbol->GetName(), CTX_LIBID ) );
888
889 newSymbols.push_back( new LIB_SYMBOL( *symbol ) );
890 symbolMap[symbol] = newSymbols.back();
891 }
892
893 // Now do the aliases using the map to hook them up to their newSymbol parents
894 for( LIB_SYMBOL* symbol : symbols )
895 {
896 if( !symbol->IsAlias() )
897 continue;
898
899 symbol->SetName( EscapeString( symbol->GetName(), CTX_LIBID ) );
900
901 newSymbols.push_back( new LIB_SYMBOL( *symbol ) );
902 newSymbols.back()->SetParent( symbolMap[ symbol->GetParent().lock().get() ] );
903 }
904
905 // Finally write out newSymbols
906 for( LIB_SYMBOL* symbol : newSymbols )
907 {
908 kicadPI->SaveSymbol( newFilepath, symbol );
909 }
910 }
911 catch( ... )
912 {
913 return false;
914 }
915
916 return true;
917}
918
919
921{
923 return false;
924
925 if( !verifyTables() )
926 return false;
927
928 if( *global_model() != *m_globalTable )
929 {
931
933 m_globalTable->m_rows.transfer( m_globalTable->m_rows.end(), global_model()->m_rows.begin(),
934 global_model()->m_rows.end(), global_model()->m_rows );
936 }
937
939 {
941
943 m_projectTable->m_rows.transfer( m_projectTable->m_rows.end(), project_model()->m_rows.begin(),
944 project_model()->m_rows.end(), project_model()->m_rows );
946 }
947
948 return true;
949}
950
951
953{
954 wxRegEx re( ".*?(\\$\\{(.+?)\\})|(\\$\\((.+?)\\)).*?", wxRE_ADVANCED );
955 wxASSERT( re.IsValid() ); // wxRE_ADVANCED is required.
956
957 std::set< wxString > unique;
958
959 // clear the table
961
963 {
964 if( !tbl )
965 continue;
966
967 for( int row = 0; row < tbl->GetNumberRows(); ++row )
968 {
969 wxString uri = tbl->GetValue( row, COL_URI );
970
971 while( re.Matches( uri ) )
972 {
973 wxString envvar = re.GetMatch( uri, 2 );
974
975 // if not ${...} form then must be $(...)
976 if( envvar.IsEmpty() )
977 envvar = re.GetMatch( uri, 4 );
978
979 // ignore duplicates
980 unique.insert( envvar );
981
982 // delete the last match and search again
983 uri.Replace( re.GetMatch( uri, 0 ), wxEmptyString );
984 }
985 }
986 }
987
988 // Make sure this special environment variable shows up even if it was
989 // not used yet. It is automatically set by KiCad to the directory holding
990 // the current project.
991 unique.insert( PROJECT_VAR_NAME );
993
994 for( const wxString& evName : unique )
995 {
996 int row = m_path_subs_grid->GetNumberRows();
997 m_path_subs_grid->AppendRows( 1 );
998
999 m_path_subs_grid->SetCellValue( row, 0, wxT( "${" ) + evName + wxT( "}" ) );
1000 m_path_subs_grid->SetCellEditor( row, 0, new GRID_CELL_READONLY_TEXT_EDITOR() );
1001
1002 wxString evValue;
1003 wxGetEnv( evName, &evValue );
1004 m_path_subs_grid->SetCellValue( row, 1, evValue );
1005 m_path_subs_grid->SetCellEditor( row, 1, new GRID_CELL_READONLY_TEXT_EDITOR() );
1006 }
1007
1008 // No combobox editors here, but it looks better if its consistent with the other
1009 // grids in the dialog.
1010 m_path_subs_grid->SetDefaultRowSize( m_path_subs_grid->GetDefaultRowSize() + 2 );
1011
1012 adjustPathSubsGridColumns( m_path_subs_grid->GetRect().GetWidth() );
1013}
1014
1015
1017{
1018 // Account for scroll bars
1019 aWidth -= ( m_path_subs_grid->GetSize().x - m_path_subs_grid->GetClientSize().x );
1020
1021 m_path_subs_grid->AutoSizeColumn( 0 );
1022 m_path_subs_grid->SetColSize( 0, std::max( 72, m_path_subs_grid->GetColSize( 0 ) ) );
1023 m_path_subs_grid->SetColSize( 1, std::max( 120, aWidth - m_path_subs_grid->GetColSize( 0 ) ) );
1024}
1025
1026
1027void PANEL_SYM_LIB_TABLE::onSizeGrid( wxSizeEvent& event )
1028{
1029 adjustPathSubsGridColumns( event.GetSize().GetX() );
1030
1031 event.Skip();
1032}
1033
1034
1036{
1037 return (SYMBOL_LIB_TABLE_GRID*) m_global_grid->GetTable();
1038}
1039
1040
1042{
1043 return m_project_grid ? (SYMBOL_LIB_TABLE_GRID*) m_project_grid->GetTable() : nullptr;
1044}
1045
1046
1048{
1049 return (SYMBOL_LIB_TABLE_GRID*) m_cur_grid->GetTable();
1050}
1051
1052
1054
1055
1056void InvokeSchEditSymbolLibTable( KIWAY* aKiway, wxWindow *aParent )
1057{
1058 auto* symbolEditor = (SYMBOL_EDIT_FRAME*) aKiway->Player( FRAME_SCH_SYMBOL_EDITOR, false );
1059
1061 wxString globalTablePath = SYMBOL_LIB_TABLE::GetGlobalTableFileName();
1062 SYMBOL_LIB_TABLE* projectTable = nullptr;
1063 wxString projectPath = aKiway->Prj().GetProjectPath();
1064 wxFileName projectTableFn( projectPath, SYMBOL_LIB_TABLE::GetSymbolLibTableFileName() );
1065 wxString msg;
1066 wxString currentLib;
1067
1068 // Don't allow editing project tables if no project is open
1069 if( !aKiway->Prj().IsNullProject() )
1070 projectTable = aKiway->Prj().SchSymbolLibTable();
1071
1072 if( symbolEditor )
1073 {
1074 currentLib = symbolEditor->GetCurLib();
1075
1076 // This prevents an ugly crash on OSX (https://bugs.launchpad.net/kicad/+bug/1765286)
1077 symbolEditor->FreezeLibraryTree();
1078
1079 if( symbolEditor->HasLibModifications() )
1080 {
1081 msg = _( "Modifications have been made to one or more symbol libraries.\n"
1082 "Changes must be saved or discarded before the symbol library "
1083 "table can be modified." );
1084
1085 switch( UnsavedChangesDialog( aParent, msg ) )
1086 {
1087 case wxID_YES: symbolEditor->SaveAll(); break;
1088 case wxID_NO: symbolEditor->RevertAll(); break;
1089 default:
1090 case wxID_CANCEL: symbolEditor->ThawLibraryTree(); return;
1091 }
1092 }
1093 }
1094
1095 DIALOG_EDIT_LIBRARY_TABLES dlg( aParent, _( "Symbol Libraries" ) );
1096 dlg.SetKiway( &dlg, aKiway );
1097
1098 dlg.InstallPanel( new PANEL_SYM_LIB_TABLE( &dlg, &aKiway->Prj(), globalTable, globalTablePath,
1099 projectTable, projectTableFn.GetFullPath() ) );
1100
1101 if( dlg.ShowModal() == wxID_CANCEL )
1102 {
1103 if( symbolEditor )
1104 symbolEditor->ThawLibraryTree();
1105
1106 return;
1107 }
1108
1109 if( dlg.m_GlobalTableChanged )
1110 {
1111 try
1112 {
1113 globalTable->Save( globalTablePath );
1114 }
1115 catch( const IO_ERROR& ioe )
1116 {
1117 msg.Printf( _( "Error saving global library table:\n\n%s" ), ioe.What() );
1118 wxMessageBox( msg, _( "File Save Error" ), wxOK | wxICON_ERROR );
1119 }
1120 }
1121
1122 if( projectTable && dlg.m_ProjectTableChanged )
1123 {
1124 try
1125 {
1126 projectTable->Save( projectTableFn.GetFullPath() );
1127 }
1128 catch( const IO_ERROR& ioe )
1129 {
1130 msg.Printf( _( "Error saving project-specific library table:\n\n%s" ), ioe.What() );
1131 wxMessageBox( msg, _( "File Save Error" ), wxOK | wxICON_ERROR );
1132 }
1133 }
1134
1135 if( symbolEditor )
1136 {
1137 symbolEditor->ThawLibraryTree();
1138 }
1139
1140 std::string payload = "";
1141 aKiway->ExpressMail( FRAME_SCH, MAIL_RELOAD_LIB, payload );
1143 aKiway->ExpressMail( FRAME_SCH_VIEWER, MAIL_RELOAD_LIB, payload );
1144}
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:106
DIALOG_PLUGIN_OPTIONS is an options editor in the form of a two column name/value spreadsheet like (t...
void SetInitialFocus(wxWindow *aWindow)
Sets the window (usually a wxTextCtrl) that should be focused when the dialog is shown.
Definition: dialog_shim.h:97
Used for text file output.
Definition: richio.h:469
Editor for wxGrid cells that adds a file/folder browser to the grid input field.
Add mouse and command handling (such as cut, copy, and paste) to a WX_GRID instance.
Definition: grid_tricks.h:61
virtual void paste_text(const wxString &cb_text)
WX_GRID * m_grid
I don't own the grid, but he owns me.
Definition: grid_tricks.h:125
Hold an error message and may be used when throwing exceptions containing meaningful error messages.
Definition: ki_exception.h:76
virtual const wxString What() const
A composite of Problem() and Where()
Definition: exceptions.cpp:30
void SetKiway(wxWindow *aDest, KIWAY *aKiway)
It is only used for debugging, since "this" is not a wxWindow*.
A minimalistic software bus for communications between various DLLs/DSOs (DSOs) within the same KiCad...
Definition: kiway.h:279
virtual KIWAY_PLAYER * Player(FRAME_T aFrameType, bool doCreate=true, wxTopLevelWindow *aParent=nullptr)
Return the KIWAY_PLAYER* given a FRAME_T.
Definition: kiway.cpp:432
virtual void ExpressMail(FRAME_T aDestination, MAIL_T aCommand, std::string &aPayload, wxWindow *aSource=nullptr)
Send aPayload to aDestination from aSource.
Definition: kiway.cpp:549
virtual PROJECT & Prj() const
Return the PROJECT associated with this KIWAY.
Definition: kiway.cpp:196
static unsigned FindIllegalLibraryNameChar(const UTF8 &aLibraryName)
Looks for characters that are illegal in library nicknames.
Definition: lib_id.cpp:242
static UTF8 FixIllegalChars(const UTF8 &aLibItemName, bool aLib)
Replace illegal LIB_ID item name characters with underscores '_'.
Definition: lib_id.cpp:190
Define a library symbol object.
Definition: lib_symbol.h:99
This abstract base class mixes any object derived from LIB_TABLE into wxGridTableBase so the result c...
void SetValue(int aRow, int aCol, const wxString &aValue) override
bool AppendRows(size_t aNumRows=1) override
int GetNumberRows() override
Hold a record identifying a library accessed by the appropriate plug in object in the LIB_TABLE.
const wxString & GetOptions() const
Return the options string, which may hold a password or anything else needed to instantiate the under...
LIB_TABLE * GetParent() const
virtual const wxString GetType() const =0
Return the type of library represented by this row.
void SetParent(LIB_TABLE *aParent)
const wxString & GetNickName() const
LIB_TABLE_ROW * clone() const
bool GetIsEnabled() const
void SetOptions(const wxString &aOptions)
Change the library options strings.
LIB_TABLE_ROW & At(unsigned aIndex)
Get the 'n'th LIB_TABLE_ROW object.
LIB_TABLE_ROWS m_rows
void Clear()
Delete all rows.
unsigned GetCount() const
Get the number of rows contained in the table.
void Save(const wxString &aFileName) const
Write this library table to aFileName in s-expression form.
void reindex()
Rebuilds the m_nickIndex.
int PRINTF_FUNC Print(int nestLevel, const char *fmt,...)
Format and write text to the output stream.
Definition: richio.cpp:475
Class PANEL_SYM_LIB_TABLE_BASE.
STD_BITMAP_BUTTON * m_browse_button
STD_BITMAP_BUTTON * m_move_up_button
STD_BITMAP_BUTTON * m_delete_button
STD_BITMAP_BUTTON * m_move_down_button
STD_BITMAP_BUTTON * m_append_button
Dialog to show and edit symbol library tables.
void OnUpdateUI(wxUpdateUIEvent &event) override
void moveUpHandler(wxCommandEvent &event) override
bool allowAutomaticPluginTypeSelection(wxString &aLibraryPath)
SYMBOL_LIB_TABLE * m_projectTable
static size_t m_pageNdx
Remember the last notebook page selected.
void deleteRowHandler(wxCommandEvent &event) override
void browseLibrariesHandler(wxCommandEvent &event) override
SYMBOL_LIB_TABLE_GRID * cur_model() const
PANEL_SYM_LIB_TABLE(DIALOG_EDIT_LIBRARY_TABLES *aParent, PROJECT *m_project, SYMBOL_LIB_TABLE *aGlobal, const wxString &aGlobalTablePath, SYMBOL_LIB_TABLE *aProject, const wxString &aProjectTablePath)
bool verifyTables()
Trim important fields, removes blank row entries, and checks for duplicates.
void adjustPathSubsGridColumns(int aWidth)
bool convertLibrary(const wxString &aLibrary, const wxString &legacyFilepath, const wxString &newFilepath)
SYMBOL_LIB_TABLE_GRID * global_model() const
SYMBOL_LIB_TABLE * m_globalTable
void onSizeGrid(wxSizeEvent &event) override
void onConvertLegacyLibraries(wxCommandEvent &event) override
SYMBOL_LIB_TABLE_GRID * project_model() const
void moveDownHandler(wxCommandEvent &event) override
void populateEnvironReadOnlyTable()
Populate the readonly environment variable table with names and values by examining all the full_uri ...
WX_GRID * m_cur_grid
changed based on tab choice
DIALOG_EDIT_LIBRARY_TABLES * m_parent
bool TransferDataFromWindow() override
void appendRowHandler(wxCommandEvent &event) override
static wxString GetDefaultUserSymbolsPath()
Gets the default path we point users to create projects.
Definition: paths.cpp:97
Container for project specific data.
Definition: project.h:64
virtual const wxString GetProjectPath() const
Return the full path of the project.
Definition: project.cpp:126
virtual bool IsNullProject() const
Check if this project is a null project (i.e.
Definition: project.cpp:138
static SCH_FILE_T EnumFromStr(const wxString &aFileType)
Return the #SCH_FILE_T from the corresponding plugin type name: "kicad", "legacy",...
Definition: sch_io_mgr.cpp:105
static const wxString ShowType(SCH_FILE_T aFileType)
Return a brief name for a plugin, given aFileType enum.
Definition: sch_io_mgr.cpp:84
static SCH_FILE_T GuessPluginTypeFromLibPath(const wxString &aLibPath)
Return a plugin type given a symbol library using the file extension of aLibPath.
Definition: sch_io_mgr.cpp:160
Helper object to release a SCH_PLUGIN in the context of a potential thrown exception through its dest...
Definition: sch_io_mgr.h:536
virtual void EnumerateSymbolLib(wxArrayString &aSymbolNameList, const wxString &aLibraryPath, const STRING_UTF8_MAP *aProperties=nullptr)
Populate a list of LIB_SYMBOL alias names contained within the library aLibraryPath.
Definition: sch_plugin.cpp:56
virtual void SaveSymbol(const wxString &aLibraryPath, const LIB_SYMBOL *aSymbol, const STRING_UTF8_MAP *aProperties=nullptr)
Write aSymbol to an existing library located at aLibraryPath.
Definition: sch_plugin.cpp:82
virtual void SymbolLibOptions(STRING_UTF8_MAP *aListToAppendTo) const
Append supported SCH_PLUGIN options to aListToAppenTo along with internationalized descriptions.
Definition: sch_plugin.cpp:119
void SetBitmap(const wxBitmapBundle &aBmp)
Is a LINE_READER that reads from a multiline 8 bit wide std::string.
Definition: richio.h:253
A name/value tuple with unique names and optional values.
The symbol library editor main window.
DIALOG_EDIT_LIBRARY_TABLES * m_dialog
virtual void optionsEditor(int aRow) override
SYMBOL_GRID_TRICKS(DIALOG_EDIT_LIBRARY_TABLES *aParent, WX_GRID *aGrid)
virtual void paste_text(const wxString &cb_text) override
handle specialized clipboard text, with leading "(sym_lib_table" or spreadsheet formatted text.
Build a wxGridTableBase by wrapping an SYMBOL_LIB_TABLE object.
void SetValue(int aRow, int aCol, const wxString &aValue) override
LIB_TABLE_ROW * at(size_t aIndex) override
LIB_TABLE_ROWS_ITER erase(LIB_TABLE_ROWS_ITER aFirst, LIB_TABLE_ROWS_ITER aLast) override
LIB_TABLE_ROWS_ITER begin() override
LIB_TABLE_ROWS_ITER insert(LIB_TABLE_ROWS_ITER aIterator, LIB_TABLE_ROW *aRow) override
LIB_TABLE_ROW * makeNewRow() override
void push_back(LIB_TABLE_ROW *aRow) override
size_t size() const override
SYMBOL_LIB_TABLE_GRID(const SYMBOL_LIB_TABLE &aTableToEdit)
Hold a record identifying a symbol library accessed by the appropriate symbol library SCH_PLUGIN obje...
bool Refresh() override
Attempt to reload the library.
static SYMBOL_LIB_TABLE & GetGlobalLibTable()
virtual void Parse(LIB_TABLE_LEXER *aLexer) override
Parse the #LIB_TABLE_LEXER s-expression library table format into the appropriate LIB_TABLE_ROW objec...
static const wxString & GetSymbolLibTableFileName()
static wxString GetGlobalTableFileName()
Fetch the global symbol library table file name.
static const wxString GlobalPathEnvVariableName()
Return the name of the environment variable used to hold the directory of locally installed "KiCad sp...
void SetTable(wxGridTableBase *table, bool aTakeOwnership=false)
Hide wxGrid's SetTable() method with one which doesn't mess up the grid column widths when setting th...
Definition: wx_grid.cpp:164
void ClearRows()
wxWidgets recently added an ASSERT which fires if the position is greater than or equal to the number...
Definition: wx_grid.h:147
bool CommitPendingChanges(bool aQuietMode=false)
Close any open cell edit controls.
Definition: wx_grid.cpp:474
const wxString ExpandEnvVarSubstitutions(const wxString &aString, const PROJECT *aProject)
Replace any environment variable & text variable references with their values.
Definition: common.cpp:299
The common library.
int OKOrCancelDialog(wxWindow *aParent, const wxString &aWarning, const wxString &aMessage, const wxString &aDetailedMessage, const wxString &aOKLabel, const wxString &aCancelLabel, bool *aApplyToAll)
Display a warning dialog with aMessage and returns the user response.
Definition: confirm.cpp:256
bool IsOK(wxWindow *aParent, const wxString &aMessage)
Display a yes/no dialog with aMessage and returns the user response.
Definition: confirm.cpp:363
void DisplayError(wxWindow *aParent, const wxString &aText, int aDisplayTime)
Display an error or warning message box with aMessage.
Definition: confirm.cpp:283
void DisplayErrorMessage(wxWindow *aParent, const wxString &aText, const wxString &aExtraInfo)
Display an error message with aMessage.
Definition: confirm.cpp:308
int UnsavedChangesDialog(wxWindow *parent, const wxString &aMessage, bool *aApplyToAll)
A specialized version of HandleUnsavedChanges which handles an apply-to-all checkbox.
Definition: confirm.cpp:180
This file is part of the common library.
#define _(s)
@ ID_END_EESCHEMA_ID_LIST
Definition: eeschema_id.h:83
wxString NormalizePath(const wxFileName &aFilePath, const ENV_VAR_MAP *aEnvVars, const wxString &aProjectPath)
Normalize a file path to an environmental variable, if possible.
Definition: env_paths.cpp:71
@ FRAME_SCH_SYMBOL_EDITOR
Definition: frame_type.h:35
@ FRAME_SCH_VIEWER
Definition: frame_type.h:36
@ FRAME_SCH
Definition: frame_type.h:34
const std::string LegacySymbolLibFileExtension
wxString DatabaseLibFileWildcard()
wxString LegacySymbolLibFileWildcard()
wxString KiCadSymbolLibFileWildcard()
wxString AllSymbolLibFilesWildcard()
std::map< wxString, ENV_VAR_ITEM > ENV_VAR_MAP
LIB_TABLE_ROWS::iterator LIB_TABLE_ROWS_ITER
@ COL_DESCR
@ COL_NICKNAME
@ COL_ENABLED
@ COL_URI
#define TO_UTF8(wxstring)
Convert a wxString to a UTF8 encoded C string for all wxWidgets build modes.
Definition: macros.h:96
@ MAIL_RELOAD_LIB
Definition: mail_type.h:55
void InvokeSchEditSymbolLibTable(KIWAY *aKiway, wxWindow *aParent)
@ ID_PANEL_SYM_LIB_LEGACY
@ ID_PANEL_SYM_LIB_KICAD
see class PGM_BASE
#define PROJECT_VAR_NAME
A variable name whose value holds the current project directory.
Definition: project.h:39
#define SEXPR_SYMBOL_LIB_FILE_VERSION
This file contains the file format version information for the s-expression schematic and symbol libr...
KIWAY Kiway & Pgm(), KFCTL_STANDALONE
The global Program "get" accessor.
Definition: single_top.cpp:115
wxString EscapeString(const wxString &aSource, ESCAPE_CONTEXT aContext)
The Escape/Unescape routines use HTML-entity-reference-style encoding to handle characters which are:...
@ CTX_LIBID
Definition: string_utils.h:55
A filename or source description, a problem input line, a line number, a byte offset,...
Definition: ki_exception.h:119
Container that describes file type info for the add a library options.
bool m_IsFile
Whether the library is a folder or a file.
wxString m_Description
Description shown in the file picker dialog.
wxString m_FileFilter
Filter used for file pickers if m_IsFile is true.
SCH_IO_MGR::SCH_FILE_T m_Plugin
wxString m_FolderSearchExtension
In case of folders it stands for extensions of files stored inside.
Definition of file extensions used in Kicad.