more fp_lib_table dialog work
This commit is contained in:
parent
07d31b9cfd
commit
e4825ee2fc
1
TODO.txt
1
TODO.txt
|
@ -154,6 +154,5 @@ Dick's Final TODO List:
|
|||
*) Apply Fabrizio and Alexander's linux desktop patches after unifying them.
|
||||
*) Get licensing cleaned up.
|
||||
*) Re-arrange the repo architecture.
|
||||
*) Merge KiCad GAL/TOM/ORSON if nobody else does.
|
||||
*) DLL-ization of pcbnew & eeschema
|
||||
http://www.eevblog.com/forum/open-source-kicad-geda/seriously-irritated-with-the-library-editor!/
|
||||
|
|
|
@ -56,7 +56,7 @@ enum COL_ORDER
|
|||
|
||||
/**
|
||||
* Class FP_TBL_MODEL
|
||||
* mixes in wxGridTableBase into FP_LIB_TABLE so that the latter can be used
|
||||
* mixes in FP_LIB_TABLE into wxGridTableBase so the result can be used
|
||||
* as a table within wxGrid.
|
||||
*/
|
||||
class FP_TBL_MODEL : public wxGridTableBase, public FP_LIB_TABLE
|
||||
|
@ -282,369 +282,17 @@ protected:
|
|||
*/
|
||||
class DIALOG_FP_LIB_TABLE : public DIALOG_FP_LIB_TABLE_BASE
|
||||
{
|
||||
typedef FP_LIB_TABLE::ROW ROW;
|
||||
|
||||
/// If the cursor is not on a valid cell, because there are no rows at all, return -1,
|
||||
/// else return a 0 based column index.
|
||||
int getCursorCol() const
|
||||
{
|
||||
return m_cur_grid->GetGridCursorCol();
|
||||
}
|
||||
|
||||
/// If the cursor is not on a valid cell, because there are no rows at all, return -1,
|
||||
/// else return a 0 based row index.
|
||||
int getCursorRow() const
|
||||
{
|
||||
return m_cur_grid->GetGridCursorRow();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Function verifyTables
|
||||
* trims important fields, removes blank row entries, and checks for duplicates.
|
||||
* @return bool - true if tables are OK, else false.
|
||||
*/
|
||||
bool verifyTables()
|
||||
{
|
||||
for( int t=0; t<2; ++t )
|
||||
{
|
||||
FP_TBL_MODEL& model = t==0 ? m_global_model : m_project_model;
|
||||
|
||||
for( int r = 0; r < model.GetNumberRows(); )
|
||||
{
|
||||
wxString nick = model.GetValue( r, COL_NICKNAME ).Trim( false ).Trim();
|
||||
wxString uri = model.GetValue( r, COL_URI ).Trim( false ).Trim();
|
||||
|
||||
if( !nick || !uri )
|
||||
{
|
||||
// Delete the "empty" row, where empty means missing nick or uri.
|
||||
// This also updates the UI which could be slow, but there should only be a few
|
||||
// rows to delete, unless the user fell asleep on the Add Row
|
||||
// button.
|
||||
model.DeleteRows( r, 1 );
|
||||
}
|
||||
else if( nick.find(':') != size_t(-1) )
|
||||
{
|
||||
wxString msg = wxString::Format(
|
||||
_( "Illegal character '%s' found in Nickname: '%s' in row %d" ),
|
||||
wxT( ":" ), GetChars( nick ), r );
|
||||
|
||||
// show the tabbed panel holding the grid we have flunked:
|
||||
if( &model != (FP_TBL_MODEL*) m_cur_grid->GetTable() )
|
||||
{
|
||||
m_auinotebook->SetSelection( &model == &m_global_model ? 0 : 1 );
|
||||
}
|
||||
|
||||
// go to the problematic row
|
||||
m_cur_grid->SetGridCursor( r, 0 );
|
||||
m_cur_grid->SelectBlock( r, 0, r, 0 );
|
||||
m_cur_grid->MakeCellVisible( r, 0 );
|
||||
|
||||
wxMessageDialog errdlg( this, msg, _( "No Colon in Nicknames" ) );
|
||||
errdlg.ShowModal();
|
||||
return false;
|
||||
}
|
||||
else
|
||||
{
|
||||
// set the trimmed values back into the table so they get saved to disk.
|
||||
model.SetValue( r, COL_NICKNAME, nick );
|
||||
model.SetValue( r, COL_URI, uri );
|
||||
++r; // this row was OK.
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// check for duplicate nickNames, separately in each table.
|
||||
for( int t=0; t<2; ++t )
|
||||
{
|
||||
FP_TBL_MODEL& model = t==0 ? m_global_model : m_project_model;
|
||||
|
||||
for( int r1 = 0; r1 < model.GetNumberRows() - 1; ++r1 )
|
||||
{
|
||||
wxString nick1 = model.GetValue( r1, COL_NICKNAME );
|
||||
|
||||
for( int r2=r1+1; r2 < model.GetNumberRows(); ++r2 )
|
||||
{
|
||||
wxString nick2 = model.GetValue( r2, COL_NICKNAME );
|
||||
|
||||
if( nick1 == nick2 )
|
||||
{
|
||||
wxString msg = wxString::Format(
|
||||
_( "Duplicate Nickname: '%s' in rows %d and %d" ),
|
||||
GetChars( nick1 ), r1+1, r2+1
|
||||
);
|
||||
|
||||
// show the tabbed panel holding the grid we have flunked:
|
||||
if( &model != (FP_TBL_MODEL*) m_cur_grid->GetTable() )
|
||||
{
|
||||
m_auinotebook->SetSelection( &model == &m_global_model ? 0 : 1 );
|
||||
}
|
||||
|
||||
// go to the lower of the two rows, it is technically the duplicate:
|
||||
m_cur_grid->SetGridCursor( r2, 0 );
|
||||
m_cur_grid->SelectBlock( r2, 0, r2, 0 );
|
||||
m_cur_grid->MakeCellVisible( r2, 0 );
|
||||
|
||||
wxMessageDialog errdlg( this, msg, _( "Please Delete or Modify One" ) );
|
||||
errdlg.ShowModal();
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
//-----<event handlers>----------------------------------
|
||||
|
||||
void onKeyDown( wxKeyEvent& ev )
|
||||
{
|
||||
#if 0
|
||||
// send the key to the current grid
|
||||
((wxEvtHandler*)m_cur_grid)->ProcessEvent( ev );
|
||||
#else
|
||||
// or no:
|
||||
// m_cur_grid has the focus most of the time anyways, so above not needed.
|
||||
ev.Skip();
|
||||
#endif
|
||||
}
|
||||
|
||||
void pageChangedHandler( wxAuiNotebookEvent& event )
|
||||
{
|
||||
int pageNdx = m_auinotebook->GetSelection();
|
||||
m_cur_grid = ( pageNdx == 0 ) ? m_global_grid : m_project_grid;
|
||||
}
|
||||
|
||||
void appendRowHandler( wxMouseEvent& event )
|
||||
{
|
||||
if( m_cur_grid->AppendRows( 1 ) )
|
||||
{
|
||||
int last_row = m_cur_grid->GetNumberRows() - 1;
|
||||
|
||||
m_cur_grid->MakeCellVisible( last_row, 0 );
|
||||
m_cur_grid->SetGridCursor( last_row, 0 );
|
||||
}
|
||||
}
|
||||
|
||||
void deleteRowHandler( wxMouseEvent& event )
|
||||
{
|
||||
int rowCount = m_cur_grid->GetNumberRows();
|
||||
int curRow = getCursorRow();
|
||||
|
||||
m_cur_grid->DeleteRows( curRow );
|
||||
|
||||
if( curRow && curRow == rowCount - 1 )
|
||||
m_cur_grid->SetGridCursor( curRow-1, getCursorCol() );
|
||||
}
|
||||
|
||||
void moveUpHandler( wxMouseEvent& event )
|
||||
{
|
||||
int curRow = getCursorRow();
|
||||
if( curRow >= 1 )
|
||||
{
|
||||
int curCol = getCursorCol();
|
||||
|
||||
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 = getCursorRow();
|
||||
if( unsigned( curRow + 1 ) < tbl->rows.size() )
|
||||
{
|
||||
int curCol = getCursorCol();
|
||||
|
||||
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 );
|
||||
}
|
||||
DBG(printf("%s\n", __func__);)
|
||||
}
|
||||
|
||||
void optionsEditor( wxMouseEvent& event )
|
||||
{
|
||||
FP_TBL_MODEL* tbl = (FP_TBL_MODEL*) m_cur_grid->GetTable();
|
||||
|
||||
int curRow = getCursorRow();
|
||||
ROW& row = tbl->rows[curRow];
|
||||
|
||||
wxString result;
|
||||
const wxString& options = row.GetOptions();
|
||||
|
||||
InvokePluginOptionsEditor( this, row.GetNickName(), options, &result );
|
||||
|
||||
if( options != result )
|
||||
{
|
||||
row.SetOptions( result );
|
||||
m_cur_grid->AutoSizeColumn( COL_OPTIONS, false );
|
||||
}
|
||||
}
|
||||
|
||||
void onCancelButtonClick( wxCommandEvent& event )
|
||||
{
|
||||
EndModal( 0 );
|
||||
}
|
||||
|
||||
void onCancelButtonClick( wxCloseEvent& event )
|
||||
{
|
||||
EndModal( 0 );
|
||||
}
|
||||
|
||||
void onOKButtonClick( wxCommandEvent& event )
|
||||
{
|
||||
int dialogRet = 0;
|
||||
|
||||
// stuff any pending cell editor text into the table.
|
||||
m_cur_grid->SaveEditControlValue();
|
||||
|
||||
if( verifyTables() )
|
||||
{
|
||||
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 );
|
||||
}
|
||||
}
|
||||
|
||||
/// Populate the readonly environment variable table with names and values
|
||||
/// by examining all the full_uri columns.
|
||||
void populateEnvironReadOnlyTable()
|
||||
{
|
||||
wxRegEx re( wxT( ".*?\\$\\{(.+?)\\}.*?" ), wxRE_ADVANCED );
|
||||
wxASSERT( re.IsValid() ); // wxRE_ADVANCED is required.
|
||||
|
||||
std::set< wxString > unique;
|
||||
typedef std::set<wxString>::const_iterator SET_CITER;
|
||||
|
||||
// clear the table
|
||||
m_path_subs_grid->DeleteRows( 0, m_path_subs_grid->GetNumberRows() );
|
||||
|
||||
int gblRowCount = m_global_model.GetNumberRows();
|
||||
int prjRowCount = m_project_model.GetNumberRows();
|
||||
int row;
|
||||
|
||||
for( row = 0; row < gblRowCount; ++row )
|
||||
{
|
||||
wxString uri = m_global_model.GetValue( row, COL_URI );
|
||||
|
||||
while( re.Matches( uri ) )
|
||||
{
|
||||
wxString envvar = re.GetMatch( uri, 1 );
|
||||
|
||||
// ignore duplicates
|
||||
unique.insert( envvar );
|
||||
|
||||
// delete the last match and search again
|
||||
uri.Replace( re.GetMatch( uri, 0 ), wxEmptyString );
|
||||
}
|
||||
}
|
||||
|
||||
for( row = 0; row < prjRowCount; ++row )
|
||||
{
|
||||
wxString uri = m_project_model.GetValue( row, COL_URI );
|
||||
|
||||
while( re.Matches( uri ) )
|
||||
{
|
||||
wxString envvar = re.GetMatch( uri, 1 );
|
||||
|
||||
// ignore duplicates
|
||||
unique.insert( envvar );
|
||||
|
||||
// delete the last match and search again
|
||||
uri.Replace( re.GetMatch( uri, 0 ), wxEmptyString );
|
||||
}
|
||||
}
|
||||
|
||||
m_path_subs_grid->AppendRows( unique.size() );
|
||||
|
||||
row = 0;
|
||||
for( SET_CITER it = unique.begin(); it != unique.end(); ++it, ++row )
|
||||
{
|
||||
wxString evName = *it;
|
||||
wxString evValue;
|
||||
|
||||
m_path_subs_grid->SetCellValue( row, 0, evName );
|
||||
|
||||
if( wxGetEnv( evName, &evValue ) )
|
||||
m_path_subs_grid->SetCellValue( row, 1, evValue );
|
||||
}
|
||||
|
||||
m_path_subs_grid->AutoSizeColumns();
|
||||
}
|
||||
|
||||
//-----</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( wxTopLevelWindow* 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_project( aProject )
|
||||
{
|
||||
m_global_grid->SetTable( (wxGridTableBase*) &m_global_model );
|
||||
m_project_grid->SetTable( (wxGridTableBase*) &m_project_model );
|
||||
// wxGrid only supports user owned tables if they exist past end of ~wxGrid(),
|
||||
// so make it a grid owned table.
|
||||
m_global_grid->SetTable( new FP_TBL_MODEL( *aGlobal ), true );
|
||||
m_project_grid->SetTable( new FP_TBL_MODEL( *aProject ), true );
|
||||
|
||||
// add Cut, Copy, and Paste to wxGrids
|
||||
m_global_grid->PushEventHandler( new FP_GRID_TRICKS( m_global_grid ) );
|
||||
|
@ -703,13 +351,366 @@ public:
|
|||
// Any additional event handlers should be popped before the window is deleted.
|
||||
m_global_grid->PopEventHandler( true );
|
||||
m_project_grid->PopEventHandler( true );
|
||||
|
||||
// ~wxGrid() examines its table, and the tables will have been destroyed before
|
||||
// the wxGrids are, so remove the tables from the wxGrids' awareness.
|
||||
// Otherwise there is a segfault.
|
||||
m_global_grid->SetTable( NULL );
|
||||
m_project_grid->SetTable( NULL );
|
||||
}
|
||||
|
||||
|
||||
private:
|
||||
typedef FP_LIB_TABLE::ROW ROW;
|
||||
|
||||
/// If the cursor is not on a valid cell, because there are no rows at all, return -1,
|
||||
/// else return a 0 based column index.
|
||||
int getCursorCol() const
|
||||
{
|
||||
return m_cur_grid->GetGridCursorCol();
|
||||
}
|
||||
|
||||
/// If the cursor is not on a valid cell, because there are no rows at all, return -1,
|
||||
/// else return a 0 based row index.
|
||||
int getCursorRow() const
|
||||
{
|
||||
return m_cur_grid->GetGridCursorRow();
|
||||
}
|
||||
|
||||
/**
|
||||
* Function verifyTables
|
||||
* trims important fields, removes blank row entries, and checks for duplicates.
|
||||
* @return bool - true if tables are OK, else false.
|
||||
*/
|
||||
bool verifyTables()
|
||||
{
|
||||
for( int t=0; t<2; ++t )
|
||||
{
|
||||
FP_TBL_MODEL& model = t==0 ? *global_model() : *project_model();
|
||||
|
||||
for( int r = 0; r < model.GetNumberRows(); )
|
||||
{
|
||||
wxString nick = model.GetValue( r, COL_NICKNAME ).Trim( false ).Trim();
|
||||
wxString uri = model.GetValue( r, COL_URI ).Trim( false ).Trim();
|
||||
|
||||
if( !nick || !uri )
|
||||
{
|
||||
// Delete the "empty" row, where empty means missing nick or uri.
|
||||
// This also updates the UI which could be slow, but there should only be a few
|
||||
// rows to delete, unless the user fell asleep on the Add Row
|
||||
// button.
|
||||
model.DeleteRows( r, 1 );
|
||||
}
|
||||
else if( nick.find(':') != size_t(-1) )
|
||||
{
|
||||
wxString msg = wxString::Format(
|
||||
_( "Illegal character '%s' found in Nickname: '%s' in row %d" ),
|
||||
wxT( ":" ), GetChars( nick ), r );
|
||||
|
||||
// show the tabbed panel holding the grid we have flunked:
|
||||
if( &model != cur_model() )
|
||||
{
|
||||
m_auinotebook->SetSelection( &model == global_model() ? 0 : 1 );
|
||||
}
|
||||
|
||||
// go to the problematic row
|
||||
m_cur_grid->SetGridCursor( r, 0 );
|
||||
m_cur_grid->SelectBlock( r, 0, r, 0 );
|
||||
m_cur_grid->MakeCellVisible( r, 0 );
|
||||
|
||||
wxMessageDialog errdlg( this, msg, _( "No Colon in Nicknames" ) );
|
||||
errdlg.ShowModal();
|
||||
return false;
|
||||
}
|
||||
else
|
||||
{
|
||||
// set the trimmed values back into the table so they get saved to disk.
|
||||
model.SetValue( r, COL_NICKNAME, nick );
|
||||
model.SetValue( r, COL_URI, uri );
|
||||
++r; // this row was OK.
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// check for duplicate nickNames, separately in each table.
|
||||
for( int t=0; t<2; ++t )
|
||||
{
|
||||
FP_TBL_MODEL& model = t==0 ? *global_model() : *project_model();
|
||||
|
||||
for( int r1 = 0; r1 < model.GetNumberRows() - 1; ++r1 )
|
||||
{
|
||||
wxString nick1 = model.GetValue( r1, COL_NICKNAME );
|
||||
|
||||
for( int r2=r1+1; r2 < model.GetNumberRows(); ++r2 )
|
||||
{
|
||||
wxString nick2 = model.GetValue( r2, COL_NICKNAME );
|
||||
|
||||
if( nick1 == nick2 )
|
||||
{
|
||||
wxString msg = wxString::Format(
|
||||
_( "Duplicate Nickname: '%s' in rows %d and %d" ),
|
||||
GetChars( nick1 ), r1+1, r2+1
|
||||
);
|
||||
|
||||
// show the tabbed panel holding the grid we have flunked:
|
||||
if( &model != cur_model() )
|
||||
{
|
||||
m_auinotebook->SetSelection( &model == global_model() ? 0 : 1 );
|
||||
}
|
||||
|
||||
// go to the lower of the two rows, it is technically the duplicate:
|
||||
m_cur_grid->SetGridCursor( r2, 0 );
|
||||
m_cur_grid->SelectBlock( r2, 0, r2, 0 );
|
||||
m_cur_grid->MakeCellVisible( r2, 0 );
|
||||
|
||||
wxMessageDialog errdlg( this, msg, _( "Please Delete or Modify One" ) );
|
||||
errdlg.ShowModal();
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
//-----<event handlers>----------------------------------
|
||||
|
||||
void onKeyDown( wxKeyEvent& ev )
|
||||
{
|
||||
#if 0
|
||||
// send the key to the current grid
|
||||
((wxEvtHandler*)m_cur_grid)->ProcessEvent( ev );
|
||||
#else
|
||||
// or no:
|
||||
// m_cur_grid has the focus most of the time anyways, so above not needed.
|
||||
ev.Skip();
|
||||
#endif
|
||||
}
|
||||
|
||||
void pageChangedHandler( wxAuiNotebookEvent& event )
|
||||
{
|
||||
int pageNdx = m_auinotebook->GetSelection();
|
||||
m_cur_grid = ( pageNdx == 0 ) ? m_global_grid : m_project_grid;
|
||||
}
|
||||
|
||||
void appendRowHandler( wxMouseEvent& event )
|
||||
{
|
||||
if( m_cur_grid->AppendRows( 1 ) )
|
||||
{
|
||||
int last_row = m_cur_grid->GetNumberRows() - 1;
|
||||
|
||||
// wx documentation is wrong, SetGridCursor does not make visible.
|
||||
m_cur_grid->MakeCellVisible( last_row, 0 );
|
||||
m_cur_grid->SetGridCursor( last_row, 0 );
|
||||
}
|
||||
}
|
||||
|
||||
void deleteRowHandler( wxMouseEvent& event )
|
||||
{
|
||||
int rowCount = m_cur_grid->GetNumberRows();
|
||||
int curRow = getCursorRow();
|
||||
|
||||
m_cur_grid->DeleteRows( curRow );
|
||||
|
||||
if( curRow && curRow == rowCount - 1 )
|
||||
m_cur_grid->SetGridCursor( curRow-1, getCursorCol() );
|
||||
}
|
||||
|
||||
void moveUpHandler( wxMouseEvent& event )
|
||||
{
|
||||
int curRow = getCursorRow();
|
||||
if( curRow >= 1 )
|
||||
{
|
||||
int curCol = getCursorCol();
|
||||
|
||||
FP_TBL_MODEL* tbl = cur_model();
|
||||
|
||||
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->MakeCellVisible( curRow, curCol );
|
||||
m_cur_grid->SetGridCursor( curRow, curCol );
|
||||
}
|
||||
}
|
||||
|
||||
void moveDownHandler( wxMouseEvent& event )
|
||||
{
|
||||
FP_TBL_MODEL* tbl = cur_model();
|
||||
|
||||
int curRow = getCursorRow();
|
||||
if( unsigned( curRow + 1 ) < tbl->rows.size() )
|
||||
{
|
||||
int curCol = getCursorCol();
|
||||
|
||||
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->MakeCellVisible( curRow, curCol );
|
||||
m_cur_grid->SetGridCursor( curRow, curCol );
|
||||
}
|
||||
}
|
||||
|
||||
void optionsEditor( wxMouseEvent& event )
|
||||
{
|
||||
FP_TBL_MODEL* tbl = cur_model();
|
||||
|
||||
int curRow = getCursorRow();
|
||||
ROW& row = tbl->rows[curRow];
|
||||
|
||||
wxString result;
|
||||
const wxString& options = row.GetOptions();
|
||||
|
||||
InvokePluginOptionsEditor( this, row.GetNickName(), options, &result );
|
||||
|
||||
if( options != result )
|
||||
{
|
||||
row.SetOptions( result );
|
||||
m_cur_grid->AutoSizeColumn( COL_OPTIONS, false );
|
||||
}
|
||||
}
|
||||
|
||||
void onCancelButtonClick( wxCommandEvent& event )
|
||||
{
|
||||
EndModal( 0 );
|
||||
}
|
||||
|
||||
void onCancelButtonClick( wxCloseEvent& event )
|
||||
{
|
||||
EndModal( 0 );
|
||||
}
|
||||
|
||||
void onOKButtonClick( wxCommandEvent& event )
|
||||
{
|
||||
int dialogRet = 0;
|
||||
|
||||
// stuff any pending cell editor text into the table.
|
||||
m_cur_grid->SaveEditControlValue();
|
||||
|
||||
if( verifyTables() )
|
||||
{
|
||||
if( *global_model() != *m_global )
|
||||
{
|
||||
dialogRet |= 1;
|
||||
|
||||
*m_global = *global_model();
|
||||
m_global->reindex();
|
||||
}
|
||||
|
||||
if( *project_model() != *m_project )
|
||||
{
|
||||
dialogRet |= 2;
|
||||
|
||||
*m_project = *project_model();
|
||||
m_project->reindex();
|
||||
}
|
||||
|
||||
EndModal( dialogRet );
|
||||
}
|
||||
}
|
||||
|
||||
/// Populate the readonly environment variable table with names and values
|
||||
/// by examining all the full_uri columns.
|
||||
void populateEnvironReadOnlyTable()
|
||||
{
|
||||
wxRegEx re( wxT( ".*?\\$\\{(.+?)\\}.*?" ), wxRE_ADVANCED );
|
||||
wxASSERT( re.IsValid() ); // wxRE_ADVANCED is required.
|
||||
|
||||
std::set< wxString > unique;
|
||||
typedef std::set<wxString>::const_iterator SET_CITER;
|
||||
|
||||
// clear the table
|
||||
m_path_subs_grid->DeleteRows( 0, m_path_subs_grid->GetNumberRows() );
|
||||
|
||||
FP_TBL_MODEL* gbl = global_model();
|
||||
FP_TBL_MODEL* prj = project_model();
|
||||
|
||||
int gblRowCount = gbl->GetNumberRows();
|
||||
int prjRowCount = prj->GetNumberRows();
|
||||
int row;
|
||||
|
||||
for( row = 0; row < gblRowCount; ++row )
|
||||
{
|
||||
wxString uri = gbl->GetValue( row, COL_URI );
|
||||
|
||||
while( re.Matches( uri ) )
|
||||
{
|
||||
wxString envvar = re.GetMatch( uri, 1 );
|
||||
|
||||
// ignore duplicates
|
||||
unique.insert( envvar );
|
||||
|
||||
// delete the last match and search again
|
||||
uri.Replace( re.GetMatch( uri, 0 ), wxEmptyString );
|
||||
}
|
||||
}
|
||||
|
||||
for( row = 0; row < prjRowCount; ++row )
|
||||
{
|
||||
wxString uri = prj->GetValue( row, COL_URI );
|
||||
|
||||
while( re.Matches( uri ) )
|
||||
{
|
||||
wxString envvar = re.GetMatch( uri, 1 );
|
||||
|
||||
// ignore duplicates
|
||||
unique.insert( envvar );
|
||||
|
||||
// delete the last match and search again
|
||||
uri.Replace( re.GetMatch( uri, 0 ), wxEmptyString );
|
||||
}
|
||||
}
|
||||
|
||||
m_path_subs_grid->AppendRows( unique.size() );
|
||||
|
||||
row = 0;
|
||||
for( SET_CITER it = unique.begin(); it != unique.end(); ++it, ++row )
|
||||
{
|
||||
wxString evName = *it;
|
||||
wxString evValue;
|
||||
|
||||
m_path_subs_grid->SetCellValue( row, 0, evName );
|
||||
|
||||
if( wxGetEnv( evName, &evValue ) )
|
||||
m_path_subs_grid->SetCellValue( row, 1, evValue );
|
||||
}
|
||||
|
||||
m_path_subs_grid->AutoSizeColumns();
|
||||
}
|
||||
|
||||
//-----</event handlers>---------------------------------
|
||||
|
||||
// caller's tables are modified only on OK button and successful verification.
|
||||
FP_LIB_TABLE* m_global;
|
||||
FP_LIB_TABLE* m_project;
|
||||
|
||||
FP_TBL_MODEL* global_model() const { return (FP_TBL_MODEL*) m_global_grid->GetTable(); }
|
||||
FP_TBL_MODEL* project_model() const { return (FP_TBL_MODEL*) m_project_grid->GetTable(); }
|
||||
FP_TBL_MODEL* cur_model() const { return (FP_TBL_MODEL*) m_cur_grid->GetTable(); }
|
||||
|
||||
wxGrid* m_cur_grid; ///< changed based on tab choice
|
||||
};
|
||||
|
||||
|
||||
|
|
|
@ -24,6 +24,7 @@
|
|||
*/
|
||||
|
||||
|
||||
#include <fctsys.h>
|
||||
#include <invoke_pcb_dialog.h>
|
||||
#include <dialog_fp_plugin_options_base.h>
|
||||
#include <fp_lib_table.h>
|
||||
|
@ -36,6 +37,12 @@ static int col_width_option;
|
|||
static int col_width_value;
|
||||
|
||||
|
||||
/**
|
||||
* Class DIALOG_FP_PLUGIN_OPTIONS
|
||||
* is an options editor in the form of a two column name/value
|
||||
* spreadsheet like (table) UI. It takes hints from a pcbnew PLUGIN as to
|
||||
* supported options.
|
||||
*/
|
||||
class DIALOG_FP_PLUGIN_OPTIONS : public DIALOG_FP_PLUGIN_OPTIONS_BASE
|
||||
{
|
||||
|
||||
|
@ -60,7 +67,7 @@ public:
|
|||
|
||||
if( props )
|
||||
{
|
||||
if( props->size() > m_grid->GetNumberRows() )
|
||||
if( (int) props->size() > m_grid->GetNumberRows() )
|
||||
m_grid->AppendRows( props->size() - m_grid->GetNumberRows() );
|
||||
|
||||
int row = 0;
|
||||
|
@ -98,6 +105,42 @@ private:
|
|||
const wxString& m_callers_options;
|
||||
wxString* m_result;
|
||||
|
||||
/// If the cursor is not on a valid cell, because there are no rows at all, return -1,
|
||||
/// else return a 0 based column index.
|
||||
int getCursorCol() const
|
||||
{
|
||||
return m_grid->GetGridCursorCol();
|
||||
}
|
||||
|
||||
/// If the cursor is not on a valid cell, because there are no rows at all, return -1,
|
||||
/// else return a 0 based row index.
|
||||
int getCursorRow() const
|
||||
{
|
||||
return m_grid->GetGridCursorRow();
|
||||
}
|
||||
|
||||
wxArrayString getRow( int aRow )
|
||||
{
|
||||
wxArrayString row;
|
||||
|
||||
const int col_count = m_grid->GetNumberCols();
|
||||
for( int col = 0; col < col_count; ++col )
|
||||
{
|
||||
row.Add( m_grid->GetCellValue( aRow, col ) );
|
||||
}
|
||||
|
||||
return row;
|
||||
}
|
||||
|
||||
void setRow( int aRow, const wxArrayString& aPair )
|
||||
{
|
||||
const int col_count = m_grid->GetNumberCols();
|
||||
for( int col = 0; col < col_count; ++col )
|
||||
{
|
||||
m_grid->SetCellValue( aRow, col, aPair[col] );
|
||||
}
|
||||
}
|
||||
|
||||
wxString makeResult()
|
||||
{
|
||||
PROPERTIES props;
|
||||
|
@ -133,21 +176,98 @@ private:
|
|||
EndModal( 0 );
|
||||
}
|
||||
|
||||
|
||||
|
||||
//-----<event handlers>------------------------------------------------------
|
||||
void onAddRow( wxCommandEvent& event )
|
||||
{
|
||||
if( m_grid->AppendRows( 1 ) )
|
||||
{
|
||||
int last_row = m_grid->GetNumberRows() - 1;
|
||||
|
||||
// wx documentation is wrong, SetGridCursor does not make visible.
|
||||
m_grid->MakeCellVisible( last_row, 0 );
|
||||
m_grid->SetGridCursor( last_row, 0 );
|
||||
}
|
||||
}
|
||||
|
||||
void onDeleteRow( wxCommandEvent& event )
|
||||
{
|
||||
int rowCount = m_grid->GetNumberRows();
|
||||
int curRow = getCursorRow();
|
||||
|
||||
m_grid->DeleteRows( curRow );
|
||||
|
||||
if( curRow && curRow == rowCount - 1 )
|
||||
{
|
||||
m_grid->MakeCellVisible( curRow-1, getCursorCol() );
|
||||
m_grid->SetGridCursor( curRow-1, getCursorCol() );
|
||||
}
|
||||
}
|
||||
|
||||
void onMoveUp( wxCommandEvent& event )
|
||||
{
|
||||
int curRow = getCursorRow();
|
||||
if( curRow >= 1 )
|
||||
{
|
||||
int curCol = getCursorCol();
|
||||
|
||||
wxArrayString move_me = getRow( curRow );
|
||||
|
||||
m_grid->DeleteRows( curRow );
|
||||
--curRow;
|
||||
m_grid->InsertRows( curRow );
|
||||
|
||||
setRow( curRow, move_me );
|
||||
|
||||
wxGridTableBase* tbl = m_grid->GetTable();
|
||||
|
||||
if( tbl->GetView() )
|
||||
{
|
||||
// fire a msg to cause redrawing
|
||||
wxGridTableMessage msg( tbl,
|
||||
wxGRIDTABLE_NOTIFY_ROWS_INSERTED,
|
||||
curRow,
|
||||
0 );
|
||||
|
||||
tbl->GetView()->ProcessTableMessage( msg );
|
||||
}
|
||||
|
||||
m_grid->MakeCellVisible( curRow, curCol );
|
||||
m_grid->SetGridCursor( curRow, curCol );
|
||||
}
|
||||
}
|
||||
|
||||
void onMoveDown( wxCommandEvent& event )
|
||||
{
|
||||
int curRow = getCursorRow();
|
||||
if( curRow + 1 < m_grid->GetNumberRows() )
|
||||
{
|
||||
int curCol = getCursorCol();
|
||||
|
||||
wxArrayString move_me = getRow( curRow );
|
||||
|
||||
m_grid->DeleteRows( curRow );
|
||||
++curRow;
|
||||
m_grid->InsertRows( curRow );
|
||||
setRow( curRow, move_me );
|
||||
|
||||
wxGridTableBase* tbl = m_grid->GetTable();
|
||||
|
||||
if( tbl->GetView() )
|
||||
{
|
||||
// fire a msg to cause redrawing
|
||||
wxGridTableMessage msg( tbl,
|
||||
wxGRIDTABLE_NOTIFY_ROWS_INSERTED,
|
||||
curRow - 1,
|
||||
0 );
|
||||
|
||||
tbl->GetView()->ProcessTableMessage( msg );
|
||||
}
|
||||
|
||||
m_grid->MakeCellVisible( curRow, curCol );
|
||||
m_grid->SetGridCursor( curRow, curCol );
|
||||
}
|
||||
}
|
||||
|
||||
void onCancelButtonClick( wxCommandEvent& event )
|
||||
|
|
Loading…
Reference in New Issue