Skip to content

Commit a5e8011

Browse files
Implemented custom close handling
1 parent 0305d8a commit a5e8011

10 files changed

+493
-420
lines changed

demo/MainWindow.cpp

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,7 @@
5353
#include <QRubberBand>
5454
#include <QPlainTextEdit>
5555
#include <QTableWidget>
56+
#include <QMessageBox>
5657

5758
#include <QMap>
5859
#include <QElapsedTimer>
@@ -171,6 +172,7 @@ static ads::CDockWidget* createEditorWidget(QMenu* ViewMenu)
171172
ads::CDockWidget* DockWidget = new ads::CDockWidget(QString("Editor %1").arg(EditorCount++));
172173
DockWidget->setWidget(w);
173174
DockWidget->setIcon(svgIcon(":/adsdemo/images/edit.svg"));
175+
DockWidget->setFeature(ads::CDockWidget::CustomCloseHandling, true);
174176
ViewMenu->addAction(DockWidget->toggleViewAction());
175177
return DockWidget;
176178
}
@@ -475,6 +477,21 @@ void CMainWindow::createEditor()
475477
DockWidget->setFeature(ads::CDockWidget::DockWidgetDeleteOnClose, true);
476478
auto FloatingWidget = d->DockManager->addDockWidgetFloating(DockWidget);
477479
FloatingWidget->move(QPoint(20, 20));
480+
connect(DockWidget, SIGNAL(closeRequested()), SLOT(onEditorCloseRequested()));
481+
}
482+
483+
484+
//============================================================================
485+
void CMainWindow::onEditorCloseRequested()
486+
{
487+
auto DockWidget = qobject_cast<ads::CDockWidget*>(sender());
488+
int Result = QMessageBox::question(this, "Close Editor", QString("Editor %1 "
489+
"contains unsaved changes? Would you like to close it?")
490+
.arg(DockWidget->windowTitle()));
491+
if (QMessageBox::Yes == Result)
492+
{
493+
DockWidget->closeDockWidget();
494+
}
478495
}
479496

480497

demo/MainWindow.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,7 @@ private slots:
6161
void onViewToggled(bool Open);
6262
void createEditor();
6363
void createTable();
64+
void onEditorCloseRequested();
6465
};
6566

6667
#endif // MAINWINDOW_H

src/DockAreaTabBar.cpp

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -478,7 +478,14 @@ void CDockAreaTabBar::onCloseOtherTabsRequested()
478478
int Offset = Tab->dockWidget()->features().testFlag(
479479
CDockWidget::DockWidgetDeleteOnClose) ? 1 : 0;
480480
closeTab(i);
481-
i -= Offset;
481+
482+
// If the the dock widget blocks closing, i.e. if the flag
483+
// CustomCloseHandling is set, and the dock widget is still open,
484+
// then we do not need to correct the index
485+
if (Tab->dockWidget()->isClosed())
486+
{
487+
i -= Offset;
488+
}
482489
}
483490
}
484491
}
@@ -569,7 +576,7 @@ void CDockAreaTabBar::closeTab(int Index)
569576
{
570577
return;
571578
}
572-
Tab->hide();
579+
//Tab->hide();
573580
emit tabCloseRequested(Index);
574581
}
575582

src/DockAreaWidget.cpp

