swift
dockwidgetinfoarea.cpp
1 // SPDX-FileCopyrightText: Copyright (C) 2013 swift Project Community / Contributors
2 // SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-swift-pilot-client-1
3 
5 
6 #include <QMenu>
7 #include <QString>
8 #include <QWidget>
9 #include <QtGlobal>
10 
12 #include "gui/infoarea.h"
13 
14 using namespace swift::gui::components;
15 
16 namespace swift::gui
17 {
19  {
20  // void
21  }
22 
24  {
25  const auto *ia = qobject_cast<const CInfoArea *>(this->parent());
26  Q_ASSERT(ia);
27  return ia;
28  }
29 
31  {
32  auto *ia = qobject_cast<CInfoArea *>(this->parent());
33  Q_ASSERT(ia);
34  return ia;
35  }
36 
38  {
39  const CInfoArea *ia = getParentInfoArea();
40  if (!ia) { return false; }
41  return ia->isSelectedDockWidgetInfoArea(this);
42  }
43 
45  {
46  // if the widget is invisible we are done
47  // but if it is visible, there is no guarantee it can be seen by the user
48  if (!this->isVisible()) { return false; }
49 
50  // further checks
51  if (this->isFloating()) { return !this->isMinimized(); }
52  else { return isSelectedDockWidget(); }
53  }
54 
56  {
57  QList<const CInfoArea *> parentInfoAreas = this->findParentInfoAreas();
58  Q_ASSERT(!parentInfoAreas.isEmpty());
59  if (parentInfoAreas.isEmpty()) return;
60 
61  // Dockable widget's context menu
62  CDockWidget::addToContextMenu(contextMenu);
63  if (!contextMenu->isEmpty()) { contextMenu->addSeparator(); }
64 
65  // first info area, myself's direct parent info area
66  parentInfoAreas.first()->addToContextMenu(contextMenu);
67 
68  // top info areas other than direct parent
69  // (parent's parent when nested info areas are used)
70  if (parentInfoAreas.size() < 2) { return; }
71  contextMenu->addSeparator();
72  for (int i = 1; i < parentInfoAreas.size(); i++)
73  {
74  const CInfoArea *infoArea = parentInfoAreas.at(i);
75  QString title(infoArea->windowTitle());
76  if (title.isEmpty()) { title = infoArea->objectName(); }
77  QMenu *m = contextMenu->addMenu(title);
78  infoArea->addToContextMenu(m);
79  }
80  }
81 
83  {
84  CDockWidget::initialFloating(); // initial floating to init position & size
85 
86  // set the top level dock widget area to all children
87  QList<CEnableForDockWidgetInfoArea *> infoAreaDockWidgets = this->findEmbeddedDockWidgetInfoAreaComponents();
88  for (CEnableForDockWidgetInfoArea *dwia : infoAreaDockWidgets)
89  {
90  Q_ASSERT_X(dwia, Q_FUNC_INFO, "Missing info area");
91  dwia->setParentDockWidgetInfoArea(this);
92  }
93  }
94 
95  QList<CEnableForDockWidgetInfoArea *> CDockWidgetInfoArea::findEmbeddedDockWidgetInfoAreaComponents()
96  {
97  QList<QWidget *> widgets = this->findChildren<QWidget *>(); // must not use Qt::FindDirectChildrenOnly here
98  QList<CEnableForDockWidgetInfoArea *> widgetsWithDockWidgetInfoAreaComponent;
99  for (QWidget *w : widgets)
100  {
101  Q_ASSERT(w);
102 
103  // CEnableForDockWidgetInfoArea is no QObject, so we use dynamic_cast
104  auto *dwc = dynamic_cast<CEnableForDockWidgetInfoArea *>(w);
105  if (dwc) { widgetsWithDockWidgetInfoAreaComponent.append(dwc); }
106  }
107  QList<CDockWidgetInfoArea *> nestedInfoAreas = this->findNestedInfoAreas();
108  if (nestedInfoAreas.isEmpty()) return widgetsWithDockWidgetInfoAreaComponent;
109 
110  // we have to exclude the nested embedded areas
111  for (CDockWidgetInfoArea *ia : nestedInfoAreas)
112  {
113  QList<CEnableForDockWidgetInfoArea *> nestedInfoAreaComponents =
114  ia->findEmbeddedDockWidgetInfoAreaComponents();
115  if (nestedInfoAreaComponents.isEmpty()) { continue; }
116  for (CEnableForDockWidgetInfoArea *iac : nestedInfoAreaComponents)
117  {
118  const bool r = widgetsWithDockWidgetInfoAreaComponent.removeOne(iac);
119  Q_ASSERT(r); // why is the nested component not in the child list?
120  Q_UNUSED(r)
121  }
122  }
123  return widgetsWithDockWidgetInfoAreaComponent;
124  }
125 
126  QList<CDockWidgetInfoArea *> CDockWidgetInfoArea::findNestedInfoAreas()
127  {
128  // must not use Qt::FindDirectChildrenOnly here
129  QList<CDockWidgetInfoArea *> nestedInfoAreas = this->findChildren<CDockWidgetInfoArea *>();
130  return nestedInfoAreas;
131  }
132 
133  QList<const CInfoArea *> CDockWidgetInfoArea::findParentInfoAreas() const
134  {
135  QList<const CInfoArea *> parents;
136  QWidget *currentWidget = this->parentWidget();
137  while (currentWidget)
138  {
139  const CInfoArea *ia = qobject_cast<CInfoArea *>(currentWidget);
140  if (ia) { parents.append(ia); }
141  currentWidget = currentWidget->parentWidget();
142  }
143  return parents;
144  }
145 } // namespace swift::gui
Our base class for dockable widgets containing some specialized functionality on top of QDockWidget.
Definition: dockwidget.h:52
virtual void addToContextMenu(QMenu *contextMenu) const
Contribute to menu.
Definition: dockwidget.cpp:383
virtual void initialFloating()
Widget is initialized by being a floating window for a shot period.
Definition: dockwidget.cpp:413
const CInfoArea * getParentInfoArea() const
The parent info area.
CDockWidgetInfoArea(QWidget *parent=nullptr)
Constructor.
void initialFloating()
Widget is initialized by being a floating window for a shot period.
bool isVisibleWidget() const
Visible widget.
bool isSelectedDockWidget() const
Is this the selected widget, means it is not floating, and it is the one selected.
void addToContextMenu(QMenu *contextMenu) const
Contribute to menu.
Helper class: If a component is residing in an dockable widget. This class provides access to its inf...
Info area, hosting dockable widgets.
Definition: infoarea.h:41
void addToContextMenu(QMenu *menu) const
Add items to context menu.
Definition: infoarea.cpp:84
bool isSelectedDockWidgetInfoArea(const CDockWidgetInfoArea *infoArea) const
Is given widget selected. Means it is not floating, and the one selected.
Definition: infoarea.cpp:177
High level reusable GUI components.
Definition: aboutdialog.cpp:14
GUI related classes.
bool isFloating() const const
void append(QList< T > &&value)
QList< T >::const_reference at(qsizetype i) const const
T & first()
bool isEmpty() const const
bool removeOne(const AT &t)
qsizetype size() const const
QAction * addMenu(QMenu *menu)
QAction * addSeparator()
bool isEmpty() const const
QObject * parent() const const
bool isEmpty() const const
bool isMinimized() const const
QWidget * parentWidget() const const
bool isVisible() const const