diff --git a/common/grid_tricks.cpp b/common/grid_tricks.cpp index fa41157b55..c690bfe43c 100644 --- a/common/grid_tricks.cpp +++ b/common/grid_tricks.cpp @@ -27,6 +27,7 @@ #include #include #include +#include // It works for table data on clipboard for an Excell spreadsheet, @@ -98,7 +99,7 @@ bool GRID_TRICKS::showEditor( int aRow, int aCol ) { if( m_grid->IsEditable() && !m_grid->IsReadOnly( aRow, aCol ) ) { - if( m_grid->GetSelectionMode() == wxGrid::wxGridSelectionModes::wxGridSelectRows ) + if( m_grid->GetSelectionMode() == wxGrid::wxGridSelectRows ) m_grid->SelectRow( aRow ); m_grid->SetGridCursor( aRow, aCol ); @@ -151,8 +152,20 @@ void GRID_TRICKS::onMouseUp( wxMouseEvent& aEvent ) // it sometimes fails. Activating the control here seems to avoid those issues. if( m_grid->CanEnableCellControl() ) { + // Yes, the first of these also shows the control. Well, at least sometimes. + // The second call corrects those (as yet undefined) "other times". m_grid->EnableCellEditControl(); m_grid->ShowCellEditControl(); + + // Yet another wxWidgets hack: setting the control to readonly results in the + // selection not getting shown. Set it again in the hopes it will get rendered. + wxGridCellEditor* editor = m_grid->GetCellEditor( m_grid->GetCursorRow(), m_grid->GetCursorColumn() ); + auto readonly = dynamic_cast( editor ); + if( readonly ) + { + readonly->GetControl()->Refresh(); + } + editor->DecRef(); } m_showEditorOnMouseUp = false; } @@ -443,7 +456,7 @@ void GRID_TRICKS::onUpdateUI( wxUpdateUIEvent& event ) { // Respect ROW selectionMode when moving cursor - if( m_grid->GetSelectionMode() == wxGrid::wxGridSelectionModes::wxGridSelectRows ) + if( m_grid->GetSelectionMode() == wxGrid::wxGridSelectRows ) { int cursorRow = m_grid->GetGridCursorRow(); bool cursorInSelectedRow = false; diff --git a/eeschema/dialogs/panel_sym_lib_table.cpp b/eeschema/dialogs/panel_sym_lib_table.cpp index 5996de656a..0bf6dd2670 100644 --- a/eeschema/dialogs/panel_sym_lib_table.cpp +++ b/eeschema/dialogs/panel_sym_lib_table.cpp @@ -37,6 +37,7 @@ #include #include #include +#include /** * Build a wxGridTableBase by wrapping an #SYMBOL_LIB_TABLE object. @@ -162,15 +163,16 @@ PANEL_SYM_LIB_TABLE::PANEL_SYM_LIB_TABLE( DIALOG_EDIT_LIBRARY_TABLES* aParent, m_project_grid->SetTable( new SYMBOL_LIB_TABLE_GRID( *aProject ), true ); // Give a bit more room for combobox editors - m_global_grid->SetDefaultRowSize( m_global_grid->GetDefaultRowSize() + 4 ); - m_project_grid->SetDefaultRowSize( m_project_grid->GetDefaultRowSize() + 4 ); + m_global_grid->SetDefaultRowSize( m_global_grid->GetDefaultRowSize() + 2 ); + m_project_grid->SetDefaultRowSize( m_project_grid->GetDefaultRowSize() + 2 ); // add Cut, Copy, and Paste to wxGrids m_global_grid->PushEventHandler( new SYMBOL_GRID_TRICKS( m_parent, m_global_grid ) ); m_project_grid->PushEventHandler( new SYMBOL_GRID_TRICKS( m_parent, m_project_grid ) ); + m_path_subs_grid->PushEventHandler( new GRID_TRICKS( m_path_subs_grid ) ); - m_global_grid->SetSelectionMode( wxGrid::wxGridSelectionModes::wxGridSelectRows ); - m_project_grid->SetSelectionMode( wxGrid::wxGridSelectionModes::wxGridSelectRows ); + m_global_grid->SetSelectionMode( wxGrid::wxGridSelectRows ); + m_project_grid->SetSelectionMode( wxGrid::wxGridSelectRows ); m_global_grid->AutoSizeColumns( false ); m_project_grid->AutoSizeColumns( false ); @@ -182,10 +184,8 @@ PANEL_SYM_LIB_TABLE::PANEL_SYM_LIB_TABLE( DIALOG_EDIT_LIBRARY_TABLES* aParent, populateEnvironReadOnlyTable(); - for( int i=0; i<2; ++i ) + for( wxGrid* g : { m_global_grid, m_project_grid } ) { - wxGrid* g = i==0 ? m_global_grid : m_project_grid; - // Set special attributes wxGridCellAttr* attr; @@ -244,19 +244,18 @@ PANEL_SYM_LIB_TABLE::~PANEL_SYM_LIB_TABLE() // Any additional event handlers should be popped before the window is deleted. m_global_grid->PopEventHandler( true ); m_project_grid->PopEventHandler( true ); + m_path_subs_grid->PopEventHandler( true ); } bool PANEL_SYM_LIB_TABLE::verifyTables() { - for( int t=0; t<2; ++t ) + for( SYMBOL_LIB_TABLE_GRID* model : { global_model(), project_model() } ) { - SYMBOL_LIB_TABLE_GRID& model = t==0 ? *global_model() : *project_model(); - - for( int r = 0; r < model.GetNumberRows(); ) + for( int r = 0; r < model->GetNumberRows(); ) { - wxString nick = model.GetValue( r, COL_NICKNAME ).Trim( false ).Trim(); - wxString uri = model.GetValue( r, COL_URI ).Trim( false ).Trim(); + wxString nick = model->GetValue( r, COL_NICKNAME ).Trim( false ).Trim(); + wxString uri = model->GetValue( r, COL_URI ).Trim( false ).Trim(); unsigned illegalCh = 0; if( !nick || !uri ) @@ -265,7 +264,7 @@ bool PANEL_SYM_LIB_TABLE::verifyTables() // 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 ); + model->DeleteRows( r, 1 ); } else if( ( illegalCh = LIB_ID::FindIllegalLibNicknameChar( nick, LIB_ID::ID_SCH ) ) ) { @@ -274,8 +273,8 @@ bool PANEL_SYM_LIB_TABLE::verifyTables() nick ); // show the tabbed panel holding the grid we have flunked: - if( &model != cur_model() ) - m_auinotebook->SetSelection( &model == global_model() ? 0 : 1 ); + if( model != cur_model() ) + m_auinotebook->SetSelection( model == global_model() ? 0 : 1 ); m_cur_grid->MakeCellVisible( r, 0 ); m_cur_grid->SetGridCursor( r, 1 ); @@ -287,33 +286,31 @@ bool PANEL_SYM_LIB_TABLE::verifyTables() else { // set the trimmed values back into the table so they get saved to disk. - model.SetValue( r, COL_NICKNAME, nick ); - model.SetValue( r, COL_URI, uri ); + model->SetValue( r, COL_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 ) + for( SYMBOL_LIB_TABLE_GRID* model : { global_model(), project_model() } ) { - SYMBOL_LIB_TABLE_GRID& model = t==0 ? *global_model() : *project_model(); - - for( int r1 = 0; r1 < model.GetNumberRows() - 1; ++r1 ) + for( int r1 = 0; r1 < model->GetNumberRows() - 1; ++r1 ) { - wxString nick1 = model.GetValue( r1, COL_NICKNAME ); + wxString nick1 = model->GetValue( r1, COL_NICKNAME ); - for( int r2=r1+1; r2 < model.GetNumberRows(); ++r2 ) + for( int r2=r1+1; r2 < model->GetNumberRows(); ++r2 ) { - wxString nick2 = model.GetValue( r2, COL_NICKNAME ); + wxString nick2 = model->GetValue( r2, COL_NICKNAME ); if( nick1 == nick2 ) { wxString msg = wxString::Format( _( "Duplicate Nickname: \"%s\"." ), nick1 ); // show the tabbed panel holding the grid we have flunked: - if( &model != cur_model() ) - m_auinotebook->SetSelection( &model == global_model() ? 0 : 1 ); + 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->MakeCellVisible( r2, 0 ); @@ -604,10 +601,8 @@ void PANEL_SYM_LIB_TABLE::populateEnvironReadOnlyTable() // clear the table m_path_subs_grid->DeleteRows( 0, m_path_subs_grid->GetNumberRows() ); - for( int i = 0; i < 2; ++i ) + for( SYMBOL_LIB_TABLE_GRID* tbl : { global_model(), project_model() } ) { - SYMBOL_LIB_TABLE_GRID* tbl = i == 0 ? global_model() : project_model(); - for( int row = 0; row < tbl->GetNumberRows(); ++row ) { wxString uri = tbl->GetValue( row, COL_URI ); @@ -641,15 +636,17 @@ void PANEL_SYM_LIB_TABLE::populateEnvironReadOnlyTable() m_path_subs_grid->AppendRows( 1 ); m_path_subs_grid->SetCellValue( row, 0, wxT( "${" ) + evName + wxT( "}" ) ); + m_path_subs_grid->SetCellEditor( row, 0, new GRID_CELL_READONLY_TEXT_EDITOR() ); wxString evValue; wxGetEnv( evName, &evValue ); m_path_subs_grid->SetCellValue( row, 1, evValue ); + m_path_subs_grid->SetCellEditor( row, 1, new GRID_CELL_READONLY_TEXT_EDITOR() ); } // No combobox editors here, but it looks better if its consistent with the other // grids in the dialog. - m_path_subs_grid->SetDefaultRowSize( m_path_subs_grid->GetDefaultRowSize() + 4 ); + m_path_subs_grid->SetDefaultRowSize( m_path_subs_grid->GetDefaultRowSize() + 2 ); adjustPathSubsGridColumns( m_path_subs_grid->GetRect().GetWidth() ); } diff --git a/eeschema/dialogs/panel_sym_lib_table_base.cpp b/eeschema/dialogs/panel_sym_lib_table_base.cpp index a833024593..deef93714b 100644 --- a/eeschema/dialogs/panel_sym_lib_table_base.cpp +++ b/eeschema/dialogs/panel_sym_lib_table_base.cpp @@ -164,7 +164,7 @@ PANEL_SYM_LIB_TABLE_BASE::PANEL_SYM_LIB_TABLE_BASE( wxWindow* parent, wxWindowID // Grid m_path_subs_grid->CreateGrid( 1, 2 ); - m_path_subs_grid->EnableEditing( false ); + 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 ); diff --git a/eeschema/dialogs/panel_sym_lib_table_base.fbp b/eeschema/dialogs/panel_sym_lib_table_base.fbp index 54d52db6ae..a8dfa4dc60 100644 --- a/eeschema/dialogs/panel_sym_lib_table_base.fbp +++ b/eeschema/dialogs/panel_sym_lib_table_base.fbp @@ -1557,7 +1557,7 @@ 1 0 1 - 0 + 1 1 1 diff --git a/include/widgets/grid_readonly_text_helpers.h b/include/widgets/grid_readonly_text_helpers.h new file mode 100644 index 0000000000..fde5975996 --- /dev/null +++ b/include/widgets/grid_readonly_text_helpers.h @@ -0,0 +1,50 @@ +/* + * This program source code file is part of KiCad, a free EDA CAD application. + * + * Copyright (C) 2018 KiCad Developers, see AUTHORS.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 GRID_READONLY_TEXT_HELPERS_H +#define GRID_READONLY_TEXT_HELPERS_H + +#include +#include +#include + + +class GRID_CELL_READONLY_TEXT_EDITOR : public wxGridCellTextEditor +{ +public: + GRID_CELL_READONLY_TEXT_EDITOR() {}; + + void Create(wxWindow* parent, wxWindowID id, wxEvtHandler* evtHandler) + { + DoCreate(parent, id, evtHandler); + Text()->SetEditable( false ); + } + +wxDECLARE_NO_COPY_CLASS( GRID_CELL_READONLY_TEXT_EDITOR ); +}; + + + + + +#endif // GRID_READONLY_TEXT_HELPERS_H diff --git a/pcbnew/dialogs/panel_fp_lib_table.cpp b/pcbnew/dialogs/panel_fp_lib_table.cpp index 2d716cb0e9..34cffed134 100644 --- a/pcbnew/dialogs/panel_fp_lib_table.cpp +++ b/pcbnew/dialogs/panel_fp_lib_table.cpp @@ -57,6 +57,7 @@ #include #include #include +#include // Filters for the file picker static constexpr int FILTER_COUNT = 4; @@ -280,16 +281,17 @@ PANEL_FP_LIB_TABLE::PANEL_FP_LIB_TABLE( DIALOG_EDIT_LIBRARY_TABLES* aParent, m_global_grid->SetTable( new FP_LIB_TABLE_GRID( *aGlobal ), true ); m_project_grid->SetTable( new FP_LIB_TABLE_GRID( *aProject ), true ); - // Give a bit more room for combobox editors - m_global_grid->SetDefaultRowSize( m_global_grid->GetDefaultRowSize() + 4 ); - m_project_grid->SetDefaultRowSize( m_project_grid->GetDefaultRowSize() + 4 ); + // Give a bit more room for wxChoice editors + m_global_grid->SetDefaultRowSize( m_global_grid->GetDefaultRowSize() + 2 ); + m_project_grid->SetDefaultRowSize( m_project_grid->GetDefaultRowSize() + 2 ); // add Cut, Copy, and Paste to wxGrids m_global_grid->PushEventHandler( new FP_GRID_TRICKS( m_parent, m_global_grid ) ); m_project_grid->PushEventHandler( new FP_GRID_TRICKS( m_parent, m_project_grid ) ); + m_path_subs_grid->PushEventHandler( new GRID_TRICKS( m_path_subs_grid ) ); - m_global_grid->SetSelectionMode( wxGrid::wxGridSelectionModes::wxGridSelectRows ); - m_project_grid->SetSelectionMode( wxGrid::wxGridSelectionModes::wxGridSelectRows ); + m_global_grid->SetSelectionMode( wxGrid::wxGridSelectRows ); + m_project_grid->SetSelectionMode( wxGrid::wxGridSelectRows ); m_global_grid->AutoSizeColumns( false ); m_project_grid->AutoSizeColumns( false ); @@ -308,10 +310,8 @@ PANEL_FP_LIB_TABLE::PANEL_FP_LIB_TABLE( DIALOG_EDIT_LIBRARY_TABLES* aParent, populateEnvironReadOnlyTable(); - for( int i=0; i<2; ++i ) + for( wxGrid* g : { m_global_grid, m_project_grid } ) { - wxGrid* g = i==0 ? m_global_grid : m_project_grid; - wxGridCellAttr* attr; attr = new wxGridCellAttr; @@ -368,19 +368,18 @@ PANEL_FP_LIB_TABLE::~PANEL_FP_LIB_TABLE() // Any additional event handlers should be popped before the window is deleted. m_global_grid->PopEventHandler( true ); m_project_grid->PopEventHandler( true ); + m_path_subs_grid->PopEventHandler( true ); } bool PANEL_FP_LIB_TABLE::verifyTables() { - for( int t=0; t<2; ++t ) + for( FP_LIB_TABLE_GRID* model : { global_model(), project_model() } ) { - FP_LIB_TABLE_GRID& model = t==0 ? *global_model() : *project_model(); - - for( int r = 0; r < model.GetNumberRows(); ) + for( int r = 0; r < model->GetNumberRows(); ) { - wxString nick = model.GetValue( r, COL_NICKNAME ).Trim( false ).Trim(); - wxString uri = model.GetValue( r, COL_URI ).Trim( false ).Trim(); + wxString nick = model->GetValue( r, COL_NICKNAME ).Trim( false ).Trim(); + wxString uri = model->GetValue( r, COL_URI ).Trim( false ).Trim(); unsigned illegalCh = 0; if( !nick || !uri ) @@ -389,7 +388,7 @@ bool PANEL_FP_LIB_TABLE::verifyTables() // 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 ); + model->DeleteRows( r, 1 ); } else if( ( illegalCh = LIB_ID::FindIllegalLibNicknameChar( nick, LIB_ID::ID_PCB ) ) ) { @@ -398,8 +397,8 @@ bool PANEL_FP_LIB_TABLE::verifyTables() nick ); // show the tabbed panel holding the grid we have flunked: - if( &model != cur_model() ) - m_auinotebook->SetSelection( &model == global_model() ? 0 : 1 ); + if( model != cur_model() ) + m_auinotebook->SetSelection( model == global_model() ? 0 : 1 ); m_cur_grid->MakeCellVisible( r, 0 ); m_cur_grid->SetGridCursor( r, 1 ); @@ -411,33 +410,31 @@ bool PANEL_FP_LIB_TABLE::verifyTables() else { // set the trimmed values back into the table so they get saved to disk. - model.SetValue( r, COL_NICKNAME, nick ); - model.SetValue( r, COL_URI, uri ); + model->SetValue( r, COL_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 ) + for( FP_LIB_TABLE_GRID* model : { global_model(), project_model() } ) { - FP_LIB_TABLE_GRID& model = t==0 ? *global_model() : *project_model(); - - for( int r1 = 0; r1 < model.GetNumberRows() - 1; ++r1 ) + for( int r1 = 0; r1 < model->GetNumberRows() - 1; ++r1 ) { - wxString nick1 = model.GetValue( r1, COL_NICKNAME ); + wxString nick1 = model->GetValue( r1, COL_NICKNAME ); - for( int r2=r1+1; r2 < model.GetNumberRows(); ++r2 ) + for( int r2 = r1 + 1; r2 < model->GetNumberRows(); ++r2 ) { - wxString nick2 = model.GetValue( r2, COL_NICKNAME ); + wxString nick2 = model->GetValue( r2, COL_NICKNAME ); if( nick1 == nick2 ) { wxString msg = wxString::Format( _( "Duplicate Nicknames \"%s\"." ), nick1 ); // show the tabbed panel holding the grid we have flunked: - if( &model != cur_model() ) - m_auinotebook->SetSelection( &model == global_model() ? 0 : 1 ); + 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->MakeCellVisible( r2, 0 ); @@ -739,10 +736,8 @@ void PANEL_FP_LIB_TABLE::populateEnvironReadOnlyTable() // clear the table m_path_subs_grid->DeleteRows( 0, m_path_subs_grid->GetNumberRows() ); - for( int i = 0; i < 2; ++i ) + for( FP_LIB_TABLE_GRID* tbl : { global_model(), project_model() } ) { - FP_LIB_TABLE_GRID* tbl = i == 0 ? global_model() : project_model(); - for( int row = 0; row < tbl->GetNumberRows(); ++row ) { wxString uri = tbl->GetValue( row, COL_URI ); @@ -778,15 +773,17 @@ void PANEL_FP_LIB_TABLE::populateEnvironReadOnlyTable() m_path_subs_grid->AppendRows( 1 ); m_path_subs_grid->SetCellValue( row, 0, wxT( "${" ) + evName + wxT( "}" ) ); + m_path_subs_grid->SetCellEditor( row, 0, new GRID_CELL_READONLY_TEXT_EDITOR() ); wxString evValue; wxGetEnv( evName, &evValue ); m_path_subs_grid->SetCellValue( row, 1, evValue ); + m_path_subs_grid->SetCellEditor( row, 1, new GRID_CELL_READONLY_TEXT_EDITOR() ); } // No combobox editors here, but it looks better if its consistent with the other // grids in the dialog. - m_path_subs_grid->SetDefaultRowSize( m_path_subs_grid->GetDefaultRowSize() + 4 ); + m_path_subs_grid->SetDefaultRowSize( m_path_subs_grid->GetDefaultRowSize() + 2 ); adjustPathSubsGridColumns( m_path_subs_grid->GetRect().GetWidth() ); } diff --git a/pcbnew/dialogs/panel_fp_lib_table_base.cpp b/pcbnew/dialogs/panel_fp_lib_table_base.cpp index ae9181cb17..5db7495c65 100644 --- a/pcbnew/dialogs/panel_fp_lib_table_base.cpp +++ b/pcbnew/dialogs/panel_fp_lib_table_base.cpp @@ -163,7 +163,7 @@ PANEL_FP_LIB_TABLE_BASE::PANEL_FP_LIB_TABLE_BASE( wxWindow* parent, wxWindowID i // Grid m_path_subs_grid->CreateGrid( 1, 2 ); - m_path_subs_grid->EnableEditing( false ); + 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 ); diff --git a/pcbnew/dialogs/panel_fp_lib_table_base.fbp b/pcbnew/dialogs/panel_fp_lib_table_base.fbp index ab7e46d59d..96c0eca5f2 100644 --- a/pcbnew/dialogs/panel_fp_lib_table_base.fbp +++ b/pcbnew/dialogs/panel_fp_lib_table_base.fbp @@ -1557,7 +1557,7 @@ 1 0 1 - 0 + 1 1 1