Fix selection expansion in row/column-only selection modes

We should never adjust the fixed coordinate of the selection blocks in
this mode, so ensure we never end up with a partially selected line in
this case by preserving the -- correct by construction -- current block
coordinates in this direction.
This commit is contained in:
Vadim Zeitlin
2020-04-12 02:27:50 +02:00
parent 32bb5e9157
commit b10755e553

View File

@@ -498,59 +498,69 @@ bool wxGridSelection::ExtendOrCreateCurrentBlock(const wxGridCellCoords& blockSt
const wxGridBlockCoords& block = *m_selection.rbegin(); const wxGridBlockCoords& block = *m_selection.rbegin();
wxGridBlockCoords newBlock = block; wxGridBlockCoords newBlock = block;
// If the new block starts at the same top row as the current one, the // Don't adjust the blocks rows at all in column selection mode as the
// end block coordinates must correspond to the new bottom row -- and // top/bottom row are always fixed to the first/last grid row anyhow in
// vice versa, if the new block starts at the bottom, its other end // this case and we shouldn't select only part of a column just because the
// must correspond to the top. // user Shift-clicked somewhere in the middle of the grid.
if ( blockStart.GetRow() == block.GetTopRow() ) if ( m_selectionMode != wxGrid::wxGridSelectColumns )
{ {
newBlock.SetBottomRow(blockEnd.GetRow()); // If the new block starts at the same top row as the current one, the
} // end block coordinates must correspond to the new bottom row -- and
else if ( blockStart.GetRow() == block.GetBottomRow() ) // vice versa, if the new block starts at the bottom, its other end
{ // must correspond to the top.
newBlock.SetTopRow(blockEnd.GetRow()); if ( blockStart.GetRow() == block.GetTopRow() )
} {
else // current and new block don't have common row boundary newBlock.SetBottomRow(blockEnd.GetRow());
{ }
// This can happen when mixing entire column and cell selection, e.g. else if ( blockStart.GetRow() == block.GetBottomRow() )
// by Shift-clicking on the column header. In this case, the right {
// thing to do is to just expand the current block to the new one newBlock.SetTopRow(blockEnd.GetRow());
// boundaries, extending the selection to the entire column height when }
// a column is selected. However notice that we should not shrink the else // current and new block don't have common row boundary
// current block here, in order to allow Shift-Left/Right (which don't {
// know anything about the column selection and so just use single row // This can happen when mixing entire column and cell selection, e.g.
// blocks) to keep the full column selection. // by Shift-clicking on the column header. In this case, the right
int top = blockStart.GetRow(), // thing to do is to just expand the current block to the new one
bottom = blockEnd.GetRow(); // boundaries, extending the selection to the entire column height when
if ( top > bottom ) // a column is selected. However notice that we should not shrink the
wxSwap(top, bottom); // current block here, in order to allow Shift-Left/Right (which don't
// know anything about the column selection and so just use single row
// blocks) to keep the full column selection.
int top = blockStart.GetRow(),
bottom = blockEnd.GetRow();
if ( top > bottom )
wxSwap(top, bottom);
if ( top < newBlock.GetTopRow() ) if ( top < newBlock.GetTopRow() )
newBlock.SetTopRow(top); newBlock.SetTopRow(top);
if ( bottom > newBlock.GetBottomRow() ) if ( bottom > newBlock.GetBottomRow() )
newBlock.SetBottomRow(bottom); newBlock.SetBottomRow(bottom);
}
} }
// Same as above but mirrored for columns. // Same as above but mirrored for columns.
if ( blockStart.GetCol() == block.GetLeftCol() ) if ( m_selectionMode != wxGrid::wxGridSelectRows )
{ {
newBlock.SetRightCol(blockEnd.GetCol()); if ( blockStart.GetCol() == block.GetLeftCol() )
} {
else if ( blockStart.GetCol() == block.GetRightCol() ) newBlock.SetRightCol(blockEnd.GetCol());
{ }
newBlock.SetLeftCol(blockEnd.GetCol()); else if ( blockStart.GetCol() == block.GetRightCol() )
} {
else newBlock.SetLeftCol(blockEnd.GetCol());
{ }
int left = blockStart.GetCol(), else
right = blockEnd.GetCol(); {
if ( left > right ) int left = blockStart.GetCol(),
wxSwap(left, right); right = blockEnd.GetCol();
if ( left > right )
wxSwap(left, right);
if ( left < newBlock.GetLeftCol() ) if ( left < newBlock.GetLeftCol() )
newBlock.SetLeftCol(left); newBlock.SetLeftCol(left);
if ( right > newBlock.GetRightCol() ) if ( right > newBlock.GetRightCol() )
newBlock.SetRightCol(right); newBlock.SetRightCol(right);
}
} }
newBlock = newBlock.Canonicalize(); newBlock = newBlock.Canonicalize();