aboutsummaryrefslogtreecommitdiffstats
path: root/src/libs
diff options
context:
space:
mode:
authorHenning Gruendl <henning.gruendl@qt.io>2020-03-13 10:44:37 +0100
committerHenning Gründl <henning.gruendl@qt.io>2020-03-13 12:29:51 +0000
commit0b7970feb4c4098f41ba537c99b4d278935e38e7 (patch)
tree64af9ef0fe37028b26c3a2ad6a32ef362ddedebf /src/libs
parent206e7d3e7011ad2a75604e3cccb7bc1a5a136065 (diff)
ADS: Fix repeatedly dropping in same area crash
6c687d28def5c24f3eeb67c9e13d5cfab40cebd0 1c2383f8eb94bc8570e554efa5f842a8ab1461ea Task-number: QDS-1751 Change-Id: I933b1f53da8ce423cd5d38ff2863f58606006596 Reviewed-by: Thomas Hartmann <thomas.hartmann@qt.io>
Diffstat (limited to 'src/libs')
-rw-r--r--src/libs/advanceddockingsystem/dockcontainerwidget.cpp47
-rw-r--r--src/libs/advanceddockingsystem/dockcontainerwidget.h8
-rw-r--r--src/libs/advanceddockingsystem/dockoverlay.cpp8
-rw-r--r--src/libs/advanceddockingsystem/dockoverlay.h7
-rw-r--r--src/libs/advanceddockingsystem/docksplitter.cpp10
-rw-r--r--src/libs/advanceddockingsystem/docksplitter.h10
-rw-r--r--src/libs/advanceddockingsystem/floatingdragpreview.cpp14
7 files changed, 67 insertions, 37 deletions
diff --git a/src/libs/advanceddockingsystem/dockcontainerwidget.cpp b/src/libs/advanceddockingsystem/dockcontainerwidget.cpp
index 10fdc8cde2..b308879a9f 100644
--- a/src/libs/advanceddockingsystem/dockcontainerwidget.cpp
+++ b/src/libs/advanceddockingsystem/dockcontainerwidget.cpp
@@ -595,7 +595,7 @@ namespace ADS
{
DockWidget *droppedDockWidget = qobject_cast<DockWidget *>(widget);
DockAreaWidget *droppedDockArea = qobject_cast<DockAreaWidget *>(widget);
- DockAreaWidget *newDockArea;
+ DockAreaWidget *newDockArea = nullptr;
if (droppedDockWidget) {
newDockArea = new DockAreaWidget(m_dockManager, q);
@@ -605,6 +605,18 @@ namespace ADS
}
newDockArea->addDockWidget(droppedDockWidget);
} else {
+ // We check, if we insert the dropped widget into the same place that
+ // it already has and do nothing, if it is the same place. It would
+ // also work without this check, but it looks nicer with the check
+ // because there will be no layout updates
+ auto splitter = internal::findParent<DockSplitter*>(droppedDockArea);
+ auto insertParam = internal::dockAreaInsertParameters(area);
+ if (splitter == m_rootSplitter && insertParam.orientation() == splitter->orientation()) {
+ if (insertParam.append() && splitter->lastWidget() == droppedDockArea)
+ return;
+ else if (!insertParam.append() && splitter->firstWidget() == droppedDockArea)
+ return;
+ }
droppedDockArea->dockContainer()->removeDockArea(droppedDockArea);
newDockArea = droppedDockArea;
}
@@ -1217,36 +1229,13 @@ namespace ADS
}
}
- void DockContainerWidget::dropWidget(QWidget *widget, const QPoint &targetPosition)
+ void DockContainerWidget::dropWidget(QWidget *widget, DockWidgetArea dropArea, DockAreaWidget *targetAreaWidget)
{
- qCInfo(adsLog) << Q_FUNC_INFO;
DockWidget *singleDockWidget = topLevelDockWidget();
- DockAreaWidget *dockArea = dockAreaAt(targetPosition);
- auto dropArea = InvalidDockWidgetArea;
- auto containerDropArea = d->m_dockManager->containerOverlay()->dropAreaUnderCursor();
-
- if (dockArea) {
- auto dropOverlay = d->m_dockManager->dockAreaOverlay();
- dropOverlay->setAllowedAreas(dockArea->allowedAreas());
- dropArea = dropOverlay->showOverlay(dockArea);
- if (containerDropArea != InvalidDockWidgetArea && containerDropArea != dropArea) {
- dropArea = InvalidDockWidgetArea;
- }
-
- if (dropArea != InvalidDockWidgetArea) {
- qCInfo(adsLog) << "Dock Area Drop Content: " << dropArea;
- d->moveToNewSection(widget, dockArea, dropArea);
- }
- }
-
- // mouse is over container
- if (InvalidDockWidgetArea == dropArea) {
- dropArea = containerDropArea;
- qCInfo(adsLog) << "Container Drop Content: " << dropArea;
- if (dropArea != InvalidDockWidgetArea) {
- d->moveToContainer(widget, dropArea);
- }
- }
+ if (targetAreaWidget)
+ d->moveToNewSection(widget, targetAreaWidget, dropArea);
+ else
+ d->moveToContainer(widget, dropArea);
// If there was a top level widget before the drop, then it is not top
// level widget anymore
diff --git a/src/libs/advanceddockingsystem/dockcontainerwidget.h b/src/libs/advanceddockingsystem/dockcontainerwidget.h
index 41d1d2f0ba..0d3b930f5d 100644
--- a/src/libs/advanceddockingsystem/dockcontainerwidget.h
+++ b/src/libs/advanceddockingsystem/dockcontainerwidget.h
@@ -104,9 +104,13 @@ protected:
void dropFloatingWidget(FloatingDockContainer *floatingWidget, const QPoint &targetPos);
/**
- * Drop a dock area or a dock widget given in widget parameter
+ * Drop a dock area or a dock widget given in widget parameter.
+ * If the TargetAreaWidget is a nullptr, then the DropArea indicates
+ * the drop area for the container. If the given TargetAreaWidget is not
+ * a nullptr, then the DropArea indicates the drop area in the given
+ * TargetAreaWidget
*/
- void dropWidget(QWidget *widget, const QPoint &targetPos);
+ void dropWidget(QWidget *widget, DockWidgetArea dropArea, DockAreaWidget *targetAreaWidget);
/**
* Adds the given dock area to this container widget
diff --git a/src/libs/advanceddockingsystem/dockoverlay.cpp b/src/libs/advanceddockingsystem/dockoverlay.cpp
index e80fcbba8b..64558e0d48 100644
--- a/src/libs/advanceddockingsystem/dockoverlay.cpp
+++ b/src/libs/advanceddockingsystem/dockoverlay.cpp
@@ -399,6 +399,14 @@ namespace ADS {
return result;
}
+ DockWidgetArea DockOverlay::visibleDropAreaUnderCursor() const
+ {
+ if (isHidden() || !d->m_dropPreviewEnabled)
+ return InvalidDockWidgetArea;
+ else
+ return dropAreaUnderCursor();
+ }
+
DockWidgetArea DockOverlay::showOverlay(QWidget *target)
{
if (d->m_targetWidget == target) {
diff --git a/src/libs/advanceddockingsystem/dockoverlay.h b/src/libs/advanceddockingsystem/dockoverlay.h
index 6d1a192512..e5ee00024e 100644
--- a/src/libs/advanceddockingsystem/dockoverlay.h
+++ b/src/libs/advanceddockingsystem/dockoverlay.h
@@ -94,6 +94,13 @@ public:
DockWidgetArea dropAreaUnderCursor() const;
/**
+ * This function returns the same like dropAreaUnderCursor() if this
+ * overlay is not hidden and if drop preview is enabled and returns
+ * InvalidDockWidgetArea if it is hidden or drop preview is disabled.
+ */
+ DockWidgetArea visibleDropAreaUnderCursor() const;
+
+ /**
* Show the drop overly for the given target widget
*/
DockWidgetArea showOverlay(QWidget *target);
diff --git a/src/libs/advanceddockingsystem/docksplitter.cpp b/src/libs/advanceddockingsystem/docksplitter.cpp
index ec6d8915df..dfc976298c 100644
--- a/src/libs/advanceddockingsystem/docksplitter.cpp
+++ b/src/libs/advanceddockingsystem/docksplitter.cpp
@@ -89,4 +89,14 @@ namespace ADS
return false;
}
+ QWidget *DockSplitter::firstWidget() const
+ {
+ return (count() > 0) ? widget(0) : nullptr;
+ }
+
+ QWidget *DockSplitter::lastWidget() const
+ {
+ return (count() > 0) ? widget(count() - 1) : nullptr;
+ }
+
} // namespace ADS
diff --git a/src/libs/advanceddockingsystem/docksplitter.h b/src/libs/advanceddockingsystem/docksplitter.h
index 45351a34e2..872f2f04d9 100644
--- a/src/libs/advanceddockingsystem/docksplitter.h
+++ b/src/libs/advanceddockingsystem/docksplitter.h
@@ -67,6 +67,16 @@ public:
* Returns true, if any of the internal widgets is visible
*/
bool hasVisibleContent() const;
+
+ /**
+ * Returns first widget or nullptr if splitter is empty
+ */
+ QWidget *firstWidget() const;
+
+ /**
+ * Returns last widget of nullptr is splitter is empty
+ */
+ QWidget *lastWidget() const;
}; // class DockSplitter
} // namespace ADS
diff --git a/src/libs/advanceddockingsystem/floatingdragpreview.cpp b/src/libs/advanceddockingsystem/floatingdragpreview.cpp
index 5732ae408e..539ef4a11c 100644
--- a/src/libs/advanceddockingsystem/floatingdragpreview.cpp
+++ b/src/libs/advanceddockingsystem/floatingdragpreview.cpp
@@ -262,12 +262,14 @@ namespace ADS
void FloatingDragPreview::finishDragging()
{
qCInfo(adsLog) << Q_FUNC_INFO;
- auto dockDropArea = d->m_dockManager->dockAreaOverlay()->dropAreaUnderCursor();
- auto containerDropArea = d->m_dockManager->containerOverlay()->dropAreaUnderCursor();
- bool dropPossible = (dockDropArea != InvalidDockWidgetArea)
- || (containerDropArea != InvalidDockWidgetArea);
- if (d->m_dropContainer && dropPossible) {
- d->m_dropContainer->dropWidget(d->m_content, QCursor::pos());
+ auto dockDropArea = d->m_dockManager->dockAreaOverlay()->visibleDropAreaUnderCursor();
+ auto containerDropArea = d->m_dockManager->containerOverlay()->visibleDropAreaUnderCursor();
+ if (d->m_dropContainer && (dockDropArea != InvalidDockWidgetArea)) {
+ d->m_dropContainer->dropWidget(d->m_content,
+ dockDropArea,
+ d->m_dropContainer->dockAreaAt(QCursor::pos()));
+ } else if (d->m_dropContainer && (containerDropArea != InvalidDockWidgetArea)) {
+ d->m_dropContainer->dropWidget(d->m_content, containerDropArea, nullptr);
} else {
DockWidget *dockWidget = qobject_cast<DockWidget *>(d->m_content);
FloatingDockContainer *floatingWidget = nullptr;