Lines changed: 19 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -495,7 +495,7 @@ void CDockAreaWidget::onTabCloseRequested(int Index)
495495
if (DockWidget->features().testFlag(CDockWidget::DockWidgetDeleteOnClose))
496496
{
497497
//DockWidget->deleteDockWidget();
498-
DockWidget->closeDockWidget();
498+
DockWidget->closeDockWidgetInternal();
499499
}
500500
else
501501
{
@@ -758,15 +758,26 @@ CDockWidget* CDockAreaWidget::nextOpenDockWidget(CDockWidget* DockWidget) const
758758

759759

760760
//============================================================================
761-
CDockWidget::DockWidgetFeatures CDockAreaWidget::features() const
761+
CDockWidget::DockWidgetFeatures CDockAreaWidget::features(eBitwiseOperator Mode) const
762762
{
763-
CDockWidget::DockWidgetFeatures Features(CDockWidget::AllDockWidgetFeatures);
764-
for (const auto DockWidget : dockWidgets())
763+
if (BitwiseAnd == Mode)
765764
{
766-
Features &= DockWidget->features();
765+
CDockWidget::DockWidgetFeatures Features(CDockWidget::AllDockWidgetFeatures);
766+
for (const auto DockWidget : dockWidgets())
767+
{
768+
Features &= DockWidget->features();
769+
}
770+
return Features;
771+
}
772+
else
773+
{
774+
CDockWidget::DockWidgetFeatures Features(CDockWidget::NoDockWidgetFeatures);
775+
for (const auto DockWidget : dockWidgets())
776+
{
777+
Features |= DockWidget->features();
778+
}
779+
return Features;
767780
}
768-
769-
return Features;
770781
}
771782

772783

@@ -805,7 +816,7 @@ void CDockAreaWidget::closeArea()
805816
auto OpenDockWidgets = openedDockWidgets();
806817
if (OpenDockWidgets.count() == 1 && OpenDockWidgets[0]->features().testFlag(CDockWidget::DockWidgetDeleteOnClose))
807818
{
808-
OpenDockWidgets[0]->deleteDockWidget();
819+
OpenDockWidgets[0]->closeDockWidgetInternal();
809820
}
810821
else
811822
{

src/DockAreaWidget.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -238,10 +238,10 @@ protected slots:
238238
* A bitwise and is used to combine the flags of all dock widgets. That
239239
* means, if only one single dock widget does not support a certain flag,
240240
* the whole dock are does not support the flag. I.e. if one single
241-
* dock widget in this area is not closabe, the whole dock are is not
241+
* dock widget in this area is not closable, the whole dock are is not
242242
* closable.
243243
*/
244-
CDockWidget::DockWidgetFeatures features() const;
244+
CDockWidget::DockWidgetFeatures features(eBitwiseOperator Mode = BitwiseAnd) const;
245245

246246
/**
247247
* Returns the title bar button corresponding to the given title bar

src/DockContainerWidget.cpp

Lines changed: 16 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1713,10 +1713,24 @@ void CDockContainerWidget::closeOtherAreas(CDockAreaWidget* KeepOpenArea)
17131713
{
17141714
for (const auto DockArea : d->DockAreas)
17151715
{
1716-
if (DockArea != KeepOpenArea && DockArea->features().testFlag(CDockWidget::DockWidgetClosable))
1716+
if (DockArea == KeepOpenArea)
17171717
{
1718-
DockArea->closeArea();
1718+
continue;
1719+
}
1720+
1721+
if (!DockArea->features(BitwiseAnd).testFlag(CDockWidget::DockWidgetClosable))
1722+
{
1723+
continue;
17191724
}
1725+
1726+
// We do not close areas with widgets with custom close handling
1727+
if (DockArea->features(BitwiseOr).testFlag(CDockWidget::CustomCloseHandling))
1728+
{
1729+
std::cout << "CDockWidget::CustomCloseHandling" << std::endl;
1730+
continue;
1731+
}
1732+
1733+
DockArea->closeArea();
17201734
}
17211735
}
17221736

src/DockWidget.cpp

Lines changed: 15 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -64,7 +64,7 @@ struct DockWidgetPrivate
6464
QBoxLayout* Layout = nullptr;
6565
QWidget* Widget = nullptr;
6666
CDockWidgetTab* TabWidget = nullptr;
67-
CDockWidget::DockWidgetFeatures Features = CDockWidget::AllDockWidgetFeatures;
67+
CDockWidget::DockWidgetFeatures Features = CDockWidget::DefaultDockWidgetFeatures;
6868
CDockManager* DockManager = nullptr;
6969
CDockAreaWidget* DockArea = nullptr;
7070
QAction* ToggleViewAction = nullptr;
@@ -744,42 +744,40 @@ void CDockWidget::deleteDockWidget()
744744
{
745745
dockManager()->removeDockWidget(this);
746746
deleteLater();
747+
d->Closed = true;
747748
}
748749

749750

750751
//============================================================================
751-
bool CDockWidget::handleCloseRequest()
752+
void CDockWidget::closeDockWidget()
752753
{
753-
std::cout << "CDockWidget::handleCloseRequest()" << std::endl;
754-
return true;
754+
closeDockWidgetInternal(true);
755755
}
756756

757757

758758
//============================================================================
759-
void CDockWidget::closeDockWidget()
759+
bool CDockWidget::closeDockWidgetInternal(bool ForceClose)
760760
{
761-
closeDockWidgetInternal();
762-
}
761+
if (!ForceClose)
762+
{
763+
emit closeRequested();
764+
}
763765

766+
if (!ForceClose && features().testFlag(CDockWidget::CustomCloseHandling))
767+
{
768+
return false;
769+
}
764770

765-
//============================================================================
766-
bool CDockWidget::closeDockWidgetInternal()
767-
{
768771
if (features().testFlag(CDockWidget::DockWidgetDeleteOnClose))
769772
{
770-
if (handleCloseRequest())
771-
{
772-
deleteDockWidget();
773-
return true;
774-
}
773+
deleteDockWidget();
775774
}
776775
else
777776
{
778777
toggleView(false);
779-
return true;
780778
}
781779

782-
return false;
780+
return true;
783781
}
784782

785783

0 commit comments

Comments
 (0)