dRonin  adbada4
dRonin GCS
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Groups Pages
splitterorview.cpp
Go to the documentation of this file.
1 
15 /*
16  * This program is free software; you can redistribute it and/or modify
17  * it under the terms of the GNU General Public License as published by
18  * the Free Software Foundation; either version 3 of the License, or
19  * (at your option) any later version.
20  *
21  * This program is distributed in the hope that it will be useful, but
22  * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
23  * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
24  * for more details.
25  *
26  * You should have received a copy of the GNU General Public License along
27  * with this program; if not, see <http://www.gnu.org/licenses/>
28  */
29 
30 #include "splitterorview.h"
31 #include "uavgadgetview.h"
32 #include "uavgadgetmanager.h"
33 #include "iuavgadget.h"
34 #include "minisplitter.h"
35 
36 #include <QtCore/QDebug>
37 
38 using namespace Core;
39 using namespace Core::Internal;
40 
42  Core::IUAVGadget *uavGadget, bool restoring)
43  : m_uavGadgetManager(uavGadgetManager)
44  , m_splitter(nullptr)
45 {
46  m_view = new UAVGadgetView(m_uavGadgetManager, uavGadget, this, restoring);
47  m_layout = new QStackedLayout(this);
48  m_layout->addWidget(m_view);
49 }
50 
52 {
53  if (m_view) {
54  delete m_view;
55  m_view = nullptr;
56  }
57  if (m_splitter) {
58  delete m_splitter;
59  m_splitter = nullptr;
60  }
61 }
62 
64 {
65  if (e->button() != Qt::LeftButton)
66  return;
67  if (gadget()) {
68  setFocus(Qt::MouseFocusReason);
69  m_uavGadgetManager->setCurrentGadget(this->gadget());
70  }
71 }
72 
73 /* Contract: return SplitterOrView that is not splitter, or 0 if not found.
74  * Implications: must not return SplitterOrView that is splitter.
75  */
77 {
78  if (m_splitter) {
79  for (int i = 0; i < m_splitter->count(); ++i) {
80  if (SplitterOrView *splitterOrView =
81  qobject_cast<SplitterOrView *>(m_splitter->widget(i)))
82  if (SplitterOrView *result = splitterOrView->findFirstView())
83  return result;
84  }
85  return nullptr;
86  }
87  return this;
88 }
89 
90 /* Contract: return SplitterOrView that has 'uavGadget', or 0 if not found.
91  * Implications: must not return SplitterOrView that is splitter.
92  */
94 {
95  if (!uavGadget || hasGadget(uavGadget))
96  return this;
97  if (m_splitter) {
98  for (int i = 0; i < m_splitter->count(); ++i) {
99  if (SplitterOrView *splitterOrView =
100  qobject_cast<SplitterOrView *>(m_splitter->widget(i)))
101  if (SplitterOrView *result = splitterOrView->findView(uavGadget))
102  return result;
103  }
104  }
105  return nullptr;
106 }
107 
108 /* Contract: return SplitterOrView that has 'view', or 0 if not found.
109  * Implications: must not return SplitterOrView that is splitter.
110  */
112 {
113  if (view == m_view)
114  return this;
115  if (m_splitter) {
116  for (int i = 0; i < m_splitter->count(); ++i) {
117  if (SplitterOrView *splitterOrView =
118  qobject_cast<SplitterOrView *>(m_splitter->widget(i)))
119  if (SplitterOrView *result = splitterOrView->findView(view))
120  return result;
121  }
122  }
123  return nullptr;
124 }
125 
126 /* Contract: return SplitterOrView that is splitter that has as child SplitterOrView containing
127  * 'uavGadget',
128  * or 0 if not found.
129  * Implications: must return SplitterOrView that is splitter.
130  */
132 {
133  if (m_splitter) {
134  for (int i = 0; i < m_splitter->count(); ++i) {
135  if (SplitterOrView *splitterOrView =
136  qobject_cast<SplitterOrView *>(m_splitter->widget(i))) {
137  if (splitterOrView->hasGadget(uavGadget))
138  return this;
139  if (SplitterOrView *result = splitterOrView->findSplitter(uavGadget))
140  return result;
141  }
142  }
143  }
144  return nullptr;
145 }
146 
147 /* Contract: return SplitterOrView that is splitter that has as child SplitterOrView 'child',
148  * or 0 if not found.
149  * Implications: must return SplitterOrView that is splitter.
150  */
152 {
153  if (m_splitter) {
154  for (int i = 0; i < m_splitter->count(); ++i) {
155  if (SplitterOrView *splitterOrView =
156  qobject_cast<SplitterOrView *>(m_splitter->widget(i))) {
157  if (splitterOrView == child)
158  return this;
159  if (SplitterOrView *result = splitterOrView->findSplitter(child))
160  return result;
161  }
162  }
163  }
164  return nullptr;
165 }
166 
167 /* Contract: return SplitterOrView that follows SplitterOrView 'view' in tree structure,
168  * or 0 if not found.
169  * Implications: must not return SplitterOrView that is splitter.
170  */
172 {
173  bool found = false;
174  return findNextView_helper(view, &found);
175 }
176 
177 SplitterOrView *SplitterOrView::findNextView_helper(SplitterOrView *view, bool *found)
178 {
179  if (*found && m_view) {
180  return this;
181  }
182 
183  if (this == view) {
184  *found = true;
185  return nullptr;
186  }
187 
188  if (m_splitter) {
189  for (int i = 0; i < m_splitter->count(); ++i) {
190  if (SplitterOrView *splitterOrView =
191  qobject_cast<SplitterOrView *>(m_splitter->widget(i))) {
192  if (SplitterOrView *result = splitterOrView->findNextView_helper(view, found))
193  return result;
194  }
195  }
196  }
197  return nullptr;
198 }
199 
201 {
202  if (m_splitter)
203  return m_splitter->minimumSizeHint();
204  return QSize(64, 64);
205 }
206 
208 {
209  QSplitter *oldSplitter = m_splitter;
210  if (m_splitter)
211  m_layout->removeWidget(m_splitter);
212  m_splitter = nullptr;
213  return oldSplitter;
214 }
215 
217 {
218  UAVGadgetView *oldView = m_view;
219  if (m_view)
220  m_layout->removeWidget(m_view);
221  m_view = nullptr;
222  return oldView;
223 }
224 
226 {
228  if (hasGadget())
229  g.append(gadget());
230  if (m_splitter) {
231  for (int i = 0; i < m_splitter->count(); ++i) {
232  if (SplitterOrView *splitterOrView =
233  qobject_cast<SplitterOrView *>(m_splitter->widget(i))) {
234  QList<IUAVGadget *> result = splitterOrView->gadgets();
235  g.append(result);
236  }
237  }
238  }
239  return g;
240 }
241 
242 void SplitterOrView::split(Qt::Orientation orientation, bool restoring)
243 {
244  Q_ASSERT(m_view);
245  Q_ASSERT(!m_splitter);
246  m_splitter = new MiniSplitter(this);
247  m_splitter->setOrientation(orientation);
248  connect(m_splitter, SIGNAL(splitterMoved(int, int)), this, SLOT(onSplitterMoved(int, int)));
249  m_layout->addWidget(m_splitter);
250  Core::IUAVGadget *ourGadget = m_view->gadget();
251 
252  if (ourGadget) {
253  // Give our gadget to the new left or top SplitterOrView.
254  m_view->removeGadget();
255  m_splitter->addWidget(new SplitterOrView(m_uavGadgetManager, ourGadget));
256  m_splitter->addWidget(new SplitterOrView(m_uavGadgetManager, nullptr, restoring));
257  } else {
258  m_splitter->addWidget(new SplitterOrView(m_uavGadgetManager, nullptr, restoring));
259  m_splitter->addWidget(new SplitterOrView(m_uavGadgetManager, nullptr, restoring));
260  }
261 
262  m_layout->setCurrentWidget(m_splitter);
263 
264  if (m_view) {
265  m_uavGadgetManager->emptyView(m_view);
266  delete m_view;
267  m_view = nullptr;
268  }
269 }
270 
271 void SplitterOrView::onSplitterMoved(int pos, int index)
272 {
273  Q_UNUSED(pos);
274  Q_UNUSED(index);
275  // Update when the splitter is actually moved.
276  m_sizes = m_splitter->sizes();
277 }
278 
280 {
281  Q_ASSERT(m_splitter);
282  Q_ASSERT(!m_view);
283  m_splitter->hide();
284  m_layout->removeWidget(m_splitter); // workaround Qt bug
285  unsplitAll_helper();
286  delete m_splitter;
287  m_splitter = nullptr;
288 
289  m_view = new UAVGadgetView(m_uavGadgetManager, currentGadget, this);
290  m_layout->addWidget(m_view);
291 }
292 
293 void SplitterOrView::unsplitAll_helper()
294 {
295  if (m_view) {
296  m_uavGadgetManager->emptyView(m_view);
297  }
298  if (m_splitter) {
299  for (int i = 0; i < m_splitter->count(); ++i) {
300  if (SplitterOrView *splitterOrView =
301  qobject_cast<SplitterOrView *>(m_splitter->widget(i))) {
302  splitterOrView->unsplitAll_helper();
303  }
304  }
305  }
306 }
307 
309 {
310  if (!m_splitter)
311  return;
312  Q_ASSERT(m_splitter->count() == 1);
313  SplitterOrView *childSplitterOrView = qobject_cast<SplitterOrView *>(m_splitter->widget(0));
314  QSplitter *oldSplitter = m_splitter;
315  m_splitter = nullptr;
316 
317  if (childSplitterOrView->isSplitter()) {
318  Q_ASSERT(childSplitterOrView->view() == nullptr);
319  m_splitter = childSplitterOrView->takeSplitter();
320  m_layout->addWidget(m_splitter);
321  m_layout->setCurrentWidget(m_splitter);
322  } else {
323  UAVGadgetView *childView = childSplitterOrView->view();
324  Q_ASSERT(childView);
325  if (m_view) {
326  if (IUAVGadget *e = childView->gadget()) {
327  childView->removeGadget();
328  m_view->setGadget(e);
329  }
330  m_uavGadgetManager->emptyView(childView);
331  } else {
332  m_view = childSplitterOrView->takeView();
333  m_layout->addWidget(m_view);
334  }
335  m_layout->setCurrentWidget(m_view);
336  }
337  delete oldSplitter;
338  m_uavGadgetManager->setCurrentGadget(findFirstView()->gadget());
339 }
340 
341 void SplitterOrView::saveState(QSettings *qSettings) const
342 {
343  if (m_splitter) {
344  qSettings->setValue("type", "splitter");
345  qSettings->setValue("splitterOrientation", (qint32)m_splitter->orientation());
346  QList<QVariant> sizesQVariant;
347  foreach (int value, m_sizes) {
348  sizesQVariant.append(value);
349  }
350  qSettings->setValue("splitterSizes", sizesQVariant);
351  qSettings->beginGroup("side0");
352  static_cast<SplitterOrView *>(m_splitter->widget(0))->saveState(qSettings);
353  qSettings->endGroup();
354  qSettings->beginGroup("side1");
355  static_cast<SplitterOrView *>(m_splitter->widget(1))->saveState(qSettings);
356  qSettings->endGroup();
357  } else if (gadget()) {
358  qSettings->setValue("type", "uavGadget");
359  qSettings->setValue("classId", gadget()->classId());
360  qSettings->beginGroup("gadget");
361  gadget()->saveState(qSettings);
362  qSettings->endGroup();
363  }
364 }
365 
366 void SplitterOrView::restoreState(QSettings *qSettings)
367 {
368  QString mode = qSettings->value("type").toString();
369  if (mode == "splitter") {
370  qint32 orientation = qSettings->value("splitterOrientation").toInt();
371  QList<QVariant> sizesQVariant = qSettings->value("splitterSizes").toList();
372  m_sizes.clear();
373  foreach (QVariant value, sizesQVariant) {
374  m_sizes.append(value.toInt());
375  }
376  split((Qt::Orientation)orientation, true);
377  m_splitter->setSizes(m_sizes);
378  qSettings->beginGroup("side0");
379  static_cast<SplitterOrView *>(m_splitter->widget(0))->restoreState(qSettings);
380  qSettings->endGroup();
381  qSettings->beginGroup("side1");
382  static_cast<SplitterOrView *>(m_splitter->widget(1))->restoreState(qSettings);
383  qSettings->endGroup();
384  } else if (mode == "uavGadget") {
385  QString classId = qSettings->value("classId").toString();
386  int index = m_view->indexOfClassId(classId);
387  m_view->selectionActivated(index, false);
388  if (qSettings->childGroups().contains("gadget")) {
389  qSettings->beginGroup("gadget");
390  gadget()->restoreState(qSettings);
391  qSettings->endGroup();
392  }
393  }
394 }
void split(Qt::Orientation orientation, bool restoring=false)
QList< Core::IUAVGadget * > gadgets()
SplitterOrView * findSplitter(Core::IUAVGadget *uavGadget)
SplitterOrView(UAVGadgetManager *uavGadgetManager, Core::IUAVGadget *uavGadget=nullptr, bool restoring=false)
void saveState(QSettings *) const
Core::IUAVGadget * gadget() const
void unsplitAll(IUAVGadget *currentGadget)
IUAVGadget * gadget() const
for i
Definition: OPPlots.m:140
virtual void restoreState(QByteArray)
Definition: iuavgadget.h:67
virtual void saveState(QSettings *)
Definition: iuavgadget.h:66
SplitterOrView * findView(Core::IUAVGadget *uavGadget)
SplitterOrView * findNextView(SplitterOrView *view)
void mousePressEvent(QMouseEvent *e)
Definition: icore.h:39
SplitterOrView * findFirstView()
e
Definition: OPPlots.m:99