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;