forked from qt-creator/qt-creator
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>
This commit is contained in:
committed by
Henning Gründl
parent
206e7d3e70
commit
0b7970feb4
@@ -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) {
|
||||
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
|
||||
|
@@ -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
|
||||
|
@@ -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) {
|
||||
|
@@ -93,6 +93,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
|
||||
*/
|
||||
|
@@ -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
|
||||
|
@@ -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
|
||||
|
@@ -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;
|
||||
|
Reference in New Issue
Block a user