Use wxGridSelection::IsInSelection() instead of GetSelectedRows/Cols()
which can be much slower as they need to produce an array containing
indices of all the selected rows/columns.
Don't extend the selection if the anchor line is not selected, as this
doesn't work correctly because the entire selection logic supposes the
anchor itself is selected and, moreover, it's not really clear how could
it would otherwise.
This commit does the same thing for rows/columns as the grandparent
commit did to the cells. Unfortunately a somewhat cleaner solution of
the parent commit can't be easily applied to the existing rows/columns
code and it's arguably not worth changing it in depth just for this.
This commit doesn't change the behaviour compared to the previous one,
but provides an alternative implementation of the same goal, which seems
preferable: instead of not extending the selection while Ctrl-dragging,
just don't enter dragging mode, i.e. don't capture the mouse and don't
set m_isDragging to true, if we start it from a previously selected, and
hence currently deselected, cell.
Property bitmap should be stored in its original size and rescaling
to the required size should be done only while drawing the property.
This way bitmap size will always fit to the actual wxPG line height.
Dragging in a grid with Ctrl key pressed starting from a previously
selected cell behaved very counterintuitively if not downright wrongly,
as the selection logic assumes that the selection anchor itself is
always selected, which wasn't true in this case.
Solve the problem by just not extending the selection at all when
starting to drag from a deselected cell. This means that Ctrl-dragging
doesn't do anything any more, but it's not a huge loss and to make it
work well while still allowing to use Ctrl-click to toggle the cell
selection, we'd need to implement a whole new and different
drag-deselect mode, as is done in Microsoft Excel 2016 (note that the
previous versions of Excel don't implement Ctrl-dragging neither).
Remove the "performDefault" variable which didn't really seem to help,
as the actual meaning of the return value is whether we should start
drag-selecting or not and the name of this variable didn't reflect this
anyhow.
Return false if we are over an invalid cell: this shouldn't change
anything when we're already dragging, but would prevent us from starting
to drag from an invalid cell which seems more correct, even if it's not
clear if this can happen in practice.
Also move hiding the edit control inside "isFirstDrag" check, there is
no reason to do it on every drag.
This is not necessary any longer as the current cell is changed on
Ctrl-click since the previous commit.
This commit is best viewed ignoring whitespace.
There isn't really any valid reason to ever set the current cell to the
corner of a block remaining after breaking up the currently selected
block after the deselection of the just clicked cell, so don't do it.
Just set the current cell to the clicked cell, whether it's selected or
not.
This is more consistent with Ctrl-clicking cells.
It also slightly improves behaviour when Ctrl-dragging mouse over the
range of selected lines, although it's still somewhat surprising.
Scroll the new end of selection into view only vertically, it would be
unexpected for the vertical Page Up/Down movement to scroll the grid
horizontally.
Update the cells that had to be deselected due to the selection mode
change.
This used to work, but the refresh was lost during a previous
refactoring.
Also make Page Up/Down themselves work consistently with the other
cursor movement keys and clear current selection if they move the
cursor.
Even though DoMoveCursorByPage() is simpler than DoMoveCursorByBlock(),
still factor out AdvanceByPage() for consistency with AdvanceByBlock()
and because it still makes the code more clear.
Extending the selection with Ctrl-arrows is different from all the other
cases, as we need to combine both the selection anchor and the current
cell coordinates when doing it.
This means that we can't reuse the same PrepareForSelectionExpansion()
helper for this case, so this function is not useful finally and this
commit removes it entirely. It also replaces GetCurrentBlockCornerRow()
and GetCurrentBlockCornerCol() functions with GetExtensionAnchor() which
combines both of them.
Finally, it adds wxGridDirectionOperations::TryToAdvance() helper to
avoid repeating the IsAtBoundary() check which was previously part of
PrepareForSelectionExpansion() in multiple places.
And because the "extending" and normal parts of DoMoveCursorByBlock()
are so different now, it also factors out AdvanceByBlock() helper which
can be used to keep these parts well separate from each other instead of
intermixing them together.
With all these preparatory changes, it's finally possible to implement
the "extending selection by block" logic relatively easily, with the
bulk of this branch actually taken by comments explaining why do we have
to do what we do.
Add unit tests verifying that the functions used by Shift-Ctrl-arrow
work as expected.
The selBlock reference could be used after the vector invalidation,
which resulted in using the wrong vector element at best and could
probably lead to a crash at worst.
Don't use it after invalidating the vector any longer.
This notably fixes a bug in row-or-column selection mode where the grid
wasn't updated visually after modifying its selection by deselecting a
single cell as soon as there were more than one selected row or column.
Mouse events in row/column headers should be just ignored when the
current selection mode disallows row/column selection.
This wasn't the case before, and while actually selecting the line
corresponding to the header was disallowed further down the call chain,
clicking it still unexpectedly cleared the existing selection and
dragging mouse in the header window selected the entire grid.
Fix this by just never entering the corresponding cursor mode in the
first place if it's incompatible with the current selection mode.
This function finally doesn't ever create a new block, except for the
trivial case when there is no current block, so rename it to a simpler
and more clear name.
No real changes.
This seems to be more consistent with the existing functions and doesn't
create ambiguity with a grid range.
Also rename wxGridSelectionRange to just wxGridBlocks as, in principle,
this class could be used for iterating over any blocks, not just the
selected ones.
No changes in functionality, this is just a renaming.
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.
Extend the current block to the entire line when the corresponding
header is Shift-clicked and, importantly, keep the full-line selection
when using Shift-arrows later to make the selection behave in the
expected way.
This made the logic of this function unnecessarily more complicated.
Instead, just fall back to the current cell coordinates in the only
place where this could happen before.
Doing this still preserves the correct behaviour of Shift-arrow
selection when entire rows/columns are selected and the current cell is
not the leftmost/topmost cell (due to scrolling), but the code is
simpler.
Remove the now always true condition check and assert that it's indeed
always true.
Note that the changes to gridsel.cpp in this commit are best viewed
ignoring whitespace changes.
The difference between calling SelectAll() and SelectBlock() with a
block covering the entire grid is that the former discards any
previously selected blocks, which become clearly redundant.
As a consequence, clicking on the grid corner 10 times in a row still
results in a selection with a single block, not 10 (identical) blocks.
These functions always returned the first partially visible line, not
the first fully visible one as intended because IsXXXShown() always
returned true when it applied to that line and we need to increment the
index first, before calling it -- even if this requires writing the loop
in a slightly uglier way.
This fixes bugs in commits 0920a1646b (Make wxGrid row selecting more
user friendly, 2020-03-04) and 89dd47edee (Make wxGrid column selecting
more user friendly, 2020-03-04).
Show the selected cells/rows/columns/blocks instead of just showing
their number, as we now have an efficient (i.e. taking time proportional
to the number of selected blocks and not to the number of the individual
cells, rows or columns) way of doing this.
See #2576.
Don't use long-lived non-const "block" reference, this makes it
difficult to see that it's never changed until the very end of the
function, when it's updated.
Compare "blockStart" with "block" itself instead of comparing it with
"newBlock" which is initially its copy but gets modified later (however
these modifications don't affect the comparisons involving it).
Add a comment explaining why are we doing what we do here.