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 CInfoArea *ia = qobject_cast<const CInfoArea *>(this->parent());
26  Q_ASSERT(ia);
27  return ia;
28  }
29 
31  {
32  CInfoArea *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())
52  {
53  if (this->isMinimized()) { return false; }
54  return true;
55  }
56  else { return isSelectedDockWidget(); }
57  }
58 
59  void CDockWidgetInfoArea::addToContextMenu(QMenu *contextMenu) const
60  {
61  QList<const CInfoArea *> parentInfoAreas = this->findParentInfoAreas();
62  Q_ASSERT(!parentInfoAreas.isEmpty());
63  if (parentInfoAreas.isEmpty()) return;
64 
65  // Dockable widget's context menu
66  CDockWidget::addToContextMenu(contextMenu);
67  if (!contextMenu->isEmpty()) { contextMenu->addSeparator(); }
68 
69  // first info area, myself's direct parent info area
70  parentInfoAreas.first()->addToContextMenu(contextMenu);
71 
72  // top info areas other than direct parent
73  // (parent's parent when nested info areas are used)
74  if (parentInfoAreas.size() < 2) { return; }
75  contextMenu->addSeparator();
76  for (int i = 1; i < parentInfoAreas.size(); i++)
77  {
78  const CInfoArea *infoArea = parentInfoAreas.at(i);
79  QString title(infoArea->windowTitle());
80  if (title.isEmpty()) { title = infoArea->objectName(); }
81  QMenu *m = contextMenu->addMenu(title);
82  infoArea->addToContextMenu(m);
83  }
84  }
85 
87  {
88  CDockWidget::initialFloating(); // initial floating to init position & size
89 
90  // set the top level dock widget area to all children
91  QList<CEnableForDockWidgetInfoArea *> infoAreaDockWidgets = this->findEmbeddedDockWidgetInfoAreaComponents();
92  for (CEnableForDockWidgetInfoArea *dwia : infoAreaDockWidgets)
93  {
94  Q_ASSERT_X(dwia, Q_FUNC_INFO, "Missing info area");
95  dwia->setParentDockWidgetInfoArea(this);
96  }
97  }
98 
99  QList<CEnableForDockWidgetInfoArea *> CDockWidgetInfoArea::findEmbeddedDockWidgetInfoAreaComponents()
100  {
101  QList<QWidget *> widgets = this->findChildren<QWidget *>(); // must not use Qt::FindDirectChildrenOnly here
102  QList<CEnableForDockWidgetInfoArea *> widgetsWithDockWidgetInfoAreaComponent;
103  for (QWidget *w : widgets)
104  {
105  Q_ASSERT(w);
106 
107  // CEnableForDockWidgetInfoArea is no QObject, so we use dynamic_cast
109  if (dwc) { widgetsWithDockWidgetInfoAreaComponent.append(dwc); }
110  }
111  QList<CDockWidgetInfoArea *> nestedInfoAreas = this->findNestedInfoAreas();
112  if (nestedInfoAreas.isEmpty()) return widgetsWithDockWidgetInfoAreaComponent;
113 
114  // we have to exclude the nested embedded areas
115  for (CDockWidgetInfoArea *ia : nestedInfoAreas)
116  {
117  QList<CEnableForDockWidgetInfoArea *> nestedInfoAreaComponents =
118  ia->findEmbeddedDockWidgetInfoAreaComponents();
119  if (nestedInfoAreaComponents.isEmpty()) { continue; }
120  for (CEnableForDockWidgetInfoArea *iac : nestedInfoAreaComponents)
121  {
122  const bool r = widgetsWithDockWidgetInfoAreaComponent.removeOne(iac);
123  Q_ASSERT(r); // why is the nested component not in the child list?
124  Q_UNUSED(r)
125  }
126  }
127  return widgetsWithDockWidgetInfoAreaComponent;
128  }
129 
130  QList<CDockWidgetInfoArea *> CDockWidgetInfoArea::findNestedInfoAreas()
131  {
132  // must not use Qt::FindDirectChildrenOnly here
133  QList<CDockWidgetInfoArea *> nestedInfoAreas = this->findChildren<CDockWidgetInfoArea *>();
134  return nestedInfoAreas;
135  }
136 
137  QList<const CInfoArea *> CDockWidgetInfoArea::findParentInfoAreas() const
138  {
139  QList<const CInfoArea *> parents;
140  QWidget *currentWidget = this->parentWidget();
141  while (currentWidget)
142  {
143  const CInfoArea *ia = qobject_cast<CInfoArea *>(currentWidget);
144  if (ia) { parents.append(ia); }
145  currentWidget = currentWidget->parentWidget();
146  }
147  return parents;
148  }
149 } // 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.
virtual 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.
virtual 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:86
bool isSelectedDockWidgetInfoArea(const CDockWidgetInfoArea *infoArea) const
Is given widget selected. Means it is not floating, and the one selected.
Definition: infoarea.cpp:179
High level reusable GUI components.
Definition: aboutdialog.cpp:13
GUI related classes.