[Solved] QTableView movable column selectionmodel woes
-
I'm new to view/model implementations in Qt, and have a particular problem I can't seem to get a handle on. I'm using a QTableView to display and edit data from a custom model subclassed from QAbstractTableModel. My model uses an internal map of columns to the properties of the object it is based on (i.e. each row shows the object values as columns in the table). This works fine - my model supplies the appropriate DisplayRole and EditRole values for indexes passed to the data() method, etc., even after the user rearranges the columns (I set the headerview to allow column moving).
My problem is with the ordering of the indexes in the view's selectionmodel. On my tableview, I create a custom context menu which contains actions for copy/paste. The copy action handler reads the view's selection model indexes and builds a tab-delimited string suitable for pasting into an external spreadsheet. As long as the user hasn't moved columns around, the indexes returned by the selectionModel's selectedIndexes() method are sorted left-to-right, then down (eg. (0,1), (0,2), (1,1), (1,2)). UNTIL the user rearranges the view's columns by dragging them around. Once this happens, the selectedIndexes() method returns them sorted down, then left-to-right (eg. (0,1), (1,1), (0,2), (1,2)).
I think what I need to do is detect the column moves and move the column-to-attribute mapping in my model, except that the view appears to keep track of the logical column indexes seperately from the visual indexes, so I'm afraid I'll confuse the view. I'm thinking since the view is doing this, I should be handing the selections differently, but I'm not sure how. I'm posting this in hopes that someone might be able to shed some light before I spend a lot of time going down the wrong road...
-
Following up, I solved this by reading more about the QItemSelection class and thinking about why after columns are rearranged the QItemSelection contains different index arrangements. QItemSelection is a list of selection ranges, not a selection range itself. Before view columns are rearranged, the selected indexes form one topLeft->bottomRight selection range that map directly to the model's notion of the column ordering. However after the view's columns have been rearranged by a user, the QItemSelection contains the indexes reordered such that we still know how the selected indexes are positionally (wrt the view) arranged. In this case, the QItemSelection will contain multiple selection ranges, one for each column in the selection where the columns are positionally arranged to correspond to the view's arrangement.
TL;DR
Check the size of the QItemSelection object returned by selectionModel->selection(). If it's 1, you parse the indexes Left-to-Right, Top-to-Bottom. Otherwise you parse the indexes Top-to-Bottom, Left-to-Right.