merge in evolving fp lib_table work
This commit is contained in:
commit
6ad94a4912
|
@ -1,6 +1,8 @@
|
|||
common/netlist_keywords.*
|
||||
common/netlist_lexer.h
|
||||
common/pcb_plot_params_lexer.h
|
||||
common/fp_lib_table_keywords.*
|
||||
include/fp_lib_table_lexer.h
|
||||
include/netlist_lexer.h
|
||||
eeschema/cmp_library_lexer.h
|
||||
eeschema/cmp_library_keywords.*
|
||||
|
|
|
@ -124,6 +124,9 @@ set(PCB_COMMON_SRCS
|
|||
pcb_plot_params_keywords.cpp
|
||||
pcb_keywords.cpp
|
||||
../pcbnew/pcb_parser.cpp
|
||||
fp_lib_table_keywords.cpp
|
||||
fp_lib_id.cpp
|
||||
fp_lib_table.cpp
|
||||
)
|
||||
|
||||
|
||||
|
@ -155,9 +158,15 @@ make_lexer(
|
|||
make_lexer( ${CMAKE_CURRENT_SOURCE_DIR}/pcb.keywords
|
||||
${PROJECT_SOURCE_DIR}/include/pcb_lexer.h
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/pcb_keywords.cpp
|
||||
PCB
|
||||
PCB_KEYS_T
|
||||
)
|
||||
|
||||
# auto-generate pcbnew s-expression footprint library table code.
|
||||
make_lexer( ${CMAKE_CURRENT_SOURCE_DIR}/fp_lib_table.keywords
|
||||
${PROJECT_SOURCE_DIR}/include/fp_lib_table_lexer.h
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/fp_lib_table_keywords.cpp
|
||||
FP_LIB_TABLE_T
|
||||
)
|
||||
|
||||
# The dsntest may not build properly using MS Visual Studio.
|
||||
if(NOT MSVC)
|
||||
|
|
|
@ -0,0 +1,335 @@
|
|||
/*
|
||||
* This program source code file is part of KiCad, a free EDA CAD application.
|
||||
*
|
||||
* Copyright (C) 2010 SoftPLC Corporation, Dick Hollenbeck <dick@softplc.com>
|
||||
* Copyright (C) 2012 Wayne Stambaugh <stambaughw@verizon.net>
|
||||
* Copyright (C) 2010 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
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* 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, you may find one here:
|
||||
* http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
|
||||
* or you may search the http://www.gnu.org website for the version 2 license,
|
||||
* or you may write to the Free Software Foundation, Inc.,
|
||||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
|
||||
*/
|
||||
|
||||
#include <cstring>
|
||||
#include <wx/wx.h> // _()
|
||||
|
||||
#include <fp_lib_id.h>
|
||||
|
||||
|
||||
static inline bool isDigit( char c )
|
||||
{
|
||||
return c >= '0' && c <= '9';
|
||||
}
|
||||
|
||||
|
||||
const char* EndsWithRev( const char* start, const char* tail, char separator )
|
||||
{
|
||||
bool sawDigit = false;
|
||||
|
||||
while( tail > start && isDigit( *--tail ) )
|
||||
{
|
||||
sawDigit = true;
|
||||
}
|
||||
|
||||
// if sawDigit, tail points to the 'v' here.
|
||||
|
||||
if( sawDigit && tail-3 >= start )
|
||||
{
|
||||
tail -= 3;
|
||||
|
||||
if( tail[0]==separator && tail[1]=='r' && tail[2]=='e' && tail[3]=='v' )
|
||||
{
|
||||
return tail+1; // omit separator, return "revN[N..]"
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
int RevCmp( const char* s1, const char* s2 )
|
||||
{
|
||||
int r = strncmp( s1, s2, 3 );
|
||||
|
||||
if( r || strlen(s1)<4 || strlen(s2)<4 )
|
||||
{
|
||||
return r;
|
||||
}
|
||||
|
||||
int rnum1 = atoi( s1+3 );
|
||||
int rnum2 = atoi( s2+3 );
|
||||
|
||||
return -(rnum1 - rnum2); // swap the sign, higher revs first
|
||||
}
|
||||
|
||||
//----<Policy and field test functions>-------------------------------------
|
||||
|
||||
|
||||
static inline int okLogical( const std::string& aField )
|
||||
{
|
||||
// std::string::npos is largest positive number, casting to int makes it -1.
|
||||
// Returning that means success.
|
||||
return int( aField.find_first_of( ":" ) );
|
||||
}
|
||||
|
||||
|
||||
static int okRevision( const std::string& aField )
|
||||
{
|
||||
char rev[32]; // C string for speed
|
||||
|
||||
if( aField.size() >= 4 )
|
||||
{
|
||||
strcpy( rev, "x/" );
|
||||
strcat( rev, aField.c_str() );
|
||||
|
||||
if( EndsWithRev( rev, rev + strlen(rev) ) == rev+2 )
|
||||
return -1; // success
|
||||
}
|
||||
|
||||
return 0; // first character position "is in error", is best we can do.
|
||||
}
|
||||
|
||||
|
||||
//----</Policy and field test functions>-------------------------------------
|
||||
|
||||
|
||||
void FP_LIB_ID::clear()
|
||||
{
|
||||
logical.clear();
|
||||
footprintName.clear();
|
||||
revision.clear();
|
||||
}
|
||||
|
||||
|
||||
int FP_LIB_ID::Parse( const std::string& aId )
|
||||
{
|
||||
clear();
|
||||
|
||||
const char* rev = EndsWithRev( aId );
|
||||
size_t revNdx;
|
||||
size_t partNdx;
|
||||
int offset;
|
||||
|
||||
//=====<revision>=========================================
|
||||
if( rev )
|
||||
{
|
||||
revNdx = rev - aId.c_str();
|
||||
|
||||
// no need to check revision, EndsWithRev did that.
|
||||
revision = aId.substr( revNdx );
|
||||
--revNdx; // back up to omit the '/' which precedes the rev
|
||||
}
|
||||
else
|
||||
{
|
||||
revNdx = aId.size();
|
||||
}
|
||||
|
||||
//=====<logical>==========================================
|
||||
if( ( partNdx = aId.find( ':' ) ) != aId.npos )
|
||||
{
|
||||
offset = SetLogicalLib( aId.substr( 0, partNdx ) );
|
||||
|
||||
if( offset > -1 )
|
||||
{
|
||||
return offset;
|
||||
}
|
||||
|
||||
++partNdx; // skip ':'
|
||||
}
|
||||
else
|
||||
{
|
||||
partNdx = 0;
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
FP_LIB_ID::FP_LIB_ID( const std::string& aId ) throw( PARSE_ERROR )
|
||||
{
|
||||
int offset = Parse( aId );
|
||||
|
||||
if( offset != -1 )
|
||||
{
|
||||
THROW_PARSE_ERROR( _( "Illegal character found in FP_LIB_ID string" ),
|
||||
wxString::FromUTF8( aId.c_str() ),
|
||||
aId.c_str(),
|
||||
0,
|
||||
offset );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
int FP_LIB_ID::SetLogicalLib( const std::string& aLogical )
|
||||
{
|
||||
int offset = okLogical( aLogical );
|
||||
|
||||
if( offset == -1 )
|
||||
{
|
||||
logical = aLogical;
|
||||
}
|
||||
|
||||
return offset;
|
||||
}
|
||||
|
||||
|
||||
int FP_LIB_ID::SetFootprintName( const std::string& aFootprintName )
|
||||
{
|
||||
int separation = int( aFootprintName.find_first_of( "/" ) );
|
||||
|
||||
if( separation != -1 )
|
||||
{
|
||||
logical = aFootprintName.substr( separation+1 );
|
||||
return separation + (int) logical.size() + 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
footprintName = aFootprintName;
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
int FP_LIB_ID::SetRevision( const std::string& aRevision )
|
||||
{
|
||||
int offset = okRevision( aRevision );
|
||||
|
||||
if( offset == -1 )
|
||||
{
|
||||
revision = aRevision;
|
||||
}
|
||||
|
||||
return offset;
|
||||
}
|
||||
|
||||
|
||||
std::string FP_LIB_ID::Format() const
|
||||
{
|
||||
std::string ret;
|
||||
|
||||
if( logical.size() )
|
||||
{
|
||||
ret += logical;
|
||||
ret += ':';
|
||||
}
|
||||
|
||||
if( revision.size() )
|
||||
{
|
||||
ret += '/';
|
||||
ret += revision;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
std::string FP_LIB_ID::GetFootprintNameAndRev() const
|
||||
{
|
||||
std::string ret;
|
||||
|
||||
if( revision.size() )
|
||||
{
|
||||
ret += '/';
|
||||
ret += revision;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
std::string FP_LIB_ID::Format( const std::string& aLogicalLib, const std::string& aFootprintName,
|
||||
const std::string& aRevision )
|
||||
throw( PARSE_ERROR )
|
||||
{
|
||||
std::string ret;
|
||||
int offset;
|
||||
|
||||
if( aLogicalLib.size() )
|
||||
{
|
||||
offset = okLogical( aLogicalLib );
|
||||
|
||||
if( offset != -1 )
|
||||
{
|
||||
THROW_PARSE_ERROR( _( "Illegal character found in logical library name" ),
|
||||
wxString::FromUTF8( aLogicalLib.c_str() ),
|
||||
aLogicalLib.c_str(),
|
||||
0,
|
||||
offset );
|
||||
}
|
||||
|
||||
ret += aLogicalLib;
|
||||
ret += ':';
|
||||
}
|
||||
|
||||
if( aRevision.size() )
|
||||
{
|
||||
offset = okRevision( aRevision );
|
||||
|
||||
if( offset != -1 )
|
||||
{
|
||||
THROW_PARSE_ERROR( _( "Illegal character found in revision" ),
|
||||
wxString::FromUTF8( aRevision.c_str() ),
|
||||
aRevision.c_str(),
|
||||
0,
|
||||
offset );
|
||||
}
|
||||
|
||||
ret += '/';
|
||||
ret += aRevision;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
#if 0 && defined(DEBUG)
|
||||
|
||||
// build this with Debug CMAKE_BUILD_TYPE
|
||||
|
||||
void FP_LIB_ID::Test()
|
||||
{
|
||||
static const char* lpids[] = {
|
||||
"smt:R_0805/rev0",
|
||||
"mysmt:R_0805/rev2",
|
||||
"device:AXIAL-0500",
|
||||
};
|
||||
|
||||
for( unsigned i=0; i<sizeof(lpids)/sizeof(lpids[0]); ++i )
|
||||
{
|
||||
// test some round tripping
|
||||
|
||||
FP_LIB_ID lpid( lpids[i] ); // parse
|
||||
|
||||
// format
|
||||
printf( "input:'%s' full:'%s' logical: %s footprintName:'%s' rev:'%s'\n",
|
||||
lpids[i],
|
||||
lpid.Format().c_str(),
|
||||
lpid.GetLogicalLib().c_str(),
|
||||
lpid.GetFootprintName().c_str(),
|
||||
lpid.GetRevision().c_str() );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
int main( int argc, char** argv )
|
||||
{
|
||||
FP_LIB_ID::Test();
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
#endif
|
|
@ -0,0 +1,272 @@
|
|||
/*
|
||||
* This program source code file is part of KiCad, a free EDA CAD application.
|
||||
*
|
||||
* Copyright (C) 2010-12 SoftPLC Corporation, Dick Hollenbeck <dick@softplc.com>
|
||||
* Copyright (C) 2012 Wayne Stambaugh <stambaughw@verizon.net>
|
||||
* Copyright (C) 2012 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
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* 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, you may find one here:
|
||||
* http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
|
||||
* or you may search the http://www.gnu.org website for the version 2 license,
|
||||
* or you may write to the Free Software Foundation, Inc.,
|
||||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
|
||||
*/
|
||||
|
||||
|
||||
#include <set>
|
||||
|
||||
#include <io_mgr.h>
|
||||
|
||||
#include <fp_lib_table_lexer.h>
|
||||
#include <fp_lib_table.h>
|
||||
|
||||
|
||||
using namespace FP_LIB_TABLE_T;
|
||||
|
||||
|
||||
FP_LIB_TABLE::FP_LIB_TABLE( FP_LIB_TABLE* aFallBackTable ) :
|
||||
fallBack( aFallBackTable )
|
||||
{
|
||||
// not copying fall back, simply search aFallBackTable separately
|
||||
// if "nickName not found".
|
||||
}
|
||||
|
||||
|
||||
void FP_LIB_TABLE::Parse( FP_LIB_TABLE_LEXER* in ) throw( IO_ERROR, PARSE_ERROR )
|
||||
{
|
||||
T tok;
|
||||
|
||||
while( ( tok = in->NextTok() ) != T_RIGHT )
|
||||
{
|
||||
// (lib (name "LOGICAL")(type "TYPE")(full_uri "FULL_URI")(options "OPTIONS"))
|
||||
|
||||
if( tok == T_EOF )
|
||||
in->Expecting( T_RIGHT );
|
||||
|
||||
if( tok != T_LEFT )
|
||||
in->Expecting( T_LEFT );
|
||||
|
||||
if( ( tok = in->NextTok() ) != T_fp_lib )
|
||||
in->Expecting( T_fp_lib );
|
||||
|
||||
// (name "LOGICAL_NAME")
|
||||
in->NeedLEFT();
|
||||
|
||||
if( ( tok = in->NextTok() ) != T_name )
|
||||
in->Expecting( T_name );
|
||||
|
||||
in->NeedSYMBOLorNUMBER();
|
||||
|
||||
ROW row;
|
||||
|
||||
row.SetNickName( in->FromUTF8() );
|
||||
|
||||
in->NeedRIGHT();
|
||||
|
||||
// (uri "FULL_URI")
|
||||
in->NeedLEFT();
|
||||
|
||||
if( ( tok = in->NextTok() ) != T_full_uri )
|
||||
in->Expecting( T_full_uri );
|
||||
|
||||
in->NeedSYMBOLorNUMBER();
|
||||
|
||||
row.SetFullURI( in->FromUTF8() );
|
||||
|
||||
in->NeedRIGHT();
|
||||
|
||||
// (type "TYPE")
|
||||
in->NeedLEFT();
|
||||
|
||||
if( ( tok = in->NextTok() ) != T_type )
|
||||
in->Expecting( T_type );
|
||||
|
||||
in->NeedSYMBOLorNUMBER();
|
||||
|
||||
row.SetType( in->FromUTF8() );
|
||||
|
||||
in->NeedRIGHT();
|
||||
|
||||
// (options "OPTIONS")
|
||||
in->NeedLEFT();
|
||||
|
||||
if( ( tok = in->NextTok() ) != T_options )
|
||||
in->Expecting( T_options );
|
||||
|
||||
in->NeedSYMBOLorNUMBER();
|
||||
|
||||
row.SetOptions( in->FromUTF8() );
|
||||
|
||||
in->NeedRIGHT();
|
||||
in->NeedRIGHT(); // terminate the (lib..)
|
||||
|
||||
// all nickNames within this table fragment must be unique, so we do not
|
||||
// use doReplace in InsertRow(). (However a fallBack table can have a
|
||||
// conflicting nickName and ours will supercede that one since in
|
||||
// FindLib() we search this table before any fall back.)
|
||||
if( !InsertRow( row ) )
|
||||
{
|
||||
wxString msg = wxString::Format(
|
||||
_( "'%s' is a duplicate footprint library nickName" ),
|
||||
GetChars( row.nickName )
|
||||
);
|
||||
THROW_IO_ERROR( msg );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void FP_LIB_TABLE::Format( OUTPUTFORMATTER* out, int nestLevel ) const
|
||||
throw( IO_ERROR )
|
||||
{
|
||||
out->Print( nestLevel, "(fp_lib_table\n" );
|
||||
|
||||
for( ROWS_CITER it = rows.begin(); it != rows.end(); ++it )
|
||||
it->Format( out, nestLevel+1 );
|
||||
|
||||
out->Print( nestLevel, ")\n" );
|
||||
}
|
||||
|
||||
|
||||
void FP_LIB_TABLE::ROW::Format( OUTPUTFORMATTER* out, int nestLevel ) const
|
||||
throw( IO_ERROR )
|
||||
{
|
||||
out->Print( nestLevel, "(lib (name %s)(full_uri %s)(type %s)(options %s))\n",
|
||||
out->Quotew( GetNickName() ).c_str(),
|
||||
out->Quotew( GetFullURI() ).c_str(),
|
||||
out->Quotew( GetType() ).c_str(),
|
||||
out->Quotew( GetOptions() ).c_str()
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
std::vector<wxString> FP_LIB_TABLE::GetLogicalLibs()
|
||||
{
|
||||
// Only return unique logical library names. Use std::set::insert() to
|
||||
// quietly reject any duplicates, which can happen when encountering a duplicate
|
||||
// nickname from one of the fall back table(s).
|
||||
|
||||
std::set<wxString> unique;
|
||||
std::vector<wxString> ret;
|
||||
const FP_LIB_TABLE* cur = this;
|
||||
|
||||
do
|
||||
{
|
||||
for( ROWS_CITER it = cur->rows.begin(); it!=cur->rows.end(); ++it )
|
||||
{
|
||||
unique.insert( it->nickName );
|
||||
}
|
||||
|
||||
} while( ( cur = cur->fallBack ) != 0 );
|
||||
|
||||
// return a sorted, unique set of nicknames in a std::vector<wxString> to caller
|
||||
for( std::set<wxString>::const_iterator it = unique.begin(); it!=unique.end(); ++it )
|
||||
ret.push_back( *it );
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
const FP_LIB_TABLE::ROW* FP_LIB_TABLE::findRow( const wxString& aNickName )
|
||||
{
|
||||
FP_LIB_TABLE* cur = this;
|
||||
|
||||
do
|
||||
{
|
||||
cur->ensureIndex();
|
||||
|
||||
INDEX_CITER it = cur->nickIndex.find( aNickName );
|
||||
|
||||
if( it != cur->nickIndex.end() )
|
||||
{
|
||||
return &cur->rows[it->second]; // found
|
||||
}
|
||||
|
||||
// not found, search fall back table(s), if any
|
||||
} while( ( cur = cur->fallBack ) != 0 );
|
||||
|
||||
return 0; // not found
|
||||
}
|
||||
|
||||
|
||||
bool FP_LIB_TABLE::InsertRow( const ROW& aRow, bool doReplace )
|
||||
{
|
||||
ensureIndex();
|
||||
|
||||
INDEX_CITER it = nickIndex.find( aRow.nickName );
|
||||
|
||||
if( it == nickIndex.end() )
|
||||
{
|
||||
rows.push_back( aRow );
|
||||
nickIndex.insert( INDEX_VALUE( aRow.nickName, rows.size() - 1 ) );
|
||||
return true;
|
||||
}
|
||||
|
||||
if( doReplace )
|
||||
{
|
||||
rows[it->second] = aRow;
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
const FP_LIB_TABLE::ROW* FP_LIB_TABLE::FindRow( const wxString& aLibraryNickName )
|
||||
throw( IO_ERROR )
|
||||
{
|
||||
const ROW* row = findRow( aLibraryNickName );
|
||||
|
||||
if( !row )
|
||||
{
|
||||
wxString msg = wxString::Format( _("lib table contains no logical lib '%s'" ),
|
||||
GetChars( aLibraryNickName ) );
|
||||
THROW_IO_ERROR( msg );
|
||||
}
|
||||
|
||||
return row;
|
||||
}
|
||||
|
||||
|
||||
PLUGIN* FP_LIB_TABLE::PluginFind( const wxString& aLibraryNickName )
|
||||
throw( IO_ERROR )
|
||||
{
|
||||
const ROW* row = FindRow( aLibraryNickName );
|
||||
|
||||
// row will never be NULL here.
|
||||
|
||||
PLUGIN* plugin = IO_MGR::PluginFind( row->type );
|
||||
|
||||
return plugin;
|
||||
}
|
||||
|
||||
|
||||
#if 0 // don't know that this is needed yet
|
||||
MODULE* FP_LIB_TABLE::LookupFootprint( const FP_LIB_ID& aFootprintId )
|
||||
throw( IO_ERROR )
|
||||
{
|
||||
const ROW* row = FindRow( aFootprintId.GetLibraryNickName() );
|
||||
|
||||
// row will never be NULL here.
|
||||
|
||||
PLUGIN::RELEASER pi( PluginFind( row->type ) );
|
||||
|
||||
return pi->FootprintLoad( aLibraryPath->GetFullURI() ),
|
||||
aFootprintId.GetFootprintName(),
|
||||
|
||||
// fetch a PROPERTIES instance on stack here
|
||||
row->GetPropertiesFromOptions()
|
||||
);
|
||||
}
|
||||
#endif
|
|
@ -0,0 +1,9 @@
|
|||
fp_lib_table
|
||||
name
|
||||
type
|
||||
kicad
|
||||
legacy
|
||||
eagle
|
||||
full_uri
|
||||
options
|
||||
fp_lib
|
|
@ -17,7 +17,7 @@
|
|||
COMPONENTS_LISTBOX::COMPONENTS_LISTBOX( CVPCB_MAINFRAME* parent, wxWindowID id,
|
||||
const wxPoint& loc, const wxSize& size,
|
||||
int nbitems, wxString choice[] ) :
|
||||
ITEMS_LISTBOX_BASE( parent, id, loc, size, LISTB_STYLE&(~wxLC_SINGLE_SEL))
|
||||
ITEMS_LISTBOX_BASE( parent, id, loc, size, LISTB_STYLE & ~wxLC_SINGLE_SEL )
|
||||
{
|
||||
}
|
||||
|
||||
|
|
|
@ -19,8 +19,7 @@
|
|||
|
||||
#define FILTERFOOTPRINTKEY "FilterFootprint"
|
||||
|
||||
#define LISTB_STYLE wxSUNKEN_BORDER | wxLC_NO_HEADER | \
|
||||
wxLC_REPORT | wxLC_VIRTUAL
|
||||
#define LISTB_STYLE (wxSUNKEN_BORDER | wxLC_NO_HEADER | wxLC_REPORT | wxLC_VIRTUAL)
|
||||
|
||||
#include <netlist_reader.h>
|
||||
|
||||
|
|
|
@ -0,0 +1,205 @@
|
|||
/*
|
||||
* This program source code file is part of KiCad, a free EDA CAD application.
|
||||
*
|
||||
* Copyright (C) 2010-2012 SoftPLC Corporation, Dick Hollenbeck <dick@softplc.com>
|
||||
* Copyright (C) 2012 Wayne Stambaugh <stambaughw@verizon.net>
|
||||
* Copyright (C) 2010 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
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* 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, you may find one here:
|
||||
* http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
|
||||
* or you may search the http://www.gnu.org website for the version 2 license,
|
||||
* or you may write to the Free Software Foundation, Inc.,
|
||||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
|
||||
*/
|
||||
|
||||
#ifndef _FP_LIB_ID_H_
|
||||
#define _FP_LIB_ID_H_
|
||||
|
||||
#include <richio.h>
|
||||
|
||||
|
||||
/**
|
||||
* Class FP_LIB_ID
|
||||
* is a Logical Footprint ID and consists of various portions much like a URI.
|
||||
* It is a container for the separated portions of a logical footprint id so they
|
||||
* can be accessed individually. The various portions of an FP_LIB_ID are:
|
||||
* logicalLibraryName (nick name), footprint name, and revision. The logical library
|
||||
* name and the footprint name are mandatory. The revision is optional and currently is
|
||||
* not used.
|
||||
*
|
||||
* Example FP_LIB_ID string:
|
||||
* "smt:R_0805/rev0".
|
||||
*
|
||||
* <p>
|
||||
* <ul>
|
||||
* <li> "smt" is the logical library name used to look up library information saved in the
|
||||
* #FP_LIB_TABLE.
|
||||
* <li> "R" is the name of the footprint within the library.
|
||||
* <li> "rev0" is the revision, which is optional. If missing then its
|
||||
* / delimiter should also not be present. A revision must begin with
|
||||
* "rev" and be followed by at least one or more decimal digits.
|
||||
* </ul>
|
||||
*
|
||||
* @author Dick Hollenbeck
|
||||
*/
|
||||
class FP_LIB_ID // aka GUID
|
||||
{
|
||||
public:
|
||||
|
||||
FP_LIB_ID() {}
|
||||
|
||||
/**
|
||||
* Constructor FP_LIB_ID
|
||||
* takes \a aId string and parses it. A typical FP_LIB_ID string consists of a logical
|
||||
* library name followed by a footprint name.
|
||||
* e.g.: "smt:R_0805", or
|
||||
* e.g.: "mylib:R_0805"
|
||||
*
|
||||
* @param aId is a string to be parsed into the FP_LIB_ID object.
|
||||
*/
|
||||
FP_LIB_ID( const std::string& aId ) throw( PARSE_ERROR );
|
||||
|
||||
/**
|
||||
* Function Parse
|
||||
* [re-]stuffs this FP_LIB_ID with the information from @a aId.
|
||||
*
|
||||
* @param aId is the string to populate the #FP_LIB_ID object.
|
||||
* @return int - minus 1 (i.e. -1) means success, >= 0 indicates the character offset into
|
||||
* aId at which an error was detected.
|
||||
*/
|
||||
int Parse( const std::string& aId );
|
||||
|
||||
/**
|
||||
* Function GetLogicalLib
|
||||
* returns the logical library name portion of a FP_LIB_ID.
|
||||
*/
|
||||
const std::string& GetLogicalLib() const
|
||||
{
|
||||
return logical;
|
||||
}
|
||||
|
||||
/**
|
||||
* Function SetLogicalLib
|
||||
* overrides the logical footprint library name portion of the FP_LIB_ID to @a aLogical.
|
||||
* @return int - minus 1 (i.e. -1) means success, >= 0 indicates the character offset
|
||||
* into the parameter at which an error was detected, usually because it
|
||||
* contained '/' or ':'.
|
||||
*/
|
||||
int SetLogicalLib( const std::string& aLogical );
|
||||
|
||||
/**
|
||||
* Function GetFootprintName
|
||||
* returns the footprint name, i.e. footprintName part without revision.
|
||||
*/
|
||||
const std::string& GetFootprintName() const
|
||||
{
|
||||
return footprintName;
|
||||
}
|
||||
|
||||
/**
|
||||
* Function GetFootprintNameAndRev
|
||||
* returns the part name with revision if any, i.e. footprintName[/revN..]
|
||||
*/
|
||||
std::string GetFootprintNameAndRev() const;
|
||||
|
||||
/**
|
||||
* Function SetFootprintName
|
||||
* overrides the footprint name portion of the FP_LIB_ID to @a aFootprintName
|
||||
*
|
||||
* @return int - minus 1 (i.e. -1) means success, >= 0 indicates the character offset
|
||||
* into the parameter at which an error was detected, usually because it contained
|
||||
* more than one '/', or one or more ':', or is blank.
|
||||
*/
|
||||
int SetFootprintName( const std::string& aFootprintName );
|
||||
|
||||
/**
|
||||
* Function GetRevision
|
||||
* returns the revision portion of the FP_LIB_ID.
|
||||
*/
|
||||
const std::string& GetRevision() const
|
||||
{
|
||||
return revision;
|
||||
}
|
||||
|
||||
/**
|
||||
* Function SetRevision
|
||||
* overrides the revision portion of the FP_LIB_ID to @a aRevision and must
|
||||
* be in the form "rev<num>" where "<num>" is "1", "2", etc.
|
||||
*
|
||||
* @return int - minus 1 (i.e. -1) means success, >= 0 indicates the character offset*
|
||||
* into the parameter at which an error was detected,because it did not
|
||||
* look like "rev23"
|
||||
*/
|
||||
int SetRevision( const std::string& aRevision );
|
||||
|
||||
/**
|
||||
* Function Format
|
||||
* returns the fully formatted text of the FP_LIB_ID.
|
||||
*/
|
||||
std::string Format() const;
|
||||
|
||||
/**
|
||||
* Function Format
|
||||
* returns a std::string in the proper format as an FP_LIB_ID for a combination of
|
||||
* aLogicalLib, aFootprintName, and aRevision.
|
||||
*
|
||||
* @throw PARSE_ERROR if any of the pieces are illegal.
|
||||
*/
|
||||
static std::string Format( const std::string& aLogicalLib, const std::string& aFootprintName,
|
||||
const std::string& aRevision="" )
|
||||
throw( PARSE_ERROR );
|
||||
|
||||
void clear();
|
||||
|
||||
#if defined(DEBUG)
|
||||
static void Test();
|
||||
#endif
|
||||
|
||||
protected:
|
||||
std::string logical; ///< logical lib name or empty
|
||||
std::string revision; ///< "revN[N..]" or empty
|
||||
std::string footprintName; ///< The name of the footprint in the logical library.
|
||||
};
|
||||
|
||||
/**
|
||||
* Function EndsWithRev
|
||||
* returns a pointer to the final string segment: "revN[N..]" or NULL if none.
|
||||
* @param start is the beginning of string segment to test, the partname or
|
||||
* any middle portion of it.
|
||||
* @param tail is a pointer to the terminating nul, or one past inclusive end of
|
||||
* segment, i.e. the string segment of interest is [start,tail)
|
||||
* @param separator is the separating byte, expected: '.' or '/', depending on context.
|
||||
*/
|
||||
const char* EndsWithRev( const char* start, const char* tail, char separator = '/' );
|
||||
|
||||
static inline const char* EndsWithRev( const std::string& aFootprintName, char separator = '/' )
|
||||
{
|
||||
return EndsWithRev( aFootprintName.c_str(), aFootprintName.c_str()+aFootprintName.size(),
|
||||
separator );
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Function RevCmp
|
||||
* compares two rev strings in a way like strcmp() except that the highest numbered
|
||||
* revision is considered first in the sort order. The function probably won't work
|
||||
* unless you give it two rev strings.
|
||||
* @param s1 is a rev string like "rev10"
|
||||
* @param s2 is a rev string like "rev1".
|
||||
* @return int - either negative, zero, or positive depending on whether the revision
|
||||
* is greater, equal, or less on the left hand side.
|
||||
*/
|
||||
int RevCmp( const char* s1, const char* s2 );
|
||||
|
||||
#endif // _FP_LIB_ID_H_
|
|
@ -0,0 +1,432 @@
|
|||
/*
|
||||
* This program source code file is part of KiCad, a free EDA CAD application.
|
||||
*
|
||||
* Copyright (C) 2010-12 SoftPLC Corporation, Dick Hollenbeck <dick@softplc.com>
|
||||
* Copyright (C) 2012 Wayne Stambaugh <stambaughw@verizon.net>
|
||||
* Copyright (C) 2012 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
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* 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, you may find one here:
|
||||
* http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
|
||||
* or you may search the http://www.gnu.org website for the version 2 license,
|
||||
* or you may write to the Free Software Foundation, Inc.,
|
||||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
|
||||
*/
|
||||
|
||||
#ifndef FP_LIB_TABLE_H_
|
||||
#define FP_LIB_TABLE_H_
|
||||
|
||||
#include <macros.h>
|
||||
|
||||
#include <vector>
|
||||
#include <map>
|
||||
|
||||
#include <fp_lib_id.h>
|
||||
#include <io_mgr.h>
|
||||
|
||||
|
||||
class OUTPUTFORMATTER;
|
||||
class MODULE;
|
||||
class FP_LIB_TABLE_LEXER;
|
||||
|
||||
/**
|
||||
* Class FP_LIB_TABLE
|
||||
* holds FP_LIB_TABLE::ROW records, and can be searched based on logical library name.
|
||||
* <p>
|
||||
* This class owns the <b>footprint library table</b>, which is like fstab in concept and maps
|
||||
* logical library name to the library URI, type, and options. It is heavily based on the SWEET
|
||||
* parser work done by Dick Hollenbeck and can be seen in new/sch_lib_table.h. A footprint
|
||||
* library table had the following columns:
|
||||
* <ul>
|
||||
* <li> Logical Library Name (Nickname)
|
||||
* <li> Library Type, used to determine which plugin to load to access the library.
|
||||
* <li> Library URI. The full URI to the library source, form dependent on Type.
|
||||
* <li> Options, used for as yet to be defined information such as user names or passwords
|
||||
* </ul>
|
||||
* <p>
|
||||
* The Library Type can be one of:
|
||||
* <ul>
|
||||
* <li> "file"
|
||||
* <li> "ftp"
|
||||
* <li> "http"
|
||||
* </ul>
|
||||
* <p>
|
||||
* For now, the Library URI types needed to support the various types can be one of those
|
||||
* shown below, which are typical of each type:
|
||||
* <ul>
|
||||
* <li> "file://C:/mylibdir"
|
||||
* <li> "ftp://kicad.org/partlib/trunk"
|
||||
* <li> "http://kicad.org/partlib"
|
||||
* </ul>
|
||||
* <p>
|
||||
* The footprint library table is built up from several additive entries (table fragments),
|
||||
* and the final table is a (conceptual) merging of the table fragments. Two
|
||||
* anticipated sources of the entries are a personal table saved in the KiCad configuration
|
||||
* and a project resident table that resides in project file. The project footprint table
|
||||
* entries are considered a higher priority in the final dynamically assembled library table.
|
||||
* An row in the project file contribution to the library table takes precedence over the
|
||||
* personal table if there is a collision of logical library names. Otherwise, the entries
|
||||
* simply combine without issue to make up the applicable library table.
|
||||
*
|
||||
* @author Wayne Stambaugh
|
||||
*/
|
||||
class FP_LIB_TABLE
|
||||
{
|
||||
friend class DIALOG_FP_LIB_TABLE;
|
||||
|
||||
public:
|
||||
|
||||
/**
|
||||
* Class ROW
|
||||
* holds a record identifying a footprint library accessed by the appropriate #PLUGIN
|
||||
* object in the #FP_LIB_TABLE.
|
||||
*/
|
||||
class ROW
|
||||
{
|
||||
friend class FP_LIB_TABLE;
|
||||
friend class DIALOG_FP_LIB_TABLE;
|
||||
|
||||
public:
|
||||
|
||||
typedef IO_MGR::PCB_FILE_T LIB_T;
|
||||
|
||||
ROW() : type( IO_MGR::KICAD )
|
||||
{
|
||||
}
|
||||
|
||||
ROW( const wxString& aNick, const wxString& aURI, const wxString& aType, const wxString& aOptions ) :
|
||||
nickName( aNick ),
|
||||
uri( aURI ),
|
||||
options( aOptions )
|
||||
{
|
||||
SetType( aType );
|
||||
}
|
||||
|
||||
bool operator==( const ROW& r ) const
|
||||
{
|
||||
return nickName==r.nickName && uri==r.uri && type==r.type && options==r.options;
|
||||
}
|
||||
|
||||
bool operator!=( const ROW& r ) const { return !( *this == r ); }
|
||||
|
||||
/**
|
||||
* Function GetNickName
|
||||
* returns the short name of this library table row.
|
||||
*/
|
||||
const wxString& GetNickName() const
|
||||
{
|
||||
return nickName;
|
||||
}
|
||||
|
||||
/**
|
||||
* Function GetType
|
||||
* returns the type of LIB represented by this record.
|
||||
*/
|
||||
const wxString GetType() const
|
||||
{
|
||||
return IO_MGR::ShowType( type );
|
||||
}
|
||||
|
||||
/**
|
||||
* Function GetFullURI
|
||||
* returns the full location specifying URI for the LIB.
|
||||
*/
|
||||
const wxString& GetFullURI() const
|
||||
{
|
||||
return uri;
|
||||
}
|
||||
|
||||
/**
|
||||
* Function GetOptions
|
||||
* returns the options string, which may hold a password or anything else needed to
|
||||
* instantiate the underlying LIB_SOURCE.
|
||||
*/
|
||||
const wxString& GetOptions() const
|
||||
{
|
||||
return options;
|
||||
}
|
||||
|
||||
/**
|
||||
* Function Format
|
||||
* serializes this object as utf8 text to an OUTPUTFORMATTER, and tries to
|
||||
* make it look good using multiple lines and indentation.
|
||||
* @param out is an #OUTPUTFORMATTER
|
||||
* @param nestLevel is the indentation level to base all lines of the output.
|
||||
* Actual indentation will be 2 spaces for each nestLevel.
|
||||
*/
|
||||
void Format( OUTPUTFORMATTER* out, int nestLevel ) const
|
||||
throw( IO_ERROR );
|
||||
|
||||
/**
|
||||
* Function SetNickName
|
||||
* changes the logical name of this library, useful for an editor.
|
||||
*/
|
||||
void SetNickName( const wxString& aNickName )
|
||||
{
|
||||
nickName = aNickName;
|
||||
}
|
||||
|
||||
/**
|
||||
* Function SetType
|
||||
* changes the type represented by this record.
|
||||
*/
|
||||
void SetType( const wxString& aType )
|
||||
{
|
||||
type = IO_MGR::EnumFromStr( aType );
|
||||
}
|
||||
|
||||
/**
|
||||
* Function SetFullURI
|
||||
* changes the full URI for the library, useful from a library table editor.
|
||||
*/
|
||||
void SetFullURI( const wxString& aFullURI )
|
||||
{
|
||||
uri = aFullURI;
|
||||
}
|
||||
|
||||
/**
|
||||
* Function SetOptions
|
||||
* changes the options string for this record, and is useful from
|
||||
* the library table editor.
|
||||
*/
|
||||
void SetOptions( const wxString& aOptions )
|
||||
{
|
||||
options = aOptions;
|
||||
}
|
||||
|
||||
private:
|
||||
|
||||
wxString nickName;
|
||||
wxString uri;
|
||||
LIB_T type;
|
||||
wxString options;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Constructor FP_LIB_TABLE
|
||||
* builds a library table by pre-pending this table fragment in front of
|
||||
* @a aFallBackTable. Loading of this table fragment is done by using Parse().
|
||||
*
|
||||
* @param aFallBackTable is another FP_LIB_TABLE which is searched only when
|
||||
* a record is not found in this table. No ownership is
|
||||
* taken of aFallBackTable.
|
||||
*/
|
||||
FP_LIB_TABLE( FP_LIB_TABLE* aFallBackTable = NULL );
|
||||
|
||||
bool operator==( const FP_LIB_TABLE& r ) const
|
||||
{
|
||||
if( rows.size() == r.rows.size() )
|
||||
{
|
||||
unsigned i;
|
||||
for( i = 0; i < rows.size() && rows[i] == r.rows[i]; ++i )
|
||||
;
|
||||
|
||||
if( i == rows.size() )
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool operator!=( const FP_LIB_TABLE& r ) const { return !( *this == r ); }
|
||||
|
||||
/**
|
||||
* Function Parse
|
||||
* fills this table fragment from information in the input stream \a aParser, which
|
||||
* is a DSNLEXER customized for the grammar needed to describe instances of this object.
|
||||
* The entire textual element spec is <br>
|
||||
*
|
||||
* <pre>
|
||||
* (fp_lib_table
|
||||
* (lib (name LOGICAL)(type TYPE)(uri FULL_URI)(options OPTIONS))
|
||||
* (lib (name LOGICAL)(type TYPE)(uri FULL_URI)(options OPTIONS))
|
||||
* (lib (name LOGICAL)(type TYPE)(uri FULL_URI)(options OPTIONS))
|
||||
* )
|
||||
* </pre>
|
||||
*
|
||||
* When this function is called, the input token stream given by \a aParser
|
||||
* is assumed to be positioned at the '^' in the following example, i.e. just
|
||||
* after the identifying keyword and before the content specifying stuff.
|
||||
* <br>
|
||||
* (lib_table ^ (....) )
|
||||
*
|
||||
* @param aParser is the input token stream of keywords and symbols.
|
||||
*/
|
||||
void Parse( FP_LIB_TABLE_LEXER* aParser ) throw( IO_ERROR, PARSE_ERROR );
|
||||
|
||||
/**
|
||||
* Function Format
|
||||
* serializes this object as utf8 text to an #OUTPUTFORMATTER, and tries to
|
||||
* make it look good using multiple lines and indentation.
|
||||
*
|
||||
* @param out is an #OUTPUTFORMATTER
|
||||
* @param nestLevel is the indentation level to base all lines of the output.
|
||||
* Actual indentation will be 2 spaces for each nestLevel.
|
||||
*/
|
||||
void Format( OUTPUTFORMATTER* out, int nestLevel ) const throw( IO_ERROR );
|
||||
|
||||
|
||||
/**
|
||||
* Function GetLogicalLibs
|
||||
* returns the logical library names, all of them that are pertinent to
|
||||
* a lookup done on this FP_LIB_TABLE.
|
||||
*/
|
||||
std::vector<wxString> GetLogicalLibs();
|
||||
|
||||
|
||||
|
||||
//----<read accessors>----------------------------------------------------
|
||||
// the returning of a const wxString* tells if not found, but might be too
|
||||
// promiscuous?
|
||||
|
||||
#if 0
|
||||
/**
|
||||
* Function GetURI
|
||||
* returns the full library path from a logical library name.
|
||||
* @param aLogicalLibraryName is the short name for the library of interest.
|
||||
* @return const wxString* - or NULL if not found.
|
||||
*/
|
||||
const wxString* GetURI( const wxString& aLogicalLibraryName ) const
|
||||
{
|
||||
const ROW* row = FindRow( aLogicalLibraryName );
|
||||
return row ? &row->uri : 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Function GetType
|
||||
* returns the type of a logical library.
|
||||
* @param aLogicalLibraryName is the short name for the library of interest.
|
||||
* @return const wxString* - or NULL if not found.
|
||||
*/
|
||||
const wxString* GetType( const wxString& aLogicalLibraryName ) const
|
||||
{
|
||||
const ROW* row = FindRow( aLogicalLibraryName );
|
||||
return row ? &row->type : 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Function GetLibOptions
|
||||
* returns the options string for \a aLogicalLibraryName.
|
||||
* @param aLogicalLibraryName is the short name for the library of interest.
|
||||
* @return const wxString* - or NULL if not found.
|
||||
*/
|
||||
const wxString* GetLibOptions( const wxString& aLogicalLibraryName ) const
|
||||
{
|
||||
const ROW* row = FindRow( aLogicalLibraryName );
|
||||
return row ? &row->options : 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
//----</read accessors>---------------------------------------------------
|
||||
|
||||
#if 1 || defined(DEBUG)
|
||||
/// implement the tests in here so we can honor the privilege levels of the
|
||||
/// accessors, something difficult to do from int main(int, char**)
|
||||
void Test();
|
||||
#endif
|
||||
|
||||
/**
|
||||
* Function InsertRow
|
||||
* adds aRow if it does not already exist or if doReplace is true. If doReplace
|
||||
* is not true and the key for aRow already exists, the function fails and returns false.
|
||||
* The key for the table is the nickName, and all in this table must be unique.
|
||||
* @param aRow is the new row to insert, or to forcibly add if doReplace is true.
|
||||
* @param doReplace if true, means insert regardless of whether aRow's key already
|
||||
* exists. If false, then fail if the key already exists.
|
||||
* @return bool - true if the operation succeeded.
|
||||
*/
|
||||
bool InsertRow( const ROW& aRow, bool doReplace = false );
|
||||
|
||||
/**
|
||||
* Function PluginFind
|
||||
* returns a PLUGIN*. Caller should wrap that in a PLUGIN::RELEASER()
|
||||
* so when it goes out of scope, IO_MGR::PluginRelease() is called.
|
||||
*/
|
||||
PLUGIN* PluginFind( const wxString& aLibraryNickName ) throw( IO_ERROR );
|
||||
|
||||
/**
|
||||
* Function FindRow
|
||||
* returns a #ROW* if aNickName is found in this table or in any chained
|
||||
* fallBack table fragment, else NULL.
|
||||
*/
|
||||
const ROW* FindRow( const wxString& aNickName ) throw( IO_ERROR );
|
||||
|
||||
|
||||
protected:
|
||||
|
||||
/**
|
||||
* Function findRow
|
||||
* returns a #ROW* if aNickName is found in this table or in any chained
|
||||
* fallBack table fragment, else NULL.
|
||||
*/
|
||||
const ROW* findRow( const wxString& aNickName );
|
||||
|
||||
void reindex()
|
||||
{
|
||||
nickIndex.clear();
|
||||
|
||||
for( ROWS_CITER it = rows.begin(); it != rows.end(); ++it )
|
||||
nickIndex.insert( INDEX_VALUE( it->nickName, it - rows.begin() ) );
|
||||
}
|
||||
|
||||
void ensureIndex()
|
||||
{
|
||||
// The dialog lib table editor may not maintain the nickIndex.
|
||||
// Lazy indexing may be required. To handle lazy indexing, we must enforce
|
||||
// that "nickIndex" is either empty or accurate, but never inaccurate.
|
||||
if( !nickIndex.size() )
|
||||
reindex();
|
||||
}
|
||||
|
||||
typedef std::vector<ROW> ROWS;
|
||||
typedef ROWS::iterator ROWS_ITER;
|
||||
typedef ROWS::const_iterator ROWS_CITER;
|
||||
|
||||
ROWS rows;
|
||||
|
||||
/// this is a non-owning index into the ROWS table
|
||||
typedef std::map<wxString,int> INDEX; // "int" is std::vector array index
|
||||
typedef INDEX::iterator INDEX_ITER;
|
||||
typedef INDEX::const_iterator INDEX_CITER;
|
||||
typedef INDEX::value_type INDEX_VALUE;
|
||||
|
||||
/// this particular key is the nickName within each row.
|
||||
INDEX nickIndex;
|
||||
|
||||
FP_LIB_TABLE* fallBack;
|
||||
};
|
||||
|
||||
|
||||
#if 0 // I don't think this is going to be needed.
|
||||
|
||||
/**
|
||||
* Function LookupPart
|
||||
* finds and loads a MODULE, and parses it. As long as the part is
|
||||
* accessible in any LIB_SOURCE, opened or not opened, this function
|
||||
* will find it and load it into its containing LIB, even if that means
|
||||
* having to open a LIB in this table that was not previously opened.
|
||||
*
|
||||
* @param aFootprintId The fully qualified name of the footprint to look up.
|
||||
*
|
||||
* @return MODULE* - this will never be NULL, and no ownership is transferred because
|
||||
* all MODULEs live in LIBs. You only get to point to them in some LIB. If the MODULE
|
||||
* cannot be found, then an exception is thrown.
|
||||
*
|
||||
* @throw IO_ERROR if any problem occurs or if the footprint cannot be found.
|
||||
*/
|
||||
MODULE* LookupFootprint( const FP_LIB_ID& aFootprintId ) throw( IO_ERROR );
|
||||
#endif
|
||||
|
||||
|
||||
#endif // FP_LIB_TABLE_H_
|
|
@ -26,8 +26,8 @@
|
|||
* @file wxPcbStruct.h
|
||||
*/
|
||||
|
||||
#ifndef WXPCB_STRUCT_H
|
||||
#define WXPCB_STRUCT_H
|
||||
#ifndef WXPCB_STRUCT_H_
|
||||
#define WXPCB_STRUCT_H_
|
||||
|
||||
|
||||
#include <wxBasePcbFrame.h>
|
||||
|
@ -1604,4 +1604,16 @@ public:
|
|||
};
|
||||
|
||||
|
||||
#endif /* WXPCB_STRUCT_H */
|
||||
class FP_LIB_TABLE;
|
||||
|
||||
/**
|
||||
* Function InvokePcbLibTableEditor
|
||||
* shows the modal DIALOG_FP_LIB_TABLE for purposes of editing two lib tables.
|
||||
*
|
||||
* @return int - bits 0 and 1 tell whether a change was made to the @a aGlobal
|
||||
* and/or the @a aProject table, respectively. If set, table was modified.
|
||||
*/
|
||||
int InvokePcbLibTableEditor( wxFrame* aParent, FP_LIB_TABLE* aGlobal, FP_LIB_TABLE* aProject );
|
||||
|
||||
|
||||
#endif // WXPCB_STRUCT_H_
|
||||
|
|
|
@ -50,6 +50,8 @@ set(PCBNEW_DIALOGS
|
|||
dialogs/dialog_export_3Dfiles_base.cpp
|
||||
dialogs/dialog_find_base.cpp
|
||||
dialogs/dialog_find.cpp
|
||||
dialogs/dialog_fp_lib_table_base.cpp
|
||||
dialogs/dialog_fp_lib_table.cpp
|
||||
dialogs/dialog_freeroute_exchange.cpp
|
||||
dialogs/dialog_freeroute_exchange_base.cpp
|
||||
dialogs/dialog_gendrill.cpp
|
||||
|
@ -247,11 +249,11 @@ set(PCBNEW_SCRIPTING_PYTHON_HELPERS
|
|||
)
|
||||
|
||||
if (KICAD_SCRIPTING)
|
||||
set(PCBNEW_SCRIPTING_SRCS
|
||||
${PCBNEW_SCRIPTING_DIALOGS}
|
||||
pcbnew_wrap.cxx
|
||||
${PCBNEW_SCRIPTING_PYTHON_HELPERS}
|
||||
)
|
||||
set(PCBNEW_SCRIPTING_SRCS
|
||||
${PCBNEW_SCRIPTING_DIALOGS}
|
||||
pcbnew_wrap.cxx
|
||||
${PCBNEW_SCRIPTING_PYTHON_HELPERS}
|
||||
)
|
||||
endif(KICAD_SCRIPTING)
|
||||
|
||||
##
|
||||
|
@ -260,34 +262,34 @@ endif(KICAD_SCRIPTING)
|
|||
|
||||
if (KICAD_SCRIPTING OR KICAD_SCRIPTING_MODULES)
|
||||
|
||||
set(SWIG_FLAGS -I${CMAKE_CURRENT_SOURCE_DIR}/../.. -I${CMAKE_CURRENT_SOURCE_DIR} -I${CMAKE_CURRENT_SOURCE_DIR}/../include -I${CMAKE_CURRENT_SOURCE_DIR}/../scripting )
|
||||
if (DEBUG)
|
||||
set(SWIG_FLAGS ${SWIG_FLAGS} -DDEBUG)
|
||||
endif(DEBUG)
|
||||
# collect CFLAGS , and pass them to swig later
|
||||
set(SWIG_FLAGS -I${CMAKE_CURRENT_SOURCE_DIR}/../.. -I${CMAKE_CURRENT_SOURCE_DIR} -I${CMAKE_CURRENT_SOURCE_DIR}/../include -I${CMAKE_CURRENT_SOURCE_DIR}/../scripting )
|
||||
if (DEBUG)
|
||||
set(SWIG_FLAGS ${SWIG_FLAGS} -DDEBUG)
|
||||
endif(DEBUG)
|
||||
# collect CFLAGS , and pass them to swig later
|
||||
|
||||
get_directory_property( DirDefs DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR} COMPILE_DEFINITIONS )
|
||||
foreach( d ${DirDefs} )
|
||||
SET(SWIG_FLAGS ${SWIG_FLAGS} -D${d} )
|
||||
endforeach()
|
||||
get_directory_property( DirDefs DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR} COMPILE_DEFINITIONS )
|
||||
foreach( d ${DirDefs} )
|
||||
SET(SWIG_FLAGS ${SWIG_FLAGS} -D${d} )
|
||||
endforeach()
|
||||
|
||||
# check if we have IO_MGR and KICAD_PLUGIN available
|
||||
if ( USE_NEW_PCBNEW_LOAD OR USE_NEW_PCBNEW_SAVE )
|
||||
SET(SWIG_FLAGS ${SWIG_FLAGS} -DBUILD_WITH_PLUGIN)
|
||||
endif(USE_NEW_PCBNEW_LOAD OR USE_NEW_PCBNEW_SAVE)
|
||||
# check if we have IO_MGR and KICAD_PLUGIN available
|
||||
if ( USE_NEW_PCBNEW_LOAD OR USE_NEW_PCBNEW_SAVE )
|
||||
SET(SWIG_FLAGS ${SWIG_FLAGS} -DBUILD_WITH_PLUGIN)
|
||||
endif(USE_NEW_PCBNEW_LOAD OR USE_NEW_PCBNEW_SAVE)
|
||||
|
||||
if ( USE_PCBNEW_NANOMETRES )
|
||||
SET(SWIG_FLAGS ${SWIG_FLAGS} -DUSE_PCBNEW_NANOMETRES)
|
||||
endif( USE_PCBNEW_NANOMETRES )
|
||||
if ( USE_PCBNEW_NANOMETRES )
|
||||
SET(SWIG_FLAGS ${SWIG_FLAGS} -DUSE_PCBNEW_NANOMETRES)
|
||||
endif( USE_PCBNEW_NANOMETRES )
|
||||
|
||||
endif(KICAD_SCRIPTING OR KICAD_SCRIPTING_MODULES)
|
||||
|
||||
if (KICAD_SCRIPTING)
|
||||
|
||||
SET(SWIG_OPTS -python -c++ -outdir ${CMAKE_CURRENT_BINARY_DIR} ${SWIG_FLAGS} )
|
||||
SET(SWIG_OPTS -python -c++ -outdir ${CMAKE_CURRENT_BINARY_DIR} ${SWIG_FLAGS} )
|
||||
|
||||
add_custom_command(
|
||||
OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/pcbnew_wrap.cxx
|
||||
add_custom_command(
|
||||
OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/pcbnew_wrap.cxx
|
||||
DEPENDS scripting/pcbnew.i
|
||||
DEPENDS scripting/board.i
|
||||
DEPENDS scripting/board_item.i
|
||||
|
@ -299,10 +301,10 @@ if (KICAD_SCRIPTING)
|
|||
DEPENDS ../scripting/wx.i
|
||||
DEPENDS ../scripting/kicadplugins.i
|
||||
|
||||
COMMAND ${SWIG_EXECUTABLE} ${SWIG_OPTS} -o ${CMAKE_CURRENT_BINARY_DIR}/pcbnew_wrap.cxx scripting/pcbnew.i
|
||||
COMMAND ${PYTHON_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/../scripting/fixswigimports.py ${CMAKE_CURRENT_BINARY_DIR}/pcbnew.py
|
||||
WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}
|
||||
)
|
||||
COMMAND ${SWIG_EXECUTABLE} ${SWIG_OPTS} -o ${CMAKE_CURRENT_BINARY_DIR}/pcbnew_wrap.cxx scripting/pcbnew.i
|
||||
COMMAND ${PYTHON_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/../scripting/fixswigimports.py ${CMAKE_CURRENT_BINARY_DIR}/pcbnew.py
|
||||
WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}
|
||||
)
|
||||
|
||||
|
||||
endif(KICAD_SCRIPTING)
|
||||
|
@ -430,7 +432,7 @@ install(TARGETS pcbnew
|
|||
COMPONENT binary)
|
||||
|
||||
if(KICAD_SCRIPTING)
|
||||
add_custom_target(FixSwigImportsScripting ALL
|
||||
add_custom_target(FixSwigImportsScripting ALL
|
||||
COMMAND ${PYTHON_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/../scripting/fixswigimports.py ${CMAKE_CURRENT_BINARY_DIR}/pcbnew.py
|
||||
DEPENDS ${CMAKE_CURRENT_BINARY_DIR}/pcbnew
|
||||
COMMENT "Fixing swig_import_helper in Kicad scripting"
|
||||
|
@ -442,7 +444,7 @@ if(KICAD_SCRIPTING)
|
|||
endif(KICAD_SCRIPTING)
|
||||
|
||||
if (KICAD_SCRIPTING_MODULES)
|
||||
add_custom_target(FixSwigImportsModuleScripting ALL
|
||||
add_custom_target(FixSwigImportsModuleScripting ALL
|
||||
COMMAND ${PYTHON_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/../scripting/fixswigimports.py ${CMAKE_CURRENT_BINARY_DIR}/pcbnew.py
|
||||
DEPENDS ${CMAKE_CURRENT_BINARY_DIR}/_pcbnew
|
||||
COMMENT "Fixing swig_import_helper in Kicad scripting modules"
|
||||
|
|
|
@ -0,0 +1,397 @@
|
|||
/*
|
||||
* This program source code file is part of KiCad, a free EDA CAD application.
|
||||
*
|
||||
* Copyright (C) 2012 SoftPLC Corporation, Dick Hollenbeck <dick@softplc.com>
|
||||
* Copyright (C) 2012 Wayne Stambaugh <stambaughw@verizon.net>
|
||||
* Copyright (C) 2012 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
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* 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, you may find one here:
|
||||
* http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
|
||||
* or you may search the http://www.gnu.org website for the version 2 license,
|
||||
* or you may write to the Free Software Foundation, Inc.,
|
||||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
|
||||
*/
|
||||
|
||||
|
||||
#include <fctsys.h>
|
||||
#include <dialog_fp_lib_table_base.h>
|
||||
#include <fp_lib_table.h>
|
||||
#include <wx/grid.h>
|
||||
|
||||
|
||||
/**
|
||||
* Class FP_TBL_MODEL
|
||||
* mixes in wxGridTableBase into FP_LIB_TABLE so that the latter can be used
|
||||
* as a table within wxGrid.
|
||||
*/
|
||||
class FP_TBL_MODEL : public wxGridTableBase, public FP_LIB_TABLE
|
||||
{
|
||||
public:
|
||||
|
||||
/**
|
||||
* Constructor FP_TBL_MODEL
|
||||
* is a copy constructor that builds a wxGridTableBase (table model) by wrapping
|
||||
* an FP_LIB_TABLE.
|
||||
*/
|
||||
FP_TBL_MODEL( const FP_LIB_TABLE& aTableToEdit ) :
|
||||
FP_LIB_TABLE( aTableToEdit ) // copy constructor
|
||||
{
|
||||
}
|
||||
|
||||
//-----<wxGridTableBase overloads>-------------------------------------------
|
||||
|
||||
int GetNumberRows () { return rows.size(); }
|
||||
int GetNumberCols () { return 4; }
|
||||
|
||||
wxString GetValue( int aRow, int aCol )
|
||||
{
|
||||
if( unsigned( aRow ) < rows.size() )
|
||||
{
|
||||
const ROW& r = rows[aRow];
|
||||
|
||||
switch( aCol )
|
||||
{
|
||||
case 0: return r.GetNickName();
|
||||
case 1: return r.GetFullURI();
|
||||
case 2: return r.GetType();
|
||||
case 3: return r.GetOptions();
|
||||
default:
|
||||
; // fall thru to wxEmptyString
|
||||
}
|
||||
}
|
||||
|
||||
return wxEmptyString;
|
||||
}
|
||||
|
||||
void SetValue( int aRow, int aCol, const wxString &aValue )
|
||||
{
|
||||
if( unsigned( aRow ) < rows.size() )
|
||||
{
|
||||
ROW& r = rows[aRow];
|
||||
|
||||
switch( aCol )
|
||||
{
|
||||
case 0: r.SetNickName( aValue ); break;
|
||||
case 1: r.SetFullURI( aValue ); break;
|
||||
case 2: r.SetType( aValue ); break;
|
||||
case 3: r.SetOptions( aValue ); break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool IsEmptyCell( int aRow, int aCol )
|
||||
{
|
||||
if( unsigned( aRow ) < rows.size() )
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool InsertRows( size_t aPos = 0, size_t aNumRows = 1 )
|
||||
{
|
||||
if( aPos < rows.size() )
|
||||
{
|
||||
rows.insert( rows.begin() + aPos, aNumRows, ROW() );
|
||||
|
||||
// use the (wxGridStringTable) source Luke.
|
||||
if( GetView() )
|
||||
{
|
||||
wxGridTableMessage msg( this,
|
||||
wxGRIDTABLE_NOTIFY_ROWS_INSERTED,
|
||||
aPos,
|
||||
aNumRows );
|
||||
|
||||
GetView()->ProcessTableMessage( msg );
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool AppendRows( size_t aNumRows = 1 )
|
||||
{
|
||||
// do not modify aNumRows, original value needed for wxGridTableMessage below
|
||||
for( int i = aNumRows; i; --i )
|
||||
rows.push_back( ROW() );
|
||||
|
||||
if( GetView() )
|
||||
{
|
||||
wxGridTableMessage msg( this,
|
||||
wxGRIDTABLE_NOTIFY_ROWS_APPENDED,
|
||||
aNumRows );
|
||||
|
||||
GetView()->ProcessTableMessage( msg );
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool DeleteRows( size_t aPos, size_t aNumRows )
|
||||
{
|
||||
if( aPos + aNumRows <= rows.size() )
|
||||
{
|
||||
ROWS_ITER start = rows.begin() + aPos;
|
||||
rows.erase( start, start + aNumRows );
|
||||
|
||||
if( GetView() )
|
||||
{
|
||||
wxGridTableMessage msg( this,
|
||||
wxGRIDTABLE_NOTIFY_ROWS_DELETED,
|
||||
aPos,
|
||||
aNumRows );
|
||||
|
||||
GetView()->ProcessTableMessage( msg );
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
void Clear()
|
||||
{
|
||||
rows.clear();
|
||||
nickIndex.clear();
|
||||
}
|
||||
|
||||
wxString GetColLabelValue( int aCol )
|
||||
{
|
||||
switch( aCol )
|
||||
{
|
||||
case 0: return _( "Nickname" );
|
||||
case 1: return _( "Library Path" );
|
||||
case 2: return _( "Plugin" );
|
||||
case 3: return _( "Options" );
|
||||
default: return wxEmptyString;
|
||||
}
|
||||
}
|
||||
|
||||
//-----</wxGridTableBase overloads>------------------------------------------
|
||||
|
||||
};
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Class DIALOG_FP_LIB_TABLE
|
||||
* shows and edits the PCB library tables. Two tables are expected, one global
|
||||
* and one project specific.
|
||||
*/
|
||||
class DIALOG_FP_LIB_TABLE : public DIALOG_FP_LIB_TABLE_BASE
|
||||
{
|
||||
typedef FP_LIB_TABLE::ROW ROW;
|
||||
|
||||
/* row & col "selection" acquisition, not currently used but works.
|
||||
// selected area by cell coordinate and count
|
||||
int selRowStart;
|
||||
int selColStart;
|
||||
int selRowCount;
|
||||
int selColCount;
|
||||
|
||||
/// Gets the selected area into a sensible rectable of sel{Row,Col}{Start,Count} above.
|
||||
void getSelectedArea()
|
||||
{
|
||||
wxGridCellCoordsArray topLeft = m_cur_grid->GetSelectionBlockTopLeft();
|
||||
wxGridCellCoordsArray botRight = m_cur_grid->GetSelectionBlockBottomRight();
|
||||
|
||||
if( topLeft.Count() && botRight.Count() )
|
||||
{
|
||||
selRowStart = topLeft[0].GetRow();
|
||||
selColStart = topLeft[0].GetCol();
|
||||
|
||||
selRowCount = botRight[0].GetRow() - selRowStart + 1;
|
||||
selColCount = botRight[0].GetCol() - selColStart + 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
selRowStart = -1;
|
||||
selColStart = -1;
|
||||
selRowCount = 0;
|
||||
selColCount = 0;
|
||||
}
|
||||
|
||||
D(printf("selRowStart:%d selColStart:%d selRowCount:%d selColCount:%d\n",
|
||||
selRowStart, selColStart, selRowCount, selColCount );)
|
||||
}
|
||||
*/
|
||||
|
||||
//-----<event handlers>----------------------------------
|
||||
|
||||
void pageChangedHandler( wxAuiNotebookEvent& event )
|
||||
{
|
||||
int pageNdx = m_auinotebook->GetSelection();
|
||||
m_cur_grid = pageNdx==0 ? m_global_grid : m_project_grid;
|
||||
|
||||
D(printf("%s cur_grid is %s\n", __func__, pageNdx==0 ? "global" : "project" );)
|
||||
}
|
||||
|
||||
void appendRowHandler( wxMouseEvent& event )
|
||||
{
|
||||
m_cur_grid->AppendRows( 1 );
|
||||
}
|
||||
|
||||
void deleteRowHandler( wxMouseEvent& event )
|
||||
{
|
||||
int curRow = m_cur_grid->GetGridCursorRow();
|
||||
m_cur_grid->DeleteRows( curRow );
|
||||
}
|
||||
|
||||
void moveUpHandler( wxMouseEvent& event )
|
||||
{
|
||||
int curRow = m_cur_grid->GetGridCursorRow();
|
||||
if( curRow >= 1 )
|
||||
{
|
||||
int curCol = m_cur_grid->GetGridCursorCol();
|
||||
|
||||
FP_TBL_MODEL* tbl = (FP_TBL_MODEL*) m_cur_grid->GetTable();
|
||||
|
||||
ROW move_me = tbl->rows[curRow];
|
||||
|
||||
tbl->rows.erase( tbl->rows.begin() + curRow );
|
||||
--curRow;
|
||||
tbl->rows.insert( tbl->rows.begin() + curRow, move_me );
|
||||
|
||||
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->SetGridCursor( curRow, curCol );
|
||||
}
|
||||
}
|
||||
|
||||
void moveDownHandler( wxMouseEvent& event )
|
||||
{
|
||||
FP_TBL_MODEL* tbl = (FP_TBL_MODEL*) m_cur_grid->GetTable();
|
||||
|
||||
int curRow = m_cur_grid->GetGridCursorRow();
|
||||
if( unsigned( curRow + 1 ) < tbl->rows.size() )
|
||||
{
|
||||
int curCol = m_cur_grid->GetGridCursorCol();
|
||||
|
||||
ROW move_me = tbl->rows[curRow];
|
||||
|
||||
tbl->rows.erase( tbl->rows.begin() + curRow );
|
||||
++curRow;
|
||||
tbl->rows.insert( tbl->rows.begin() + curRow, move_me );
|
||||
|
||||
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->SetGridCursor( curRow, curCol );
|
||||
}
|
||||
D(printf("%s\n", __func__);)
|
||||
}
|
||||
|
||||
void onCancelButtonClick( wxCommandEvent& event )
|
||||
{
|
||||
EndModal( 0 );
|
||||
}
|
||||
|
||||
void onOKButtonClick( wxCommandEvent& event )
|
||||
{
|
||||
int dialogRet = 0;
|
||||
|
||||
if( m_global_model != *m_global )
|
||||
{
|
||||
dialogRet |= 1;
|
||||
|
||||
*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 );
|
||||
}
|
||||
|
||||
//-----</event handlers>---------------------------------
|
||||
|
||||
|
||||
// caller's tables are modified only on OK button.
|
||||
FP_LIB_TABLE* m_global;
|
||||
FP_LIB_TABLE* m_project;
|
||||
|
||||
// local copies which are edited, but aborted if Cancel button.
|
||||
FP_TBL_MODEL m_global_model;
|
||||
FP_TBL_MODEL m_project_model;
|
||||
|
||||
wxGrid* m_cur_grid; ///< changed based on tab choice
|
||||
|
||||
|
||||
public:
|
||||
DIALOG_FP_LIB_TABLE( wxFrame* aParent, FP_LIB_TABLE* aGlobal, FP_LIB_TABLE* aProject ) :
|
||||
DIALOG_FP_LIB_TABLE_BASE( aParent ),
|
||||
m_global( aGlobal ),
|
||||
m_project( aProject ),
|
||||
m_global_model( *aGlobal ),
|
||||
m_project_model( *aProject )
|
||||
{
|
||||
m_global_grid->SetTable( (wxGridTableBase*) &m_global_model );
|
||||
m_project_grid->SetTable( (wxGridTableBase*) &m_project_model );
|
||||
|
||||
m_global_grid->AutoSizeColumns( false );
|
||||
|
||||
m_project_grid->AutoSizeColumns( false );
|
||||
|
||||
m_path_subs_grid->AutoSizeColumns( false );
|
||||
|
||||
// fire pageChangedHandler() so m_cur_grid gets set
|
||||
wxAuiNotebookEvent uneventful;
|
||||
pageChangedHandler( uneventful );
|
||||
}
|
||||
|
||||
~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();
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
|
||||
int InvokePcbLibTableEditor( wxFrame* aParent, FP_LIB_TABLE* aGlobal, FP_LIB_TABLE* aProject )
|
||||
{
|
||||
DIALOG_FP_LIB_TABLE dlg( aParent, aGlobal, aProject );
|
||||
|
||||
int dialogRet = dlg.ShowModal(); // returns value passed to EndModal() above
|
||||
|
||||
return dialogRet;
|
||||
}
|
||||
|
|
@ -0,0 +1,221 @@
|
|||
///////////////////////////////////////////////////////////////////////////
|
||||
// C++ code generated with wxFormBuilder (version Oct 8 2012)
|
||||
// http://www.wxformbuilder.org/
|
||||
//
|
||||
// PLEASE DO "NOT" EDIT THIS FILE!
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#include "dialog_fp_lib_table_base.h"
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
|
||||
DIALOG_FP_LIB_TABLE_BASE::DIALOG_FP_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( wxDefaultSize, wxDefaultSize );
|
||||
|
||||
wxBoxSizer* bSizer1;
|
||||
bSizer1 = new wxBoxSizer( wxVERTICAL );
|
||||
|
||||
m_splitter = new wxSplitterWindow( this, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxSP_3DSASH );
|
||||
m_splitter->Connect( wxEVT_IDLE, wxIdleEventHandler( DIALOG_FP_LIB_TABLE_BASE::m_splitterOnIdle ), NULL, this );
|
||||
m_splitter->SetMinimumPaneSize( 10 );
|
||||
|
||||
m_top = new wxPanel( m_splitter, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxTAB_TRAVERSAL );
|
||||
wxStaticBoxSizer* m_top_sizer;
|
||||
m_top_sizer = new wxStaticBoxSizer( new wxStaticBox( m_top, wxID_ANY, _("Library Tables by Scope") ), wxVERTICAL );
|
||||
|
||||
m_auinotebook = new wxAuiNotebook( m_top, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxAUI_NB_BOTTOM );
|
||||
m_global_panel = new wxPanel( m_auinotebook, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxTAB_TRAVERSAL );
|
||||
m_global_panel->SetToolTip( _("Module libraries which are visible for all projects") );
|
||||
|
||||
wxBoxSizer* m_global_sizer;
|
||||
m_global_sizer = new wxBoxSizer( wxVERTICAL );
|
||||
|
||||
m_global_grid = new wxGrid( m_global_panel, wxID_ANY, wxDefaultPosition, wxDefaultSize, 0 );
|
||||
|
||||
// Grid
|
||||
m_global_grid->CreateGrid( 1, 4 );
|
||||
m_global_grid->EnableEditing( true );
|
||||
m_global_grid->EnableGridLines( true );
|
||||
m_global_grid->EnableDragGridSize( true );
|
||||
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->EnableDragRowSize( true );
|
||||
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, 1, 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 );
|
||||
|
||||
m_project_grid = new wxGrid( m_project_panel, wxID_ANY, wxDefaultPosition, wxDefaultSize, 0 );
|
||||
|
||||
// Grid
|
||||
m_project_grid->CreateGrid( 1, 4 );
|
||||
m_project_grid->EnableEditing( true );
|
||||
m_project_grid->EnableGridLines( true );
|
||||
m_project_grid->EnableDragGridSize( true );
|
||||
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( true );
|
||||
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, 1, 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, wxID_ANY, _("Append Row"), 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, wxID_ANY, _("Delete Row"), 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, 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, 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 );
|
||||
|
||||
|
||||
m_top->SetSizer( m_top_sizer );
|
||||
m_top->Layout();
|
||||
m_top_sizer->Fit( m_top );
|
||||
m_bottom = new wxPanel( m_splitter, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxTAB_TRAVERSAL );
|
||||
wxBoxSizer* m_bottom_sizer;
|
||||
m_bottom_sizer = new wxBoxSizer( wxVERTICAL );
|
||||
|
||||
wxStaticBoxSizer* sbSizer1;
|
||||
sbSizer1 = new wxStaticBoxSizer( new wxStaticBox( m_bottom, wxID_ANY, _("Path Substitutions") ), wxVERTICAL );
|
||||
|
||||
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->EnableEditing( true );
|
||||
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, _("Category") );
|
||||
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
|
||||
|
||||
// Cell Defaults
|
||||
m_path_subs_grid->SetDefaultCellAlignment( wxALIGN_LEFT, wxALIGN_TOP );
|
||||
sbSizer1->Add( m_path_subs_grid, 1, wxALL|wxEXPAND, 5 );
|
||||
|
||||
|
||||
m_bottom_sizer->Add( sbSizer1, 1, wxALL|wxEXPAND, 5 );
|
||||
|
||||
m_sdbSizer1 = new wxStdDialogButtonSizer();
|
||||
m_sdbSizer1OK = new wxButton( m_bottom, wxID_OK );
|
||||
m_sdbSizer1->AddButton( m_sdbSizer1OK );
|
||||
m_sdbSizer1Cancel = new wxButton( m_bottom, wxID_CANCEL );
|
||||
m_sdbSizer1->AddButton( m_sdbSizer1Cancel );
|
||||
m_sdbSizer1->Realize();
|
||||
|
||||
m_bottom_sizer->Add( m_sdbSizer1, 0, wxALL|wxEXPAND, 5 );
|
||||
|
||||
|
||||
m_bottom->SetSizer( m_bottom_sizer );
|
||||
m_bottom->Layout();
|
||||
m_bottom_sizer->Fit( m_bottom );
|
||||
m_splitter->SplitHorizontally( m_top, m_bottom, 343 );
|
||||
bSizer1->Add( m_splitter, 2, wxEXPAND, 5 );
|
||||
|
||||
|
||||
this->SetSizer( bSizer1 );
|
||||
this->Layout();
|
||||
|
||||
this->Centre( wxBOTH );
|
||||
|
||||
// Connect Events
|
||||
m_auinotebook->Connect( wxEVT_COMMAND_AUINOTEBOOK_PAGE_CHANGED, wxAuiNotebookEventHandler( DIALOG_FP_LIB_TABLE_BASE::pageChangedHandler ), NULL, this );
|
||||
m_append_button->Connect( wxEVT_LEFT_DOWN, wxMouseEventHandler( DIALOG_FP_LIB_TABLE_BASE::appendRowHandler ), NULL, this );
|
||||
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_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 );
|
||||
}
|
||||
|
||||
DIALOG_FP_LIB_TABLE_BASE::~DIALOG_FP_LIB_TABLE_BASE()
|
||||
{
|
||||
// Disconnect Events
|
||||
m_auinotebook->Disconnect( wxEVT_COMMAND_AUINOTEBOOK_PAGE_CHANGED, wxAuiNotebookEventHandler( DIALOG_FP_LIB_TABLE_BASE::pageChangedHandler ), NULL, this );
|
||||
m_append_button->Disconnect( wxEVT_LEFT_DOWN, wxMouseEventHandler( DIALOG_FP_LIB_TABLE_BASE::appendRowHandler ), NULL, this );
|
||||
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_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 );
|
||||
|
||||
}
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,85 @@
|
|||
///////////////////////////////////////////////////////////////////////////
|
||||
// C++ code generated with wxFormBuilder (version Oct 8 2012)
|
||||
// http://www.wxformbuilder.org/
|
||||
//
|
||||
// PLEASE DO "NOT" EDIT THIS FILE!
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#ifndef __DIALOG_FP_LIB_TABLE_BASE_H__
|
||||
#define __DIALOG_FP_LIB_TABLE_BASE_H__
|
||||
|
||||
#include <wx/artprov.h>
|
||||
#include <wx/xrc/xmlres.h>
|
||||
#include <wx/intl.h>
|
||||
class DIALOG_SHIM;
|
||||
|
||||
#include "dialog_shim.h"
|
||||
#include <wx/colour.h>
|
||||
#include <wx/settings.h>
|
||||
#include <wx/string.h>
|
||||
#include <wx/font.h>
|
||||
#include <wx/grid.h>
|
||||
#include <wx/gdicmn.h>
|
||||
#include <wx/sizer.h>
|
||||
#include <wx/panel.h>
|
||||
#include <wx/bitmap.h>
|
||||
#include <wx/image.h>
|
||||
#include <wx/icon.h>
|
||||
#include <wx/aui/auibook.h>
|
||||
#include <wx/button.h>
|
||||
#include <wx/statbox.h>
|
||||
#include <wx/splitter.h>
|
||||
#include <wx/dialog.h>
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
/// Class DIALOG_FP_LIB_TABLE_BASE
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
class DIALOG_FP_LIB_TABLE_BASE : public DIALOG_SHIM
|
||||
{
|
||||
private:
|
||||
|
||||
protected:
|
||||
wxSplitterWindow* m_splitter;
|
||||
wxPanel* m_top;
|
||||
wxAuiNotebook* m_auinotebook;
|
||||
wxPanel* m_global_panel;
|
||||
wxGrid* m_global_grid;
|
||||
wxPanel* m_project_panel;
|
||||
wxGrid* m_project_grid;
|
||||
wxButton* m_append_button;
|
||||
wxButton* m_delete_button;
|
||||
wxButton* m_move_up_button;
|
||||
wxButton* m_move_down_button;
|
||||
wxPanel* m_bottom;
|
||||
wxGrid* m_path_subs_grid;
|
||||
wxStdDialogButtonSizer* m_sdbSizer1;
|
||||
wxButton* m_sdbSizer1OK;
|
||||
wxButton* m_sdbSizer1Cancel;
|
||||
|
||||
// Virtual event handlers, overide them in your derived class
|
||||
virtual void pageChangedHandler( wxAuiNotebookEvent& event ) { event.Skip(); }
|
||||
virtual void appendRowHandler( wxMouseEvent& event ) { event.Skip(); }
|
||||
virtual void deleteRowHandler( wxMouseEvent& event ) { event.Skip(); }
|
||||
virtual void moveUpHandler( wxMouseEvent& event ) { event.Skip(); }
|
||||
virtual void moveDownHandler( wxMouseEvent& event ) { event.Skip(); }
|
||||
virtual void onCancelButtonClick( wxCommandEvent& event ) { event.Skip(); }
|
||||
virtual void onOKButtonClick( wxCommandEvent& event ) { event.Skip(); }
|
||||
|
||||
|
||||
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();
|
||||
|
||||
void m_splitterOnIdle( wxIdleEvent& )
|
||||
{
|
||||
m_splitter->SetSashPosition( 343 );
|
||||
m_splitter->Disconnect( wxEVT_IDLE, wxIdleEventHandler( DIALOG_FP_LIB_TABLE_BASE::m_splitterOnIdle ), NULL, this );
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
#endif //__DIALOG_FP_LIB_TABLE_BASE_H__
|
|
@ -80,22 +80,50 @@ void IO_MGR::PluginRelease( PLUGIN* aPlugin )
|
|||
}
|
||||
|
||||
|
||||
const wxString IO_MGR::ShowType( PCB_FILE_T aFileType )
|
||||
const wxString IO_MGR::ShowType( PCB_FILE_T aType )
|
||||
{
|
||||
switch( aFileType )
|
||||
// keep this function in sync with EnumFromStr() relative to the
|
||||
// text spellings. If you change the spellings, you will obsolete
|
||||
// library tables, so don't do change, only additions are ok.
|
||||
|
||||
switch( aType )
|
||||
{
|
||||
default:
|
||||
return wxString::Format( _( "Unknown PCB_FILE_T value: %d" ), aFileType );
|
||||
return wxString::Format( _( "Unknown PCB_FILE_T value: %d" ), aType );
|
||||
|
||||
case LEGACY:
|
||||
return wxString( wxT( "KiCad Legacy" ) );
|
||||
return wxString( wxT( "Legacy" ) );
|
||||
|
||||
case KICAD:
|
||||
return wxString( wxT( "KiCad" ) );
|
||||
|
||||
case EAGLE:
|
||||
return wxString( wxT( "Eagle" ) );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
IO_MGR::PCB_FILE_T IO_MGR::EnumFromStr( const wxString& aType )
|
||||
{
|
||||
// keep this function in sync with ShowType() relative to the
|
||||
// text spellings. If you change the spellings, you will obsolete
|
||||
// library tables, so don't do change, only additions are ok.
|
||||
|
||||
if( aType == wxT( "KiCad" ) )
|
||||
return KICAD;
|
||||
|
||||
if( aType == wxT( "Legacy" ) )
|
||||
return LEGACY;
|
||||
|
||||
if( aType == wxT( "Eagle" ) )
|
||||
return EAGLE;
|
||||
|
||||
// wxASSERT( blow up here )
|
||||
|
||||
return PCB_FILE_T( -1 );
|
||||
}
|
||||
|
||||
|
||||
const wxString IO_MGR::GetFileExtension( PCB_FILE_T aFileType )
|
||||
{
|
||||
wxString ext = wxEmptyString;
|
||||
|
|
|
@ -87,6 +87,12 @@ public:
|
|||
*/
|
||||
static const wxString ShowType( PCB_FILE_T aFileType );
|
||||
|
||||
/**
|
||||
* Function EnumFromStr
|
||||
* returns the PCB_FILE_T from the corresponding plugin type name: "kicad", "legacy", etc.
|
||||
*/
|
||||
static PCB_FILE_T EnumFromStr( const wxString& aFileType );
|
||||
|
||||
/**
|
||||
* Function GetFileExtension
|
||||
* returns the file extension for \a aFileType.
|
||||
|
|
|
@ -426,6 +426,10 @@ void PCB_EDIT_FRAME::ReCreateMenuBar()
|
|||
_( "Li&brary" ), _( "Setting libraries, directories and others..." ),
|
||||
KiBitmap( library_xpm ) );
|
||||
|
||||
AddMenuItem( configmenu, ID_PCB_LIB_TABLE_EDIT,
|
||||
_( "Li&brary Tables" ), _( "Setup footprint libraries" ),
|
||||
KiBitmap( library_xpm ) );
|
||||
|
||||
// Colors and Visibility are also handled by the layers manager toolbar
|
||||
AddMenuItem( configmenu, ID_MENU_PCB_SHOW_HIDE_LAYERS_MANAGER_DIALOG,
|
||||
m_show_layer_manager_tools ?
|
||||
|
|
|
@ -32,7 +32,7 @@
|
|||
#include <pcb_lexer.h>
|
||||
#include <hashtables.h>
|
||||
|
||||
using namespace PCB;
|
||||
using namespace PCB_KEYS_T;
|
||||
|
||||
|
||||
class BOARD;
|
||||
|
|
|
@ -109,6 +109,7 @@ BEGIN_EVENT_TABLE( PCB_EDIT_FRAME, PCB_BASE_FRAME )
|
|||
// menu Config
|
||||
EVT_MENU( ID_PCB_DRAWINGS_WIDTHS_SETUP, PCB_EDIT_FRAME::OnConfigurePcbOptions )
|
||||
EVT_MENU( ID_CONFIG_REQ, PCB_EDIT_FRAME::Process_Config )
|
||||
EVT_MENU( ID_PCB_LIB_TABLE_EDIT, PCB_EDIT_FRAME::Process_Config )
|
||||
EVT_MENU( ID_CONFIG_SAVE, PCB_EDIT_FRAME::Process_Config )
|
||||
EVT_MENU( ID_CONFIG_READ, PCB_EDIT_FRAME::Process_Config )
|
||||
EVT_MENU_RANGE( ID_PREFERENCES_HOTKEY_START, ID_PREFERENCES_HOTKEY_END,
|
||||
|
|
|
@ -43,6 +43,7 @@
|
|||
#include <dialog_hotkeys_editor.h>
|
||||
|
||||
#include <class_board.h>
|
||||
#include <fp_lib_table.h>
|
||||
|
||||
#include <pcbplot.h>
|
||||
#include <pcbnew.h>
|
||||
|
@ -58,8 +59,8 @@
|
|||
|
||||
void PCB_EDIT_FRAME::Process_Config( wxCommandEvent& event )
|
||||
{
|
||||
int id = event.GetId();
|
||||
wxFileName fn;
|
||||
int id = event.GetId();
|
||||
wxFileName fn;
|
||||
|
||||
switch( id )
|
||||
{
|
||||
|
@ -81,6 +82,37 @@ void PCB_EDIT_FRAME::Process_Config( wxCommandEvent& event )
|
|||
InstallConfigFrame();
|
||||
break;
|
||||
|
||||
case ID_PCB_LIB_TABLE_EDIT:
|
||||
{
|
||||
// scaffolding: dummy up some data into tables, until actual load/save are in place.
|
||||
FP_LIB_TABLE gbl;
|
||||
FP_LIB_TABLE prj;
|
||||
|
||||
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" ) ) );
|
||||
|
||||
int r = InvokePcbLibTableEditor( this, &gbl, &prj );
|
||||
|
||||
if( r & 1 )
|
||||
{
|
||||
// save global table to disk and apply it
|
||||
D( printf( "global has changed\n" );)
|
||||
}
|
||||
|
||||
if( r & 2 )
|
||||
{
|
||||
// save project table to disk and apply it
|
||||
D( printf( "project has changed\n" );)
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case ID_PCB_MASK_CLEARANCE:
|
||||
{
|
||||
DIALOG_PADS_MASK_CLEARANCE dlg( this );
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
#ifndef __PCBNEW_ID_H__
|
||||
#define __PCBNEW_ID_H__
|
||||
#ifndef PCBNEW_ID_H_
|
||||
#define PCBNEW_ID_H_
|
||||
|
||||
#include <id.h>
|
||||
|
||||
|
@ -250,6 +250,7 @@ enum pcbnew_ids
|
|||
ID_MENU_PCB_SHOW_3D_FRAME,
|
||||
ID_PCB_USER_GRID_SETUP,
|
||||
ID_PCB_GEN_BOM_FILE_FROM_BOARD,
|
||||
ID_PCB_LIB_TABLE_EDIT,
|
||||
ID_MENU_PCB_SHOW_DESIGN_RULES_DIALOG,
|
||||
ID_MENU_PCB_SHOW_HIDE_LAYERS_MANAGER_DIALOG,
|
||||
|
||||
|
@ -330,7 +331,7 @@ enum pcbnew_ids
|
|||
ID_MODVIEW_NEXT,
|
||||
ID_MODVIEW_SHOW_3D_VIEW,
|
||||
ID_MODVIEW_FOOTPRINT_EXPORT_TO_BOARD,
|
||||
ID_FOOTPRINT_WIZARD_WINDOW,
|
||||
ID_FOOTPRINT_WIZARD_WINDOW,
|
||||
ID_FOOTPRINT_WIZARD_PAGES,
|
||||
ID_FOOTPRINT_WIZARD_PARAMETERS,
|
||||
ID_FOOTPRINT_WIZARD_NEXT,
|
||||
|
@ -343,7 +344,7 @@ enum pcbnew_ids
|
|||
ID_FOOTPRINT_WIZARD_PARAMETERS_WINDOW,
|
||||
ID_FOOTPRINT_WIZARD_SELECT_WIZARD,
|
||||
ID_FOOTPRINT_WIZARD_EXPORT_TO_BOARD,
|
||||
|
||||
|
||||
};
|
||||
|
||||
#endif /* __PCBNEW_IDS_H__ */
|
||||
#endif // PCBNEW_ID_H_
|
||||
|
|
Loading…
Reference in New Issue