From 8fd0c322cd19fb6807e761d5a566ff7f005e0970 Mon Sep 17 00:00:00 2001 From: Dick Hollenbeck Date: Sun, 20 Jan 2013 21:12:16 -0600 Subject: [PATCH] more fp lib table work --- pcbnew/dialogs/dialog_fp_lib_table.cpp | 142 ++++++++++++++++++-- pcbnew/dialogs/dialog_fp_lib_table_base.cpp | 8 +- pcbnew/dialogs/dialog_fp_lib_table_base.fbp | 10 +- pcbnew/dialogs/dialog_fp_lib_table_base.h | 4 +- pcbnew/io_mgr.h | 2 + pcbnew/pcbnew_config.cpp | 35 ++--- 6 files changed, 161 insertions(+), 40 deletions(-) diff --git a/pcbnew/dialogs/dialog_fp_lib_table.cpp b/pcbnew/dialogs/dialog_fp_lib_table.cpp index 711b4f17f4..1dbae2af63 100644 --- a/pcbnew/dialogs/dialog_fp_lib_table.cpp +++ b/pcbnew/dialogs/dialog_fp_lib_table.cpp @@ -24,12 +24,27 @@ */ +/* TODO: + +*) Check for duplicate nicknames per table + +*) Grab text from any pending ChoiceEditor when OK button pressed. + +*) Test wxRE_ADVANCED on Windows. + +*/ + + + #include #include #include #include #include #include +#include +#include +#include /** * Class FP_TBL_MODEL @@ -184,18 +199,32 @@ public: { case COL_NICKNAME: return _( "Nickname" ); case COL_URI: return _( "Library Path" ); - case COL_TYPE: return _( "Plugin" ); + + // keep this text fairly long so column is sized wide enough + case COL_TYPE: return _( "Plugin Type" ); case COL_OPTIONS: return _( "Options" ); case COL_DESCR: return _( "Description" ); default: return wxEmptyString; } } + /* + wxGridCellAttr* GetAttr( int aRow, int aCol, wxGridCellAttr::wxAttrKind aKind ) const // overload + { + if( aCol != COL_TYPE ) + return wxGridTableBase::GetAttr( aRow, aCol, aKind ); + else + { + + } + } + */ + //----------------------------------------------- }; -// It works for table data on clipboard for an excell spreadsheet, +// It works for table data on clipboard for an Excell spreadsheet, // why not us too for now. #define COL_SEP wxT( '\t' ) #define ROW_SEP wxT( '\n' ) @@ -509,6 +538,71 @@ class DIALOG_FP_LIB_TABLE : public DIALOG_FP_LIB_TABLE_BASE event.Skip(); } + /// Populate the readonly environment variable table with names and values + /// by examining all the full_uri columns. + void populateEnvironReadOnlyTable() + { + wxRegEx re( wxT( ".*?\\$\\{(.+?)\\}.*?" ), wxRE_ADVANCED ); + wxASSERT( re.IsValid() ); // wxRE_ADVANCED is required. + + std::set< wxString > unique; + typedef std::set::const_iterator SET_CITER; + + m_path_subs_grid->DeleteRows( 0, m_path_subs_grid->GetNumberRows() ); + + int gblRowCount = m_global_model.GetNumberRows(); + int prjRowCount = m_project_model.GetNumberRows(); + int row; + + for( row = 0; row < gblRowCount; ++row ) + { + wxString uri = m_global_model.GetValue( row, FP_TBL_MODEL::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 = m_project_model.GetValue( row, FP_TBL_MODEL::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 ); + } + } + + 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(); + } + //-------------------------------------- // caller's tables are modified only on OK button. @@ -540,14 +634,38 @@ public: m_project_grid->SetTable( (wxGridTableBase*) &m_project_model ); m_global_grid->AutoSizeColumns( false ); - m_project_grid->AutoSizeColumns( false ); - m_path_subs_grid->AutoSizeColumns( false ); + wxArrayString choices; + choices.Add( IO_MGR::ShowType( IO_MGR::KICAD ) ); + choices.Add( IO_MGR::ShowType( IO_MGR::LEGACY ) ); + choices.Add( IO_MGR::ShowType( IO_MGR::EAGLE ) ); + //choices.Add( IO_MGR::ShowType( IO_MGR::GEDA_PCB ) ); + + wxGridCellAttr* attr; + + attr = new wxGridCellAttr; + attr->SetEditor( new wxGridCellChoiceEditor( choices ) ); + m_project_grid->SetColAttr( FP_TBL_MODEL::COL_TYPE, attr ); + + attr = new wxGridCellAttr; + attr->SetEditor( new wxGridCellChoiceEditor( choices ) ); + m_global_grid->SetColAttr( FP_TBL_MODEL::COL_TYPE, attr ); + + m_global_grid->AutoSizeColumns(); + m_project_grid->AutoSizeColumns(); + + m_path_subs_grid->AutoSizeColumns(); Connect( ID_CUT, ID_PASTE, wxEVT_COMMAND_MENU_SELECTED, wxCommandEventHandler( DIALOG_FP_LIB_TABLE::onPopupSelection ), NULL, this ); + populateEnvironReadOnlyTable(); + + /* This scrunches the dialog hideously + Fit(); + */ + // fire pageChangedHandler() so m_cur_grid gets set wxAuiNotebookEvent uneventful; pageChangedHandler( uneventful ); @@ -555,18 +673,18 @@ public: ~DIALOG_FP_LIB_TABLE() { - // Destroy the gui stuff first, with a goal of destroying the two wxGrids now, - // since the ~wxGrid() wants the wxGridTableBase to still be non-destroyed. - // Without this call, the wxGridTableBase objects are destroyed first - // (i.e. destructor called) and there is a segfault since wxGridTableBase's vtable - // is then no longer valid. If ~wxGrid() would not examine a wxGridTableBase that - // it does not own, then this would not be a concern. But it is, since it does. - DestroyChildren(); + Disconnect( ID_CUT, ID_PASTE, wxEVT_COMMAND_MENU_SELECTED, + wxCommandEventHandler( DIALOG_FP_LIB_TABLE::onPopupSelection ), NULL, this ); + + // ~wxGrid() examines its table, and the tables will have been destroyed before + // the wxGrids are, so remove the tables from the wxGrids' awareness. + // Otherwise there is a segfault. + m_global_grid->SetTable( NULL ); + m_project_grid->SetTable( NULL ); } }; - int InvokePcbLibTableEditor( wxFrame* aParent, FP_LIB_TABLE* aGlobal, FP_LIB_TABLE* aProject ) { DIALOG_FP_LIB_TABLE dlg( aParent, aGlobal, aProject ); diff --git a/pcbnew/dialogs/dialog_fp_lib_table_base.cpp b/pcbnew/dialogs/dialog_fp_lib_table_base.cpp index 5e525ecd3f..c5a43fbef5 100644 --- a/pcbnew/dialogs/dialog_fp_lib_table_base.cpp +++ b/pcbnew/dialogs/dialog_fp_lib_table_base.cpp @@ -142,7 +142,7 @@ DIALOG_FP_LIB_TABLE_BASE::DIALOG_FP_LIB_TABLE_BASE( wxWindow* parent, wxWindowID m_path_subs_grid = new wxGrid( m_bottom, wxID_ANY, wxDefaultPosition, wxDefaultSize, 0 ); // Grid - m_path_subs_grid->CreateGrid( 2, 2 ); + m_path_subs_grid->CreateGrid( 1, 2 ); m_path_subs_grid->EnableEditing( true ); m_path_subs_grid->EnableGridLines( true ); m_path_subs_grid->EnableDragGridSize( false ); @@ -155,15 +155,13 @@ DIALOG_FP_LIB_TABLE_BASE::DIALOG_FP_LIB_TABLE_BASE( wxWindow* parent, wxWindowID m_path_subs_grid->EnableDragColMove( false ); m_path_subs_grid->EnableDragColSize( true ); m_path_subs_grid->SetColLabelSize( 30 ); - m_path_subs_grid->SetColLabelValue( 0, _("Category") ); + 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->SetRowLabelValue( 0, _("%S") ); - m_path_subs_grid->SetRowLabelValue( 1, _("%P") ); m_path_subs_grid->SetRowLabelAlignment( wxALIGN_CENTRE, wxALIGN_CENTRE ); // Label Appearance @@ -188,7 +186,7 @@ DIALOG_FP_LIB_TABLE_BASE::DIALOG_FP_LIB_TABLE_BASE( wxWindow* parent, wxWindowID m_bottom->SetSizer( m_bottom_sizer ); m_bottom->Layout(); m_bottom_sizer->Fit( m_bottom ); - m_splitter->SplitHorizontally( m_top, m_bottom, 343 ); + m_splitter->SplitHorizontally( m_top, m_bottom, 398 ); bSizer1->Add( m_splitter, 2, wxEXPAND, 5 ); diff --git a/pcbnew/dialogs/dialog_fp_lib_table_base.fbp b/pcbnew/dialogs/dialog_fp_lib_table_base.fbp index 79bdad58e7..a5e4b1ff83 100644 --- a/pcbnew/dialogs/dialog_fp_lib_table_base.fbp +++ b/pcbnew/dialogs/dialog_fp_lib_table_base.fbp @@ -42,7 +42,7 @@ DIALOG_FP_LIB_TABLE_BASE - 864,652 + 996,652 wxDEFAULT_DIALOG_STYLE|wxRESIZE_BORDER DIALOG_SHIM; dialog_shim.h PCB Library Tables @@ -140,7 +140,7 @@ Resizable 0.0 - 343 + 398 -1 1 @@ -1297,7 +1297,7 @@ 1 wxALIGN_CENTRE 30 - "Category" "Path Segment" + "Environment Variable" "Path Segment" wxALIGN_CENTRE 2 150,500 @@ -1343,10 +1343,10 @@ Resizable wxALIGN_CENTRE 40 - "%S" "%P" + wxALIGN_CENTRE - 2 + 1 1 diff --git a/pcbnew/dialogs/dialog_fp_lib_table_base.h b/pcbnew/dialogs/dialog_fp_lib_table_base.h index 44ef78ef8a..5a0e15dcd0 100644 --- a/pcbnew/dialogs/dialog_fp_lib_table_base.h +++ b/pcbnew/dialogs/dialog_fp_lib_table_base.h @@ -75,12 +75,12 @@ class DIALOG_FP_LIB_TABLE_BASE : public DIALOG_SHIM public: - DIALOG_FP_LIB_TABLE_BASE( wxWindow* parent, wxWindowID id = wxID_ANY, const wxString& title = _("PCB Library Tables"), const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxSize( 864,652 ), long style = wxDEFAULT_DIALOG_STYLE|wxRESIZE_BORDER ); + DIALOG_FP_LIB_TABLE_BASE( wxWindow* parent, wxWindowID id = wxID_ANY, const wxString& title = _("PCB Library Tables"), const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxSize( 996,652 ), long style = wxDEFAULT_DIALOG_STYLE|wxRESIZE_BORDER ); ~DIALOG_FP_LIB_TABLE_BASE(); void m_splitterOnIdle( wxIdleEvent& ) { - m_splitter->SetSashPosition( 343 ); + m_splitter->SetSashPosition( 398 ); m_splitter->Disconnect( wxEVT_IDLE, wxIdleEventHandler( DIALOG_FP_LIB_TABLE_BASE::m_splitterOnIdle ), NULL, this ); } diff --git a/pcbnew/io_mgr.h b/pcbnew/io_mgr.h index 53778ca310..2806e0346f 100644 --- a/pcbnew/io_mgr.h +++ b/pcbnew/io_mgr.h @@ -51,6 +51,8 @@ public: LEGACY, //< Legacy Pcbnew file formats prior to s-expression. KICAD, //< S-expression Pcbnew file format. EAGLE, + PCAD, + GEDA_PCB, //< Geda PCB file formats. // add your type here. diff --git a/pcbnew/pcbnew_config.cpp b/pcbnew/pcbnew_config.cpp index bc9fce26fa..2504034eb8 100644 --- a/pcbnew/pcbnew_config.cpp +++ b/pcbnew/pcbnew_config.cpp @@ -45,9 +45,7 @@ #include #include -#if defined(DEBUG) - #include -#endif +#include #include #include @@ -92,7 +90,6 @@ void PCB_EDIT_FRAME::Process_Config( wxCommandEvent& event ) FP_LIB_TABLE gbl; FP_LIB_TABLE prj; -#if defined(DEBUG) FP_LIB_TABLE_LEXER glex( "(fp_lib_table\n" " (lib (name passives)(descr \"R/C Lib\")(type KiCad)(uri ${KISYSMODS}/passives.pretty))\n" @@ -124,29 +121,35 @@ void PCB_EDIT_FRAME::Process_Config( wxCommandEvent& event ) DisplayError( this, ioe.errorText ); break; } -#else - gbl.InsertRow( FP_LIB_TABLE::ROW( - wxT( "passives" ), wxT( "%G/passives" ), wxT( "KiCad" ), wxT( "speed=fast,purpose=testing" ) ) ); - - gbl.InsertRow( FP_LIB_TABLE::ROW( - wxT( "micros" ), wxT( "%P/micros" ), wxT( "Legacy" ), wxT( "speed=fast,purpose=testing" ) ) ); - - prj.InsertRow( FP_LIB_TABLE::ROW( - wxT( "micros" ), wxT( "%P/potato_chips" ), wxT( "Eagle" ), wxT( "speed=fast,purpose=testing" ) ) ); -#endif int r = InvokePcbLibTableEditor( this, &gbl, &prj ); if( r & 1 ) { +#if defined(DEBUG) + printf( "changed global:\n" );) + + STRING_FORMATTER sf; + + gbl.Format( &sf, 0 ); + + printf( "%s\n", sf.GetString().c_str() ); +#endif // save global table to disk and apply it - D( printf( "global has changed\n" );) } if( r & 2 ) { +#if defined(DEBUG) + D( printf( "changed project:n" );) + + STRING_FORMATTER sf; + + prj.Format( &sf, 0 ); + + printf( "%s\n", sf.GetString().c_str() ); +#endif // save project table to disk and apply it - D( printf( "project has changed\n" );) } } break;