aboutsummaryrefslogtreecommitdiffstats
path: root/examples/quickcontrols/spreadsheets
diff options
context:
space:
mode:
authorMohammadHossein Qanbari <[email protected]>2025-01-24 16:09:24 +0100
committerMohammadHossein Qanbari <[email protected]>2025-01-28 12:48:00 +0100
commit2e9f2c9a1dab0aba555815fd264aa5621d14e8b3 (patch)
tree4d186253f1342fc6ccb078355beebadd492a557a /examples/quickcontrols/spreadsheets
parentbfdadbac489b4a06d0caee94c3453d2039b73fcc (diff)
Spreadsheets: Fix drag and drop issue after scrolling in table view
This patch fixes an issue with drag and drop functionality in the example, particularly after long scrolling. The problem stemmed from two main factors: - The table view was stealing DropArea events when interactive. - The drop area was positioned behind the table view's contentItem, preventing it from receiving the events. The drop area is now positioned above the table view, ensuring it can receive events during dragging operations. The table view's interactive mode is temporarily disabled when dragging begins and restored to its previous state when dragging ends. Task-number: QTBUG-125767 Change-Id: I8920284f4652464bccd92109a2a9685228e11783 Reviewed-by: Richard Moe Gustavsen <[email protected]>
Diffstat (limited to 'examples/quickcontrols/spreadsheets')
-rw-r--r--examples/quickcontrols/spreadsheets/Spreadsheets/Main.qml196
1 files changed, 102 insertions, 94 deletions
diff --git a/examples/quickcontrols/spreadsheets/Spreadsheets/Main.qml b/examples/quickcontrols/spreadsheets/Spreadsheets/Main.qml
index 97e9c0600b..a030b8da13 100644
--- a/examples/quickcontrols/spreadsheets/Spreadsheets/Main.qml
+++ b/examples/quickcontrols/spreadsheets/Spreadsheets/Main.qml
@@ -342,111 +342,119 @@ ApplicationWindow {
dragCell = Qt.point(-1, -1)
}
}
+ }
+ }
- DropArea {
- id: dropArea
-
- property point dropCell: Qt.point(-1, -1)
+ DropArea {
+ id: dropArea
- anchors.fill: parent
- Drag.active: dragArea.drag.active
- enabled: dragArea.drag.active
+ property point dropCell: Qt.point(-1, -1)
+ // This property keeps the interactive value to restore it after
+ // dragging is finished. The reason is that when the interactive
+ // mode is true, it steals the events and prevents the drop area
+ // from working.
+ property bool restoreInteractiveValue: tableView.interactive
- function startDragging()
- {
- // block updating visible area
- visibleCellsConnection.blockConnection()
- }
-
- function stopDragging()
- {
- Drag.drop()
- // unblock update visible area
- visibleCellsConnection.blockConnection(false)
- visibleCellsConnection.updateViewArea() // now update visible area
- }
-
- function isDropPossible(dropCell) {
- for (let i = 0; i < mimeDataProvider.size(); ++i) {
- let cell = mimeDataProvider.cellAt(i)
- cell.x += dropCell.x - dragArea.dragCell.x
- cell.y += dropCell.y - dragArea.dragCell.y
- const index = tableView.index(cell.y, cell.x)
- if (!index.valid)
- return false
- }
- return true
- }
+ anchors.fill: parent
+ Drag.active: dragArea.drag.active
+ enabled: dragArea.drag.active
+
+ function startDragging()
+ {
+ restoreInteractiveValue = tableView.interactive
+ tableView.interactive = false
+ // block updating visible area
+ visibleCellsConnection.blockConnection()
+ }
- onDropped: {
- const position = Qt.point(dragArea.mouseX, dragArea.mouseY)
- dropCell = tableView.cellAtPosition(position, true)
- if (dropCell.x < 0 || dropCell.y < 0)
- return
- if (dragArea.dragCell === dropCell)
- return
+ function stopDragging()
+ {
+ Drag.drop()
+ // unblock update visible area
+ visibleCellsConnection.blockConnection(false)
+ visibleCellsConnection.updateViewArea() // now update visible area
+ tableView.interactive = restoreInteractiveValue
+ }
- if (!isDropPossible(dropCell)) {
- tableView.model.clearHighlight()
- return
- }
+ function isDropPossible(dropCell) {
+ for (let i = 0; i < mimeDataProvider.size(); ++i) {
+ let cell = mimeDataProvider.cellAt(i)
+ cell.x += dropCell.x - dragArea.dragCell.x
+ cell.y += dropCell.y - dragArea.dragCell.y
+ const index = tableView.index(cell.y, cell.x)
+ if (!index.valid)
+ return false
+ }
+ return true
+ }
- tableView.model.clearItemData(_spreadSelectionModel.selectedIndexes)
- for (let i = 0; i < mimeDataProvider.size(); ++i) {
- let cell = mimeDataProvider.cellAt(i)
- cell.x += dropCell.x - dragArea.dragCell.x
- cell.y += dropCell.y - dragArea.dragCell.y
- const index = tableView.index(cell.y, cell.x)
- mimeDataProvider.saveDataToModel(i, index, tableView.model)
- }
- mimeDataProvider.reset()
- _spreadSelectionModel.clearSelection()
+ onDropped: {
+ const position = Qt.point(dragArea.mouseX, dragArea.mouseY)
+ dropCell = tableView.cellAtPosition(position, true)
+ if (dropCell.x < 0 || dropCell.y < 0)
+ return
+ if (dragArea.dragCell === dropCell)
+ return
+
+ if (!isDropPossible(dropCell)) {
+ tableView.model.clearHighlight()
+ return
+ }
- const drop_index = tableView.index(dropCell.y, dropCell.x)
- _spreadSelectionModel.setCurrentIndex(drop_index, ItemSelectionModel.Current)
+ tableView.model.clearItemData(_spreadSelectionModel.selectedIndexes)
+ for (let i = 0; i < mimeDataProvider.size(); ++i) {
+ let cell = mimeDataProvider.cellAt(i)
+ cell.x += dropCell.x - dragArea.dragCell.x
+ cell.y += dropCell.y - dragArea.dragCell.y
+ const index = tableView.index(cell.y, cell.x)
+ mimeDataProvider.saveDataToModel(i, index, tableView.model)
+ }
+ mimeDataProvider.reset()
+ _spreadSelectionModel.clearSelection()
- tableView.model.clearHighlight()
- }
+ const drop_index = tableView.index(dropCell.y, dropCell.x)
+ _spreadSelectionModel.setCurrentIndex(drop_index, ItemSelectionModel.Current)
- onPositionChanged: {
- const position = Qt.point(dragArea.mouseX, dragArea.mouseY)
- // cell is the cell that currently mouse is over it
- const cell = tableView.cellAtPosition(position, true)
- // dropCell is the cell that it was under the mouse's last position
- // if the last and current cells are the same, then there is no need
- // to update highlight, as nothing is changed since last time.
- if (cell === dropCell)
- return
+ tableView.model.clearHighlight()
+ }
- if (!isDropPossible(cell)) {
- tableView.model.clearHighlight()
- return
- }
+ onPositionChanged: {
+ const position = Qt.point(dragArea.mouseX, dragArea.mouseY)
+ // cell is the cell that currently mouse is over it
+ const cell = tableView.cellAtPosition(position, true)
+ // dropCell is the cell that it was under the mouse's last position
+ // if the last and current cells are the same, then there is no need
+ // to update highlight, as nothing is changed since last time.
+ if (cell === dropCell)
+ return
+
+ if (!isDropPossible(cell)) {
+ tableView.model.clearHighlight()
+ return
+ }
- // if something is changed, it means that if the current cell is changed,
- // then clear highlighted cells and update the dropCell.
- tableView.model.clearHighlight()
- dropCell = cell
- // if the current cell was invalid (mouse is out side of the TableView)
- // then no need to update highlight
- if (cell.x < 0 || cell.y < 0)
- return
- // if dragged cell is the same as the (possibly) dropCell
- // then no need to highlight any cells
- if (dragArea.dragCell === dropCell)
- return
- // if the dropCell is not the same as the dragging cell and also
- // is not the same as the cell at the mouse's last position
- // then highlights the target cells
- for (let i in _spreadSelectionModel.selectedIndexes) {
- const old_index = _spreadSelectionModel.selectedIndexes[i]
- let cell = tableView.cellAtIndex(old_index)
- cell.x += dropCell.x - dragArea.dragCell.x
- cell.y += dropCell.y - dragArea.dragCell.y
- const new_index = tableView.index(cell.y, cell.x)
- tableView.model.setHighlight(new_index, true)
- }
- }
+ // if something is changed, it means that if the current cell is changed,
+ // then clear highlighted cells and update the dropCell.
+ tableView.model.clearHighlight()
+ dropCell = cell
+ // if the current cell was invalid (mouse is out side of the TableView)
+ // then no need to update highlight
+ if (cell.x < 0 || cell.y < 0)
+ return
+ // if dragged cell is the same as the (possibly) dropCell
+ // then no need to highlight any cells
+ if (dragArea.dragCell === dropCell)
+ return
+ // if the dropCell is not the same as the dragging cell and also
+ // is not the same as the cell at the mouse's last position
+ // then highlights the target cells
+ for (let i in _spreadSelectionModel.selectedIndexes) {
+ const old_index = _spreadSelectionModel.selectedIndexes[i]
+ let cell = tableView.cellAtIndex(old_index)
+ cell.x += dropCell.x - dragArea.dragCell.x
+ cell.y += dropCell.y - dragArea.dragCell.y
+ const new_index = tableView.index(cell.y, cell.x)
+ tableView.model.setHighlight(new_index, true)
}
}
}