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);
|
DockWidget *droppedDockWidget = qobject_cast<DockWidget *>(widget);
|
||||||
DockAreaWidget *droppedDockArea = qobject_cast<DockAreaWidget *>(widget);
|
DockAreaWidget *droppedDockArea = qobject_cast<DockAreaWidget *>(widget);
|
||||||
DockAreaWidget *newDockArea;
|
DockAreaWidget *newDockArea = nullptr;
|
||||||
|
|
||||||
if (droppedDockWidget) {
|
if (droppedDockWidget) {
|
||||||
newDockArea = new DockAreaWidget(m_dockManager, q);
|
newDockArea = new DockAreaWidget(m_dockManager, q);
|
||||||
@@ -605,6 +605,18 @@ namespace ADS
|
|||||||
}
|
}
|
||||||
newDockArea->addDockWidget(droppedDockWidget);
|
newDockArea->addDockWidget(droppedDockWidget);
|
||||||
} else {
|
} 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);
|
droppedDockArea->dockContainer()->removeDockArea(droppedDockArea);
|
||||||
newDockArea = 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();
|
DockWidget *singleDockWidget = topLevelDockWidget();
|
||||||
DockAreaWidget *dockArea = dockAreaAt(targetPosition);
|
if (targetAreaWidget)
|
||||||
auto dropArea = InvalidDockWidgetArea;
|
d->moveToNewSection(widget, targetAreaWidget, dropArea);
|
||||||
auto containerDropArea = d->m_dockManager->containerOverlay()->dropAreaUnderCursor();
|
else
|
||||||
|
|
||||||
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);
|
d->moveToContainer(widget, dropArea);
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// If there was a top level widget before the drop, then it is not top
|
// If there was a top level widget before the drop, then it is not top
|
||||||
// level widget anymore
|
// level widget anymore
|
||||||
|
@@ -104,9 +104,13 @@ protected:
|
|||||||
void dropFloatingWidget(FloatingDockContainer *floatingWidget, const QPoint &targetPos);
|
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
|
* Adds the given dock area to this container widget
|
||||||
|
@@ -399,6 +399,14 @@ namespace ADS {
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
DockWidgetArea DockOverlay::visibleDropAreaUnderCursor() const
|
||||||
|
{
|
||||||
|
if (isHidden() || !d->m_dropPreviewEnabled)
|
||||||
|
return InvalidDockWidgetArea;
|
||||||
|
else
|
||||||
|
return dropAreaUnderCursor();
|
||||||
|
}
|
||||||
|
|
||||||
DockWidgetArea DockOverlay::showOverlay(QWidget *target)
|
DockWidgetArea DockOverlay::showOverlay(QWidget *target)
|
||||||
{
|
{
|
||||||
if (d->m_targetWidget == target) {
|
if (d->m_targetWidget == target) {
|
||||||
|
@@ -93,6 +93,13 @@ public:
|
|||||||
*/
|
*/
|
||||||
DockWidgetArea dropAreaUnderCursor() const;
|
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
|
* Show the drop overly for the given target widget
|
||||||
*/
|
*/
|
||||||
|
@@ -89,4 +89,14 @@ namespace ADS
|
|||||||
return false;
|
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
|
} // namespace ADS
|
||||||
|
@@ -67,6 +67,16 @@ public:
|
|||||||
* Returns true, if any of the internal widgets is visible
|
* Returns true, if any of the internal widgets is visible
|
||||||
*/
|
*/
|
||||||
bool hasVisibleContent() const;
|
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
|
}; // class DockSplitter
|
||||||
|
|
||||||
} // namespace ADS
|
} // namespace ADS
|
||||||
|
@@ -262,12 +262,14 @@ namespace ADS
|
|||||||
void FloatingDragPreview::finishDragging()
|
void FloatingDragPreview::finishDragging()
|
||||||
{
|
{
|
||||||
qCInfo(adsLog) << Q_FUNC_INFO;
|
qCInfo(adsLog) << Q_FUNC_INFO;
|
||||||
auto dockDropArea = d->m_dockManager->dockAreaOverlay()->dropAreaUnderCursor();
|
auto dockDropArea = d->m_dockManager->dockAreaOverlay()->visibleDropAreaUnderCursor();
|
||||||
auto containerDropArea = d->m_dockManager->containerOverlay()->dropAreaUnderCursor();
|
auto containerDropArea = d->m_dockManager->containerOverlay()->visibleDropAreaUnderCursor();
|
||||||
bool dropPossible = (dockDropArea != InvalidDockWidgetArea)
|
if (d->m_dropContainer && (dockDropArea != InvalidDockWidgetArea)) {
|
||||||
|| (containerDropArea != InvalidDockWidgetArea);
|
d->m_dropContainer->dropWidget(d->m_content,
|
||||||
if (d->m_dropContainer && dropPossible) {
|
dockDropArea,
|
||||||
d->m_dropContainer->dropWidget(d->m_content, QCursor::pos());
|
d->m_dropContainer->dockAreaAt(QCursor::pos()));
|
||||||
|
} else if (d->m_dropContainer && (containerDropArea != InvalidDockWidgetArea)) {
|
||||||
|
d->m_dropContainer->dropWidget(d->m_content, containerDropArea, nullptr);
|
||||||
} else {
|
} else {
|
||||||
DockWidget *dockWidget = qobject_cast<DockWidget *>(d->m_content);
|
DockWidget *dockWidget = qobject_cast<DockWidget *>(d->m_content);
|
||||||
FloatingDockContainer *floatingWidget = nullptr;
|
FloatingDockContainer *floatingWidget = nullptr;
|
||||||
|
Reference in New Issue
Block a user