Opened 16 years ago

Closed 18 months ago

#2576 closed defect (fixed)

wxGrid selection API works not intuitively

Reported by: bwallis42 Owned by:
Priority: normal Milestone:
Component: wxGrid Version:
Keywords: wxGrid Cc: bwallis42, robind, mmacleod, neis
Blocked By: Blocking:
Patch: no

Description (last modified by vadz)

When I create a grid and register an event handler
for a right button mouse click and also a 5 second
timer. I never get any rows, cols or cells returned
as selected regardless of how many I select.

I've attached the simple example showing this
behaviour.

This is running on Gentoo linux (kernel 2.6.11,libc
2.3.4), xorg 6.8, python 2.3.5, wxPython 2.4.2.4 or
2.6.0.0 (tried both) and wxGTK 2.4.2 and 2.6.0.

Attachments (1)

GridSelectBug.py download (2.4 KB) - added by bwallis42 16 years ago.
Example source showing the bug

Download all attachments as: .zip

Change History (11)

Changed 16 years ago by bwallis42

Example source showing the bug

comment:1 Changed 16 years ago by robind

There are different kinds of selections, so the results of
your test depend on how you make the selection. If you
click or drag across the row labels then you will have row
selections, if you drag across the col labels then you will
have column selections. If you select one or more single
cells (by ctrl clicking on them) then your test will report
selected cells. The one thing you are not testing for is
range of cells selections, which is what you get when
dragging across cells. You can get the range(s) of selected
cells with GetSelectionBlockTopLeft/GetSelectionBlockBottomRight

comment:2 Changed 16 years ago by bwallis42

OK, had another play with it. The GetSelectionBlock...
calls are useful and will help me work around the
problem in my real app, thanks for that.

But I still think it is inconsistent. If I set the grid selection
mode to wxGridSelectRows I get different results for
GetSelectedRows and GetSelectionBlock depending on
whether I select the rows in the title column or in the
body of the grid. If I select usingthe title column then I
get a result in GetSelectedRows but *not* for
GetSelectionBlock. If I select the rows in the body of the
grid then it is the other way around. Selecting the whole
table with the top left cell also returns no rows for
GetSelectedRows.

If I set wxGridSelectColumns mode then I get equivalent
results.

What this means is that I now think that there are two
issues:
1) the behaviour should be the same when you have the
selection mode set to rows or columns and select via
either the title or body
2) GetSelectionBlock... should return the selection area
when you select using the row or column title (it does if
you select the whole table with the upper left cell)

comment:3 Changed 14 years ago by mmacleod

Ran into the same/similar issue here.
With wxGrid::wxGridSelectRows enabled if user clicks on a cell then wxGrid::GetSelectedRows() does not return the selection, If he clicks on the row heading then it does.

While it can be worked around (which is what I have done for now) I agree with bwallis42 on both the issues he identified below.
I also think that this behaviour is both inconsistent and counter intuative.

comment:4 follow-up: Changed 14 years ago by neis

Well, the problem is that originally that m_selection struct which the GetSelectedCell/Rows/Cols and GetSelectionBlock... functions give access to was meant to just be an efficient internal representation of the selection state, with the officially available interface just being "IsInSelection".

However, "IsInSelection" turned out to be just not efficient enough (especially for small changes in huge selections), and since nobody found time to contribute an interface that's both efficient and comfortable, we just added those functions giving access to the internal structures.

If anybody feels like contributing an interface which evaluates the internal data and returns them in a more comfortable way, that would be much appreciated. Be warned however, that just extending GetSelectedRows/Cols/Cells to return an array of all selected rows/cols/cells (possibly many many millions) is not acceptable.

One possibility could be an iterator that's iterating through all the selected rows/cols/cells
in row/column/cell selection mode, which probably would be okay for row and column selection mode, but iterating through all the individual cells in cell selection mode might not be sufficiently efficient if there are large blocks of selected cells, so I don't really know what to suggest there...

comment:5 Changed 13 years ago by wojdyr

  • Keywords wxGrid added

comment:6 Changed 13 years ago by wxsite

  • Component changed from GUI-generic to wxGrid

comment:7 in reply to: ↑ 4 Changed 12 years ago by rodrigogq

Replying to neis:

Well, the problem is that originally that m_selection struct which the GetSelectedCell/Rows/Cols and GetSelectionBlock... functions give access to was meant to just be an efficient internal representation of the selection state, with the officially available interface just being "IsInSelection".

However, "IsInSelection" turned out to be just not efficient enough (especially for small changes in huge selections), and since nobody found time to contribute an interface that's both efficient and comfortable, we just added those functions giving access to the internal structures.

If anybody feels like contributing an interface which evaluates the internal data and returns them in a more comfortable way, that would be much appreciated. Be warned however, that just extending GetSelectedRows/Cols/Cells to return an array of all selected rows/cols/cells (possibly many many millions) is not acceptable.

One possibility could be an iterator that's iterating through all the selected rows/cols/cells
in row/column/cell selection mode, which probably would be okay for row and column selection mode, but iterating through all the individual cells in cell selection mode might not be sufficiently efficient if there are large blocks of selected cells, so I don't really know what to suggest there...

I suggest to use two sets of functions to get the results... one to work as intuitive as the function names are and another for efficiency.

We could extend GetSelectedRows/Cols/Cells to return the arrays of selected rows/cols/cells, and create another set of functions to access these elemments on huge grids. Eg.:

  • GetSelectedRowCount/ColCount/CellCount;
  • GetFirstSelectedRow/Col/Cell;
  • GetNextSelectedRow/Col/Cell(fromSelection);
  • GetLastSelectedRow/Col/Cell;

I believe those creating such grids are not using GetSelectedRows/Cols/Cells functions today, so there wouldn't be any impact on it. Also, someone working with these huge sets are already concerned about performance... they would look for alternatives for GetSelectedRows/Cols/Cells at first.

On the other hand, it is pretty usefull to keep GetSelectedRows/Cols/Cells as intuitive as returning arrays, since most applications don't handle huge grids on memory that would return such large arrays. These arrays could be created IN each of the GetSelectedRows/Cols/Cells in order not to destroy performance on huge grids.

I would like to code this.

comment:8 Changed 12 years ago by vadz

  • Status changed from new to confirmed
  • Summary changed from wxGrid selection not working to wxGrid selection API works not intuitively

This looks like a perfectly reasonable proposal to me, I'd love to see such a patch. TIA!

comment:9 Changed 18 months ago by Vadim Zeitlin <vadim@…>

In b095e67ac/git-wxWidgets:

Show more detailed information about selection in the grid sample

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.

comment:10 Changed 18 months ago by vadz

  • Description modified (diff)
  • Resolution set to fixed
  • Status changed from confirmed to closed

I think we can finally (better very, very late than never...) close this one after the commit above was merged as part of a5a76416162a87d898f99646bf3e4a1c2757917d as there is now an efficient and reasonably simple way to get access to the selection using wxGrid::GetSelectedBlocks() that you can iterate over using

    for ( const wxGridBlockCoords& block : grid->GetSelectedBlocks() )
    {
         ... do something with block ...
    }
Note: See TracTickets for help on using tickets.