From f781691049f7131917e73938c65631b606a13f86 Mon Sep 17 00:00:00 2001 From: Wayne Stambaugh Date: Sat, 12 Aug 2017 08:09:39 -0400 Subject: [PATCH] Eeschema: add symbol library table editor dialog. Create a new dialog to edit global and project specific symbol library tables. Add menu entries for new symbol library table editor in schematic editor and symbol library editor main frame menus. Add command event handler for symbol library table editor dialog to SCH_BASE_FRAME so it is accessible from derived frames. Fix bug in default environment variables initialization. A test for existing user defined environment variables was preventing any new default environment variables added to the list from being initialized. --- common/pgm_base.cpp | 156 +- eeschema/CMakeLists.txt | 2 + eeschema/dialogs/dialog_sym_lib_table.cpp | 595 ++++++ eeschema/dialogs/dialog_sym_lib_table.h | 88 + .../dialogs/dialog_sym_lib_table_base.cpp | 237 +++ .../dialogs/dialog_sym_lib_table_base.fbp | 1590 +++++++++++++++++ eeschema/dialogs/dialog_sym_lib_table_base.h | 78 + eeschema/eeschema_id.h | 5 +- eeschema/libeditframe.cpp | 6 + eeschema/menubar.cpp | 6 + eeschema/menubar_libedit.cpp | 8 +- eeschema/sch_base_frame.cpp | 67 +- eeschema/sch_base_frame.h | 4 + eeschema/schframe.cpp | 6 + eeschema/symbol_lib_table.h | 4 +- 15 files changed, 2768 insertions(+), 84 deletions(-) create mode 100644 eeschema/dialogs/dialog_sym_lib_table.cpp create mode 100644 eeschema/dialogs/dialog_sym_lib_table.h create mode 100644 eeschema/dialogs/dialog_sym_lib_table_base.cpp create mode 100644 eeschema/dialogs/dialog_sym_lib_table_base.fbp create mode 100644 eeschema/dialogs/dialog_sym_lib_table_base.h diff --git a/common/pgm_base.cpp b/common/pgm_base.cpp index 812b8a0fa9..9058cbf75d 100644 --- a/common/pgm_base.cpp +++ b/common/pgm_base.cpp @@ -454,90 +454,94 @@ bool PGM_BASE::InitPgm() // OS specific instantiation of wxConfigBase derivative: m_common_settings = GetNewConfig( KICAD_COMMON ); - // Only define the default environment variable if they haven't been set in the - // .kicad_common configuration file. - if( m_common_settings && !m_common_settings->HasGroup( pathEnvVariables ) ) + wxString envVarName = wxT( "KIGITHUB" ); + ENV_VAR_ITEM envVarItem; + wxString envValue; + wxFileName tmpFileName; + + if( wxGetEnv( envVarName, &envValue ) == true && !envValue.IsEmpty() ) + { + tmpFileName.AssignDir( envValue ); + envVarItem.SetDefinedExternally( true ); + } + else { - wxString envVarName = wxT( "KIGITHUB" ); - ENV_VAR_ITEM envVarItem; - wxString envValue; - wxFileName tmpFileName; - envVarItem.SetValue( wxString( wxT( "https://github.com/KiCad" ) ) ); - envVarItem.SetDefinedExternally( wxGetEnv( envVarName, NULL ) ); - m_local_env_vars[ envVarName ] = envVarItem; + envVarItem.SetDefinedExternally( false ); + } - wxFileName baseSharePath; - baseSharePath.AssignDir( wxString( wxT( DEFAULT_INSTALL_PATH ) ) ); + m_local_env_vars[ envVarName ] = envVarItem; + + wxFileName baseSharePath; + baseSharePath.AssignDir( wxString( wxT( DEFAULT_INSTALL_PATH ) ) ); #if !defined( __WXMAC__ ) - baseSharePath.AppendDir( wxT( "share" ) ); - baseSharePath.AppendDir( wxT( "kicad" ) ); + baseSharePath.AppendDir( wxT( "share" ) ); + baseSharePath.AppendDir( wxT( "kicad" ) ); #endif - // KISYSMOD - envVarName = wxT( "KISYSMOD" ); - if( wxGetEnv( envVarName, &envValue ) == true && !envValue.IsEmpty() ) - { - tmpFileName.AssignDir( envValue ); - envVarItem.SetDefinedExternally( true ); - } - else - { - tmpFileName = baseSharePath; - tmpFileName.AppendDir( wxT( "modules" ) ); - envVarItem.SetDefinedExternally( false ); - } - envVarItem.SetValue( tmpFileName.GetFullPath() ); - m_local_env_vars[ envVarName ] = envVarItem; - - // KISYS3DMOD - envVarName = wxT( "KISYS3DMOD" ); - if( wxGetEnv( envVarName, &envValue ) == true && !envValue.IsEmpty() ) - { - tmpFileName.AssignDir( envValue ); - envVarItem.SetDefinedExternally( true ); - } - else - { - tmpFileName.AppendDir( wxT( "packages3d" ) ); - envVarItem.SetDefinedExternally( false ); - } - envVarItem.SetValue( tmpFileName.GetFullPath() ); - m_local_env_vars[ envVarName ] = envVarItem; - - // KICAD_PTEMPLATES - envVarName = wxT( "KICAD_PTEMPLATES" ); - if( wxGetEnv( envVarName, &envValue ) == true && !envValue.IsEmpty() ) - { - tmpFileName.AssignDir( envValue ); - envVarItem.SetDefinedExternally( true ); - } - else - { - tmpFileName = baseSharePath; - tmpFileName.AppendDir( wxT( "template" ) ); - envVarItem.SetDefinedExternally( false ); - } - envVarItem.SetValue( tmpFileName.GetFullPath() ); - m_local_env_vars[ envVarName ] = envVarItem; - - // KICAD_SYMBOLS - envVarName = wxT( "KICAD_SYMBOL_DIR" ); - if( wxGetEnv( envVarName, &envValue ) == true && !envValue.IsEmpty() ) - { - tmpFileName.AssignDir( envValue ); - envVarItem.SetDefinedExternally( true ); - } - else - { - tmpFileName = baseSharePath; - tmpFileName.AppendDir( wxT( "library" ) ); - envVarItem.SetDefinedExternally( false ); - } - envVarItem.SetValue( tmpFileName.GetFullPath() ); - m_local_env_vars[ envVarName ] = envVarItem; + // KISYSMOD + envVarName = wxT( "KISYSMOD" ); + if( wxGetEnv( envVarName, &envValue ) == true && !envValue.IsEmpty() ) + { + tmpFileName.AssignDir( envValue ); + envVarItem.SetDefinedExternally( true ); } + else + { + tmpFileName = baseSharePath; + tmpFileName.AppendDir( wxT( "modules" ) ); + envVarItem.SetDefinedExternally( false ); + } + envVarItem.SetValue( tmpFileName.GetFullPath() ); + m_local_env_vars[ envVarName ] = envVarItem; + + // KISYS3DMOD + envVarName = wxT( "KISYS3DMOD" ); + if( wxGetEnv( envVarName, &envValue ) == true && !envValue.IsEmpty() ) + { + tmpFileName.AssignDir( envValue ); + envVarItem.SetDefinedExternally( true ); + } + else + { + tmpFileName.AppendDir( wxT( "packages3d" ) ); + envVarItem.SetDefinedExternally( false ); + } + envVarItem.SetValue( tmpFileName.GetFullPath() ); + m_local_env_vars[ envVarName ] = envVarItem; + + // KICAD_PTEMPLATES + envVarName = wxT( "KICAD_PTEMPLATES" ); + if( wxGetEnv( envVarName, &envValue ) == true && !envValue.IsEmpty() ) + { + tmpFileName.AssignDir( envValue ); + envVarItem.SetDefinedExternally( true ); + } + else + { + tmpFileName = baseSharePath; + tmpFileName.AppendDir( wxT( "template" ) ); + envVarItem.SetDefinedExternally( false ); + } + envVarItem.SetValue( tmpFileName.GetFullPath() ); + m_local_env_vars[ envVarName ] = envVarItem; + + // KICAD_SYMBOLS + envVarName = wxT( "KICAD_SYMBOL_DIR" ); + if( wxGetEnv( envVarName, &envValue ) == true && !envValue.IsEmpty() ) + { + tmpFileName.AssignDir( envValue ); + envVarItem.SetDefinedExternally( true ); + } + else + { + tmpFileName = baseSharePath; + tmpFileName.AppendDir( wxT( "library" ) ); + envVarItem.SetDefinedExternally( false ); + } + envVarItem.SetValue( tmpFileName.GetFullPath() ); + m_local_env_vars[ envVarName ] = envVarItem; ReadPdfBrowserInfos(); // needs m_common_settings diff --git a/eeschema/CMakeLists.txt b/eeschema/CMakeLists.txt index b4ed4a4ab1..dc7c0c050b 100644 --- a/eeschema/CMakeLists.txt +++ b/eeschema/CMakeLists.txt @@ -70,6 +70,8 @@ set( EESCHEMA_DLGS dialogs/dialog_sch_sheet_props_base.cpp dialogs/dialog_schematic_find.cpp dialogs/dialog_schematic_find_base.cpp + dialogs/dialog_sym_lib_table.cpp + dialogs/dialog_sym_lib_table_base.cpp dialogs/dialog_symbol_remap.cpp dialogs/dialog_symbol_remap_base.cpp dialogs/dialog_global_sym_lib_table_config.cpp diff --git a/eeschema/dialogs/dialog_sym_lib_table.cpp b/eeschema/dialogs/dialog_sym_lib_table.cpp new file mode 100644 index 0000000000..ccaead2c9c --- /dev/null +++ b/eeschema/dialogs/dialog_sym_lib_table.cpp @@ -0,0 +1,595 @@ +/* + * This program source code file is part of KiCad, a free EDA CAD application. + * + * Copyright (C) 2017 Wayne Stambaugh + * Copyright (C) 2017 KiCad Developers, see AUTHORS.txt for contributors. + * + * 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 3 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, see . + */ + +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include + + +/** + * Build a wxGridTableBase by wrapping an #SYMBOL_LIB_TABLE object. + */ +class SYMBOL_LIB_TABLE_GRID : public LIB_TABLE_GRID, public SYMBOL_LIB_TABLE +{ + friend class SYMBOL_GRID_TRICKS; + +protected: + LIB_TABLE_ROW* at( size_t aIndex ) override { return &rows.at( aIndex ); } + + size_t size() const override { return rows.size(); } + + LIB_TABLE_ROW* makeNewRow() override + { + return dynamic_cast< LIB_TABLE_ROW* >( new SYMBOL_LIB_TABLE_ROW ); + } + + LIB_TABLE_ROWS_ITER begin() override { return rows.begin(); } + + LIB_TABLE_ROWS_ITER insert( LIB_TABLE_ROWS_ITER aIterator, LIB_TABLE_ROW* aRow ) override + { + return rows.insert( aIterator, aRow ); + } + + void push_back( LIB_TABLE_ROW* aRow ) override { rows.push_back( aRow ); } + + LIB_TABLE_ROWS_ITER erase( LIB_TABLE_ROWS_ITER aFirst, LIB_TABLE_ROWS_ITER aLast ) override + { + return rows.erase( aFirst, aLast ); + } + +public: + + SYMBOL_LIB_TABLE_GRID( const SYMBOL_LIB_TABLE& aTableToEdit ) + { + rows = aTableToEdit.rows; + } +}; + + +class SYMBOL_GRID_TRICKS : public GRID_TRICKS +{ +public: + SYMBOL_GRID_TRICKS( wxGrid* aGrid ) : + GRID_TRICKS( aGrid ) + { + } + +protected: + + /// handle specialized clipboard text, with leading "(sym_lib_table" or + /// spreadsheet formatted text. + virtual void paste_text( const wxString& cb_text ) override + { + SYMBOL_LIB_TABLE_GRID* tbl = (SYMBOL_LIB_TABLE_GRID*) m_grid->GetTable(); + + size_t ndx = cb_text.find( "(sym_lib_table" ); + + if( ndx != std::string::npos ) + { + // paste the SYMBOL_LIB_TABLE_ROWs of s-expression (sym_lib_table), starting + // at column 0 regardless of current cursor column. + + STRING_LINE_READER slr( TO_UTF8( cb_text ), "Clipboard" ); + LIB_TABLE_LEXER lexer( &slr ); + SYMBOL_LIB_TABLE tmp_tbl; + bool parsed = true; + + try + { + tmp_tbl.Parse( &lexer ); + } + catch( PARSE_ERROR& pe ) + { + DisplayError( NULL, pe.What() ); + parsed = false; + } + + if( parsed ) + { + const int cur_row = std::max( getCursorRow(), 0 ); + + // if clipboard rows would extend past end of current table size... + if( tmp_tbl.GetCount() > tbl->GetNumberRows() - cur_row ) + { + int newRowsNeeded = tmp_tbl.GetCount() - ( tbl->GetNumberRows() - cur_row ); + tbl->AppendRows( newRowsNeeded ); + } + + for( int i = 0; i < tmp_tbl.GetCount(); ++i ) + { + tbl->rows.replace( cur_row+i, tmp_tbl.At( i ) ); + } + } + + m_grid->AutoSizeColumns( false ); + } + else + { + // paste spreadsheet formatted text. + GRID_TRICKS::paste_text( cb_text ); + } + } +}; + + +DIALOG_SYMBOL_LIB_TABLE::DIALOG_SYMBOL_LIB_TABLE( wxTopLevelWindow* aParent, + SYMBOL_LIB_TABLE* aGlobal, + SYMBOL_LIB_TABLE* aProject ) : + DIALOG_SYMBOL_LIB_TABLE_BASE( aParent ), + m_global( aGlobal ), + m_project( aProject ) +{ + // For user info, shows the table filenames: + m_PrjTableFilename->SetLabel( Prj().FootprintLibTblName() ); + m_GblTableFilename->SetLabel( SYMBOL_LIB_TABLE::GetGlobalTableFileName() ); + + // wxGrid only supports user owned tables if they exist past end of ~wxGrid(), + // so make it a grid owned table. + m_global_grid->SetTable( new SYMBOL_LIB_TABLE_GRID( *aGlobal ), true ); + m_project_grid->SetTable( new SYMBOL_LIB_TABLE_GRID( *aProject ), true ); + + // add Cut, Copy, and Paste to wxGrids + m_global_grid->PushEventHandler( new SYMBOL_GRID_TRICKS( m_global_grid ) ); + m_project_grid->PushEventHandler( new SYMBOL_GRID_TRICKS( m_project_grid ) ); + + m_global_grid->AutoSizeColumns( false ); + m_project_grid->AutoSizeColumns( false ); + + wxArrayString pluginChoices; + + pluginChoices.Add( SCH_IO_MGR::ShowType( SCH_IO_MGR::SCH_KICAD ) ); + pluginChoices.Add( SCH_IO_MGR::ShowType( SCH_IO_MGR::SCH_LEGACY ) ); + + wxGridCellAttr* attr; + + attr = new wxGridCellAttr; + attr->SetEditor( new wxGridCellChoiceEditor( pluginChoices ) ); + m_project_grid->SetColAttr( COL_TYPE, attr ); + + attr = new wxGridCellAttr; + attr->SetEditor( new wxGridCellChoiceEditor( pluginChoices ) ); + m_global_grid->SetColAttr( COL_TYPE, attr ); + + populateEnvironReadOnlyTable(); + + for( int i=0; i<2; ++i ) + { + wxGrid* g = i==0 ? m_global_grid : m_project_grid; + + // all but COL_OPTIONS, which is edited with Option Editor anyways. + g->AutoSizeColumn( COL_NICKNAME, false ); + g->AutoSizeColumn( COL_TYPE, false ); + g->AutoSizeColumn( COL_URI, false ); + g->AutoSizeColumn( COL_DESCR, false ); + + // would set this to width of title, if it was easily known. + g->SetColSize( COL_OPTIONS, 80 ); + } + + // select the last selected page + m_auinotebook->SetSelection( m_pageNdx ); + + // Gives a selection for each grid, mainly for delete lib button. + // Without that, we do not see what lib will be deleted + m_global_grid->SelectRow( 0 ); + m_project_grid->SelectRow( 0 ); + + // for ALT+A handling, we want the initial focus to be on the first selected grid. + if( m_pageNdx == 0 ) + m_global_grid->SetFocus(); + else + m_project_grid->SetFocus(); + + // On some window managers (Unity, XFCE), this dialog is + // not always raised, depending on this dialog is run. + // Force it to be raised + Raise(); +} + + +DIALOG_SYMBOL_LIB_TABLE::~DIALOG_SYMBOL_LIB_TABLE() +{ + // Delete the GRID_TRICKS. + // Any additional event handlers should be popped before the window is deleted. + m_global_grid->PopEventHandler( true ); + m_project_grid->PopEventHandler( true ); +} + + +int DIALOG_SYMBOL_LIB_TABLE::getCursorCol() const +{ + return m_cur_grid->GetGridCursorCol(); +} + + +int DIALOG_SYMBOL_LIB_TABLE::getCursorRow() const +{ + return m_cur_grid->GetGridCursorRow(); +} + + +bool DIALOG_SYMBOL_LIB_TABLE::verifyTables() +{ + for( int t=0; t<2; ++t ) + { + SYMBOL_LIB_TABLE_GRID& model = t==0 ? *global_model() : *project_model(); + + for( int r = 0; r < model.GetNumberRows(); ) + { + wxString nick = model.GetValue( r, COL_NICKNAME ).Trim( false ).Trim(); + wxString uri = model.GetValue( r, COL_URI ).Trim( false ).Trim(); + + if( !nick || !uri ) + { + // Delete the "empty" row, where empty means missing nick or uri. + // This also updates the UI which could be slow, but there should only be a few + // rows to delete, unless the user fell asleep on the Add Row + // button. + model.DeleteRows( r, 1 ); + } + else if( nick.find( ':' ) != size_t( -1 ) ) + { + wxString msg = wxString::Format( + _( "Illegal character '%s' found in Nickname: '%s' in row %d" ), + ":", GetChars( nick ), r ); + + // show the tabbed panel holding the grid we have flunked: + if( &model != cur_model() ) + { + m_auinotebook->SetSelection( &model == global_model() ? 0 : 1 ); + } + + // go to the problematic row + m_cur_grid->SetGridCursor( r, 0 ); + m_cur_grid->SelectBlock( r, 0, r, 0 ); + m_cur_grid->MakeCellVisible( r, 0 ); + + wxMessageDialog errdlg( this, msg, _( "No Colon in Nicknames" ) ); + errdlg.ShowModal(); + return false; + } + else + { + // set the trimmed values back into the table so they get saved to disk. + model.SetValue( r, COL_NICKNAME, nick ); + model.SetValue( r, COL_URI, uri ); + ++r; // this row was OK. + } + } + } + + // check for duplicate nickNames, separately in each table. + for( int t=0; t<2; ++t ) + { + SYMBOL_LIB_TABLE_GRID& model = t==0 ? *global_model() : *project_model(); + + for( int r1 = 0; r1 < model.GetNumberRows() - 1; ++r1 ) + { + wxString nick1 = model.GetValue( r1, COL_NICKNAME ); + + for( int r2=r1+1; r2 < model.GetNumberRows(); ++r2 ) + { + wxString nick2 = model.GetValue( r2, COL_NICKNAME ); + + if( nick1 == nick2 ) + { + wxString msg = wxString::Format( + _( "Duplicate Nickname: '%s' in rows %d and %d" ), + GetChars( nick1 ), r1+1, r2+1 + ); + + // show the tabbed panel holding the grid we have flunked: + if( &model != cur_model() ) + { + m_auinotebook->SetSelection( &model == global_model() ? 0 : 1 ); + } + + // go to the lower of the two rows, it is technically the duplicate: + m_cur_grid->SetGridCursor( r2, 0 ); + m_cur_grid->SelectBlock( r2, 0, r2, 0 ); + m_cur_grid->MakeCellVisible( r2, 0 ); + + wxMessageDialog errdlg( this, msg, _( "Please Delete or Modify One" ) ); + errdlg.ShowModal(); + return false; + } + } + } + } + + return true; +} + + +void DIALOG_SYMBOL_LIB_TABLE::pageChangedHandler( wxAuiNotebookEvent& event ) +{ + m_pageNdx = m_auinotebook->GetSelection(); + m_cur_grid = ( m_pageNdx == 0 ) ? m_global_grid : m_project_grid; +} + + +void DIALOG_SYMBOL_LIB_TABLE::appendRowHandler( wxCommandEvent& event ) +{ + if( m_cur_grid->AppendRows( 1 ) ) + { + int last_row = m_cur_grid->GetNumberRows() - 1; + + // wx documentation is wrong, SetGridCursor does not make visible. + m_cur_grid->MakeCellVisible( last_row, 0 ); + m_cur_grid->SetGridCursor( last_row, 0 ); + m_cur_grid->SelectRow( m_cur_grid->GetGridCursorRow() ); + } +} + + +void DIALOG_SYMBOL_LIB_TABLE::deleteRowHandler( wxCommandEvent& event ) +{ + int currRow = getCursorRow(); + + // In a wxGrid, collect rows that have a selected cell, or are selected + // is not so easy: it depend on the way the selection was made. + // Here, we collect row selected by clicking on a row label, and + // row that contain a cell previously selected. + // If no candidate, just delete the row with the grid cursor. + wxArrayInt selectedRows = m_cur_grid->GetSelectedRows(); + wxGridCellCoordsArray cells = m_cur_grid->GetSelectedCells(); + + // Add all row having cell selected to list: + for( unsigned ii = 0; ii < cells.GetCount(); ii++ ) + selectedRows.Add( cells[ii].GetRow() ); + + // Use the row having the grid cursor only if we have no candidate: + if( selectedRows.size() == 0 && getCursorRow() >= 0 ) + selectedRows.Add( getCursorRow() ); + + std::sort( selectedRows.begin(), selectedRows.end() ); + + // Remove selected rows (note: a row can be stored more than once in list) + int last_row = -1; + + for( int ii = selectedRows.GetCount()-1; ii >= 0; ii-- ) + { + int row = selectedRows[ii]; + + if( row != last_row ) + { + last_row = row; + m_cur_grid->DeleteRows( row, 1 ); + } + } + + if( currRow >= m_cur_grid->GetNumberRows() ) + m_cur_grid->SetGridCursor(m_cur_grid->GetNumberRows()-1, getCursorCol() ); + + m_cur_grid->SelectRow( m_cur_grid->GetGridCursorRow() ); +} + + +void DIALOG_SYMBOL_LIB_TABLE::moveUpHandler( wxCommandEvent& event ) +{ + wxArrayInt rowsSelected = m_cur_grid->GetSelectedRows(); + + if( rowsSelected.GetCount() == 0 ) + return; + + // @todo: add multiple selection moves. + int curRow = rowsSelected[0]; + + if( curRow >= 1 ) + { + int curCol = getCursorCol(); + + SYMBOL_LIB_TABLE_GRID* tbl = cur_model(); + + boost::ptr_vector< LIB_TABLE_ROW >::auto_type move_me = + tbl->rows.release( tbl->rows.begin() + curRow ); + + --curRow; + tbl->rows.insert( tbl->rows.begin() + curRow, move_me.release() ); + + if( tbl->GetView() ) + { + // fire a msg to cause redrawing + wxGridTableMessage msg( tbl, + wxGRIDTABLE_NOTIFY_ROWS_INSERTED, + curRow, + 0 ); + + tbl->GetView()->ProcessTableMessage( msg ); + } + + m_cur_grid->MakeCellVisible( curRow, curCol ); + m_cur_grid->SetGridCursor( curRow, curCol ); + m_cur_grid->SelectRow( getCursorRow() ); + } +} + + +void DIALOG_SYMBOL_LIB_TABLE::moveDownHandler( wxCommandEvent& event ) +{ + wxArrayInt rowsSelected = m_cur_grid->GetSelectedRows(); + + if( rowsSelected.GetCount() == 0 ) + return; + + SYMBOL_LIB_TABLE_GRID* tbl = cur_model(); + + // @todo: add multiple selection moves. + int curRow = rowsSelected[0]; + + if( unsigned( curRow + 1 ) < tbl->rows.size() ) + { + int curCol = getCursorCol(); + + boost::ptr_vector< LIB_TABLE_ROW >::auto_type move_me = + tbl->rows.release( tbl->rows.begin() + curRow ); + + ++curRow; + tbl->rows.insert( tbl->rows.begin() + curRow, move_me.release() ); + + if( tbl->GetView() ) + { + // fire a msg to cause redrawing + wxGridTableMessage msg( tbl, + wxGRIDTABLE_NOTIFY_ROWS_INSERTED, + curRow - 1, + 0 ); + + tbl->GetView()->ProcessTableMessage( msg ); + } + + m_cur_grid->MakeCellVisible( curRow, curCol ); + m_cur_grid->SetGridCursor( curRow, curCol ); + m_cur_grid->SelectRow( getCursorRow() ); + } +} + + +bool DIALOG_SYMBOL_LIB_TABLE::TransferDataFromWindow() +{ + // stuff any pending cell editor text into the table. + m_cur_grid->SaveEditControlValue(); + + if( !wxDialog::TransferDataFromWindow() || !verifyTables() ) + return false; + + if( *global_model() != *m_global ) + { + m_global->Clear(); + m_global->rows.transfer( m_global->rows.end(), global_model()->rows.begin(), + global_model()->rows.end(), global_model()->rows ); + m_global->reindex(); + } + + if( *project_model() != *m_project ) + { + m_project->Clear(); + m_project->rows.transfer( m_project->rows.end(), project_model()->rows.begin(), + project_model()->rows.end(), project_model()->rows ); + m_project->reindex(); + } + + return true; +} + + +void DIALOG_SYMBOL_LIB_TABLE::populateEnvironReadOnlyTable() +{ + wxRegEx re( ".*?\\$\\{(.+?)\\}.*?", wxRE_ADVANCED ); + wxASSERT( re.IsValid() ); // wxRE_ADVANCED is required. + + std::set< wxString > unique; + typedef std::set::const_iterator SET_CITER; + + // clear the table + m_path_subs_grid->DeleteRows( 0, m_path_subs_grid->GetNumberRows() ); + + SYMBOL_LIB_TABLE_GRID* gbl = global_model(); + SYMBOL_LIB_TABLE_GRID* prj = project_model(); + + int gblRowCount = gbl->GetNumberRows(); + int prjRowCount = prj->GetNumberRows(); + int row; + + for( row = 0; row < gblRowCount; ++row ) + { + wxString uri = gbl->GetValue( row, COL_URI ); + + while( re.Matches( uri ) ) + { + wxString envvar = re.GetMatch( uri, 1 ); + + // ignore duplicates + unique.insert( envvar ); + + // delete the last match and search again + uri.Replace( re.GetMatch( uri, 0 ), wxEmptyString ); + } + } + + for( row = 0; row < prjRowCount; ++row ) + { + wxString uri = prj->GetValue( row, COL_URI ); + + while( re.Matches( uri ) ) + { + wxString envvar = re.GetMatch( uri, 1 ); + + // ignore duplicates + unique.insert( envvar ); + + // delete the last match and search again + uri.Replace( re.GetMatch( uri, 0 ), wxEmptyString ); + } + } + + // Make sure this special environment variable shows up even if it was + // not used yet. It is automatically set by KiCad to the directory holding + // the current project. + unique.insert( PROJECT_VAR_NAME ); + unique.insert( SYMBOL_LIB_TABLE::GlobalPathEnvVariableName() ); + + m_path_subs_grid->AppendRows( unique.size() ); + + row = 0; + + for( SET_CITER it = unique.begin(); it != unique.end(); ++it, ++row ) + { + wxString evName = *it; + wxString evValue; + + m_path_subs_grid->SetCellValue( row, 0, evName ); + + if( wxGetEnv( evName, &evValue ) ) + m_path_subs_grid->SetCellValue( row, 1, evValue ); + } + + m_path_subs_grid->AutoSizeColumns(); +} + + +SYMBOL_LIB_TABLE_GRID* DIALOG_SYMBOL_LIB_TABLE::global_model() const +{ + return (SYMBOL_LIB_TABLE_GRID*) m_global_grid->GetTable(); +} + + +SYMBOL_LIB_TABLE_GRID* DIALOG_SYMBOL_LIB_TABLE::project_model() const +{ + return (SYMBOL_LIB_TABLE_GRID*) m_project_grid->GetTable(); +} + + +SYMBOL_LIB_TABLE_GRID* DIALOG_SYMBOL_LIB_TABLE::cur_model() const +{ + return (SYMBOL_LIB_TABLE_GRID*) m_cur_grid->GetTable(); +} + + +int DIALOG_SYMBOL_LIB_TABLE::m_pageNdx = 0; diff --git a/eeschema/dialogs/dialog_sym_lib_table.h b/eeschema/dialogs/dialog_sym_lib_table.h new file mode 100644 index 0000000000..6ce7515c8f --- /dev/null +++ b/eeschema/dialogs/dialog_sym_lib_table.h @@ -0,0 +1,88 @@ +/* + * This program source code file is part of KiCad, a free EDA CAD application. + * + * Copyright (C) 2017 Wayne Stambaugh + * Copyright (C) 2017 KiCad Developers, see AUTHORS.txt for contributors. + * + * 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 3 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, see . + */ + +#ifndef _DIALOG_SYM_LIB_TABLE_H_ +#define _DIALOG_SYM_LIB_TABLE_H_ + +#include + +class SYMBOL_LIB_TABLE; +class SYMBOL_LIB_TABLE_GRID; + + +/** + * Dialog to show and edit symbol library tables. + */ +class DIALOG_SYMBOL_LIB_TABLE : public DIALOG_SYMBOL_LIB_TABLE_BASE +{ + +public: + DIALOG_SYMBOL_LIB_TABLE( wxTopLevelWindow* aParent, SYMBOL_LIB_TABLE* aGlobal, + SYMBOL_LIB_TABLE* aProject ); + virtual ~DIALOG_SYMBOL_LIB_TABLE(); + + +private: + /// If the cursor is not on a valid cell, because there are no rows at all, return -1, + /// else return a 0 based column index. + int getCursorCol() const; + + /// If the cursor is not on a valid cell, because there are no rows at all, return -1, + /// else return a 0 based row index. + int getCursorRow() const; + + /** + * Trim important fields, removes blank row entries, and checks for duplicates. + * + * @return bool - true if tables are OK, else false. + */ + bool verifyTables(); + + void pageChangedHandler( wxAuiNotebookEvent& event ) override; + + void appendRowHandler( wxCommandEvent& event ) override; + + void deleteRowHandler( wxCommandEvent& event ) override; + + void moveUpHandler( wxCommandEvent& event ) override; + + void moveDownHandler( wxCommandEvent& event ) override; + + bool TransferDataFromWindow() override; + + /// Populate the readonly environment variable table with names and values + /// by examining all the full_uri columns. + void populateEnvironReadOnlyTable(); + + // Caller's tables are modified only on OK button and successful verification. + SYMBOL_LIB_TABLE* m_global; + SYMBOL_LIB_TABLE* m_project; + + SYMBOL_LIB_TABLE_GRID* global_model() const; + + SYMBOL_LIB_TABLE_GRID* project_model() const; + + SYMBOL_LIB_TABLE_GRID* cur_model() const; + + wxGrid* m_cur_grid; ///< changed based on tab choice + static int m_pageNdx; ///< Remember the last notebook page selected during a session +}; + +#endif // _DIALOG_SYM_LIB_TABLE_H_ diff --git a/eeschema/dialogs/dialog_sym_lib_table_base.cpp b/eeschema/dialogs/dialog_sym_lib_table_base.cpp new file mode 100644 index 0000000000..cabded4f62 --- /dev/null +++ b/eeschema/dialogs/dialog_sym_lib_table_base.cpp @@ -0,0 +1,237 @@ +/////////////////////////////////////////////////////////////////////////// +// C++ code generated with wxFormBuilder (version Jul 29 2017) +// http://www.wxformbuilder.org/ +// +// PLEASE DO "NOT" EDIT THIS FILE! +/////////////////////////////////////////////////////////////////////////// + +#include "dialog_sym_lib_table_base.h" + +/////////////////////////////////////////////////////////////////////////// + +DIALOG_SYMBOL_LIB_TABLE_BASE::DIALOG_SYMBOL_LIB_TABLE_BASE( wxWindow* parent, wxWindowID id, const wxString& title, const wxPoint& pos, const wxSize& size, long style ) : DIALOG_SHIM( parent, id, title, pos, size, style ) +{ + this->SetSizeHints( wxSize( -1,-1 ), wxDefaultSize ); + + wxBoxSizer* bSizer1; + bSizer1 = new wxBoxSizer( wxVERTICAL ); + + wxStaticBoxSizer* m_top_sizer; + m_top_sizer = new wxStaticBoxSizer( new wxStaticBox( this, wxID_ANY, _("Library Tables by Scope") ), wxVERTICAL ); + + m_auinotebook = new wxAuiNotebook( m_top_sizer->GetStaticBox(), wxID_ANY, wxDefaultPosition, wxDefaultSize, wxAUI_NB_BOTTOM ); + m_global_panel = new wxPanel( m_auinotebook, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxTAB_TRAVERSAL ); + wxBoxSizer* m_global_sizer; + m_global_sizer = new wxBoxSizer( wxVERTICAL ); + + wxFlexGridSizer* fgSizer1; + fgSizer1 = new wxFlexGridSizer( 1, 2, 0, 0 ); + fgSizer1->SetFlexibleDirection( wxBOTH ); + fgSizer1->SetNonFlexibleGrowMode( wxFLEX_GROWMODE_SPECIFIED ); + + m_staticText3 = new wxStaticText( m_global_panel, wxID_ANY, _("Table:"), wxDefaultPosition, wxDefaultSize, 0 ); + m_staticText3->Wrap( -1 ); + fgSizer1->Add( m_staticText3, 0, wxRIGHT|wxLEFT, 5 ); + + m_GblTableFilename = new wxStaticText( m_global_panel, wxID_ANY, _("Table Name"), wxDefaultPosition, wxDefaultSize, 0 ); + m_GblTableFilename->Wrap( -1 ); + fgSizer1->Add( m_GblTableFilename, 0, wxRIGHT|wxLEFT, 5 ); + + + m_global_sizer->Add( fgSizer1, 0, wxEXPAND, 5 ); + + m_global_grid = new wxGrid( m_global_panel, wxID_ANY, wxDefaultPosition, wxDefaultSize, 0 ); + + // Grid + m_global_grid->CreateGrid( 1, 5 ); + m_global_grid->EnableEditing( true ); + m_global_grid->EnableGridLines( true ); + m_global_grid->EnableDragGridSize( false ); + m_global_grid->SetMargins( 0, 0 ); + + // Columns + m_global_grid->AutoSizeColumns(); + m_global_grid->EnableDragColMove( false ); + m_global_grid->EnableDragColSize( true ); + m_global_grid->SetColLabelSize( 30 ); + m_global_grid->SetColLabelAlignment( wxALIGN_CENTRE, wxALIGN_CENTRE ); + + // Rows + m_global_grid->AutoSizeRows(); + m_global_grid->EnableDragRowSize( false ); + m_global_grid->SetRowLabelSize( 40 ); + m_global_grid->SetRowLabelAlignment( wxALIGN_CENTRE, wxALIGN_CENTRE ); + + // Label Appearance + + // Cell Defaults + m_global_grid->SetDefaultCellAlignment( wxALIGN_LEFT, wxALIGN_TOP ); + m_global_sizer->Add( m_global_grid, 5, wxALL|wxEXPAND, 5 ); + + + m_global_panel->SetSizer( m_global_sizer ); + m_global_panel->Layout(); + m_global_sizer->Fit( m_global_panel ); + m_auinotebook->AddPage( m_global_panel, _("Global Libraries"), true, wxNullBitmap ); + m_project_panel = new wxPanel( m_auinotebook, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxTAB_TRAVERSAL ); + wxBoxSizer* m_project_sizer; + m_project_sizer = new wxBoxSizer( wxVERTICAL ); + + wxFlexGridSizer* fgSizer2; + fgSizer2 = new wxFlexGridSizer( 1, 2, 0, 0 ); + fgSizer2->SetFlexibleDirection( wxBOTH ); + fgSizer2->SetNonFlexibleGrowMode( wxFLEX_GROWMODE_SPECIFIED ); + + m_staticText4 = new wxStaticText( m_project_panel, wxID_ANY, _("Table:"), wxDefaultPosition, wxDefaultSize, 0 ); + m_staticText4->Wrap( -1 ); + fgSizer2->Add( m_staticText4, 0, wxRIGHT|wxLEFT, 5 ); + + m_PrjTableFilename = new wxStaticText( m_project_panel, wxID_ANY, _("Table Name"), wxDefaultPosition, wxDefaultSize, 0 ); + m_PrjTableFilename->Wrap( -1 ); + fgSizer2->Add( m_PrjTableFilename, 0, wxRIGHT|wxLEFT, 5 ); + + + m_project_sizer->Add( fgSizer2, 0, wxEXPAND, 5 ); + + m_project_grid = new wxGrid( m_project_panel, wxID_ANY, wxDefaultPosition, wxDefaultSize, 0 ); + + // Grid + m_project_grid->CreateGrid( 1, 5 ); + m_project_grid->EnableEditing( true ); + m_project_grid->EnableGridLines( true ); + m_project_grid->EnableDragGridSize( false ); + m_project_grid->SetMargins( 0, 0 ); + + // Columns + m_project_grid->AutoSizeColumns(); + m_project_grid->EnableDragColMove( false ); + m_project_grid->EnableDragColSize( true ); + m_project_grid->SetColLabelSize( 30 ); + m_project_grid->SetColLabelAlignment( wxALIGN_CENTRE, wxALIGN_CENTRE ); + + // Rows + m_project_grid->EnableDragRowSize( false ); + m_project_grid->SetRowLabelSize( 40 ); + m_project_grid->SetRowLabelAlignment( wxALIGN_CENTRE, wxALIGN_CENTRE ); + + // Label Appearance + + // Cell Defaults + m_project_grid->SetDefaultCellAlignment( wxALIGN_LEFT, wxALIGN_TOP ); + m_project_sizer->Add( m_project_grid, 2, wxALL|wxEXPAND, 5 ); + + + m_project_panel->SetSizer( m_project_sizer ); + m_project_panel->Layout(); + m_project_sizer->Fit( m_project_panel ); + m_auinotebook->AddPage( m_project_panel, _("Project Specific Libraries"), false, wxNullBitmap ); + + m_top_sizer->Add( m_auinotebook, 1, wxEXPAND | wxALL, 5 ); + + wxBoxSizer* bSizer51; + bSizer51 = new wxBoxSizer( wxHORIZONTAL ); + + m_append_button = new wxButton( m_top_sizer->GetStaticBox(), wxID_ANY, _("Append Library"), wxDefaultPosition, wxDefaultSize, 0 ); + m_append_button->SetToolTip( _("Add a PCB library row to this table") ); + + bSizer51->Add( m_append_button, 0, wxALL, 5 ); + + m_delete_button = new wxButton( m_top_sizer->GetStaticBox(), wxID_ANY, _("Remove Library"), wxDefaultPosition, wxDefaultSize, 0 ); + m_delete_button->SetToolTip( _("Remove a PCB library from this library table") ); + + bSizer51->Add( m_delete_button, 0, wxALL, 5 ); + + m_move_up_button = new wxButton( m_top_sizer->GetStaticBox(), wxID_ANY, _("Move Up"), wxDefaultPosition, wxDefaultSize, 0 ); + m_move_up_button->SetToolTip( _("Move the currently selected row up one position") ); + + bSizer51->Add( m_move_up_button, 0, wxALL, 5 ); + + m_move_down_button = new wxButton( m_top_sizer->GetStaticBox(), wxID_ANY, _("Move Down"), wxDefaultPosition, wxDefaultSize, 0 ); + m_move_down_button->SetToolTip( _("Move the currently selected row down one position") ); + + bSizer51->Add( m_move_down_button, 0, wxALL, 5 ); + + + m_top_sizer->Add( bSizer51, 0, wxALIGN_CENTER|wxBOTTOM, 8 ); + + + bSizer1->Add( m_top_sizer, 1, wxEXPAND, 5 ); + + wxStaticBoxSizer* sbSizer1; + sbSizer1 = new wxStaticBoxSizer( new wxStaticBox( this, wxID_ANY, _("Path Substitutions") ), wxVERTICAL ); + + m_path_subs_grid = new wxGrid( sbSizer1->GetStaticBox(), wxID_ANY, wxDefaultPosition, wxDefaultSize, 0 ); + + // Grid + m_path_subs_grid->CreateGrid( 1, 2 ); + m_path_subs_grid->EnableEditing( false ); + m_path_subs_grid->EnableGridLines( true ); + m_path_subs_grid->EnableDragGridSize( false ); + m_path_subs_grid->SetMargins( 0, 0 ); + + // Columns + m_path_subs_grid->SetColSize( 0, 150 ); + m_path_subs_grid->SetColSize( 1, 500 ); + m_path_subs_grid->AutoSizeColumns(); + m_path_subs_grid->EnableDragColMove( false ); + m_path_subs_grid->EnableDragColSize( true ); + m_path_subs_grid->SetColLabelSize( 30 ); + m_path_subs_grid->SetColLabelValue( 0, _("Environment Variable") ); + m_path_subs_grid->SetColLabelValue( 1, _("Path Segment") ); + m_path_subs_grid->SetColLabelAlignment( wxALIGN_CENTRE, wxALIGN_CENTRE ); + + // Rows + m_path_subs_grid->EnableDragRowSize( true ); + m_path_subs_grid->SetRowLabelSize( 40 ); + m_path_subs_grid->SetRowLabelAlignment( wxALIGN_CENTRE, wxALIGN_CENTRE ); + + // Label Appearance + + // Cell Defaults + m_path_subs_grid->SetDefaultCellAlignment( wxALIGN_LEFT, wxALIGN_TOP ); + m_path_subs_grid->SetToolTip( _("This is a read-only table which shows pertinent environment variables.") ); + + sbSizer1->Add( m_path_subs_grid, 1, wxALL|wxEXPAND, 5 ); + + + bSizer1->Add( sbSizer1, 0, wxALL|wxEXPAND, 5 ); + + wxBoxSizer* m_bottom_sizer; + m_bottom_sizer = new wxBoxSizer( wxVERTICAL ); + + m_sdbSizer = new wxStdDialogButtonSizer(); + m_sdbSizerOK = new wxButton( this, wxID_OK ); + m_sdbSizer->AddButton( m_sdbSizerOK ); + m_sdbSizerCancel = new wxButton( this, wxID_CANCEL ); + m_sdbSizer->AddButton( m_sdbSizerCancel ); + m_sdbSizer->Realize(); + + m_bottom_sizer->Add( m_sdbSizer, 0, wxALL|wxEXPAND, 5 ); + + + bSizer1->Add( m_bottom_sizer, 0, wxEXPAND, 5 ); + + + this->SetSizer( bSizer1 ); + this->Layout(); + + this->Centre( wxBOTH ); + + // Connect Events + m_auinotebook->Connect( wxEVT_COMMAND_AUINOTEBOOK_PAGE_CHANGED, wxAuiNotebookEventHandler( DIALOG_SYMBOL_LIB_TABLE_BASE::pageChangedHandler ), NULL, this ); + m_append_button->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DIALOG_SYMBOL_LIB_TABLE_BASE::appendRowHandler ), NULL, this ); + m_delete_button->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DIALOG_SYMBOL_LIB_TABLE_BASE::deleteRowHandler ), NULL, this ); + m_move_up_button->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DIALOG_SYMBOL_LIB_TABLE_BASE::moveUpHandler ), NULL, this ); + m_move_down_button->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DIALOG_SYMBOL_LIB_TABLE_BASE::moveDownHandler ), NULL, this ); +} + +DIALOG_SYMBOL_LIB_TABLE_BASE::~DIALOG_SYMBOL_LIB_TABLE_BASE() +{ + // Disconnect Events + m_auinotebook->Disconnect( wxEVT_COMMAND_AUINOTEBOOK_PAGE_CHANGED, wxAuiNotebookEventHandler( DIALOG_SYMBOL_LIB_TABLE_BASE::pageChangedHandler ), NULL, this ); + m_append_button->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DIALOG_SYMBOL_LIB_TABLE_BASE::appendRowHandler ), NULL, this ); + m_delete_button->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DIALOG_SYMBOL_LIB_TABLE_BASE::deleteRowHandler ), NULL, this ); + m_move_up_button->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DIALOG_SYMBOL_LIB_TABLE_BASE::moveUpHandler ), NULL, this ); + m_move_down_button->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DIALOG_SYMBOL_LIB_TABLE_BASE::moveDownHandler ), NULL, this ); + +} diff --git a/eeschema/dialogs/dialog_sym_lib_table_base.fbp b/eeschema/dialogs/dialog_sym_lib_table_base.fbp new file mode 100644 index 0000000000..ca509f9d2d --- /dev/null +++ b/eeschema/dialogs/dialog_sym_lib_table_base.fbp @@ -0,0 +1,1590 @@ + + + + + + C++ + 1 + source_name + 0 + 0 + res + UTF-8 + connect + dialog_sym_lib_table_base + 1000 + none + 1 + MyProject1 + + . + + 1 + 1 + 1 + 1 + UI + 0 + 0 + + 0 + wxAUI_MGR_DEFAULT + + wxBOTH + + 0 + 1 + decl_pure_virtual + + + + 0 + wxID_ANY + + -1,-1 + DIALOG_SYMBOL_LIB_TABLE_BASE + + 800,600 + wxCAPTION|wxCLOSE_BOX|wxDEFAULT_DIALOG_STYLE|wxMAXIMIZE_BOX|wxRESIZE_BORDER|wxSYSTEM_MENU + DIALOG_SHIM; dialog_shim.h + Schematic Library Tables + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + bSizer1 + wxVERTICAL + none + + 5 + wxEXPAND + 1 + + wxID_ANY + Library Tables by Scope + + m_top_sizer + wxVERTICAL + 1 + none + + + 5 + wxEXPAND | wxALL + 1 + + 1 + 1 + 1 + 1 + + + + + + + + 1 + 0 + 1 + + 0 + 0 + Dock + 0 + Left + 1 + + 1 + + 0 + 0 + wxID_ANY + + 0 + + + 0 + + 1 + m_auinotebook + 1 + + + protected + 1 + + Resizable + 1 + + wxAUI_NB_BOTTOM + + -1 + 0 + + + + + + + + + + + pageChangedHandler + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Global Libraries + 1 + + 1 + 1 + 1 + 1 + + + + + + + + 1 + 0 + 0 + + 0 + 0 + Dock + 0 + Left + 1 + + 1 + + 0 + 0 + wxID_ANY + + 0 + + -1,80 + 0 + + 1 + m_global_panel + 1 + + + protected + 0 + + Resizable + 1 + + + 0 + + + + wxTAB_TRAVERSAL + + + + + + + + + + + + + + + + + + + + + + + + + + m_global_sizer + wxVERTICAL + none + + 5 + wxEXPAND + 0 + + 2 + wxBOTH + + + 0 + + fgSizer1 + wxFLEX_GROWMODE_SPECIFIED + none + 1 + 0 + + 5 + wxRIGHT|wxLEFT + 0 + + 1 + 1 + 1 + 1 + + + + + + + + 1 + 0 + 1 + + 1 + 0 + Dock + 0 + Left + 1 + + 1 + + 0 + 0 + wxID_ANY + Table: + + 0 + + + 0 + + 1 + m_staticText3 + 1 + + + protected + 1 + + Resizable + 1 + + + + 0 + + + + + -1 + + + + + + + + + + + + + + + + + + + + + + + + + + + 5 + wxRIGHT|wxLEFT + 0 + + 1 + 1 + 1 + 1 + + + + + + + + 1 + 0 + 1 + + 1 + 0 + Dock + 0 + Left + 1 + + 1 + + 0 + 0 + wxID_ANY + Table Name + + 0 + + + 0 + + 1 + m_GblTableFilename + 1 + + + protected + 1 + + Resizable + 1 + + + + 0 + + + + + -1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 5 + wxALL|wxEXPAND + 5 + + 1 + 1 + 1 + 1 + + + + + 1 + 1 + + + + 1 + + + wxALIGN_LEFT + + wxALIGN_TOP + 0 + 1 + wxALIGN_CENTRE + 30 + + wxALIGN_CENTRE + 5 + + + 1 + 0 + Dock + 1 + Left + 0 + 1 + 0 + 0 + 1 + 1 + + 0 + + + 1 + 0 + 0 + wxID_ANY + + + + 0 + 0 + + 0 + + + 0 + -1,-1 + 0 + m_global_grid + 1 + + + protected + 1 + + Fixed + wxALIGN_CENTRE + 40 + + wxALIGN_CENTRE + + 1 + 1 + + + 0 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Project Specific Libraries + 0 + + 1 + 1 + 1 + 1 + + + + + + + + 1 + 0 + 1 + + 0 + 0 + Dock + 0 + Left + 1 + + 1 + + 0 + 0 + wxID_ANY + + 0 + + + 0 + + 1 + m_project_panel + 1 + + + protected + 1 + + Resizable + 1 + + + 0 + + + + wxTAB_TRAVERSAL + + + + + + + + + + + + + + + + + + + + + + + + + + m_project_sizer + wxVERTICAL + none + + 5 + wxEXPAND + 0 + + 2 + wxBOTH + + + 0 + + fgSizer2 + wxFLEX_GROWMODE_SPECIFIED + none + 1 + 0 + + 5 + wxRIGHT|wxLEFT + 0 + + 1 + 1 + 1 + 1 + + + + + + + + 1 + 0 + 1 + + 1 + 0 + Dock + 0 + Left + 1 + + 1 + + 0 + 0 + wxID_ANY + Table: + + 0 + + + 0 + + 1 + m_staticText4 + 1 + + + protected + 1 + + Resizable + 1 + + + + 0 + + + + + -1 + + + + + + + + + + + + + + + + + + + + + + + + + + + 5 + wxRIGHT|wxLEFT + 0 + + 1 + 1 + 1 + 1 + + + + + + + + 1 + 0 + 1 + + 1 + 0 + Dock + 0 + Left + 1 + + 1 + + 0 + 0 + wxID_ANY + Table Name + + 0 + + + 0 + + 1 + m_PrjTableFilename + 1 + + + protected + 1 + + Resizable + 1 + + + + 0 + + + + + -1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 5 + wxALL|wxEXPAND + 2 + + 1 + 1 + 1 + 1 + + + + + 1 + 0 + + + + 1 + + + wxALIGN_LEFT + + wxALIGN_TOP + 0 + 1 + wxALIGN_CENTRE + 30 + + wxALIGN_CENTRE + 5 + + + 1 + 0 + Dock + 1 + Left + 0 + 1 + 0 + 0 + 1 + 1 + + 0 + + + 1 + 0 + 0 + wxID_ANY + + + + 0 + 0 + + 0 + + + 0 + + 0 + m_project_grid + 1 + + + protected + 1 + + Fixed + wxALIGN_CENTRE + 40 + + wxALIGN_CENTRE + + 1 + 1 + + + 0 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 8 + wxALIGN_CENTER|wxBOTTOM + 0 + + + bSizer51 + wxHORIZONTAL + none + + 5 + wxALL + 0 + + 1 + 1 + 1 + 1 + + + + + + + + 1 + 0 + 1 + + 1 + 0 + 0 + Dock + 0 + Left + 1 + + 1 + + 0 + 0 + wxID_ANY + Append Library + + 0 + + + 0 + + 1 + m_append_button + 1 + + + protected + 1 + + Resizable + 1 + + + + 0 + Add a PCB library row to this table + + wxFILTER_NONE + wxDefaultValidator + + + + + appendRowHandler + + + + + + + + + + + + + + + + + + + + + + + + + + + 5 + wxALL + 0 + + 1 + 1 + 1 + 1 + + + + + + + + 1 + 0 + 1 + + 1 + 0 + 0 + Dock + 0 + Left + 1 + + 1 + + 0 + 0 + wxID_ANY + Remove Library + + 0 + + + 0 + + 1 + m_delete_button + 1 + + + protected + 1 + + Resizable + 1 + + + + 0 + Remove a PCB library from this library table + + wxFILTER_NONE + wxDefaultValidator + + + + + deleteRowHandler + + + + + + + + + + + + + + + + + + + + + + + + + + + 5 + wxALL + 0 + + 1 + 1 + 1 + 1 + + + + + + + + 1 + 0 + 1 + + 1 + 0 + 0 + Dock + 0 + Left + 1 + + 1 + + 0 + 0 + wxID_ANY + Move Up + + 0 + + + 0 + + 1 + m_move_up_button + 1 + + + protected + 1 + + Resizable + 1 + + + + 0 + Move the currently selected row up one position + + wxFILTER_NONE + wxDefaultValidator + + + + + moveUpHandler + + + + + + + + + + + + + + + + + + + + + + + + + + + 5 + wxALL + 0 + + 1 + 1 + 1 + 1 + + + + + + + + 1 + 0 + 1 + + 1 + 0 + 0 + Dock + 0 + Left + 1 + + 1 + + 0 + 0 + wxID_ANY + Move Down + + 0 + + + 0 + + 1 + m_move_down_button + 1 + + + protected + 1 + + Resizable + 1 + + + + 0 + Move the currently selected row down one position + + wxFILTER_NONE + wxDefaultValidator + + + + + moveDownHandler + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 5 + wxALL|wxEXPAND + 0 + + wxID_ANY + Path Substitutions + + sbSizer1 + wxVERTICAL + 1 + none + + + 5 + wxALL|wxEXPAND + 1 + + 1 + 1 + 1 + 1 + + + + + 1 + 0 + + + + 1 + + + wxALIGN_LEFT + + wxALIGN_TOP + 0 + 1 + wxALIGN_CENTRE + 30 + "Environment Variable" "Path Segment" + wxALIGN_CENTRE + 2 + 150,500 + + 1 + 0 + Dock + 0 + Left + 0 + 1 + 0 + 1 + 0 + 1 + + 1 + + + 1 + 0 + 0 + wxID_ANY + + + + 0 + 0 + + 0 + + + 0 + + 1 + m_path_subs_grid + 1 + + + protected + 1 + + Resizable + wxALIGN_CENTRE + 40 + + wxALIGN_CENTRE + + 1 + 1 + + + 0 + This is a read-only table which shows pertinent environment variables. + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 5 + wxEXPAND + 0 + + + m_bottom_sizer + wxVERTICAL + none + + 5 + wxALL|wxEXPAND + 0 + + 0 + 1 + 0 + 0 + 0 + 1 + 0 + 0 + + m_sdbSizer + protected + + + + + + + + + + + + + + + + diff --git a/eeschema/dialogs/dialog_sym_lib_table_base.h b/eeschema/dialogs/dialog_sym_lib_table_base.h new file mode 100644 index 0000000000..92a5485e4e --- /dev/null +++ b/eeschema/dialogs/dialog_sym_lib_table_base.h @@ -0,0 +1,78 @@ +/////////////////////////////////////////////////////////////////////////// +// C++ code generated with wxFormBuilder (version Jul 29 2017) +// http://www.wxformbuilder.org/ +// +// PLEASE DO "NOT" EDIT THIS FILE! +/////////////////////////////////////////////////////////////////////////// + +#ifndef __DIALOG_SYM_LIB_TABLE_BASE_H__ +#define __DIALOG_SYM_LIB_TABLE_BASE_H__ + +#include +#include +#include +class DIALOG_SHIM; + +#include "dialog_shim.h" +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +/////////////////////////////////////////////////////////////////////////// + + +/////////////////////////////////////////////////////////////////////////////// +/// Class DIALOG_SYMBOL_LIB_TABLE_BASE +/////////////////////////////////////////////////////////////////////////////// +class DIALOG_SYMBOL_LIB_TABLE_BASE : public DIALOG_SHIM +{ + private: + + protected: + wxAuiNotebook* m_auinotebook; + wxPanel* m_global_panel; + wxStaticText* m_staticText3; + wxStaticText* m_GblTableFilename; + wxGrid* m_global_grid; + wxPanel* m_project_panel; + wxStaticText* m_staticText4; + wxStaticText* m_PrjTableFilename; + wxGrid* m_project_grid; + wxButton* m_append_button; + wxButton* m_delete_button; + wxButton* m_move_up_button; + wxButton* m_move_down_button; + wxGrid* m_path_subs_grid; + wxStdDialogButtonSizer* m_sdbSizer; + wxButton* m_sdbSizerOK; + wxButton* m_sdbSizerCancel; + + // Virtual event handlers, overide them in your derived class + virtual void pageChangedHandler( wxAuiNotebookEvent& event ) = 0; + virtual void appendRowHandler( wxCommandEvent& event ) = 0; + virtual void deleteRowHandler( wxCommandEvent& event ) = 0; + virtual void moveUpHandler( wxCommandEvent& event ) = 0; + virtual void moveDownHandler( wxCommandEvent& event ) = 0; + + + public: + + DIALOG_SYMBOL_LIB_TABLE_BASE( wxWindow* parent, wxWindowID id = wxID_ANY, const wxString& title = _("Schematic Library Tables"), const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxSize( 800,600 ), long style = wxCAPTION|wxCLOSE_BOX|wxDEFAULT_DIALOG_STYLE|wxMAXIMIZE_BOX|wxRESIZE_BORDER|wxSYSTEM_MENU ); + ~DIALOG_SYMBOL_LIB_TABLE_BASE(); + +}; + +#endif //__DIALOG_SYM_LIB_TABLE_BASE_H__ diff --git a/eeschema/eeschema_id.h b/eeschema/eeschema_id.h index c282b64675..f68d5edae2 100644 --- a/eeschema/eeschema_id.h +++ b/eeschema/eeschema_id.h @@ -1,8 +1,8 @@ /* * This program source code file is part of KiCad, a free EDA CAD application. * - * Copyright (C) 2008-2017 Wayne Stambaugh - * Copyright (C) 2004-2017 KiCad Developers, see change_log.txt for contributors. + * Copyright (C) 2008 Wayne Stambaugh + * Copyright (C) 2008-2017 KiCad Developers, see change_log.txt for contributors. * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License @@ -63,6 +63,7 @@ enum id_eeschema_frm /* Schematic editor main menubar IDs. */ ID_RESCUE_CACHED, + ID_EDIT_SYM_LIB_TABLE, /* Schematic editor horizontal toolbar IDs */ ID_HIERARCHY, diff --git a/eeschema/libeditframe.cpp b/eeschema/libeditframe.cpp index 4fbee0cd01..18bf13ef3d 100644 --- a/eeschema/libeditframe.cpp +++ b/eeschema/libeditframe.cpp @@ -294,6 +294,9 @@ LIB_EDIT_FRAME::LIB_EDIT_FRAME( KIWAY* aKiway, wxWindow* aParent ) : Raise(); Show( true ); + Bind( wxEVT_COMMAND_MENU_SELECTED, &OnEditSymbolLibTable, this, + ID_EDIT_SYM_LIB_TABLE ); + wxCommandEvent evt( wxEVT_COMMAND_MENU_SELECTED, ID_ZOOM_PAGE ); wxPostEvent( this, evt ); } @@ -301,6 +304,9 @@ LIB_EDIT_FRAME::LIB_EDIT_FRAME( KIWAY* aKiway, wxWindow* aParent ) : LIB_EDIT_FRAME::~LIB_EDIT_FRAME() { + Unbind( wxEVT_COMMAND_MENU_SELECTED, &OnEditSymbolLibTable, this, + ID_EDIT_SYM_LIB_TABLE ); + m_drawItem = m_lastDrawItem = NULL; delete m_tempCopyComponent; diff --git a/eeschema/menubar.cpp b/eeschema/menubar.cpp index 94683de434..1ead98328c 100644 --- a/eeschema/menubar.cpp +++ b/eeschema/menubar.cpp @@ -610,6 +610,12 @@ static void preparePreferencesMenu( SCH_EDIT_FRAME* aFrame, wxMenu* aParentMenu _( "Configure component libraries and paths" ), KiBitmap( library_xpm ) ); + AddMenuItem( aParentMenu, + ID_EDIT_SYM_LIB_TABLE, + _( "Symbol Library &Table" ), + _( "Edit the symbol library table." ), + KiBitmap( library_xpm ) ); + // Options (Preferences on WXMAC) #ifdef __WXMAC__ aParentMenu->Append( wxID_PREFERENCES ); diff --git a/eeschema/menubar_libedit.cpp b/eeschema/menubar_libedit.cpp index 049b8ca9d8..b726325691 100644 --- a/eeschema/menubar_libedit.cpp +++ b/eeschema/menubar_libedit.cpp @@ -239,8 +239,14 @@ void LIB_EDIT_FRAME::ReCreateMenuBar() _( "Configure component libraries and paths" ), KiBitmap( library_xpm ) ); + AddMenuItem( preferencesMenu, + ID_EDIT_SYM_LIB_TABLE, + _( "Symbol Library &Table" ), + _( "Edit the symbol library table." ), + KiBitmap( library_xpm ) ); + // Default values and options - AddMenuItem( preferencesMenu, + AddMenuItem( preferencesMenu, wxID_PREFERENCES, _( "Component Editor &Options" ), _( "Set Component Editor default values and options" ), diff --git a/eeschema/sch_base_frame.cpp b/eeschema/sch_base_frame.cpp index 8a0d957bc1..dc038962ed 100644 --- a/eeschema/sch_base_frame.cpp +++ b/eeschema/sch_base_frame.cpp @@ -2,7 +2,7 @@ * This program source code file is part of KiCad, a free EDA CAD application. * * Copyright (C) 2012 SoftPLC Corporation, Dick Hollenbeck - * Copyright (C) 2015 KiCad Developers, see change_log.txt for contributors. + * Copyright (C) 2015-2017 KiCad Developers, see change_log.txt for contributors. * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License @@ -22,13 +22,18 @@ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA */ -#include -#include -#include #include #include #include +#include +#include +#include +#include +#include +#include "dialogs/dialog_sym_lib_table.h" + + // Sttaic members: @@ -48,6 +53,12 @@ SCH_BASE_FRAME::SCH_BASE_FRAME( KIWAY* aKiway, wxWindow* aParent, } + +SCH_BASE_FRAME::~SCH_BASE_FRAME() +{ +} + + void SCH_BASE_FRAME::OnOpenLibraryViewer( wxCommandEvent& event ) { LIB_VIEW_FRAME* viewlibFrame = (LIB_VIEW_FRAME*) Kiway().Player( FRAME_SCH_VIEWER, true ); @@ -62,12 +73,14 @@ void SCH_BASE_FRAME::OnOpenLibraryViewer( wxCommandEvent& event ) viewlibFrame->Raise(); } + // Virtual from EDA_DRAW_FRAME COLOR4D SCH_BASE_FRAME::GetDrawBgColor() const { return GetLayerColor( LAYER_SCHEMATIC_BACKGROUND ); } + void SCH_BASE_FRAME::SetDrawBgColor( COLOR4D aColor) { m_drawBgColor= aColor; @@ -201,3 +214,49 @@ void SCH_BASE_FRAME::UpdateStatusBar() // refresh units display DisplayUnitsMsg(); } + + +void SCH_BASE_FRAME::OnEditSymbolLibTable( wxCommandEvent& aEvent ) +{ + DIALOG_SYMBOL_LIB_TABLE dlg( this, &SYMBOL_LIB_TABLE::GetGlobalLibTable(), + Prj().SchSymbolLibTable() ); + + if( dlg.ShowModal() == wxID_CANCEL ) + return; + + try + { + FILE_OUTPUTFORMATTER sf( SYMBOL_LIB_TABLE::GetGlobalTableFileName() ); + + SYMBOL_LIB_TABLE::GetGlobalLibTable().Format( &sf, 0 ); + } + catch( const IO_ERROR& ioe ) + { + wxString msg = wxString::Format( _( "Error occurred saving the global symbol library " + "table:\n\n%s" ), + GetChars( ioe.What().GetData() ) ); + wxMessageBox( msg, _( "File Save Error" ), wxOK | wxICON_ERROR ); + } + + if( !Prj().GetProjectName().IsEmpty() ) + { + wxFileName fn( Prj().GetProjectPath(), SYMBOL_LIB_TABLE::GetSymbolLibTableFileName() ); + + try + { + Prj().SchSymbolLibTable()->Save( fn.GetFullPath() ); + } + catch( const IO_ERROR& ioe ) + { + wxString msg = wxString::Format( _( "Error occurred saving project specific " + "symbol library table:\n\n%s" ), + GetChars( ioe.What() ) ); + wxMessageBox( msg, _( "File Save Error" ), wxOK | wxICON_ERROR ); + } + } + + LIB_VIEW_FRAME* viewer = (LIB_VIEW_FRAME*) Kiway().Player( FRAME_SCH_VIEWER, false ); + + if( viewer ) + viewer->ReCreateListLib(); +} diff --git a/eeschema/sch_base_frame.h b/eeschema/sch_base_frame.h index 41ae0e46c7..c79055610d 100644 --- a/eeschema/sch_base_frame.h +++ b/eeschema/sch_base_frame.h @@ -61,6 +61,8 @@ public: const wxPoint& aPosition, const wxSize& aSize, long aStyle, const wxString & aFrameName ); + virtual ~SCH_BASE_FRAME(); + SCH_SCREEN* GetScreen() const override; /** @@ -172,6 +174,8 @@ public: const wxString& aHighlight = wxEmptyString, bool aAllowFields = true ); + void OnEditSymbolLibTable( wxCommandEvent& aEvent ); + protected: /** diff --git a/eeschema/schframe.cpp b/eeschema/schframe.cpp index ec547ea4ef..1e62e64c60 100644 --- a/eeschema/schframe.cpp +++ b/eeschema/schframe.cpp @@ -436,11 +436,17 @@ SCH_EDIT_FRAME::SCH_EDIT_FRAME( KIWAY* aKiway, wxWindow* aParent ): // Net list generator DefaultExecFlags(); + + Bind( wxEVT_COMMAND_MENU_SELECTED, &OnEditSymbolLibTable, this, + ID_EDIT_SYM_LIB_TABLE ); } SCH_EDIT_FRAME::~SCH_EDIT_FRAME() { + Unbind( wxEVT_COMMAND_MENU_SELECTED, &OnEditSymbolLibTable, this, + ID_EDIT_SYM_LIB_TABLE ); + delete m_item_to_repeat; // we own the cloned object, see this->SetRepeatItem() SetScreen( NULL ); diff --git a/eeschema/symbol_lib_table.h b/eeschema/symbol_lib_table.h index f23f8870bc..d183cca56c 100644 --- a/eeschema/symbol_lib_table.h +++ b/eeschema/symbol_lib_table.h @@ -1,7 +1,7 @@ /* * This program source code file is part of KiCad, a free EDA CAD application. * - * Copyright (C) 2016-2017 Wayne Stambaugh + * Copyright (C) 2016 Wayne Stambaugh * Copyright (C) 2016-2017 KiCad Developers, see change_log.txt for contributors. * * This program is free software; you can redistribute it and/or @@ -31,6 +31,7 @@ class LIB_PART; class SYMBOL_LIB_TABLE_GRID; +class DIALOG_SYMBOL_LIB_TABLE; /** @@ -98,6 +99,7 @@ private: class SYMBOL_LIB_TABLE : public LIB_TABLE { friend class SYMBOL_LIB_TABLE_GRID; + friend class DIALOG_SYMBOL_LIB_TABLE; public: virtual void Parse( LIB_TABLE_LEXER* aLexer ) override;