diff --git a/common/fp_lib_table.cpp b/common/fp_lib_table.cpp index d4f8500b50..95e20b8a62 100644 --- a/common/fp_lib_table.cpp +++ b/common/fp_lib_table.cpp @@ -142,6 +142,9 @@ void FP_LIB_TABLE::Parse( FP_LIB_TABLE_LEXER* in ) throw( IO_ERROR, PARSE_ERROR sawOpts = true; in->NeedSYMBOLorNUMBER(); row.SetOptions( in->FromUTF8() ); + + // create PROPERTIES* from options, set into the ROW + row.properties = ParseOptions( in->CurText() ); break; case T_descr: @@ -205,6 +208,101 @@ void FP_LIB_TABLE::ROW::Format( OUTPUTFORMATTER* out, int nestLevel ) const } +#define OPT_SEP '|' ///< options separator character + +PROPERTIES* FP_LIB_TABLE::ParseOptions( const std::string& aOptionsList ) +{ + const char* cp = &aOptionsList[0]; + const char* end = cp + aOptionsList.size(); + + PROPERTIES props; + std::string pair; + + // Parse all name=value pairs + while( cp < end ) + { + pair.clear(); + + // Skip leading white space. + while( cp < end && isspace( *cp ) ) + ++cp; + + // Find the end of pair/field + while( cp<end ) + { + if( *cp == '\\' && cp+1 < end && cp[1]==OPT_SEP ) + { + ++cp; // skip the escape + pair += *cp++; // add the separator + } + + else if( *cp==OPT_SEP ) + { + ++cp; // skip the separator + break; // process the pair + } + else + pair += *cp++; + } + + // stash the pair + if( pair.size() ) + { + // the first equals size established the end of the name + size_t eqNdx = pair.find( '=' ); + if( eqNdx != pair.npos ) + { + std::string name = pair.substr( 0, eqNdx ); + std::string value = pair.substr( eqNdx + 1 ); + props[name] = value; + } + else + props[pair] = ""; + } + } + + if( props.size() ) + return new PROPERTIES( props ); + else + return NULL; +} + + +std::string FP_LIB_TABLE::FormatOptions( const PROPERTIES* aProperties ) +{ + std::string ret; + + if( aProperties ) + { + for( PROPERTIES::const_iterator it = aProperties->begin(); it != aProperties->end(); ++it ) + { + const std::string& name = it->first; + const std::string& value = it->second; + + if( ret.size() ) + ret += OPT_SEP; + + ret += name; + + // the separation between name and value is '=' + if( value.size() ) + ret += '='; + + for( std::string::const_iterator si = value.begin(); si != value.end(); ++si ) + { + // escape any separator in the value. + if( *si == OPT_SEP ) + ret += '\\'; + + ret += *si; + } + } + } + + return ret; +} + + std::vector<wxString> FP_LIB_TABLE::GetLogicalLibs() { // Only return unique logical library names. Use std::set::insert() to diff --git a/include/fp_lib_table.h b/include/fp_lib_table.h index 1ac53c7576..c23fd4609e 100644 --- a/include/fp_lib_table.h +++ b/include/fp_lib_table.h @@ -103,7 +103,9 @@ public: typedef IO_MGR::PCB_FILE_T LIB_T; - ROW() : type( IO_MGR::KICAD ) + ROW() : + type( IO_MGR::KICAD ), + properties( 0 ) { } @@ -112,11 +114,39 @@ public: nickName( aNick ), uri( aURI ), options( aOptions ), - description( aDescr ) + description( aDescr ), + properties( 0 ) { SetType( aType ); } + ROW( const ROW& a ) : + nickName( a.nickName ), + uri( a.uri ), + type( a.type ), + options( a.options ), + description( a.description ), + properties( 0 ) + { + if( a.properties ) + properties = new PROPERTIES( *a.properties ); + } + + ~ROW() + { + delete properties; + } + + ROW& operator=( const ROW& r ) + { + nickName = r.nickName; + uri = r.uri; + type = r.type; + options = r.options; + properties = r.properties ? new PROPERTIES( *r.properties ) : NULL; + return *this; + } + bool operator==( const ROW& r ) const { return nickName==r.nickName && uri==r.uri && type==r.type && options==r.options; @@ -206,6 +236,7 @@ public: LIB_T type; wxString options; wxString description; + PROPERTIES* properties; }; @@ -261,6 +292,31 @@ public: */ void Parse( FP_LIB_TABLE_LEXER* aParser ) throw( IO_ERROR, PARSE_ERROR ); + /** + * Function ParseOptions + * parses @a aOptionsList and places the result into a PROPERTIES object + * which is returned. If the options field is empty, then the returned PROPERTIES + * will be a NULL pointer. + * <p> + * Typically aOptionsList comes from the "options" field within a ROW and + * the format is simply a comma separated list of name value pairs. e.g.: + * [name1[=value1][|name2[=value2]]] etc. When using the UI to create or edit + * a fp lib table, this formatting is handled for you. + */ + static PROPERTIES* ParseOptions( const std::string& aOptionsList ); + + /** + * Function FormatOptions + * returns a list of options from the aProperties parameter. The name=value + * pairs will be separted with the '|' character. The =value portion may not + * be present. You might expect something like "name1=value1|name2=value2|flag_me". + * Notice that flag_me does not have a value. This is ok. + * + * @param aProperties is the PROPERTIES to format or NULL. If NULL the returned + * string will be empty. + */ + static std::string FormatOptions( const PROPERTIES* aProperties ); + /** * Function Format * serializes this object as utf8 text to an #OUTPUTFORMATTER, and tries to @@ -272,7 +328,6 @@ public: */ void Format( OUTPUTFORMATTER* out, int nestLevel ) const throw( IO_ERROR ); - /** * Function GetLogicalLibs * returns the logical library names, all of them that are pertinent to @@ -280,8 +335,6 @@ public: */ std::vector<wxString> GetLogicalLibs(); - - //----<read accessors>---------------------------------------------------- // the returning of a const wxString* tells if not found, but might be too // promiscuous? @@ -480,7 +533,7 @@ protected: typedef ROWS::iterator ROWS_ITER; typedef ROWS::const_iterator ROWS_CITER; - ROWS rows; + ROWS rows; /// this is a non-owning index into the ROWS table typedef std::map<wxString,int> INDEX; // "int" is std::vector array index @@ -491,7 +544,7 @@ protected: /// this particular key is the nickName within each row. INDEX nickIndex; - FP_LIB_TABLE* fallBack; + FP_LIB_TABLE* fallBack; }; diff --git a/include/hashtables.h b/include/hashtables.h index 2523baa057..d117a59abc 100644 --- a/include/hashtables.h +++ b/include/hashtables.h @@ -37,14 +37,14 @@ #include <unordered_map> /// Map a C string to a wxString, used in PLUGINs. -typedef std::unordered_map< std::string, wxString > PROPERTIES; +typedef std::unordered_map< std::string, std::string > PROPERTIES; /// Map a C string to an integer. Used in DSNLEXER. -typedef std::unordered_map< std::string, int > KEYWORD_MAP; +typedef std::unordered_map< std::string, int > KEYWORD_MAP; /// Map a C string to an EDA_RECT. /// The key is the classname of the derived wxformbuilder dialog. -typedef std::unordered_map< std::string, EDA_RECT > RECT_MAP; +typedef std::unordered_map< std::string, EDA_RECT > RECT_MAP; #elif 1 // boost::unordered_map @@ -57,7 +57,7 @@ typedef std::unordered_map< std::string, EDA_RECT > RECT_MAP; // see http://www.boost.org/doc/libs/1_49_0/doc/html/boost/unordered_map.html /// Map a std::string to a wxString, used in PLUGINs. -typedef boost::unordered_map< std::string, wxString > PROPERTIES; +typedef boost::unordered_map< std::string, std::string > PROPERTIES; /// Equality test for "const char*" type used in very specialized KEYWORD_MAP below diff --git a/pcbnew/CMakeLists.txt b/pcbnew/CMakeLists.txt index cf7b8f9804..7aa7cfaeb4 100644 --- a/pcbnew/CMakeLists.txt +++ b/pcbnew/CMakeLists.txt @@ -1,3 +1,6 @@ + +set( MAKE_LINK_MAPS true ) + add_definitions( -DPCBNEW ) if( KICAD_SCRIPTING OR KICAD_SCRIPTING_MODULES ) @@ -322,7 +325,6 @@ endif() # _pcbnew DLL/DSO file creation ### -unset( GITHUB_PLUGIN_LIBRARIES ) if( BUILD_GITHUB_PLUGIN ) set( GITHUB_PLUGIN_LIBRARIES github_plugin ) endif() @@ -362,6 +364,11 @@ if( KICAD_SCRIPTING_MODULES ) WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/scripting/qa ) + if( MAKE_LINK_MAPS ) + # generate a link map with cross reference + set_target_properties( _pcbnew PROPERTIES LINK_FLAGS "-Wl,-cref -Wl,-Map=_pcbnew.map" ) + endif() + endif() @@ -507,6 +514,7 @@ target_link_libraries( pcbnew pcad2kicadpcb polygon bitmaps + ${GITHUB_PLUGIN_LIBRARIES} ${wxWidgets_LIBRARIES} ${OPENGL_LIBRARIES} ${GDI_PLUS_LIBRARIES} @@ -514,8 +522,10 @@ target_link_libraries( pcbnew ${PCBNEW_EXTRA_LIBS} ) -if( BUILD_GITHUB_PLUGIN ) - target_link_libraries( pcbnew github_plugin ) + +if( MAKE_LINK_MAPS ) + # generate a link map with cross reference + set_target_properties( pcbnew PROPERTIES LINK_FLAGS "-Wl,-cref -Wl,-Map=pcbnew.map" ) endif() diff --git a/pcbnew/dialogs/dialog_fp_lib_table.cpp b/pcbnew/dialogs/dialog_fp_lib_table.cpp index e3886b0628..29a1aaf2a5 100644 --- a/pcbnew/dialogs/dialog_fp_lib_table.cpp +++ b/pcbnew/dialogs/dialog_fp_lib_table.cpp @@ -48,6 +48,19 @@ #include <wx/regex.h> #include <set> + +/// grid column order is established by this sequence +enum COL_ORDER +{ + COL_NICKNAME, + COL_URI, + COL_TYPE, + COL_OPTIONS, + COL_DESCR, + COL_COUNT // keep as last +}; + + /** * Class FP_TBL_MODEL * mixes in wxGridTableBase into FP_LIB_TABLE so that the latter can be used @@ -57,16 +70,6 @@ class FP_TBL_MODEL : public wxGridTableBase, public FP_LIB_TABLE { public: - enum COL_ORDER ///< grid column order, established by this sequence - { - COL_NICKNAME, - COL_URI, - COL_TYPE, - COL_OPTIONS, - COL_DESCR, - COL_COUNT // keep as last - }; - /** * Constructor FP_TBL_MODEL * is a copy constructor that builds a wxGridTableBase (table model) by wrapping @@ -79,8 +82,8 @@ public: //-----<wxGridTableBase overloads>------------------------------------------- - int GetNumberRows () { return rows.size(); } - int GetNumberCols () { return COL_COUNT; } + int GetNumberRows() { return rows.size(); } + int GetNumberCols() { return COL_COUNT; } wxString GetValue( int aRow, int aCol ) { @@ -394,6 +397,102 @@ class DIALOG_FP_LIB_TABLE : public DIALOG_FP_LIB_TABLE_BASE } } + /** + * Function verifyTables + * trims important fields, removes blank row entries, and checks for duplicates. + * @return bool - true if tables are OK, else false. + */ + bool verifyTables() + { + for( int t=0; t<2; ++t ) + { + FP_TBL_MODEL& model = t==0 ? m_global_model : m_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(); + wxString type = model.GetValue( r, COL_TYPE ).Trim( false ).Trim(); + + if( !nick || !uri || !type ) + { + // Delete the "empty" row, where empty means missing nick, uri, or type. + // 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" ), + wxT( ":" ), GetChars( nick ), r ); + + // show the tabbed panel holding the grid we have flunked: + if( &model != (FP_TBL_MODEL*) m_cur_grid->GetTable() ) + { + m_auinotebook->SetSelection( &model == &m_global_model ? 0 : 1 ); + } + + // go to the bottom of the two rows, it is technically the duplicate: + 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 ); + model.SetValue( r, COL_TYPE, type ); + ++r; // this row was OK. + } + } + } + + // check for duplicate nickNames, separately in each table. + for( int t=0; t<2; ++t ) + { + FP_TBL_MODEL& model = t==0 ? m_global_model : m_project_model; + + for( int r1 = 0; r1 < model.GetNumberRows() - 1; ++r1 ) + { + for( int r2=r1+1; r2 < model.GetNumberRows(); ++r2 ) + { + wxString nick1 = model.GetValue( r1, COL_NICKNAME ); + 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 != (FP_TBL_MODEL*) m_cur_grid->GetTable() ) + { + m_auinotebook->SetSelection( &model == &m_global_model ? 0 : 1 ); + } + + // go to the bottom of the two rows, it is technically the duplicate: + 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; + } + //-----<event handlers>---------------------------------- void pageChangedHandler( wxAuiNotebookEvent& event ) @@ -404,7 +503,13 @@ class DIALOG_FP_LIB_TABLE : public DIALOG_FP_LIB_TABLE_BASE void appendRowHandler( wxMouseEvent& event ) { - m_cur_grid->AppendRows( 1 ); + if( m_cur_grid->AppendRows( 1 ) ) + { + int last_row = m_cur_grid->GetNumberRows() - 1; + + m_cur_grid->SelectBlock( last_row, 0, last_row, 0 ); + m_cur_grid->MakeCellVisible( last_row, 0 ); + } } void deleteRowHandler( wxMouseEvent& event ) @@ -474,6 +579,12 @@ class DIALOG_FP_LIB_TABLE : public DIALOG_FP_LIB_TABLE_BASE D(printf("%s\n", __func__);) } + void optionsEditor( wxMouseEvent& event ) + { + // @todo: write the options editor, and pass the options to the Footprint*() calls. + D(printf("%s:%d\n", __func__, (int) m_cur_grid->GetRowCount() );) + } + void onCancelButtonClick( wxCommandEvent& event ) { EndModal( 0 ); @@ -483,23 +594,26 @@ class DIALOG_FP_LIB_TABLE : public DIALOG_FP_LIB_TABLE_BASE { int dialogRet = 0; - if( m_global_model != *m_global ) + if( verifyTables() ) { - dialogRet |= 1; + if( m_global_model != *m_global ) + { + dialogRet |= 1; - *m_global = m_global_model; - m_global->reindex(); + *m_global = m_global_model; + m_global->reindex(); + } + + if( m_project_model != *m_project ) + { + dialogRet |= 2; + + *m_project = m_project_model; + m_project->reindex(); + } + + EndModal( dialogRet ); } - - if( m_project_model != *m_project ) - { - dialogRet |= 2; - - *m_project = m_project_model; - m_project->reindex(); - } - - EndModal( dialogRet ); } void onGridCellLeftClick( wxGridEvent& event ) @@ -546,7 +660,7 @@ class DIALOG_FP_LIB_TABLE : public DIALOG_FP_LIB_TABLE_BASE for( row = 0; row < gblRowCount; ++row ) { - wxString uri = m_global_model.GetValue( row, FP_TBL_MODEL::COL_URI ); + wxString uri = m_global_model.GetValue( row, COL_URI ); while( re.Matches( uri ) ) { @@ -562,7 +676,7 @@ class DIALOG_FP_LIB_TABLE : public DIALOG_FP_LIB_TABLE_BASE for( row = 0; row < prjRowCount; ++row ) { - wxString uri = m_project_model.GetValue( row, FP_TBL_MODEL::COL_URI ); + wxString uri = m_project_model.GetValue( row, COL_URI ); while( re.Matches( uri ) ) { @@ -643,11 +757,11 @@ public: attr = new wxGridCellAttr; attr->SetEditor( new wxGridCellChoiceEditor( choices ) ); - m_project_grid->SetColAttr( FP_TBL_MODEL::COL_TYPE, attr ); + m_project_grid->SetColAttr( COL_TYPE, attr ); attr = new wxGridCellAttr; attr->SetEditor( new wxGridCellChoiceEditor( choices ) ); - m_global_grid->SetColAttr( FP_TBL_MODEL::COL_TYPE, attr ); + m_global_grid->SetColAttr( COL_TYPE, attr ); m_global_grid->AutoSizeColumns(); m_project_grid->AutoSizeColumns(); @@ -688,4 +802,3 @@ int InvokePcbLibTableEditor( wxFrame* aParent, FP_LIB_TABLE* aGlobal, FP_LIB_TAB return dialogRet; } - diff --git a/pcbnew/dialogs/dialog_fp_lib_table_base.cpp b/pcbnew/dialogs/dialog_fp_lib_table_base.cpp index c392d8c018..01bc85152f 100644 --- a/pcbnew/dialogs/dialog_fp_lib_table_base.cpp +++ b/pcbnew/dialogs/dialog_fp_lib_table_base.cpp @@ -1,5 +1,5 @@ /////////////////////////////////////////////////////////////////////////// -// C++ code generated with wxFormBuilder (version Oct 8 2012) +// C++ code generated with wxFormBuilder (version Apr 30 2013) // http://www.wxformbuilder.org/ // // PLEASE DO "NOT" EDIT THIS FILE! @@ -127,6 +127,11 @@ DIALOG_FP_LIB_TABLE_BASE::DIALOG_FP_LIB_TABLE_BASE( wxWindow* parent, wxWindowID bSizer51->Add( m_move_down_button, 0, wxALL, 5 ); + m_edit_options = new wxButton( m_top, wxID_ANY, _("Options Editor"), wxDefaultPosition, wxDefaultSize, 0 ); + m_edit_options->SetToolTip( _("Zoom into the options table for current row") ); + + bSizer51->Add( m_edit_options, 0, wxALL, 5 ); + m_top_sizer->Add( bSizer51, 0, wxALIGN_CENTER|wxBOTTOM, 8 ); @@ -211,6 +216,7 @@ DIALOG_FP_LIB_TABLE_BASE::DIALOG_FP_LIB_TABLE_BASE( wxWindow* parent, wxWindowID m_delete_button->Connect( wxEVT_LEFT_DOWN, wxMouseEventHandler( DIALOG_FP_LIB_TABLE_BASE::deleteRowHandler ), NULL, this ); m_move_up_button->Connect( wxEVT_LEFT_DOWN, wxMouseEventHandler( DIALOG_FP_LIB_TABLE_BASE::moveUpHandler ), NULL, this ); m_move_down_button->Connect( wxEVT_LEFT_DOWN, wxMouseEventHandler( DIALOG_FP_LIB_TABLE_BASE::moveDownHandler ), NULL, this ); + m_edit_options->Connect( wxEVT_LEFT_DOWN, wxMouseEventHandler( DIALOG_FP_LIB_TABLE_BASE::optionsEditor ), NULL, this ); m_sdbSizer1Cancel->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DIALOG_FP_LIB_TABLE_BASE::onCancelButtonClick ), NULL, this ); m_sdbSizer1OK->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DIALOG_FP_LIB_TABLE_BASE::onOKButtonClick ), NULL, this ); } @@ -231,6 +237,7 @@ DIALOG_FP_LIB_TABLE_BASE::~DIALOG_FP_LIB_TABLE_BASE() m_delete_button->Disconnect( wxEVT_LEFT_DOWN, wxMouseEventHandler( DIALOG_FP_LIB_TABLE_BASE::deleteRowHandler ), NULL, this ); m_move_up_button->Disconnect( wxEVT_LEFT_DOWN, wxMouseEventHandler( DIALOG_FP_LIB_TABLE_BASE::moveUpHandler ), NULL, this ); m_move_down_button->Disconnect( wxEVT_LEFT_DOWN, wxMouseEventHandler( DIALOG_FP_LIB_TABLE_BASE::moveDownHandler ), NULL, this ); + m_edit_options->Disconnect( wxEVT_LEFT_DOWN, wxMouseEventHandler( DIALOG_FP_LIB_TABLE_BASE::optionsEditor ), NULL, this ); m_sdbSizer1Cancel->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DIALOG_FP_LIB_TABLE_BASE::onCancelButtonClick ), NULL, this ); m_sdbSizer1OK->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DIALOG_FP_LIB_TABLE_BASE::onOKButtonClick ), NULL, this ); diff --git a/pcbnew/dialogs/dialog_fp_lib_table_base.fbp b/pcbnew/dialogs/dialog_fp_lib_table_base.fbp index c2ad44dfee..aea158009e 100644 --- a/pcbnew/dialogs/dialog_fp_lib_table_base.fbp +++ b/pcbnew/dialogs/dialog_fp_lib_table_base.fbp @@ -1172,6 +1172,94 @@ <event name="OnUpdateUI"></event> </object> </object> + <object class="sizeritem" expanded="1"> + <property name="border">5</property> + <property name="flag">wxALL</property> + <property name="proportion">0</property> + <object class="wxButton" expanded="1"> + <property name="BottomDockable">1</property> + <property name="LeftDockable">1</property> + <property name="RightDockable">1</property> + <property name="TopDockable">1</property> + <property name="aui_layer"></property> + <property name="aui_name"></property> + <property name="aui_position"></property> + <property name="aui_row"></property> + <property name="best_size"></property> + <property name="bg"></property> + <property name="caption"></property> + <property name="caption_visible">1</property> + <property name="center_pane">0</property> + <property name="close_button">1</property> + <property name="context_help"></property> + <property name="context_menu">1</property> + <property name="default">0</property> + <property name="default_pane">0</property> + <property name="dock">Dock</property> + <property name="dock_fixed">0</property> + <property name="docking">Left</property> + <property name="enabled">1</property> + <property name="fg"></property> + <property name="floatable">1</property> + <property name="font"></property> + <property name="gripper">0</property> + <property name="hidden">0</property> + <property name="id">wxID_ANY</property> + <property name="label">Options Editor</property> + <property name="max_size"></property> + <property name="maximize_button">0</property> + <property name="maximum_size"></property> + <property name="min_size"></property> + <property name="minimize_button">0</property> + <property name="minimum_size"></property> + <property name="moveable">1</property> + <property name="name">m_edit_options</property> + <property name="pane_border">1</property> + <property name="pane_position"></property> + <property name="pane_size"></property> + <property name="permission">protected</property> + <property name="pin_button">1</property> + <property name="pos"></property> + <property name="resize">Resizable</property> + <property name="show">1</property> + <property name="size"></property> + <property name="style"></property> + <property name="subclass"></property> + <property name="toolbar_pane">0</property> + <property name="tooltip">Zoom into the options table for current row</property> + <property name="validator_data_type"></property> + <property name="validator_style">wxFILTER_NONE</property> + <property name="validator_type">wxDefaultValidator</property> + <property name="validator_variable"></property> + <property name="window_extra_style"></property> + <property name="window_name"></property> + <property name="window_style"></property> + <event name="OnButtonClick"></event> + <event name="OnChar"></event> + <event name="OnEnterWindow"></event> + <event name="OnEraseBackground"></event> + <event name="OnKeyDown"></event> + <event name="OnKeyUp"></event> + <event name="OnKillFocus"></event> + <event name="OnLeaveWindow"></event> + <event name="OnLeftDClick"></event> + <event name="OnLeftDown">optionsEditor</event> + <event name="OnLeftUp"></event> + <event name="OnMiddleDClick"></event> + <event name="OnMiddleDown"></event> + <event name="OnMiddleUp"></event> + <event name="OnMotion"></event> + <event name="OnMouseEvents"></event> + <event name="OnMouseWheel"></event> + <event name="OnPaint"></event> + <event name="OnRightDClick"></event> + <event name="OnRightDown"></event> + <event name="OnRightUp"></event> + <event name="OnSetFocus"></event> + <event name="OnSize"></event> + <event name="OnUpdateUI"></event> + </object> + </object> </object> </object> </object> diff --git a/pcbnew/dialogs/dialog_fp_lib_table_base.h b/pcbnew/dialogs/dialog_fp_lib_table_base.h index 5a0e15dcd0..7cef046001 100644 --- a/pcbnew/dialogs/dialog_fp_lib_table_base.h +++ b/pcbnew/dialogs/dialog_fp_lib_table_base.h @@ -1,5 +1,5 @@ /////////////////////////////////////////////////////////////////////////// -// C++ code generated with wxFormBuilder (version Oct 8 2012) +// C++ code generated with wxFormBuilder (version Apr 30 2013) // http://www.wxformbuilder.org/ // // PLEASE DO "NOT" EDIT THIS FILE! @@ -53,6 +53,7 @@ class DIALOG_FP_LIB_TABLE_BASE : public DIALOG_SHIM wxButton* m_delete_button; wxButton* m_move_up_button; wxButton* m_move_down_button; + wxButton* m_edit_options; wxPanel* m_bottom; wxGrid* m_path_subs_grid; wxStdDialogButtonSizer* m_sdbSizer1; @@ -69,6 +70,7 @@ class DIALOG_FP_LIB_TABLE_BASE : public DIALOG_SHIM virtual void deleteRowHandler( wxMouseEvent& event ) { event.Skip(); } virtual void moveUpHandler( wxMouseEvent& event ) { event.Skip(); } virtual void moveDownHandler( wxMouseEvent& event ) { event.Skip(); } + virtual void optionsEditor( wxMouseEvent& event ) { event.Skip(); } virtual void onCancelButtonClick( wxCommandEvent& event ) { event.Skip(); } virtual void onOKButtonClick( wxCommandEvent& event ) { event.Skip(); } diff --git a/pcbnew/files.cpp b/pcbnew/files.cpp index e728f64d73..0da4e45233 100644 --- a/pcbnew/files.cpp +++ b/pcbnew/files.cpp @@ -281,10 +281,15 @@ bool PCB_EDIT_FRAME::LoadOnePcbFile( const wxString& aFileName, bool aAppend, try { PROPERTIES props; + char xbuf[30]; + char ybuf[30]; // EAGLE_PLUGIN can use this info to center the BOARD, but it does not yet. - props["page_width"] = wxString::Format( wxT( "%d" ), GetPageSizeIU().x ); - props["page_height"] = wxString::Format( wxT( "%d" ), GetPageSizeIU().y ); + sprintf( xbuf, "%d", GetPageSizeIU().x ); + sprintf( ybuf, "%d", GetPageSizeIU().y ); + + props["page_width"] = xbuf; + props["page_height"] = ybuf; #if USE_INSTRUMENTATION // measure the time to load a BOARD. diff --git a/pcbnew/io_mgr.cpp b/pcbnew/io_mgr.cpp index a89e6c0da9..0a3d222748 100644 --- a/pcbnew/io_mgr.cpp +++ b/pcbnew/io_mgr.cpp @@ -126,11 +126,8 @@ const wxString IO_MGR::ShowType( PCB_FILE_T aType ) case GEDA_PCB: return wxString( wxT( "Geda-PCB" ) ); -#if defined(BUILD_GITHUB_PLUGIN) case GITHUB: return wxString( wxT( "Github" ) ); -#endif - } } @@ -156,10 +153,8 @@ IO_MGR::PCB_FILE_T IO_MGR::EnumFromStr( const wxString& aType ) if( aType == wxT( "Geda-PCB" ) ) return GEDA_PCB; -#if defined(BUILD_GITHUB_PLUGIN) if( aType == wxT( "Github" ) ) return GITHUB; -#endif // wxASSERT( blow up here ) diff --git a/scripts/test_plugin.py b/scripts/test_plugin.py index 6ffb1298fb..3755607013 100755 --- a/scripts/test_plugin.py +++ b/scripts/test_plugin.py @@ -1,6 +1,6 @@ #!/usr/bin/python -# Convert a footprint library from one format to another, e.g. legacy to pretty. +# Test a basic back to back FootprintLoad() of a single footprint, and FootprintEnumerate() # 1) Build target _pcbnew after enabling scripting in cmake. # $ make _pcbnew