Add wxGrid::CopySelection()

This code was already used for Ctrl-C handling, refactor it into a
separate function that can be called from the application now.

This commit is best viewed with --color-moved-ws=ignore-all-space Git
option.

Closes #24124.
This commit is contained in:
Blake-Madden 2023-12-08 06:10:33 -05:00 committed by Vadim Zeitlin
parent 188b5b8942
commit 6d89a14c72
3 changed files with 87 additions and 64 deletions

View file

@ -2284,6 +2284,8 @@ public:
void ClearSelection();
bool CopySelection();
bool IsInSelection( int row, int col ) const;
bool IsInSelection( const wxGridCellCoords& coords ) const

View file

@ -4997,6 +4997,21 @@ public:
*/
void ClearSelection();
/**
Copies all cells that are currently selected.
Note that the cells most be contiguously selected;
otherwise, nothing will be copied.
Returns @c true if content is successfully copied,
@c false otherwise. @c false will be returned if
nothing was selected, the selected cells weren't contiguous,
or a clipboard error occurred.
@since 3.3.0
*/
bool CopySelection();
/**
Deselects a row of cells.
*/

View file

@ -6095,72 +6095,12 @@ void wxGrid::OnKeyDown( wxKeyEvent& event )
case 'C':
if ( event.GetModifiers() == wxMOD_CONTROL )
{
// Coordinates of the selected block to copy to clipboard.
wxGridBlockCoords sel;
// Check if we have any selected blocks and if we don't
// have too many of them.
const wxGridBlocks blocks = GetSelectedBlocks();
wxGridBlocks::iterator iter = blocks.begin();
if ( iter == blocks.end() )
if ( !CopySelection() )
{
// No selection, copy just the current cell.
if ( m_currentCellCoords == wxGridNoCellCoords )
{
// But we don't even have it -- nothing to do then.
event.Skip();
break;
}
sel = wxGridBlockCoords(GetGridCursorRow(),
GetGridCursorCol(),
GetGridCursorRow(),
GetGridCursorCol());
wxLogWarning(_("Error copying grid to the clipboard. "
"Either selected cells were not contiguous or "
"no cell was selected."));
}
else // We do have at least one selected block.
{
sel = *blocks.begin();
if ( ++iter != blocks.end() )
{
// As we use simple text format, we can't copy more
// than one block to clipboard.
wxLogWarning
(
_("Copying more than one selected block "
"to clipboard is not supported.")
);
break;
}
}
wxClipboardLocker lockClipboard;
if ( !lockClipboard )
{
// Error message should have been already given and we
// don't have much to add.
break;
}
wxString buf;
for ( int row = sel.GetTopRow(); row <= sel.GetBottomRow(); row++ )
{
bool first = true;
for ( int col = sel.GetLeftCol(); col <= sel.GetRightCol(); col++ )
{
if ( first )
first = false;
else
buf += '\t';
buf += GetCellValue(row, col);
}
buf += wxTextFile::GetEOL();
}
wxTheClipboard->SetData(new wxTextDataObject(buf));
break;
}
wxFALLTHROUGH;
@ -10852,6 +10792,72 @@ void wxGrid::ClearSelection()
m_selection->ClearSelection();
}
bool wxGrid::CopySelection()
{
#if wxUSE_CLIPBOARD
// Coordinates of the selected block to copy to clipboard.
wxGridBlockCoords sel;
// Check if we have any selected blocks and if we don't
// have too many of them.
const wxGridBlocks blocks = GetSelectedBlocks();
wxGridBlocks::iterator iter = blocks.begin();
if (iter == blocks.end())
{
// No selection, copy just the current cell.
if (m_currentCellCoords == wxGridNoCellCoords)
{
// But we don't even have it -- nothing to do then.
return false;
}
sel = wxGridBlockCoords(GetGridCursorRow(),
GetGridCursorCol(),
GetGridCursorRow(),
GetGridCursorCol());
}
else // We do have at least one selected block.
{
sel = *blocks.begin();
if (++iter != blocks.end())
{
// As we use simple text format, we can't copy more
// than one block to clipboard.
return false;
}
}
wxClipboardLocker lockClipboard;
if (!lockClipboard)
{
return false;
}
wxString buf;
for (int row = sel.GetTopRow(); row <= sel.GetBottomRow(); row++)
{
bool first = true;
for (int col = sel.GetLeftCol(); col <= sel.GetRightCol(); col++)
{
if (first)
first = false;
else
buf += '\t';
buf += GetCellValue(row, col);
}
buf += wxTextFile::GetEOL();
}
wxTheClipboard->SetData(new wxTextDataObject(buf));
#endif // wxUSE_CLIPBOARD
return true;
}
// This function returns the rectangle that encloses the given block
// in device coords clipped to the client size of the grid window.
//