Fraxinus  2023.01.05-dev+develop.0da12
An IGT application
cxDynamicMainWindowWidgets.cpp
Go to the documentation of this file.
2 #include <QDockWidget>
3 #include <QMainWindow>
4 #include <QScrollArea>
5 #include <QToolBar>
6 #include <QMenu>
7 #include <iostream>
8 #include "cxLogger.h"
9 #include "cxStateService.h"
10 
11 namespace cx
12 {
13 
15  mMainWindow(mainWindow)
16 {
17  // use dummy toolbar to force default preset toolbars to the left
18  mFirstDummyToolbar = new QToolBar;
19  mFirstDummyToolbar->setObjectName("dummy_toolbar");
20 // mFirstDummyToolbar->hide();
21  mMainWindow->addToolBar(mFirstDummyToolbar);
22 }
23 
24 QDockWidget* DynamicMainWindowWidgets::addAsDockWidget(QWidget* widget, QString groupname, QObject* owningPlugin)
25 {
26  QDockWidget* dockWidget = this->createDockWidget(widget);
27  mMainWindow->addDockWidget(Qt::LeftDockWidgetArea, dockWidget);
28 
29  this->tabifyWidget(dockWidget);
30 
31  DynamicWidget item;
32  item.mWidget = dockWidget;
33  dockWidget->setVisible(false); // default visibility
34 
35  item.mGroup = groupname;
36  item.mName = widget->windowTitle();
37  mMainWindow->restoreDockWidget(dockWidget); // restore if added after construction
38 
39  item.mOwningService = owningPlugin;
40 
41  connect(dockWidget->toggleViewAction(), &QAction::triggered, this, &DynamicMainWindowWidgets::onWidgetActionTriggered);
42 
43  mItems.push_back(item);
44  return dockWidget;
45 }
46 
47 void DynamicMainWindowWidgets::registerToolBar(QToolBar* toolbar, QString groupname)
48 {
49  DynamicWidget item;
50  item.mWidget = toolbar;
51  item.mGroup = groupname;
52  item.mName = toolbar->windowTitle();
53  mItems.push_back(item);
54 
55  mMainWindow->addToolBar(toolbar);
56  // this avoids overpopulation of gui at startup, and is the same functionality as for dockwidgets.
57  // also gives correct size of mainwindow at startup.
58  toolbar->hide();
59 }
60 
61 QDockWidget* DynamicMainWindowWidgets::createDockWidget(QWidget* widget)
62 {
63  QScrollArea* scroller = this->addVerticalScroller(widget);
64  QDockWidget* dockWidget = new QDockWidget(widget->windowTitle(), mMainWindow);
65  connect(widget, &QWidget::windowTitleChanged, this, &DynamicMainWindowWidgets::onConsoleWindowTitleChanged);
66  dockWidget->setObjectName(widget->objectName() + "DockWidget");
67  dockWidget->setFocusPolicy(Qt::StrongFocus); // we really want to focus on the embedded widget, see focusInsideDockWidget()
68  dockWidget->setWidget(scroller);
69  return dockWidget;
70 }
71 
73 {
74  for (unsigned i=0; i<mItems.size(); ++i)
75  {
76  DynamicWidget item = mItems[i];
77 
78  if (item.mName != name)
79  {
80  continue;
81  }
82 
83  QDockWidget* dockWidget = dynamic_cast<QDockWidget*>(item.mWidget);
84  if (!dockWidget)
85  continue;
86 
87  dockWidget->show();
88  dockWidget->raise();
89  }
90 }
91 
93 {
94  this->hideAll();
95  mMainWindow->restoreState(desktop.mMainWindowState);
96 
97  for (unsigned i=0; i<desktop.mPresets.size(); ++i)
98  this->restorePreset(desktop.mPresets[i]);
99 }
100 
101 void DynamicMainWindowWidgets::restorePreset(const Desktop::Preset& preset)
102 {
103  QToolBar* tb = mMainWindow->findChild<QToolBar*>(preset.name);
104  if (tb)
105  {
106  // add before dummy
107  mMainWindow->removeToolBar(tb);
108  mMainWindow->insertToolBar(mFirstDummyToolbar, tb);
109  tb->show();
110  return;
111  }
112 
113  QDockWidget* dw = mMainWindow->findChild<QDockWidget*>(preset.name+"DockWidget");
114  if (dw)
115  {
116  dw->show();
117  if (preset.tabbed)
118  {
119  QDockWidget* first = this->getFirstDockWidget(Qt::DockWidgetArea(preset.position));
120  if (first)
121  mMainWindow->tabifyDockWidget(first, dw);
122  else
123  mMainWindow->addDockWidget(Qt::DockWidgetArea(preset.position), dw);
124  }
125  else
126  {
127  mMainWindow->addDockWidget(Qt::DockWidgetArea(preset.position), dw);
128  }
129  return;
130  }
131 
132  CX_LOG_WARNING() << QString("Attempted to restore a nonexitent preset widget: [%1]").arg(preset.name);
133 }
134 
135 void DynamicMainWindowWidgets::onWidgetActionTriggered(bool checked)
136 {
137  QAction* action = dynamic_cast<QAction*>(sender());
138  if (!action)
139  return;
140  QWidget* widget = dynamic_cast<QWidget*>(action->parent());
141  if (!widget)
142  return;
143 
144  // if dockwidgets is tabbed, this ensures that the widget is shown instead
145  // of merely showing the tab.
146  if (checked)
147  widget->raise();
148 }
149 
151 {
152  for (unsigned i=0; i<mItems.size(); )
153  {
154  DynamicWidget item = mItems[i];
155 
156  if (item.mOwningService != service)
157  {
158  ++i;
159  continue;
160  }
161  else
162  {
163  mItems.erase(mItems.begin()+i);
164 
165  QDockWidget* dockWidget = dynamic_cast<QDockWidget*>(item.mWidget);
166  if (dockWidget)
167  mMainWindow->removeDockWidget(dockWidget);
168  }
169  }
170 }
171 
172 void DynamicMainWindowWidgets::onConsoleWindowTitleChanged(const QString & title)
173 {
174  QWidget* widget = dynamic_cast<QWidget*>(sender());
175 
176  for (int i=0; i<3; ++i)
177  {
178  if (!widget)
179  return;
180  QDockWidget* dockWidget = dynamic_cast<QDockWidget*>(widget);
181  if (dockWidget)
182  {
183  dockWidget->setWindowTitle(title);
184  return;
185  }
186  widget = widget->parentWidget();
187  }
188 }
189 
190 QScrollArea* DynamicMainWindowWidgets::addVerticalScroller(QWidget *widget)
191 {
192  QScrollArea* scroller = new QScrollArea(NULL);
193  scroller->setWidget(widget);
194  widget->setParent(scroller);
195  scroller->setWidgetResizable(true);
196  scroller->setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
197  QSizePolicy policy = scroller->sizePolicy();
198  policy.setHorizontalPolicy(QSizePolicy::Minimum);
199  scroller->setSizePolicy(policy);
200  return scroller;
201 }
202 
203 void DynamicMainWindowWidgets::tabifyWidget(QDockWidget* dockWidget)
204 {
205  QDockWidget* widget = this->getFirstDockWidget(Qt::LeftDockWidgetArea);
206 
207  if (widget)
208  mMainWindow->tabifyDockWidget(widget, dockWidget);
209 }
210 
211 QDockWidget* DynamicMainWindowWidgets::getFirstDockWidget(Qt::DockWidgetArea area)
212 {
213  for (unsigned i=0; i<mItems.size(); ++i)
214  {
215  QDockWidget* widget = dynamic_cast<QDockWidget*>(mItems[i].mWidget);
216  if (!widget)
217  continue;
218  if (mMainWindow->dockWidgetArea(widget) == Qt::LeftDockWidgetArea)
219  return widget;
220  }
221  return NULL;
222 }
223 
225 {
226  for (unsigned i=0; i<mItems.size(); ++i)
227  {
228  mItems[i].mWidget->hide();
229 
230  QToolBar* toolbar = dynamic_cast<QToolBar*>(mItems[i].mWidget);
231  if (toolbar)
232  {
233  // move to end of list (i.e. after dummy)
234  mMainWindow->removeToolBar(toolbar);
235  mMainWindow->addToolBar(toolbar);
236  }
237  }
238 
239 }
240 
241 void DynamicMainWindowWidgets::addToWidgetGroupMap(ActionGroupMap& groups, QAction* action, QString groupname)
242 {
243  action->setMenuRole(QAction::NoRole);
244 
245  if (!groups.count(groupname))
246  {
247  QActionGroup* group = new QActionGroup(this);
248  group->setExclusive(false);
249  groups[groupname] = group;
250 
251  QAction* heading = new QAction(groupname, this);
252  heading->setDisabled(true);
253  groups[groupname]->addAction(heading);
254  }
255 
256  groups[groupname]->addAction(action);
257 }
258 
260 {
261  // temp attempt: split menu into two parts: widgets and toolbars. - fix
262 
263  QMenu* popupMenu = new QMenu;
264 
265  ActionGroupMap groups;
266  ActionGroupMap tgroups;
267  for (unsigned i=0; i<mItems.size(); ++i)
268  {
269  QDockWidget* widget = dynamic_cast<QDockWidget*>(mItems[i].mWidget);
270  if (widget)
271  this->addToWidgetGroupMap(groups, widget->toggleViewAction(), mItems[i].mGroup);
272  QToolBar* toolbar = dynamic_cast<QToolBar*>(mItems[i].mWidget);
273  if (toolbar)
274  this->addToWidgetGroupMap(tgroups, toolbar->toggleViewAction(), mItems[i].mGroup);
275  }
276 
277  QMenu* widgets = popupMenu->addMenu("Widgets");
278 
279  for(std::map<QString, QActionGroup*>::iterator it = groups.begin(); it != groups.end(); ++it)
280  {
281  widgets->addSeparator();
282  widgets->addActions(it->second->actions());
283  }
284 
285  QMenu* toolbars = popupMenu->addMenu("Toolbars");
286 
287  for(std::map<QString, QActionGroup*>::iterator it = tgroups.begin(); it != tgroups.end(); ++it)
288  {
289  toolbars->addSeparator();
290  toolbars->addActions(it->second->actions());
291  }
292 
293  return popupMenu;
294 }
295 
296 } // namespace cx
std::vector< Preset > mPresets
void registerToolBar(QToolBar *toolbar, QString groupname="Toolbars")
DynamicMainWindowWidgets(QMainWindow *mainWindow)
void restoreFrom(const Desktop &desktop)
QByteArray mMainWindowState
Data class for CustusX desktop.
#define CX_LOG_WARNING
Definition: cxLogger.h:98
QDockWidget * addAsDockWidget(QWidget *widget, QString groupname, QObject *owningPlugin=NULL)
Namespace for all CustusX production code.