Fraxinus  16.5.0-fx-rc6
An IGT application
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
cxConsoleWidgetCollection.cpp
Go to the documentation of this file.
1 /*=========================================================================
2 This file is part of CustusX, an Image Guided Therapy Application.
3 
4 Copyright (c) 2008-2014, SINTEF Department of Medical Technology
5 All rights reserved.
6 
7 Redistribution and use in source and binary forms, with or without
8 modification, are permitted provided that the following conditions are met:
9 
10 1. Redistributions of source code must retain the above copyright notice,
11  this list of conditions and the following disclaimer.
12 
13 2. Redistributions in binary form must reproduce the above copyright notice,
14  this list of conditions and the following disclaimer in the documentation
15  and/or other materials provided with the distribution.
16 
17 3. Neither the name of the copyright holder nor the names of its contributors
18  may be used to endorse or promote products derived from this software
19  without specific prior written permission.
20 
21 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
22 AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
23 IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
24 DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
25 FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
26 DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
27 SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
28 CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
29 OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
30 OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
31 =========================================================================*/
32 
34 
35 #include <QDockWidget>
36 #include <QMenu>
37 #include <QTimer>
38 //#include <QApplication>
39 #include <QDebug>
40 //#include <QDesktopWidget>
41 #include <QBuffer>
42 #include <QDataStream>
43 #include "cxProfile.h"
44 #include "cxConsoleWidget.h"
45 #include "cxNullDeleter.h"
46 
47 namespace cx
48 {
49 
50 ConsoleWidgetCollection::ConsoleWidgetCollection(QWidget* parent, QString objectName, QString windowTitle, XmlOptionFile options, LogPtr log) :
51  QMainWindow(parent), mObjectName(objectName), mWindowTitle(windowTitle)
52 {
53  this->setObjectName(mObjectName);
54  this->setWindowTitle(mWindowTitle);
55  mOptions = options;
56  mLog = log;
57 
58  this->setupUI();
59 }
60 
61 ConsoleWidgetCollection::ConsoleWidgetCollection(QWidget* parent, QString objectName, QString windowTitle) :
62  QMainWindow(parent), mObjectName(objectName), mWindowTitle(windowTitle)
63 {
64  this->setObjectName(mObjectName);
65  this->setWindowTitle(mWindowTitle);
66  mOptions = profile()->getXmlSettings().descend(this->objectName());
67  mLog = reporter();
68 
69  this->setupUI();
70 }
71 
72 void ConsoleWidgetCollection::setupUI()
73 {
74  this->setFocusPolicy(Qt::StrongFocus); // needed for help system: focus is used to display help text
75 
76  this->setDockNestingEnabled(true);
77  this->setTabPosition(Qt::AllDockWidgetAreas, QTabWidget::North);
78 
79  int consoleCount = this->option("consoleCount").readVariant(-1).toInt();
80 
81  for (int i=0; i<consoleCount; ++i)
82  {
83  this->addConsole();
84  }
85 
86  // Restore saved window states
87  // Must be done after all DockWidgets are created
88 
89  this->restoreState(this->option("windowState").readVariant().toByteArray());
90 
91  // default: add two consoles
92  if (mDockWidgets.empty())
93  {
94  this->onNewConsole();
95  this->onNewConsole();
96  }
97 }
98 
99 XmlOptionItem ConsoleWidgetCollection::option(QString name)
100 {
101  return XmlOptionItem(name, mOptions.getElement());
102 }
103 
105 {
106  this->option("windowState").writeVariant(this->saveState());
107  this->option("consoleCount").writeVariant(QVariant::fromValue<int>(mDockWidgets.size()));
108 }
109 
110 void ConsoleWidgetCollection::onDockWidgetVisibilityChanged(bool val)
111 {
112  if (!this->isVisible())
113  {
114 // std::cout << "ignore remove - parent hidden" << std::endl;
115  return;
116  }
117 
118  QTimer::singleShot(0, this, SLOT(checkVisibility()));
119 }
120 
121 void ConsoleWidgetCollection::checkVisibility()
122 {
123  this->removeHiddenConsoles();
124 }
125 
126 void ConsoleWidgetCollection::removeHiddenConsoles()
127 {
128  for (int i=0; i<mDockWidgets.size(); )
129  {
130  if (!mDockWidgets[i]->isVisible())
131  this->deleteDockWidget(mDockWidgets[i]);
132  else
133  ++i;
134  }
135 }
136 
137 QDockWidget* ConsoleWidgetCollection::addAsDockWidget(QWidget* widget)
138 {
139  QDockWidget* dockWidget = this->createDockWidget(widget);
140 
141  mDockWidgets.push_back(dockWidget);
142 
143  connect(dockWidget, &QDockWidget::visibilityChanged,
144  this, &ConsoleWidgetCollection::onDockWidgetVisibilityChanged);
145 
146  this->addDockWidget(Qt::LeftDockWidgetArea, dockWidget);
147  return dockWidget;
148 }
149 
150 QDockWidget* ConsoleWidgetCollection::createDockWidget(QWidget* widget)
151 {
152  QDockWidget* dockWidget = new QDockWidget(widget->windowTitle(), this);
153  connect(widget, &QWidget::windowTitleChanged, this, &ConsoleWidgetCollection::onConsoleWindowTitleChanged);
154  dockWidget->setFeatures(QDockWidget::DockWidgetClosable | QDockWidget::DockWidgetMovable);
155  dockWidget->setObjectName(widget->objectName() + "DockWidget");
156  dockWidget->setWidget(widget);
157  return dockWidget;
158 }
159 
160 void ConsoleWidgetCollection::onConsoleWindowTitleChanged(const QString & title)
161 {
162  QWidget* widget = dynamic_cast<QWidget*>(sender());
163  QDockWidget* dockWidget = dynamic_cast<QDockWidget*>(sender()->parent());
164  if (!widget || !dockWidget)
165  return;
166  dockWidget->setWindowTitle(widget->windowTitle());
167 }
168 
169 void ConsoleWidgetCollection::deleteDockWidget(QDockWidget* dockWidget)
170 {
171  disconnect(dockWidget, &QDockWidget::visibilityChanged,
172  this, &ConsoleWidgetCollection::onDockWidgetVisibilityChanged);
173 
174  this->removeDockWidget(dockWidget);
175  mDockWidgets.removeAll(dockWidget);
176  dockWidget->deleteLater();
177 
178  for (int i=0; i<mDockWidgets.size(); ++i)
179  {
180  QString uid = QString("ConsoleWidget%1").arg(i);
181  QString dock_uid = uid + "DockWidget";
182  mDockWidgets[i]->setObjectName(dock_uid);
183  mDockWidgets[i]->widget()->setObjectName(uid);
184  }
185 }
186 
187 ConsoleWidget* ConsoleWidgetCollection::addConsole()
188 {
189  QString uid = QString("ConsoleWidget%1").arg(mDockWidgets.size());
190  ConsoleWidget* console = new ConsoleWidget(this, uid, "Console", mOptions.descend(uid), mLog);
191  this->addAsDockWidget(console);
192  return console;
193 }
194 
195 void ConsoleWidgetCollection::onNewConsole()
196 {
197  ConsoleWidget* console = this->addConsole();
198  console->setDetails(true);
199 }
200 
202 {
203  this->removeHiddenConsoles();
204 
205  QMenu* popupMenu = new QMenu(this);
206 
207  QAction* addConsoleAction = new QAction("New Console", this);
208  connect(addConsoleAction, &QAction::triggered, this, &ConsoleWidgetCollection::onNewConsole);
209  popupMenu->addAction(addConsoleAction);
210 
211  for (int i=0; i<mDockWidgets.size(); ++i)
212  {
213  popupMenu->addAction(mDockWidgets[i]->toggleViewAction());
214  }
215 
216  return popupMenu;
217 }
218 
219 
220 
221 } //namespace cx
222 
cxResource_EXPORT ProfilePtr profile()
Definition: cxProfile.cpp:176
ConsoleWidgetCollection(QWidget *parent, QString objectName, QString windowTitle, XmlOptionFile options, LogPtr log)
ReporterPtr reporter()
Definition: cxReporter.cpp:59
void writeVariant(const QVariant &val)
QDomElement getElement()
return the current element
boost::shared_ptr< class Log > LogPtr
Definition: cxLog.h:68
QVariant readVariant(const QVariant &defval=QVariant()) const
Helper class for xml files used to store ssc/cx data.
XmlOptionFile descend(QString element) const
step one level down in the xml tree