Commit 69dbeab9 authored by Dick Hollenbeck's avatar Dick Hollenbeck

decouple wxGridTableBase from FP_LIB_TABLE, this was poor information hiding

parent fb43f4ad
...@@ -68,7 +68,7 @@ void FP_LIB_TABLE::Parse( FP_LIB_TABLE_LEXER* in ) throw( IO_ERROR, PARSE_ERROR ...@@ -68,7 +68,7 @@ void FP_LIB_TABLE::Parse( FP_LIB_TABLE_LEXER* in ) throw( IO_ERROR, PARSE_ERROR
in->NeedSYMBOLorNUMBER(); in->NeedSYMBOLorNUMBER();
ROW row( this ); ROW row;
row.SetNickName( in->FromUTF8() ); row.SetNickName( in->FromUTF8() );
...@@ -112,9 +112,9 @@ void FP_LIB_TABLE::Parse( FP_LIB_TABLE_LEXER* in ) throw( IO_ERROR, PARSE_ERROR ...@@ -112,9 +112,9 @@ void FP_LIB_TABLE::Parse( FP_LIB_TABLE_LEXER* in ) throw( IO_ERROR, PARSE_ERROR
in->NeedRIGHT(); // terminate the (lib..) in->NeedRIGHT(); // terminate the (lib..)
// all nickNames within this table fragment must be unique, so we do not // all nickNames within this table fragment must be unique, so we do not
// use doReplace in InsertRow(). However a fallBack table can have a // use doReplace in InsertRow(). (However a fallBack table can have a
// conflicting nickName and ours will supercede that one since in // conflicting nickName and ours will supercede that one since in
// FindLib() we search this table before any fall back. // FindLib() we search this table before any fall back.)
if( !InsertRow( row ) ) if( !InsertRow( row ) )
{ {
wxString msg = wxString::Format( wxString msg = wxString::Format(
......
...@@ -31,7 +31,6 @@ ...@@ -31,7 +31,6 @@
#include <vector> #include <vector>
#include <map> #include <map>
#include <wx/grid.h>
#include <fp_lib_id.h> #include <fp_lib_id.h>
...@@ -80,7 +79,7 @@ class FP_LIB_TABLE_LEXER; ...@@ -80,7 +79,7 @@ class FP_LIB_TABLE_LEXER;
* *
* @author Wayne Stambaugh * @author Wayne Stambaugh
*/ */
class FP_LIB_TABLE : public wxGridTableBase class FP_LIB_TABLE
{ {
friend class DIALOG_FP_LIB_TABLE; friend class DIALOG_FP_LIB_TABLE;
...@@ -135,11 +134,6 @@ public: ...@@ -135,11 +134,6 @@ public:
return options; return options;
} }
~ROW()
{
// delete lib;
}
/** /**
* Function Format * Function Format
* serializes this object as utf8 text to an OUTPUTFORMATTER, and tries to * serializes this object as utf8 text to an OUTPUTFORMATTER, and tries to
...@@ -151,11 +145,6 @@ public: ...@@ -151,11 +145,6 @@ public:
void Format( OUTPUTFORMATTER* out, int nestLevel ) const void Format( OUTPUTFORMATTER* out, int nestLevel ) const
throw( IO_ERROR ); throw( IO_ERROR );
ROW( FP_LIB_TABLE* aOwner ) :
owner( aOwner )
// lib( 0 )
{}
/** /**
* Function SetNickName * Function SetNickName
* changes the logical name of this library, useful for an editor. * changes the logical name of this library, useful for an editor.
...@@ -194,7 +183,6 @@ public: ...@@ -194,7 +183,6 @@ public:
} }
private: private:
FP_LIB_TABLE* owner;
wxString nickName; wxString nickName;
wxString type; wxString type;
wxString uri; wxString uri;
...@@ -279,106 +267,6 @@ public: ...@@ -279,106 +267,6 @@ public:
*/ */
std::vector<wxString> GetLogicalLibs(); std::vector<wxString> GetLogicalLibs();
//-----<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.GetType();
case 2: return r.GetFullURI();
case 3: return r.GetOptions();
default:
; // fall thru to wxEmptyString
}
}
return wxEmptyString;
}
void SetValue( int aRow, int aCol, const wxString &aValue )
{
if( aCol == 0 )
{
// when the nickname is changed, there's careful work to do, including
// ensuring uniqueness of the nickname.
}
else if( unsigned( aRow ) < rows.size() )
{
ROW& r = rows[aRow];
switch( aCol )
{
case 1: r.SetType( aValue ); break;
case 2: r.SetFullURI( 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( this ) );
return true;
}
return false;
}
bool AppendRows( size_t aNumRows = 1 )
{
while( aNumRows-- )
rows.push_back( ROW( this ) );
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 );
return true;
}
return false;
}
void Clear()
{
rows.clear();
}
wxString GetColLabelValue( int aCol )
{
switch( aCol )
{
case 0: return _( "Nickname" );
case 1: return _( "Plugin" );
case 2: return _( "Library Path" );
case 3: return _( "Options" );
default: return wxEmptyString;
}
}
//-----</wxGridTableBase overloads>------------------------------------------
//----<read accessors>---------------------------------------------------- //----<read accessors>----------------------------------------------------
// the returning of a const wxString* tells if not found, but might be too // the returning of a const wxString* tells if not found, but might be too
// promiscuous? // promiscuous?
...@@ -427,6 +315,7 @@ public: ...@@ -427,6 +315,7 @@ public:
void Test(); void Test();
#endif #endif
protected: // only a table editor can use these protected: // only a table editor can use these
/** /**
...@@ -448,7 +337,33 @@ protected: // only a table editor can use these ...@@ -448,7 +337,33 @@ protected: // only a table editor can use these
*/ */
ROW* FindRow( const wxString& aNickName ) const; ROW* FindRow( const wxString& aNickName ) const;
private: void reindex()
{
nickIndex.clear();
for( ROWS_CITER it = rows.begin(); it != rows.end(); ++it )
nickIndex.insert( INDEX_VALUE( it->nickName, it - rows.begin() ) );
}
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 // lets see what we need. #if 0 // lets see what we need.
/** /**
...@@ -479,23 +394,5 @@ private: ...@@ -479,23 +394,5 @@ private:
void loadLib( ROW* aRow ) throw( IO_ERROR ); void loadLib( ROW* aRow ) throw( IO_ERROR );
#endif #endif
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;
/// the particular key is the nickName within each row.
INDEX nickIndex;
FP_LIB_TABLE* fallBack;
};
#endif // _FP_LIB_TABLE_H_ #endif // _FP_LIB_TABLE_H_
...@@ -27,6 +27,132 @@ ...@@ -27,6 +27,132 @@
#include <fctsys.h> #include <fctsys.h>
#include <dialog_fp_lib_table_base.h> #include <dialog_fp_lib_table_base.h>
#include <fp_lib_table.h> #include <fp_lib_table.h>
#include <wx/grid.h>
#include <wx/grid.h>
class FP_TBL_MODEL : public wxGridTableBase, public FP_LIB_TABLE
{
public:
/**
* Constructor FP_TBL_MODEL
* builds a wxGridTableBase (table model) by wrapping an FP_LIB_TABLE.
* @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_TBL_MODEL( const FP_LIB_TABLE& aTableToEdit ) :
FP_LIB_TABLE( aTableToEdit ) // copy constructor
{
}
~FP_TBL_MODEL()
{
D(printf("%s\n", __func__ );)
}
//-----<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.SetType( aValue ); break;
case 2: r.SetFullURI( 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() );
return true;
}
return false;
}
bool AppendRows( size_t aNumRows = 1 )
{
while( aNumRows-- )
rows.push_back( ROW() );
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 );
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 * Class DIALOG_FP_LIB_TABLE
...@@ -66,16 +192,16 @@ class DIALOG_FP_LIB_TABLE : public DIALOG_FP_LIB_TABLE_BASE ...@@ -66,16 +192,16 @@ class DIALOG_FP_LIB_TABLE : public DIALOG_FP_LIB_TABLE_BASE
void onCancelButtonClick( wxCommandEvent& event ) void onCancelButtonClick( wxCommandEvent& event )
{ {
m_global->rows = m_orig_global;
m_project->rows = m_orig_project;
// @todo reindex, or add member function for wholesale row replacement
EndModal( wxID_CANCEL ); EndModal( wxID_CANCEL );
} }
void onOKButtonClick( wxCommandEvent& event ) void onOKButtonClick( wxCommandEvent& event )
{ {
*m_global = m_global_model;
*m_project = m_project_model;
// @todo reindex, or add member function for wholesale row replacement
EndModal( wxID_OK ); EndModal( wxID_OK );
} }
...@@ -87,9 +213,9 @@ class DIALOG_FP_LIB_TABLE : public DIALOG_FP_LIB_TABLE_BASE ...@@ -87,9 +213,9 @@ class DIALOG_FP_LIB_TABLE : public DIALOG_FP_LIB_TABLE_BASE
FP_LIB_TABLE* m_global; FP_LIB_TABLE* m_global;
FP_LIB_TABLE* m_project; FP_LIB_TABLE* m_project;
// local copies are saved and restored if Cancel button. // local copies which are edited, but aborted if Cancel button.
FP_LIB_TABLE::ROWS m_orig_global; FP_TBL_MODEL m_global_model;
FP_LIB_TABLE::ROWS m_orig_project; FP_TBL_MODEL m_project_model;
wxGrid* m_cur_grid; ///< changed based on tab choice wxGrid* m_cur_grid; ///< changed based on tab choice
...@@ -99,8 +225,8 @@ public: ...@@ -99,8 +225,8 @@ public:
DIALOG_FP_LIB_TABLE_BASE( aParent ), DIALOG_FP_LIB_TABLE_BASE( aParent ),
m_global( aGlobal ), m_global( aGlobal ),
m_project( aProject ), m_project( aProject ),
m_orig_global( aGlobal->rows ), m_global_model( *aGlobal ),
m_orig_project( aProject->rows ) m_project_model( *aProject )
{ {
/* /*
GetSizer()->SetSizeHints( this ); GetSizer()->SetSizeHints( this );
...@@ -111,28 +237,27 @@ public: ...@@ -111,28 +237,27 @@ public:
#if 1 && defined(DEBUG) #if 1 && defined(DEBUG)
// put some dummy data into table(s) // put some dummy data into table(s)
FP_LIB_TABLE::ROW row( m_global ); FP_LIB_TABLE::ROW row;
row.SetNickName( wxT( "passives" ) ); row.SetNickName( wxT( "passives" ) );
row.SetType( wxT( "kicad" ) ); row.SetType( wxT( "kicad" ) );
row.SetFullURI( wxT( "%G/passives" ) ); row.SetFullURI( wxT( "%G/passives" ) );
row.SetOptions( wxT( "speed=fast,purpose=testing" ) ); row.SetOptions( wxT( "speed=fast,purpose=testing" ) );
m_global->InsertRow( row ); m_global_model.InsertRow( row );
row.SetNickName( wxT( "micros" ) ); row.SetNickName( wxT( "micros" ) );
row.SetType( wxT( "legacy" ) ); row.SetType( wxT( "legacy" ) );
row.SetFullURI( wxT( "%P/micros" ) ); row.SetFullURI( wxT( "%P/micros" ) );
row.SetOptions( wxT( "speed=fast,purpose=testing" ) ); row.SetOptions( wxT( "speed=fast,purpose=testing" ) );
m_global->InsertRow( row ); m_global_model.InsertRow( row );
row.owner = m_project;
row.SetFullURI( wxT( "%P/chips" ) ); row.SetFullURI( wxT( "%P/chips" ) );
m_project->InsertRow( row ); m_project_model.InsertRow( row );
#endif #endif
m_global_grid->SetTable( m_global ); m_global_grid->SetTable( (wxGridTableBase*) &m_global_model );
m_project_grid->SetTable( m_project ); m_project_grid->SetTable( (wxGridTableBase*) &m_project_model );
//m_global_grid->AutoSize(); //m_global_grid->AutoSize();
m_global_grid->AutoSizeColumns( false ); m_global_grid->AutoSizeColumns( false );
...@@ -143,6 +268,16 @@ public: ...@@ -143,6 +268,16 @@ public:
//m_path_subs_grid->AutoSize(); //m_path_subs_grid->AutoSize();
m_path_subs_grid->AutoSizeColumns( false ); m_path_subs_grid->AutoSizeColumns( false );
} }
~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.
DestroyChildren();
}
}; };
......
...@@ -28,8 +28,8 @@ DIALOG_FP_LIB_TABLE_BASE::DIALOG_FP_LIB_TABLE_BASE( wxWindow* parent, wxWindowID ...@@ -28,8 +28,8 @@ DIALOG_FP_LIB_TABLE_BASE::DIALOG_FP_LIB_TABLE_BASE( wxWindow* parent, wxWindowID
m_global_panel = new wxPanel( m_auinotebook, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxTAB_TRAVERSAL ); 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") ); m_global_panel->SetToolTip( _("Module libraries which are visible for all projects") );
wxBoxSizer* m_global_box_sizer; wxBoxSizer* m_global_sizer;
m_global_box_sizer = new wxBoxSizer( wxVERTICAL ); m_global_sizer = new wxBoxSizer( wxVERTICAL );
m_global_grid = new wxGrid( m_global_panel, wxID_ANY, wxDefaultPosition, wxDefaultSize, 0 ); m_global_grid = new wxGrid( m_global_panel, wxID_ANY, wxDefaultPosition, wxDefaultSize, 0 );
...@@ -56,12 +56,12 @@ DIALOG_FP_LIB_TABLE_BASE::DIALOG_FP_LIB_TABLE_BASE( wxWindow* parent, wxWindowID ...@@ -56,12 +56,12 @@ DIALOG_FP_LIB_TABLE_BASE::DIALOG_FP_LIB_TABLE_BASE( wxWindow* parent, wxWindowID
// Cell Defaults // Cell Defaults
m_global_grid->SetDefaultCellAlignment( wxALIGN_LEFT, wxALIGN_TOP ); m_global_grid->SetDefaultCellAlignment( wxALIGN_LEFT, wxALIGN_TOP );
m_global_box_sizer->Add( m_global_grid, 1, wxALL|wxEXPAND, 5 ); m_global_sizer->Add( m_global_grid, 1, wxALL|wxEXPAND, 5 );
m_global_panel->SetSizer( m_global_box_sizer ); m_global_panel->SetSizer( m_global_sizer );
m_global_panel->Layout(); m_global_panel->Layout();
m_global_box_sizer->Fit( m_global_panel ); m_global_sizer->Fit( m_global_panel );
m_auinotebook->AddPage( m_global_panel, _("Global Libraries"), true, wxNullBitmap ); m_auinotebook->AddPage( m_global_panel, _("Global Libraries"), true, wxNullBitmap );
m_project_panel = new wxPanel( m_auinotebook, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxTAB_TRAVERSAL ); m_project_panel = new wxPanel( m_auinotebook, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxTAB_TRAVERSAL );
wxBoxSizer* m_project_sizer; wxBoxSizer* m_project_sizer;
...@@ -92,7 +92,7 @@ DIALOG_FP_LIB_TABLE_BASE::DIALOG_FP_LIB_TABLE_BASE( wxWindow* parent, wxWindowID ...@@ -92,7 +92,7 @@ DIALOG_FP_LIB_TABLE_BASE::DIALOG_FP_LIB_TABLE_BASE( wxWindow* parent, wxWindowID
// Cell Defaults // Cell Defaults
m_project_grid->SetDefaultCellAlignment( wxALIGN_LEFT, wxALIGN_TOP ); m_project_grid->SetDefaultCellAlignment( wxALIGN_LEFT, wxALIGN_TOP );
m_project_sizer->Add( m_project_grid, 0, wxALL, 5 ); m_project_sizer->Add( m_project_grid, 1, wxALL|wxEXPAND, 5 );
m_project_panel->SetSizer( m_project_sizer ); m_project_panel->SetSizer( m_project_sizer );
......
...@@ -431,7 +431,7 @@ ...@@ -431,7 +431,7 @@
<event name="OnUpdateUI"></event> <event name="OnUpdateUI"></event>
<object class="wxBoxSizer" expanded="1"> <object class="wxBoxSizer" expanded="1">
<property name="minimum_size"></property> <property name="minimum_size"></property>
<property name="name">m_global_box_sizer</property> <property name="name">m_global_sizer</property>
<property name="orient">wxVERTICAL</property> <property name="orient">wxVERTICAL</property>
<property name="permission">none</property> <property name="permission">none</property>
<object class="sizeritem" expanded="0"> <object class="sizeritem" expanded="0">
...@@ -665,8 +665,8 @@ ...@@ -665,8 +665,8 @@
<property name="permission">none</property> <property name="permission">none</property>
<object class="sizeritem" expanded="0"> <object class="sizeritem" expanded="0">
<property name="border">5</property> <property name="border">5</property>
<property name="flag">wxALL</property> <property name="flag">wxALL|wxEXPAND</property>
<property name="proportion">0</property> <property name="proportion">1</property>
<object class="wxGrid" expanded="0"> <object class="wxGrid" expanded="0">
<property name="BottomDockable">1</property> <property name="BottomDockable">1</property>
<property name="LeftDockable">1</property> <property name="LeftDockable">1</property>
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment