Merged in f5soh/librepilot/update_credits (pull request #529)
[librepilot.git] / ground / gcs / src / plugins / coreplugin / uavgadgetmanager / uavgadgetmanager.cpp
blob48c2795bf0cb1de2383b6bfdc7850b7f029ec276
1 /**
2 ******************************************************************************
4 * @file uavgadgetmanager.cpp
5 * @author The OpenPilot Team, http://www.openpilot.org Copyright (C) 2010.
6 * Parts by Nokia Corporation (qt-info@nokia.com) Copyright (C) 2009.
7 * @addtogroup GCSPlugins GCS Plugins
8 * @{
9 * @addtogroup CorePlugin Core Plugin
10 * @{
11 * @brief The Core GCS plugin
12 *****************************************************************************/
14 * This program is free software; you can redistribute it and/or modify
15 * it under the terms of the GNU General Public License as published by
16 * the Free Software Foundation; either version 3 of the License, or
17 * (at your option) any later version.
19 * This program is distributed in the hope that it will be useful, but
20 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
21 * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
22 * for more details.
24 * You should have received a copy of the GNU General Public License along
25 * with this program; if not, write to the Free Software Foundation, Inc.,
26 * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
29 #include "uavgadgetmanager.h"
31 #include "uavgadgetview.h"
32 #include "splitterorview.h"
33 #include "uavgadgetinstancemanager.h"
34 #include "iuavgadgetfactory.h"
35 #include "iuavgadget.h"
36 #include "icore.h"
38 #include <coreplugin/coreconstants.h>
39 #include <coreplugin/modemanager.h>
40 #include <coreplugin/uniqueidmanager.h>
41 #include <coreplugin/baseview.h>
42 #include <coreplugin/imode.h>
44 #include <extensionsystem/pluginmanager.h>
46 #include <utils/qtcassert.h>
48 #include <QDebug>
49 #include <QApplication>
50 #include <QHBoxLayout>
52 Q_DECLARE_METATYPE(Core::IUAVGadget *)
54 using namespace Core;
55 using namespace Core::Internal;
56 using namespace Utils;
58 enum { debugUAVGadgetManager = 0 };
60 // ===================UAVGadgetManager=====================
62 UAVGadgetManager::UAVGadgetManager(ICore *core, QString name, QIcon icon, int priority, QString uniqueName, QWidget *parent) :
63 m_showToolbars(true),
64 m_splitterOrView(0),
65 m_currentGadget(0),
66 m_core(core),
67 m_name(name),
68 m_icon(icon),
69 m_priority(priority),
70 m_widget(new QWidget(parent))
72 // checking that the mode name is unique gives harmless
73 // warnings on the console output
74 ModeManager *modeManager = ModeManager::instance();
76 if (!modeManager->mode(uniqueName)) {
77 m_uniqueName = uniqueName;
78 } else {
79 // this shouldn't happen
80 m_uniqueName = uniqueName + QString::number(quint64(this));
82 m_uniqueNameBA = m_uniqueName.toLatin1();
83 m_uniqueModeName = m_uniqueNameBA.data();
85 connect(m_core, SIGNAL(contextAboutToChange(Core::IContext *)),
86 this, SLOT(handleContextChange(Core::IContext *)));
88 connect(modeManager, SIGNAL(currentModeChanged(Core::IMode *)),
89 this, SLOT(modeChanged(Core::IMode *)));
91 // other setup
92 m_splitterOrView = new SplitterOrView(this);
94 // SplitterOrView with 0 as gadget calls our setCurrentGadget, which relies on currentSplitterOrView(),
95 // which needs our m_splitterorView to be set, which isn't set yet at that time.
96 // So directly set our currentGadget to 0, and do it again.
97 m_currentGadget = 0;
98 setCurrentGadget(m_splitterOrView->view()->gadget());
100 QHBoxLayout *layout = new QHBoxLayout(m_widget);
101 layout->setMargin(0);
102 layout->setSpacing(0);
103 layout->addWidget(m_splitterOrView);
105 showToolbars(m_showToolbars);
108 UAVGadgetManager::~UAVGadgetManager()
111 QList<int> UAVGadgetManager::context() const
113 static QList<int> contexts = QList<int>() <<
114 UniqueIDManager::instance()->uniqueIdentifier(Constants::C_UAVGADGETMANAGER);
116 return contexts;
119 void UAVGadgetManager::modeChanged(Core::IMode *mode)
121 if (mode != this) {
122 return;
125 m_currentGadget->widget()->setFocus();
126 showToolbars(toolbarsShown());
129 void UAVGadgetManager::init()
131 QList<int> context;
132 context << m_core->uniqueIDManager()->uniqueIdentifier("OpenPilot.UAVGadgetManager");
135 void UAVGadgetManager::handleContextChange(Core::IContext *context)
137 // if (debugUAVGadgetManager)
138 // qDebug() << Q_FUNC_INFO << context;
139 IUAVGadget *uavGadget = context ? qobject_cast<IUAVGadget *>(context) : 0;
141 if (uavGadget) {
142 setCurrentGadget(uavGadget);
146 void UAVGadgetManager::setCurrentGadget(IUAVGadget *uavGadget)
148 if (m_currentGadget == uavGadget) {
149 return;
152 SplitterOrView *oldView = currentSplitterOrView();
153 m_currentGadget = uavGadget;
154 SplitterOrView *view = currentSplitterOrView();
155 if (oldView != view) {
156 if (oldView) {
157 oldView->update();
159 if (view) {
160 view->update();
163 uavGadget->widget()->setFocus();
164 emit currentGadgetChanged(uavGadget);
167 /* Contract: return current SplitterOrView.
168 * Implications: must not return SplitterOrView that is splitter.
170 Core::Internal::SplitterOrView *UAVGadgetManager::currentSplitterOrView() const
172 if (!m_splitterOrView) { // this is only for startup
173 return 0;
175 SplitterOrView *view = m_currentGadget ?
176 m_splitterOrView->findView(m_currentGadget) :
178 return view;
181 IUAVGadget *UAVGadgetManager::currentGadget() const
183 return m_currentGadget;
186 void UAVGadgetManager::emptyView(Core::Internal::UAVGadgetView *view)
188 if (!view) {
189 return;
192 IUAVGadget *uavGadget = view->gadget();
193 // emit uavGadgetAboutToClose(uavGadget);
194 removeGadget(uavGadget);
195 view->removeGadget();
196 // emit uavGadgetsClosed(uavGadgets);
200 void UAVGadgetManager::closeView(Core::Internal::UAVGadgetView *view)
202 if (!view) {
203 return;
206 IUAVGadget *gadget = view->gadget();
208 // find SplitterOrView splitter that contains the view to delete
209 SplitterOrView *splitter = m_splitterOrView->findSplitter(gadget);
210 if (!splitter) {
211 return;
213 Q_ASSERT(splitter->isSplitter() == true);
215 splitter->unsplit(gadget);
217 UAVGadgetInstanceManager *im = ICore::instance()->uavGadgetInstanceManager();
218 im->removeGadget(gadget);
220 SplitterOrView *newCurrent = splitter->findFirstView();
221 Q_ASSERT(newCurrent);
222 if (newCurrent) {
223 setCurrentGadget(newCurrent->gadget());
227 void UAVGadgetManager::addGadgetToContext(IUAVGadget *gadget)
229 if (!gadget) {
230 return;
232 m_core->addContextObject(gadget);
233 // emit uavGadgetOpened(uavGadget);
236 void UAVGadgetManager::removeGadget(IUAVGadget *gadget)
238 if (!gadget) {
239 return;
241 m_core->removeContextObject(qobject_cast<IContext *>(gadget));
244 void UAVGadgetManager::ensureUAVGadgetManagerVisible()
246 if (!m_widget->isVisible()) {
247 m_core->modeManager()->activateMode(this->uniqueModeName());
251 void UAVGadgetManager::showToolbars(bool show)
253 if (m_core->modeManager()->currentMode() != this) {
254 return;
257 m_showToolbars = show;
258 SplitterOrView *next = m_splitterOrView->findFirstView();
259 do {
260 next->view()->showToolbar(show);
261 next = m_splitterOrView->findNextView(next);
262 } while (next);
264 updateUavGadgetMenus();
267 void UAVGadgetManager::updateUavGadgetMenus()
269 if (m_core->modeManager()->currentMode() != this) {
270 return;
272 if (!m_splitterOrView) { // this is only for startup
273 return;
275 // Splitting is only possible when the toolbars are shown
276 bool hasSplitter = m_splitterOrView->isSplitter();
277 emit showUavGadgetMenus(m_showToolbars, hasSplitter);
280 void UAVGadgetManager::saveState(QSettings &settings) const
282 settings.setValue("version", "UAVGadgetManagerV1");
283 settings.setValue("showToolbars", m_showToolbars);
284 settings.beginGroup("splitter");
285 m_splitterOrView->saveState(settings);
286 settings.endGroup();
289 bool UAVGadgetManager::restoreState(QSettings &settings)
291 removeAllSplits();
293 UAVGadgetInstanceManager *im = ICore::instance()->uavGadgetInstanceManager();
294 IUAVGadget *gadget = m_splitterOrView->view()->gadget();
295 emptyView(m_splitterOrView->view());
296 im->removeGadget(gadget);
298 QString version = settings.value("version").toString();
299 if (version != "UAVGadgetManagerV1") {
300 return false;
303 m_showToolbars = settings.value("showToolbars").toBool();
305 QApplication::setOverrideCursor(Qt::WaitCursor);
307 settings.beginGroup("splitter");
308 m_splitterOrView->restoreState(settings);
309 settings.endGroup();
311 QApplication::restoreOverrideCursor();
312 return true;
315 void UAVGadgetManager::saveSettings(QSettings &settings) const
317 settings.beginGroup("UAVGadgetManager");
318 settings.beginGroup(this->uniqueModeName());
320 // Make sure the old tree is wiped.
321 settings.remove("");
323 // Do actual saving
324 saveState(settings);
326 settings.endGroup();
327 settings.endGroup();
330 void UAVGadgetManager::readSettings(QSettings &settings)
332 QString uavGadgetManagerRootKey = "UAVGadgetManager";
334 if (!settings.childGroups().contains(uavGadgetManagerRootKey)) {
335 return;
337 settings.beginGroup(uavGadgetManagerRootKey);
339 if (!settings.childGroups().contains(uniqueModeName())) {
340 settings.endGroup();
341 return;
343 settings.beginGroup(uniqueModeName());
345 restoreState(settings);
347 showToolbars(m_showToolbars);
349 settings.endGroup();
350 settings.endGroup();
353 void UAVGadgetManager::split(Qt::Orientation orientation)
355 if (m_core->modeManager()->currentMode() != this) {
356 return;
359 IUAVGadget *uavGadget = m_currentGadget;
360 Q_ASSERT(uavGadget);
361 SplitterOrView *view = currentSplitterOrView();
362 Q_ASSERT(view);
363 view->split(orientation);
365 SplitterOrView *sor = m_splitterOrView->findView(uavGadget);
366 SplitterOrView *next = m_splitterOrView->findNextView(sor);
367 setCurrentGadget(next->gadget());
368 updateUavGadgetMenus();
371 void UAVGadgetManager::split()
373 split(Qt::Vertical);
376 void UAVGadgetManager::splitSideBySide()
378 split(Qt::Horizontal);
381 void UAVGadgetManager::removeCurrentSplit()
383 if (m_core->modeManager()->currentMode() != this) {
384 return;
387 SplitterOrView *viewToClose = currentSplitterOrView();
388 if (viewToClose == m_splitterOrView) {
389 return;
391 closeView(viewToClose->view());
392 updateUavGadgetMenus();
395 // Removes all gadgets and splits in the workspace, except the current/active gadget.
396 void UAVGadgetManager::removeAllSplits()
398 if (m_core->modeManager()->currentMode() != this) {
399 return;
402 if (!m_splitterOrView->isSplitter()) {
403 return;
406 // Use a QPointer, just in case we accidently delete the gadget we want to keep.
407 QPointer<IUAVGadget> currentGadget = m_currentGadget;
409 Q_ASSERT(currentGadget);
410 QList<IUAVGadget *> gadgets = m_splitterOrView->gadgets();
411 Q_ASSERT(gadgets.count(currentGadget) == 1);
412 gadgets.removeOne(currentGadget);
414 // Remove all splits and their gadgets, then create a new view with the current gadget.
415 m_splitterOrView->unsplitAll(currentGadget);
417 // Zeroing the current gadget means setCurrentGadget will do something when we call it.
418 m_currentGadget = 0;
419 setCurrentGadget(currentGadget);
421 // Remove all other gadgets from the instance manager.
422 UAVGadgetInstanceManager *im = ICore::instance()->uavGadgetInstanceManager();
423 foreach(IUAVGadget * g, gadgets) {
424 im->removeGadget(g);
426 updateUavGadgetMenus();
429 void UAVGadgetManager::gotoOtherSplit()
431 if (m_core->modeManager()->currentMode() != this) {
432 return;
435 if (m_splitterOrView->isSplitter()) {
436 SplitterOrView *currentView = currentSplitterOrView();
437 SplitterOrView *view = m_splitterOrView->findNextView(currentView);
438 if (!view) {
439 view = m_splitterOrView->findFirstView();
441 if (view) {
442 setCurrentGadget(view->gadget());