Fix copy-paste for dropdown cells in grid tables
Dropdown editors in grid cells (like Electrical Type in the pin table) didn't support copy-paste operations. The Ctrl+C handler was missing for edit mode, Ctrl+V only worked for multi-cell paste, and the context menu cut item was disabled because isTextEntry() didn't recognize choice editors as editable. Added keyboard handling for copy/paste with active choice editors and included them in the writable cell check for the context menu. Fixes https://gitlab.com/kicad/code/kicad/-/issues/11722
This commit is contained in:
+87
-23
@@ -30,6 +30,8 @@
|
||||
#include <wx/log.h>
|
||||
#include <wx/stc/stc.h>
|
||||
#include <widgets/grid_text_helpers.h>
|
||||
#include <widgets/grid_icon_text_helpers.h>
|
||||
#include <widgets/grid_combobox.h>
|
||||
#include <search_stack.h>
|
||||
#include <widgets/grid_text_button_helpers.h>
|
||||
|
||||
@@ -105,6 +107,18 @@ bool GRID_TRICKS::isTextEntry( int aRow, int aCol )
|
||||
}
|
||||
|
||||
|
||||
bool GRID_TRICKS::isChoiceEditor( int aRow, int aCol )
|
||||
{
|
||||
wxGridCellEditor* editor = m_grid->GetCellEditor( aRow, aCol );
|
||||
bool retval = ( dynamic_cast<wxGridCellChoiceEditor*>( editor )
|
||||
|| dynamic_cast<GRID_CELL_ICON_TEXT_POPUP*>( editor )
|
||||
|| dynamic_cast<GRID_CELL_COMBOBOX*>( editor ) );
|
||||
|
||||
editor->DecRef();
|
||||
return retval;
|
||||
}
|
||||
|
||||
|
||||
bool GRID_TRICKS::isCheckbox( int aRow, int aCol )
|
||||
{
|
||||
wxGridCellRenderer* renderer = m_grid->GetCellRenderer( aRow, aCol );
|
||||
@@ -329,6 +343,8 @@ void GRID_TRICKS::getSelectedArea()
|
||||
|
||||
void GRID_TRICKS::onGridCellRightClick( wxGridEvent& aEvent )
|
||||
{
|
||||
m_grid->CommitPendingChanges( true );
|
||||
|
||||
wxMenu menu;
|
||||
|
||||
showPopupMenu( menu, aEvent );
|
||||
@@ -389,8 +405,11 @@ void GRID_TRICKS::showPopupMenu( wxMenu& menu, wxGridEvent& aEvent )
|
||||
{
|
||||
for( int col = m_sel_col_start; col < m_sel_col_start + m_sel_col_count; ++col )
|
||||
{
|
||||
if( !isReadOnly( row, col ) && isTextEntry( row, col ) )
|
||||
if( !isReadOnly( row, col )
|
||||
&& ( isTextEntry( row, col ) || isChoiceEditor( row, col ) ) )
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -492,37 +511,82 @@ void GRID_TRICKS::onCharHook( wxKeyEvent& ev )
|
||||
handled = true;
|
||||
}
|
||||
}
|
||||
else if( ev.GetModifiers() == wxMOD_CONTROL && ev.GetKeyCode() == 'V' )
|
||||
else if( ev.GetModifiers() == wxMOD_CONTROL && ev.GetKeyCode() == 'C' )
|
||||
{
|
||||
if( m_grid->IsCellEditControlShown() && wxTheClipboard->Open() )
|
||||
if( m_grid->IsCellEditControlShown() )
|
||||
{
|
||||
if( wxTheClipboard->IsSupported( wxDF_TEXT )
|
||||
|| wxTheClipboard->IsSupported( wxDF_UNICODETEXT ) )
|
||||
wxTextEntry* te = dynamic_cast<wxTextEntry*>( ev.GetEventObject() );
|
||||
|
||||
if( te )
|
||||
{
|
||||
wxTextDataObject data;
|
||||
wxTheClipboard->GetData( data );
|
||||
wxString selectedText = te->GetStringSelection();
|
||||
|
||||
if( data.GetText().Contains( COL_SEP ) || data.GetText().Contains( ROW_SEP ) )
|
||||
if( !selectedText.IsEmpty() )
|
||||
{
|
||||
wxString stripped( data.GetText() );
|
||||
stripped.Replace( ROW_SEP, " " );
|
||||
stripped.Replace( ROW_SEP_R, " " );
|
||||
stripped.Replace( COL_SEP, " " );
|
||||
wxLogNull doNotLog;
|
||||
|
||||
// Write to the CellEditControl if we can
|
||||
wxTextEntry* te = dynamic_cast<wxTextEntry*>( ev.GetEventObject() );
|
||||
|
||||
if( te && te->IsEditable() )
|
||||
te->WriteText( stripped );
|
||||
else
|
||||
paste_text( stripped );
|
||||
|
||||
handled = true;
|
||||
if( wxTheClipboard->Open() )
|
||||
{
|
||||
wxTheClipboard->SetData( new wxTextDataObject( selectedText ) );
|
||||
wxTheClipboard->Flush();
|
||||
wxTheClipboard->Close();
|
||||
handled = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
wxTheClipboard->Close();
|
||||
m_grid->ForceRefresh();
|
||||
if( !handled )
|
||||
{
|
||||
m_grid->CancelPendingChanges();
|
||||
getSelectedArea();
|
||||
cutcopy( true, false );
|
||||
handled = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
else if( ev.GetModifiers() == wxMOD_CONTROL && ev.GetKeyCode() == 'V' )
|
||||
{
|
||||
if( m_grid->IsCellEditControlShown() )
|
||||
{
|
||||
wxLogNull doNotLog;
|
||||
|
||||
if( wxTheClipboard->Open() )
|
||||
{
|
||||
if( wxTheClipboard->IsSupported( wxDF_TEXT )
|
||||
|| wxTheClipboard->IsSupported( wxDF_UNICODETEXT ) )
|
||||
{
|
||||
wxTextDataObject data;
|
||||
wxTheClipboard->GetData( data );
|
||||
wxString text = data.GetText();
|
||||
|
||||
bool hasMultipleCells = text.Contains( COL_SEP ) || text.Contains( ROW_SEP );
|
||||
|
||||
if( hasMultipleCells )
|
||||
{
|
||||
text.Replace( ROW_SEP, wxS( " " ) );
|
||||
text.Replace( ROW_SEP_R, wxS( " " ) );
|
||||
text.Replace( COL_SEP, wxS( " " ) );
|
||||
}
|
||||
|
||||
wxTextEntry* te = dynamic_cast<wxTextEntry*>( ev.GetEventObject() );
|
||||
|
||||
if( te && te->IsEditable() )
|
||||
{
|
||||
te->WriteText( text );
|
||||
handled = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
m_grid->CancelPendingChanges();
|
||||
getSelectedArea();
|
||||
paste_text( text );
|
||||
handled = true;
|
||||
}
|
||||
}
|
||||
|
||||
wxTheClipboard->Close();
|
||||
m_grid->ForceRefresh();
|
||||
}
|
||||
}
|
||||
}
|
||||
else if( ev.GetKeyCode() == WXK_ESCAPE )
|
||||
|
||||
@@ -114,6 +114,7 @@ protected:
|
||||
virtual void doPopupSelection( wxCommandEvent& event );
|
||||
|
||||
bool isTextEntry( int aRow, int aCol );
|
||||
bool isChoiceEditor( int aRow, int aCol );
|
||||
bool isCheckbox( int aRow, int aCol );
|
||||
bool isReadOnly( int aRow, int aCol );
|
||||
|
||||
|
||||
Reference in New Issue
Block a user