dRonin  adbada4
dRonin GCS
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Groups Pages
mainwindow.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  * Additional note on redistribution: The copyright and license notices above
30  * must be maintained in each individual source file that is a derivative work
31  * of this source file; otherwise redistribution is prohibited.
32  */
33 
34 #include "mainwindow.h"
35 #include "actioncontainer.h"
36 #include "actionmanager_p.h"
37 #include "basemode.h"
38 #include "connectionmanager.h"
39 #include "boardmanager.h"
40 #include "coreimpl.h"
41 #include "coreconstants.h"
42 #include "utils/mytabwidget.h"
43 #include "generalsettings.h"
44 #include "modemanager.h"
45 #include "plugindialog.h"
46 #include "shortcutsettings.h"
47 #include "uavgadgetmanager.h"
49 #include "workspacesettings.h"
50 #include "globalmessaging.h"
51 #include "authorsdialog.h"
52 #include "baseview.h"
53 #include "ioutputpane.h"
54 #include "icorelistener.h"
55 #include "iconfigurableplugin.h"
56 #include <QStyleFactory>
57 #include "settingsdialog.h"
58 #include "uniqueidmanager.h"
59 #include "versiondialog.h"
60 
62 #include "dialogs/iwizard.h"
63 #include <utils/hostosinfo.h>
64 #include <utils/pathchooser.h>
65 #include <utils/xmlconfig.h>
66 #include <utils/pathutils.h>
67 
68 #include <QtCore/QDebug>
69 #include <QtCore/QFileInfo>
70 #include <QtCore/QSettings>
71 #include <QtCore/QTimer>
72 #include <QtCore/QtPlugin>
73 #include <QtCore/QUrl>
74 
75 #include <QApplication>
76 #include <QCloseEvent>
77 #include <QMenu>
78 #include <QPixmap>
79 #include <QShortcut>
80 #include <QStatusBar>
81 #include <QWizard>
82 #include <QToolButton>
83 #include <QMessageBox>
84 #include <QDesktopServices>
85 #include "dialogs/importsettings.h"
86 #include <QDir>
87 #include <QMimeData>
88 #include <QNetworkProxy>
89 #include <QDir>
90 
91 using namespace Core;
92 using namespace Core::Internal;
93 
94 static const char *uriListMimeFormatC = "text/uri-list";
95 
96 enum { debugMainWindow = 0 };
97 
100  , m_coreImpl(new CoreImpl(this))
101  , m_uniqueIDManager(new UniqueIDManager())
102  , m_globalContext(QList<int>() << Constants::C_GLOBAL_ID)
103  , m_additionalContexts(m_globalContext)
104  , m_dontSaveSettings(false)
105  , m_actionManager(new ActionManagerPrivate(this))
106  , m_modeManager(nullptr)
107  , m_connectionManager(nullptr)
108  , m_boardManager(nullptr)
109  , m_versionDialog(nullptr)
110  , m_authorsDialog(nullptr)
111  , m_activeContext(nullptr)
112  , m_generalSettings(new GeneralSettings)
113  , m_shortcutSettings(new ShortcutSettings)
114  , m_workspaceSettings(new WorkspaceSettings)
115  , m_focusToEditor(nullptr)
116  , m_newAction(nullptr)
117  , m_openAction(nullptr)
118  , m_openWithAction(nullptr)
119  , m_saveAllAction(nullptr)
120  , m_exitAction(nullptr)
121  , m_optionsAction(nullptr)
122  ,
123 #ifdef Q_OS_MAC
124  m_minimizeAction(0)
125  , m_zoomAction(0)
126  ,
127 #endif /* Q_OS_MAC */
128  m_toggleFullScreenAction(nullptr)
129 {
130  // keep this in sync with main() in app/main.cpp
131  m_settings = new QSettings(QDir::tempPath() + QDir::separator() + GCS_PROJECT_BRANDING
132  + QDir::separator() + "config_autosave",
134  // Copy original settings file to working settings. Do this in scope so that
135  // we are guaranteed that the originalSettings file is closed. This prevents corruption
136  // since the QSettings being used are copies of the original file.
137  {
138  QSettings originalSettings(Utils::PathUtils().getSettingsFilename(),
140 
141  // There is no copy constructor for QSettings, so we have to do it manually
142  m_settings->clear();
143  QStringList keys = originalSettings.allKeys();
144  for (QStringList::iterator i = keys.begin(); i != keys.end(); i++) {
145  m_settings->setValue(*i, originalSettings.value(*i));
146  }
147 
148  if (!originalSettings.isWritable()) {
149  QMessageBox msgBox(QMessageBox::Warning, tr("Settings Not Saved"),
150  tr("Your settings file (%0) is not writable! "
151  "All GCS configuration changes will be lost!")
152  .arg(Utils::PathUtils().getSettingsFilename()),
153  QMessageBox::Ok, this);
154  msgBox.exec();
155  }
156  }
157 
158  setWindowTitle(QLatin1String(Core::Constants::GCS_NAME));
160  QApplication::setWindowIcon(QIcon(Core::Constants::ICON_GCS));
161  QCoreApplication::setApplicationName(QLatin1String(Core::Constants::GCS_NAME));
162  QCoreApplication::setApplicationVersion(QLatin1String(Core::Constants::GCS_VERSION_LONG));
163  QCoreApplication::setOrganizationName(QLatin1String(Core::Constants::GCS_AUTHOR));
164  QCoreApplication::setOrganizationDomain(QLatin1String(GCS_PROJECT_BRANDING_HELP));
165  QSettings::setDefaultFormat(XmlConfig::XmlSettingsFormat);
166  QString baseName = QApplication::style()->objectName();
167 
168  qDebug() << baseName;
170  if (baseName == QLatin1String("windows")) {
171  // Sometimes we get the standard windows 95 style as a fallback
172  if (QStyleFactory::keys().contains(QLatin1String("Fusion"))) {
173  baseName = QLatin1String("fusion"); // Qt5
174  } else { // Qt4
175  // e.g. if we are running on a KDE4 desktop
176  QByteArray desktopEnvironment = qgetenv("DESKTOP_SESSION");
177  if (desktopEnvironment == "kde")
178  baseName = QLatin1String("plastique");
179  else
180  baseName = QLatin1String("cleanlooks");
181  }
182  }
183  }
184  qApp->setStyle(QStyleFactory::create(baseName));
185 
186  setDockNestingEnabled(true);
187 
188  setCorner(Qt::BottomLeftCorner, Qt::LeftDockWidgetArea);
189  setCorner(Qt::BottomRightCorner, Qt::BottomDockWidgetArea);
190 
191  registerDefaultContainers();
192  registerDefaultActions();
193 
194  QGridLayout *gridLayout = new QGridLayout();
195  gridLayout->setSizeConstraint(QLayout::SetNoConstraint);
196 
197  m_contentFrame = new QFrame(this);
198  m_contentFrame->setObjectName(QString("MainContentFrame"));
199  m_contentFrame->setLayout(gridLayout);
200 
201  m_modeStack = new MyTabWidget(m_contentFrame);
202  m_modeStack->setIconSize(QSize(24, 24));
203  m_modeStack->setTabPosition(QTabWidget::South);
204  m_modeStack->setMovable(false);
205  m_modeStack->setMinimumWidth(512);
206  m_modeStack->setMinimumHeight(384);
207  m_modeStack->setMaximumWidth(16777215);
208  m_modeStack->setMaximumHeight(16777215);
209  m_modeStack->setSizePolicy(QSizePolicy::MinimumExpanding, QSizePolicy::MinimumExpanding);
210  m_modeStack->setElideMode(Qt::ElideRight);
211 
212  gridLayout->addWidget(m_modeStack, 0, 0);
213  gridLayout->setContentsMargins(0, 0, 0, 0);
214 
215  m_globalMessaging = new GlobalMessaging(this);
216 
217  m_modeManager = new ModeManager(this, m_modeStack);
218 
219  m_connectionManager = new ConnectionManager(this, m_modeStack);
220 
221  m_boardManager = new BoardManager();
222 
223  setCentralWidget(m_contentFrame);
224 
225  connect(QApplication::instance(), SIGNAL(focusChanged(QWidget *, QWidget *)), this,
226  SLOT(updateFocusWidget(QWidget *, QWidget *)));
227  connect(m_workspaceSettings, SIGNAL(tabBarSettingsApplied(QTabWidget::TabPosition, bool)), this,
228  SLOT(applyTabBarSettings(QTabWidget::TabPosition, bool)));
229  connect(m_modeManager, SIGNAL(newModeOrder(QVector<IMode *>)), m_workspaceSettings,
230  SLOT(newModeOrder(QVector<IMode *>)));
231  statusBar()->setProperty("p_styled", true);
232  setAcceptDrops(true);
233 }
234 
236 {
237  if (m_connectionManager) {
238  m_connectionManager->disconnectDevice();
239  m_connectionManager->suspendPolling();
240  }
241 
242  hide();
243 
244  ExtensionSystem::PluginManager *pm = ExtensionSystem::PluginManager::instance();
245  if (m_uavGadgetManagers.count() > 0) {
246  foreach (UAVGadgetManager *mode, m_uavGadgetManagers) {
247  pm->removeObject(mode);
248  delete mode;
249  }
250  }
251 
252  pm->removeObject(m_shortcutSettings);
253  pm->removeObject(m_generalSettings);
254  pm->removeObject(m_workspaceSettings);
255  delete m_globalMessaging;
256  m_globalMessaging = nullptr;
257  delete m_shortcutSettings;
258  m_shortcutSettings = nullptr;
259  delete m_generalSettings;
260  m_generalSettings = nullptr;
261  delete m_workspaceSettings;
262  m_workspaceSettings = nullptr;
263 
264  // Copy working settings back to original settings file. Do this in scope so that
265  // we are guaranteed that the originalSettings file is closed. This minimizes the risk
266  // of corruption since the QSettings are saved (almost) atomically.
267  {
268  QSettings originalSettings(Utils::PathUtils().getSettingsFilename(),
270 
271  // There is no copy constructor for QSettings, so we have to do it manually
272  originalSettings.clear();
273  QStringList keys = m_settings->allKeys();
274  for (QStringList::iterator i = keys.begin(); i != keys.end(); i++) {
275  originalSettings.setValue(*i, m_settings->value(*i));
276  }
277 
278  originalSettings.sync();
279  if (originalSettings.status() != QSettings::NoError)
280  qWarning() << "Failed to saved GCS settings!"
281  << Utils::PathUtils().getSettingsFilename() << originalSettings.status();
282  }
283 
284  delete m_settings;
285  m_settings = nullptr;
286  delete m_uniqueIDManager;
287  m_uniqueIDManager = nullptr;
288 
289  pm->removeObject(m_coreImpl);
290  delete m_coreImpl;
291  m_coreImpl = nullptr;
292 
293  delete m_modeManager;
294  m_modeManager = nullptr;
295 }
296 
297 bool MainWindow::init(QString *errorMessage)
298 {
299  Q_UNUSED(errorMessage)
300 
301  ExtensionSystem::PluginManager *pm = ExtensionSystem::PluginManager::instance();
302  pm->addObject(m_coreImpl);
303  m_modeManager->init();
304  m_connectionManager->init();
305  m_boardManager->init();
306 
307  pm->addObject(m_generalSettings);
308  pm->addObject(m_shortcutSettings);
309  pm->addObject(m_workspaceSettings);
310 
311  return true;
312 }
313 
314 void MainWindow::modeChanged(Core::IMode * /*mode*/)
315 {
316 }
317 
319 {
320 
321  QSettings *qs = m_settings;
322  QSettings *settings;
323  QString commandLine;
324  if (!qs->allKeys().count()) {
325  foreach (QString str, qApp->arguments()) {
326  if (str.contains("configfile")) {
327  qDebug() << "ass";
328  commandLine = str.split("=").at(1);
329  qDebug() << commandLine;
330  }
331  }
332  QDir directory(QCoreApplication::applicationDirPath());
333 #ifdef Q_OS_MAC
334  directory.cdUp();
335  directory.cd("Resources");
336 #else
337  directory.cdUp();
338  directory.cd("share");
339 #endif
340  directory.cd("default_configurations");
341 
342  qDebug() << "Looking for default config files in: " + directory.absolutePath();
343  bool showDialog = true;
344  QString filename;
345  if (!commandLine.isEmpty()) {
346  if (QFile::exists(directory.absolutePath() + QDir::separator() + commandLine)) {
347  filename = directory.absolutePath() + QDir::separator() + commandLine;
348  emit splashMessages(tr("Loading configuration from command line"));
349  qDebug() << "Load configuration from command line";
350  settings = new QSettings(filename, XmlConfig::XmlSettingsFormat);
351  showDialog = false;
352  }
353  }
354  if (showDialog) {
355  // This has often ended up behind the splash screen, which looks
356  // bad.
357  emit hideSplash();
358 
359  importSettings *dialog = new importSettings(this);
360  dialog->loadFiles(directory.absolutePath());
361  dialog->exec();
362  filename = dialog->choosenConfig();
363 
364  emit showSplash();
365 
366  settings = new QSettings(filename, XmlConfig::XmlSettingsFormat);
367  delete dialog;
368  }
369  qs = settings;
370  emit splashMessages(QString(tr("Loading default configuration from %1")).arg(filename));
371  qDebug() << "Load default config from resource " << filename;
372  }
373  qs->beginGroup("General");
374  m_config_description = qs->value("Description", "none").toString();
375  m_config_details = qs->value("Details", "none").toString();
376  loadStyleSheet();
377  qs->endGroup();
378  m_uavGadgetInstanceManager = new UAVGadgetInstanceManager(this);
379  connect(m_uavGadgetInstanceManager, SIGNAL(splashMessages(QString)), this,
380  SIGNAL(splashMessages(QString)));
381  m_uavGadgetInstanceManager->readSettings(qs);
382 
383  readSettings(qs);
384  updateContext();
385  emit splashMessages(tr("Preparing to open core"));
386 
387  QString currentPath = QDir::currentPath();
388 
389  if ((currentPath.length() < 4) || currentPath.contains(".app", Qt::CaseInsensitive)
390  || currentPath.contains("Program Files", Qt::CaseInsensitive)
391  || !QDir(currentPath).exists()) {
392  QDir::setCurrent(QDir::homePath());
393  }
394 
395  emit m_coreImpl->coreAboutToOpen();
396  show();
397  emit m_coreImpl->coreOpened();
398 }
399 
400 void MainWindow::readStyleSheet(QFile *file, QString name, QString *style)
401 {
402  QString tmp;
403  if (file->open(QFile::ReadOnly)) {
404  /* QTextStream... */
405  QTextStream styleIn(file);
406  /* ...read file to a string. */
407  tmp = styleIn.readAll();
408  file->close();
409  style->append(tmp);
410  emit splashMessages(QString(tr("Loading stylesheet %1")).arg(name));
411  qDebug() << "Loaded stylesheet:" << name;
412  } else {
413  qDebug() << "Failed to openstylesheet file" << name;
414  }
415 }
416 
417 void MainWindow::loadStyleSheet()
418 {
419  /* Let's use QFile and point to a resource... */
420  QDir directory(QCoreApplication::applicationDirPath());
421 #ifdef Q_OS_MAC
422  directory.cdUp();
423  directory.cd("Resources");
424 #else
425  directory.cdUp();
426  directory.cd("share");
427 #endif
428  directory.cd("stylesheets");
429  QFile global(directory.absolutePath() + QDir::separator() + "global.qss");
430 #ifdef Q_OS_MAC
431  QFile data(directory.absolutePath() + QDir::separator() + "macos.qss");
432 #elif defined(Q_OS_LINUX)
433  QFile data(directory.absolutePath() + QDir::separator() + "linux.qss");
434 #else
435  QFile data(directory.absolutePath() + QDir::separator() + "windows.qss");
436 #endif
437  QString style;
438  /* ...to open the file */
439 
440  readStyleSheet(&global, "Global", &style);
441  readStyleSheet(&data, "OS", &style);
442 
443  if (style.length() > 0) {
444  qApp->setStyleSheet(style);
445  } else {
446  qDebug() << "No stylesheets loaded.";
447  }
448 }
449 
450 void MainWindow::closeEvent(QCloseEvent *event)
451 {
452  if (!m_generalSettings->saveSettingsOnExit()) {
453  m_dontSaveSettings = true;
454  }
455  if (!m_dontSaveSettings) {
456  emit m_coreImpl->saveSettingsRequested();
457  }
458 
459  const QList<ICoreListener *> listeners =
460  ExtensionSystem::PluginManager::instance()->getObjects<ICoreListener>();
461  foreach (ICoreListener *listener, listeners) {
462  if (!listener->coreAboutToClose()) {
463  event->ignore();
464  return;
465  }
466  }
467 
468  emit m_coreImpl->coreAboutToClose();
469 
470  if (!m_dontSaveSettings) {
471  saveSettings(m_settings);
472  m_uavGadgetInstanceManager->saveSettings(m_settings);
473  }
474  event->accept();
475 }
476 
477 // Check for desktop file manager file drop events
478 
479 static bool isDesktopFileManagerDrop(const QMimeData *d, QStringList *files = nullptr)
480 {
481  if (files)
482  files->clear();
483  // Extract dropped files from Mime data.
484  if (!d->hasFormat(QLatin1String(uriListMimeFormatC)))
485  return false;
486  const QList<QUrl> urls = d->urls();
487  if (urls.empty())
488  return false;
489  // Try to find local files
490  bool hasFiles = false;
491  const QList<QUrl>::const_iterator cend = urls.constEnd();
492  for (QList<QUrl>::const_iterator it = urls.constBegin(); it != cend; ++it) {
493  const QString fileName = it->toLocalFile();
494  if (!fileName.isEmpty()) {
495  hasFiles = true;
496  if (files) {
497  files->push_back(fileName);
498  } else {
499  break; // No result list, sufficient for checking
500  }
501  }
502  }
503  return hasFiles;
504 }
505 
506 void MainWindow::dragEnterEvent(QDragEnterEvent *event)
507 {
508  if (isDesktopFileManagerDrop(event->mimeData())) {
509  event->accept();
510  } else {
511  event->ignore();
512  }
513 }
514 
515 void MainWindow::dropEvent(QDropEvent *event)
516 {
517  QStringList files;
518  if (isDesktopFileManagerDrop(event->mimeData(), &files)) {
519  event->accept();
520  // openFiles(files);
521  } else {
522  event->ignore();
523  }
524 }
525 
527 {
528  return m_activeContext;
529 }
530 
531 QStatusBar *MainWindow::statusBar() const
532 {
533  // TODO: This is a memory leak waiting to happen. We should try to use
534  // a real status bar and add the connection widgets there. Unfortunately
535  // what is returned so returning NULL segfaults right now.
536  return new QStatusBar();
537 }
538 
539 void MainWindow::registerDefaultContainers()
540 {
541  ActionManagerPrivate *am = m_actionManager;
542 
544 
545 #ifndef Q_OS_MAC // System menu bar on Mac
546  setMenuBar(menubar->menuBar());
547 #endif /* Q_OS_MAC */
548  menubar->appendGroup(Constants::G_FILE);
549  menubar->appendGroup(Constants::G_EDIT);
550  menubar->appendGroup(Constants::G_VIEW);
553  menubar->appendGroup(Constants::G_HELP);
554 
555  // File Menu
557  menubar->addMenu(filemenu, Constants::G_FILE);
558  filemenu->menu()->setTitle(tr("&File"));
565  connect(filemenu->menu(), SIGNAL(aboutToShow()), this, SLOT(aboutToShowRecentFiles()));
566 
567  // Edit Menu
569  menubar->addMenu(medit, Constants::G_EDIT);
570  medit->menu()->setTitle(tr("&Edit"));
571  medit->appendGroup(Constants::G_EDIT_UNDOREDO);
572  medit->appendGroup(Constants::G_EDIT_COPYPASTE);
573  medit->appendGroup(Constants::G_EDIT_SELECTALL);
574  medit->appendGroup(Constants::G_EDIT_ADVANCED);
575  medit->appendGroup(Constants::G_EDIT_FIND);
576  medit->appendGroup(Constants::G_EDIT_OTHER);
577 
578  // Tools Menu
580  menubar->addMenu(ac, Constants::G_TOOLS);
581  ac->menu()->setTitle(tr("&Tools"));
582 
583  // Window Menu
585  menubar->addMenu(mwindow, Constants::G_WINDOW);
586  mwindow->menu()->setTitle(tr("&Window"));
593 
594  // Help Menu
595  ac = am->createMenu(Constants::M_HELP);
596  menubar->addMenu(ac, Constants::G_HELP);
597  ac->menu()->setTitle(tr("&Help"));
600 }
601 
602 static Command *createSeparator(ActionManager *am, QObject *parent, const QString &name,
603  const QList<int> &context)
604 {
605  QAction *tmpaction = new QAction(parent);
606  tmpaction->setSeparator(true);
607  Command *cmd = am->registerAction(tmpaction, name, context);
608  return cmd;
609 }
610 
611 void MainWindow::registerDefaultActions()
612 {
613  ActionManagerPrivate *am = m_actionManager;
619 
620  // File menu separators
621  Command *cmd =
622  createSeparator(am, this, QLatin1String("QtCreator.File.Sep.Save"), m_globalContext);
623  mfile->addAction(cmd, Constants::G_FILE_SAVE);
624 
625  cmd = createSeparator(am, this, QLatin1String("QtCreator.File.Sep.Close"), m_globalContext);
626  mfile->addAction(cmd, Constants::G_FILE_CLOSE);
627 
628  cmd = createSeparator(am, this, QLatin1String("QtCreator.File.Sep.Other"), m_globalContext);
629  mfile->addAction(cmd, Constants::G_FILE_OTHER);
630 
631  // Edit menu separators
632  cmd = createSeparator(am, this, QLatin1String("QtCreator.Edit.Sep.CopyPaste"), m_globalContext);
634 
635  cmd = createSeparator(am, this, QLatin1String("QtCreator.Edit.Sep.SelectAll"), m_globalContext);
637 
638  cmd = createSeparator(am, this, QLatin1String("QtCreator.Edit.Sep.Find"), m_globalContext);
639  medit->addAction(cmd, Constants::G_EDIT_FIND);
640 
641  cmd = createSeparator(am, this, QLatin1String("QtCreator.Edit.Sep.Advanced"), m_globalContext);
643 
644  // Tools menu separators
645  cmd = createSeparator(am, this, QLatin1String("QtCreator.Tools.Sep.Options"), m_globalContext);
647 
648  // Help menu separators
649 
650  // Return to editor shortcut: Note this requires Qt to fix up
651  // handling of shortcut overrides in menus, item views, combos....
652  m_focusToEditor = new QShortcut(this);
653  cmd = am->registerShortcut(m_focusToEditor, Constants::S_RETURNTOEDITOR, m_globalContext);
654  cmd->setDefaultKeySequence(QKeySequence(Qt::Key_Escape));
655  connect(m_focusToEditor, SIGNAL(activated()), this, SLOT(setFocusToEditor()));
656 
657  // SaveAll Action
658  m_saveAllAction = new QAction(tr("Save &GCS Default Settings"), this);
659  cmd = am->registerAction(m_saveAllAction, Constants::SAVEALL, m_globalContext);
660 #ifndef Q_OS_MAC
661  cmd->setDefaultKeySequence(QKeySequence(tr("Ctrl+Shift+S")));
662 #endif
663  mfile->addAction(cmd, Constants::G_FILE_SAVE);
664  connect(m_saveAllAction, SIGNAL(triggered()), this, SLOT(saveAll()));
665 
666  // Exit Action
667  m_exitAction = new QAction(QIcon(Constants::ICON_EXIT), tr("E&xit"), this);
668  cmd = am->registerAction(m_exitAction, Constants::EXIT, m_globalContext);
669  cmd->setDefaultKeySequence(QKeySequence(tr("Ctrl+Q")));
670  mfile->addAction(cmd, Constants::G_FILE_OTHER);
671  connect(m_exitAction, SIGNAL(triggered()), this, SLOT(exit()));
672 
673  // Undo Action
674  QAction *tmpaction = new QAction(QIcon(Constants::ICON_UNDO), tr("&Undo"), this);
675  cmd = am->registerAction(tmpaction, Constants::UNDO, m_globalContext);
676  cmd->setDefaultKeySequence(QKeySequence::Undo);
678  cmd->setDefaultText(tr("&Undo"));
680  tmpaction->setEnabled(false);
681 
682  // Redo Action
683  tmpaction = new QAction(QIcon(Constants::ICON_REDO), tr("&Redo"), this);
684  cmd = am->registerAction(tmpaction, Constants::REDO, m_globalContext);
685  cmd->setDefaultKeySequence(QKeySequence::Redo);
687  cmd->setDefaultText(tr("&Redo"));
689  tmpaction->setEnabled(false);
690 
691  // Cut Action
692  tmpaction = new QAction(QIcon(Constants::ICON_CUT), tr("Cu&t"), this);
693  cmd = am->registerAction(tmpaction, Constants::CUT, m_globalContext);
694  cmd->setDefaultKeySequence(QKeySequence::Cut);
696  tmpaction->setEnabled(false);
697 
698  // Copy Action
699  tmpaction = new QAction(QIcon(Constants::ICON_COPY), tr("&Copy"), this);
700  cmd = am->registerAction(tmpaction, Constants::COPY, m_globalContext);
701  cmd->setDefaultKeySequence(QKeySequence::Copy);
703  tmpaction->setEnabled(false);
704 
705  // Paste Action
706  tmpaction = new QAction(QIcon(Constants::ICON_PASTE), tr("&Paste"), this);
707  cmd = am->registerAction(tmpaction, Constants::PASTE, m_globalContext);
708  cmd->setDefaultKeySequence(QKeySequence::Paste);
710  tmpaction->setEnabled(false);
711 
712  // Select All
713  tmpaction = new QAction(tr("&Select All"), this);
714  cmd = am->registerAction(tmpaction, Constants::SELECTALL, m_globalContext);
715  cmd->setDefaultKeySequence(QKeySequence::SelectAll);
717  tmpaction->setEnabled(false);
718 
719  // Options Action
720  m_optionsAction = new QAction(QIcon(Constants::ICON_OPTIONS), tr("&Options..."), this);
721  cmd = am->registerAction(m_optionsAction, Constants::OPTIONS, m_globalContext);
722 #ifdef Q_OS_MAC
723  cmd->setDefaultKeySequence(QKeySequence("Ctrl+,"));
724  cmd->action()->setMenuRole(QAction::PreferencesRole);
725 #endif
727  connect(m_optionsAction, SIGNAL(triggered()), this, SLOT(showOptionsDialog()));
728 
729 #ifdef Q_OS_MAC
730  // Minimize Action
731  m_minimizeAction = new QAction(tr("Minimize"), this);
732  cmd = am->registerAction(m_minimizeAction, Constants::MINIMIZE_WINDOW, m_globalContext);
733  cmd->setDefaultKeySequence(QKeySequence("Ctrl+M"));
734  mwindow->addAction(cmd, Constants::G_WINDOW_SIZE);
735  connect(m_minimizeAction, SIGNAL(triggered()), this, SLOT(showMinimized()));
736 
737  // Zoom Action
738  m_zoomAction = new QAction(tr("Zoom"), this);
739  cmd = am->registerAction(m_zoomAction, Constants::ZOOM_WINDOW, m_globalContext);
740  mwindow->addAction(cmd, Constants::G_WINDOW_SIZE);
741  connect(m_zoomAction, SIGNAL(triggered()), this, SLOT(showMaximized()));
742 
743  // Window separator
744  cmd = createSeparator(am, this, QLatin1String("QtCreator.Window.Sep.Size"), m_globalContext);
745  mwindow->addAction(cmd, Constants::G_WINDOW_SIZE);
746 #endif
747 
748 #ifndef Q_OS_MAC
749  // Full Screen Action
750  m_toggleFullScreenAction = new QAction(tr("Full Screen"), this);
751  m_toggleFullScreenAction->setCheckable(true);
752  cmd =
753  am->registerAction(m_toggleFullScreenAction, Constants::TOGGLE_FULLSCREEN, m_globalContext);
754  cmd->setDefaultKeySequence(QKeySequence("Ctrl+Shift+F11"));
755  mwindow->addAction(cmd, Constants::G_WINDOW_SIZE);
756  connect(m_toggleFullScreenAction, SIGNAL(triggered(bool)), this, SLOT(setFullScreen(bool)));
757 #endif
758 
759  /*
760  * UavGadgetManager Actions
761  */
762  const QList<int> uavGadgetManagerContext = QList<int>()
764  // Window menu separators
765  QAction *tmpaction1 = new QAction(this);
766  tmpaction1->setSeparator(true);
767  cmd = am->registerAction(tmpaction1, QLatin1String("GCS.Window.Sep.Split"),
768  uavGadgetManagerContext);
770 
771  m_showToolbarsAction = new QAction(tr("Edit Gadgets Mode"), this);
772  m_showToolbarsAction->setCheckable(true);
773  cmd =
774  am->registerAction(m_showToolbarsAction, Constants::HIDE_TOOLBARS, uavGadgetManagerContext);
775  cmd->setDefaultKeySequence(QKeySequence(tr("Ctrl+Shift+F10")));
777 
778  // Window menu separators
779  QAction *tmpaction2 = new QAction(this);
780  tmpaction2->setSeparator(true);
781  cmd = am->registerAction(tmpaction2, QLatin1String("GCS.Window.Sep.Split2"),
782  uavGadgetManagerContext);
783  mwindow->addAction(cmd, Constants::G_WINDOW_SPLIT);
784 
785 #ifdef Q_OS_MAC
786  QString prefix = tr("Meta+Shift");
787 #else
788  QString prefix = tr("Ctrl+Shift");
789 #endif
790 
791  m_splitAction = new QAction(tr("Split"), this);
792  cmd = am->registerAction(m_splitAction, Constants::SPLIT, uavGadgetManagerContext);
793  cmd->setDefaultKeySequence(QKeySequence(tr("%1+Down").arg(prefix)));
794  mwindow->addAction(cmd, Constants::G_WINDOW_SPLIT);
795 
796  m_splitSideBySideAction = new QAction(tr("Split Side by Side"), this);
797  cmd = am->registerAction(m_splitSideBySideAction, Constants::SPLIT_SIDE_BY_SIDE,
798  uavGadgetManagerContext);
799  cmd->setDefaultKeySequence(QKeySequence(tr("%1+Right").arg(prefix)));
800  mwindow->addAction(cmd, Constants::G_WINDOW_SPLIT);
801 
802  m_removeCurrentSplitAction = new QAction(tr("Close Current View"), this);
803  cmd = am->registerAction(m_removeCurrentSplitAction, Constants::REMOVE_CURRENT_SPLIT,
804  uavGadgetManagerContext);
805  cmd->setDefaultKeySequence(QKeySequence(tr("%1+C").arg(prefix)));
806  mwindow->addAction(cmd, Constants::G_WINDOW_SPLIT);
807 
808  m_removeAllSplitsAction = new QAction(tr("Close All Other Views"), this);
809  cmd = am->registerAction(m_removeAllSplitsAction, Constants::REMOVE_ALL_SPLITS,
810  uavGadgetManagerContext);
811  cmd->setDefaultKeySequence(QKeySequence(tr("%1+A").arg(prefix)));
812  mwindow->addAction(cmd, Constants::G_WINDOW_SPLIT);
813 
814  m_gotoOtherSplitAction = new QAction(tr("Goto Next View"), this);
815  cmd = am->registerAction(m_gotoOtherSplitAction, Constants::GOTO_OTHER_SPLIT,
816  uavGadgetManagerContext);
817  cmd->setDefaultKeySequence(QKeySequence(tr("%1+N").arg(prefix)));
818  mwindow->addAction(cmd, Constants::G_WINDOW_SPLIT);
819 
820  // Help Action
821  tmpaction = new QAction(QIcon(Constants::ICON_HELP), tr("&Help..."), this);
822  cmd = am->registerAction(tmpaction, Constants::G_HELP_HELP, m_globalContext);
823  mhelp->addAction(cmd, Constants::G_HELP_HELP);
824  tmpaction->setEnabled(true);
825  connect(tmpaction, SIGNAL(triggered()), this, SLOT(showHelp()));
826 
827 // About sep
828 #ifndef Q_OS_MAC // doesn't have the "About" actions in the Help menu
829  tmpaction = new QAction(this);
830  tmpaction->setSeparator(true);
831  cmd = am->registerAction(tmpaction, QLatin1String("QtCreator.Help.Sep.About"), m_globalContext);
832  mhelp->addAction(cmd, Constants::G_HELP_ABOUT);
833 #endif
834 
835  // About Plugins Action
836  tmpaction = new QAction(QIcon(Constants::ICON_PLUGIN), tr("About &Plugins..."), this);
837  cmd = am->registerAction(tmpaction, Constants::ABOUT_PLUGINS, m_globalContext);
838  mhelp->addAction(cmd, Constants::G_HELP_ABOUT);
839  tmpaction->setEnabled(true);
840 #ifdef Q_OS_MAC
841  cmd->action()->setMenuRole(QAction::ApplicationSpecificRole);
842 #endif
843  connect(tmpaction, SIGNAL(triggered()), this, SLOT(aboutPlugins()));
844 
845 // About GCS Action
846 #ifdef Q_OS_MAC
847  tmpaction = new QAction(QIcon(Constants::ICON_GCS), tr("About &GCS"),
848  this); // it's convention not to add dots to the about menu
849 #else
850  tmpaction = new QAction(QIcon(Constants::ICON_GCS), tr("About &GCS..."), this);
851 #endif
852  cmd = am->registerAction(tmpaction, Constants::ABOUT_GCS, m_globalContext);
853  mhelp->addAction(cmd, Constants::G_HELP_ABOUT);
854  tmpaction->setEnabled(true);
855 #ifdef Q_OS_MAC
856  cmd->action()->setMenuRole(QAction::ApplicationSpecificRole);
857 #endif
858  connect(tmpaction, SIGNAL(triggered()), this, SLOT(aboutGCS()));
859 
860  // Credits Action
861  tmpaction = new QAction(QIcon(Constants::ICON_PLUGIN), tr("About &Authors..."), this);
862  cmd = am->registerAction(tmpaction, Constants::ABOUT_AUTHORS, m_globalContext);
863  mhelp->addAction(cmd, Constants::G_HELP_ABOUT);
864  tmpaction->setEnabled(true);
865 #ifdef Q_OS_MAC
866  cmd->action()->setMenuRole(QAction::ApplicationSpecificRole);
867 #endif
868  connect(tmpaction, SIGNAL(triggered()), this, SLOT(aboutAuthors()));
869 }
870 
872 {
873 }
874 
875 void MainWindow::openFile()
876 {
877 }
878 
879 void MainWindow::setFocusToEditor()
880 {
881 }
882 
883 bool MainWindow::showOptionsDialog(const QString &category, const QString &page, QWidget *parent)
884 {
885  emit m_coreImpl->optionsDialogRequested();
886  if (!parent)
887  parent = this;
888  SettingsDialog dlg(parent, category, page);
889  return dlg.execDialog();
890 }
891 
892 void MainWindow::saveAll()
893 {
894  if (m_dontSaveSettings)
895  return;
896 
897  emit m_coreImpl->saveSettingsRequested();
898  saveSettings();
899 }
900 
902 {
903  // this function is most likely called from a user action
904  // that is from an event handler of an object
905  // since on close we are going to delete everything
906  // so to prevent the deleting of that object we
907  // just append it
908  QTimer::singleShot(0, this, SLOT(close()));
909 }
910 
912 {
913 }
914 
915 void MainWindow::applyTabBarSettings(QTabWidget::TabPosition pos, bool movable)
916 {
917  if (m_modeStack->tabPosition() != pos)
918  m_modeStack->setTabPosition(pos);
919  m_modeStack->setMovable(movable);
920 }
921 
922 void MainWindow::showHelp()
923 {
924  QDesktopServices::openUrl(QUrl(Constants::GCS_HELP, QUrl::StrictMode));
925 }
926 
928 {
929  return m_actionManager;
930 }
931 
933 {
934  return m_uniqueIDManager;
935 }
936 
938 {
939  return m_globalMessaging;
940 }
941 
942 QSettings *MainWindow::settings(QSettings::Scope scope) const
943 {
944  if (scope == QSettings::UserScope)
945  return m_settings;
946  else
947  return m_globalSettings;
948 }
949 
951 {
952  return m_connectionManager;
953 }
954 
956 {
957  return m_boardManager;
958 }
959 
961 {
962  return m_uavGadgetManagers;
963 }
964 
966 {
967  return m_uavGadgetInstanceManager;
968 }
969 
971 {
972  return m_modeManager;
973 }
974 
976 {
977  return m_generalSettings;
978 }
979 
981 {
982  return m_contextWidgets.value(widget);
983 }
984 
986 {
987  if (!context)
988  return;
989  QWidget *widget = context->widget();
990  if (m_contextWidgets.contains(widget))
991  return;
992 
993  m_contextWidgets.insert(widget, context);
994 }
995 
997 {
998  if (!context)
999  return;
1000 
1001  QWidget *widget = context->widget();
1002  if (!m_contextWidgets.contains(widget))
1003  return;
1004 
1005  m_contextWidgets.remove(widget);
1006  if (m_activeContext == context)
1007  updateContextObject(nullptr);
1008 }
1009 
1011 {
1012  QMainWindow::changeEvent(e);
1013  if (e->type() == QEvent::ActivationChange) {
1014  if (isActiveWindow()) {
1015  if (debugMainWindow)
1016  qDebug() << "main window activated";
1017  emit windowActivated();
1018  }
1019  } else if (e->type() == QEvent::WindowStateChange) {
1020 #ifdef Q_OS_MAC
1021  bool minimized = isMinimized();
1022  if (debugMainWindow)
1023  qDebug() << "main window state changed to minimized=" << minimized;
1024  m_minimizeAction->setEnabled(!minimized);
1025  m_zoomAction->setEnabled(!minimized);
1026 #else
1027  bool isFullScreen = (windowState() & Qt::WindowFullScreen) != 0;
1028  m_toggleFullScreenAction->setChecked(isFullScreen);
1029 #endif
1030  }
1031 }
1032 
1033 void MainWindow::updateFocusWidget(QWidget *old, QWidget *now)
1034 {
1035  Q_UNUSED(old)
1036 
1037  // Prevent changing the context object just because the menu is activated
1038  if (qobject_cast<QMenuBar *>(now))
1039  return;
1040 
1041  IContext *newContext = nullptr;
1042  if (focusWidget()) {
1043  IContext *context = nullptr;
1044  QWidget *p = focusWidget();
1045  while (p) {
1046  context = m_contextWidgets.value(p);
1047  if (context) {
1048  newContext = context;
1049  break;
1050  }
1051  p = p->parentWidget();
1052  }
1053  }
1054  updateContextObject(newContext);
1055 }
1056 
1057 void MainWindow::updateContextObject(IContext *context)
1058 {
1059  if (context == m_activeContext)
1060  return;
1061  IContext *oldContext = m_activeContext;
1062  m_activeContext = context;
1063  if (!context || oldContext != m_activeContext) {
1064  emit m_coreImpl->contextAboutToChange(context);
1065  updateContext();
1066  if (debugMainWindow)
1067  qDebug() << "new context object =" << context << (context ? context->widget() : nullptr)
1068  << (context ? context->widget()->metaObject()->className() : nullptr);
1069  emit m_coreImpl->contextChanged(context);
1070  }
1071 }
1072 
1074 {
1075  updateContextObject(nullptr);
1076 }
1077 
1079 {
1080  disconnect(QApplication::instance(), SIGNAL(focusChanged(QWidget *, QWidget *)), this,
1081  SLOT(updateFocusWidget(QWidget *, QWidget *)));
1082  m_activeContext = nullptr;
1083 
1084  // We have to remove all the existing gagdets at his point, not
1085  // later!
1087 }
1088 
1089 /* Enable/disable menus for uavgadgets */
1090 void MainWindow::showUavGadgetMenus(bool show, bool hasSplitter)
1091 {
1092  m_showToolbarsAction->setChecked(show);
1093  m_splitAction->setEnabled(show);
1094  m_splitSideBySideAction->setEnabled(show);
1095  m_removeCurrentSplitAction->setEnabled(show && hasSplitter);
1096  m_removeAllSplitsAction->setEnabled(show && hasSplitter);
1097  m_gotoOtherSplitAction->setEnabled(show && hasSplitter);
1098 }
1099 
1100 inline int
1102 {
1103  int index = 0;
1104  int prio = m_uavGadgetManagers.at(0)->priority();
1105  for (int i = 0; i < m_uavGadgetManagers.count(); i++) {
1106  int prio2 = m_uavGadgetManagers.at(i)->priority();
1107  if (prio2 < prio) {
1108  prio = prio2;
1109  index = i;
1110  }
1111  }
1112  return index;
1113 }
1114 
1115 void MainWindow::createWorkspaces(QSettings *qs, bool diffOnly)
1116 {
1117 
1118  ExtensionSystem::PluginManager *pm = ExtensionSystem::PluginManager::instance();
1119 
1120  Core::UAVGadgetManager *uavGadgetManager;
1121 
1122  // If diffOnly is true, we only add/remove the number of workspaces
1123  // that has changed,
1124  // otherwise a complete reload of workspaces is done
1125  int toRemoveFirst = m_uavGadgetManagers.count();
1126  int newWorkspacesNo = m_workspaceSettings->numberOfWorkspaces();
1127  if (diffOnly && m_uavGadgetManagers.count() > newWorkspacesNo)
1128  toRemoveFirst = m_uavGadgetManagers.count() - newWorkspacesNo;
1129  else
1130  toRemoveFirst = 0;
1131 
1132  int removed = 0;
1133 
1134  while (!m_uavGadgetManagers.isEmpty() && (toRemoveFirst > removed)) {
1135  int index = takeLeastPriorityUavGadgetManager(m_uavGadgetManagers);
1136  uavGadgetManager = m_uavGadgetManagers.takeAt(index);
1137  uavGadgetManager->removeAllSplits();
1138  pm->removeObject(uavGadgetManager);
1139  delete uavGadgetManager;
1140  removed++;
1141  }
1142 
1143  int start = 0;
1144  if (diffOnly) {
1145  start = m_uavGadgetManagers.count();
1146  } else {
1147  m_uavGadgetManagers.clear();
1148  }
1149  for (int i = start; i < newWorkspacesNo; ++i) {
1150 
1151  const QString name = m_workspaceSettings->name(i);
1152  const QString iconName = m_workspaceSettings->iconName(i);
1153  const QString modeName = m_workspaceSettings->modeName(i);
1154  uavGadgetManager = new Core::UAVGadgetManager(CoreImpl::instance(), name, QIcon(iconName),
1155  90 - i + 1, modeName, this);
1156 
1157  connect(uavGadgetManager, SIGNAL(showUavGadgetMenus(bool, bool)), this,
1158  SLOT(showUavGadgetMenus(bool, bool)));
1159 
1160  connect(m_showToolbarsAction, SIGNAL(triggered(bool)), uavGadgetManager,
1161  SLOT(showToolbars(bool)));
1162  connect(m_splitAction, SIGNAL(triggered()), uavGadgetManager, SLOT(split()));
1163  connect(m_splitSideBySideAction, SIGNAL(triggered()), uavGadgetManager,
1164  SLOT(splitSideBySide()));
1165  connect(m_removeCurrentSplitAction, SIGNAL(triggered()), uavGadgetManager,
1166  SLOT(removeCurrentSplit()));
1167  connect(m_removeAllSplitsAction, SIGNAL(triggered()), uavGadgetManager,
1168  SLOT(removeAllSplits()));
1169  connect(m_gotoOtherSplitAction, SIGNAL(triggered()), uavGadgetManager,
1170  SLOT(gotoOtherSplit()));
1171 
1172  pm->addObject(uavGadgetManager);
1173  m_uavGadgetManagers.append(uavGadgetManager);
1174  uavGadgetManager->readSettings(qs);
1175  }
1176 }
1177 
1178 static const char *settingsGroup = "MainWindow";
1179 static const char *geometryKey = "Geometry";
1180 static const char *maxKey = "Maximized";
1181 static const char *fullScreenKey = "FullScreen";
1182 static const char *modePriorities = "ModePriorities";
1183 
1184 void MainWindow::readSettings(QSettings *qs, bool workspaceDiffOnly)
1185 {
1186  if (!qs) {
1187  qs = m_settings;
1188  }
1189 
1190  if (workspaceDiffOnly) {
1191  createWorkspaces(qs, workspaceDiffOnly);
1192  return;
1193  }
1194 
1195  m_generalSettings->readSettings(qs);
1196  QNetworkProxy::setApplicationProxy(m_generalSettings->getNetworkProxy());
1197  m_actionManager->readSettings(qs);
1198 
1199  qs->beginGroup(QLatin1String(settingsGroup));
1200 
1201  const QVariant geom = qs->value(QLatin1String(geometryKey));
1202  if (geom.isValid()) {
1203  setGeometry(geom.toRect());
1204  } else {
1205  resize(750, 400);
1206  }
1207  if (qs->value(QLatin1String(maxKey), false).toBool())
1208  setWindowState(Qt::WindowMaximized);
1209  setFullScreen(qs->value(QLatin1String(fullScreenKey), false).toBool());
1210 
1211  qs->endGroup();
1212 
1213  m_workspaceSettings->readSettings(qs);
1214 
1215  createWorkspaces(qs);
1216 
1217  // Read tab ordering
1218  qs->beginGroup(QLatin1String(modePriorities));
1219  QStringList modeNames = qs->childKeys();
1220  QMap<QString, int> map;
1221  foreach (QString modeName, modeNames) {
1222  map.insert(modeName, qs->value(modeName).toInt());
1223  }
1224  m_modeManager->reorderModes(map);
1225 
1226  qs->endGroup();
1227 }
1228 
1229 void MainWindow::saveSettings(QSettings *qs)
1230 {
1231  if (m_dontSaveSettings)
1232  return;
1233 
1234  if (!qs) {
1235  qs = m_settings;
1236  }
1237 
1238  m_workspaceSettings->saveSettings(qs);
1239 
1240  qs->beginGroup(QLatin1String(settingsGroup));
1241 
1242  if (windowState() & (Qt::WindowMaximized | Qt::WindowFullScreen)) {
1243  qs->setValue(QLatin1String(maxKey), (bool)(windowState() & Qt::WindowMaximized));
1244  qs->setValue(QLatin1String(fullScreenKey), (bool)(windowState() & Qt::WindowFullScreen));
1245  } else {
1246  qs->setValue(QLatin1String(maxKey), false);
1247  qs->setValue(QLatin1String(fullScreenKey), false);
1248  qs->setValue(QLatin1String(geometryKey), geometry());
1249  }
1250 
1251  qs->endGroup();
1252 
1253  // Write tab ordering
1254  qs->beginGroup(QLatin1String(modePriorities));
1255  QVector<IMode *> modes = m_modeManager->modes();
1256  foreach (IMode *mode, modes) {
1257  qs->setValue(QLatin1String(mode->uniqueModeName()), mode->priority());
1258  }
1259  qs->endGroup();
1260 
1261  foreach (UAVGadgetManager *manager, m_uavGadgetManagers) {
1262  manager->saveSettings(qs);
1263  }
1264 
1265  m_actionManager->saveSettings(qs);
1266  m_generalSettings->saveSettings(qs);
1267  qs->beginGroup("General");
1268  qs->setValue("Description", m_config_description);
1269  qs->setValue("Details", m_config_details);
1270  qs->endGroup();
1271 }
1272 
1273 void MainWindow::readSettings(IConfigurablePlugin *plugin, QSettings *qs)
1274 {
1275  if (!qs) {
1276  qs = m_settings;
1277  }
1278 
1279  UAVConfigInfo configInfo;
1280  QObject *qo = reinterpret_cast<QObject *>(plugin);
1281  QString configName = qo->metaObject()->className();
1282 
1283  qs->beginGroup("Plugins");
1284  qs->beginGroup(configName);
1285  configInfo.read(qs);
1286  configInfo.setNameOfConfigurable("Plugin-" + configName);
1287  qs->beginGroup("data");
1288  plugin->readConfig(qs, &configInfo);
1289 
1290  qs->endGroup();
1291  qs->endGroup();
1292  qs->endGroup();
1293 }
1294 
1295 void MainWindow::saveSettings(IConfigurablePlugin *plugin, QSettings *qs)
1296 {
1297  if (m_dontSaveSettings)
1298  return;
1299  if (!qs) {
1300  qs = m_settings;
1301  }
1302 
1303  UAVConfigInfo configInfo;
1304  QString configName = plugin->metaObject()->className();
1305 
1306  qs->beginGroup("Plugins");
1307  qs->beginGroup(configName);
1308  qs->beginGroup("data");
1309  plugin->saveConfig(qs, &configInfo);
1310  qs->endGroup();
1311  configInfo.save(qs);
1312  qs->endGroup();
1313  qs->endGroup();
1314 }
1315 
1317 {
1318  // Clear the in-memory settings
1319  m_settings->clear();
1320  m_settings->sync();
1321 
1322  // Clear the on-disk settings
1323  QSettings originalSettings(Utils::PathUtils().getSettingsFilename(),
1325  originalSettings.clear();
1326  originalSettings.sync();
1327 
1328  // Don't save the settings when exiting
1329  m_dontSaveSettings = true;
1330 }
1331 
1333 {
1334  if (context == 0)
1335  return;
1336 
1337  if (!m_additionalContexts.contains(context))
1338  m_additionalContexts.prepend(context);
1339 }
1340 
1342 {
1343  if (context == 0)
1344  return;
1345 
1346  int index = m_additionalContexts.indexOf(context);
1347  if (index != -1)
1348  m_additionalContexts.removeAt(index);
1349 }
1350 
1351 bool MainWindow::hasContext(int context) const
1352 {
1353  return m_actionManager->hasContext(context);
1354 }
1355 
1357 {
1358  QList<int> contexts;
1359 
1360  if (m_activeContext)
1361  contexts += m_activeContext->context();
1362 
1363  contexts += m_additionalContexts;
1364 
1365  QList<int> uniquecontexts;
1366  for (int i = 0; i < contexts.size(); ++i) {
1367  const int c = contexts.at(i);
1368  if (!uniquecontexts.contains(c))
1369  uniquecontexts << c;
1370  }
1371 
1372  m_actionManager->setContext(uniquecontexts);
1373 }
1374 
1375 void MainWindow::aboutToShowRecentFiles()
1376 {
1378  if (aci) {
1379  aci->menu()->clear();
1380 
1381  bool hasRecentFiles = false;
1382 
1383  aci->menu()->setEnabled(hasRecentFiles);
1384  }
1385 }
1386 
1387 void MainWindow::openRecentFile()
1388 {
1389  QAction *action = qobject_cast<QAction *>(sender());
1390  if (!action)
1391  return;
1392  QString fileName = action->data().toString();
1393  if (!fileName.isEmpty()) {
1394  }
1395 }
1396 
1397 void MainWindow::aboutGCS()
1398 {
1399  if (!m_versionDialog) {
1400  m_versionDialog = new VersionDialog(this);
1401  connect(m_versionDialog, SIGNAL(finished(int)), this, SLOT(destroyVersionDialog()));
1402  }
1403  m_versionDialog->show();
1404 }
1405 
1406 void MainWindow::destroyVersionDialog()
1407 {
1408  if (m_versionDialog) {
1409  m_versionDialog->deleteLater();
1410  m_versionDialog = nullptr;
1411  }
1412 }
1413 
1414 void MainWindow::aboutAuthors()
1415 {
1416  if (!m_authorsDialog) {
1417  m_authorsDialog = new AuthorsDialog(this);
1418  connect(m_authorsDialog, SIGNAL(finished(int)), this, SLOT(destroyAuthorsDialog()));
1419  }
1420  m_authorsDialog->show();
1421 }
1422 
1423 void MainWindow::destroyAuthorsDialog()
1424 {
1425  if (m_authorsDialog) {
1426  m_authorsDialog->deleteLater();
1427  m_authorsDialog = nullptr;
1428  }
1429 }
1430 
1431 void MainWindow::aboutPlugins()
1432 {
1433  PluginDialog dialog(this);
1434  dialog.exec();
1435 }
1436 
1438 {
1439  if (bool(windowState() & Qt::WindowFullScreen) == on)
1440  return;
1441 
1442  if (on) {
1443  setWindowState(windowState() | Qt::WindowFullScreen);
1444  // statusBar()->hide();
1445  // menuBar()->hide();
1446  } else {
1447  setWindowState(windowState() & ~Qt::WindowFullScreen);
1448  // menuBar()->show();
1449  // statusBar()->show();
1450  }
1451 }
const char *const MINIMIZE_WINDOW
const char *const G_FILE_OPEN
const char *const M_HELP
Definition: coreconstants.h:86
virtual bool coreAboutToClose()
Definition: icorelistener.h:69
const char *const PASTE
const char *const G_EDIT_UNDOREDO
const char *const M_WINDOW
Definition: coreconstants.h:84
int uniqueIdentifier(const QString &id)
const char *const ICON_PASTE
const char *const GCS_HELP
Definition: coreconstants.h:43
const char *const M_EDIT
Definition: coreconstants.h:81
virtual QMenuBar * menuBar() const =0
QString getSettingsFilename()
Definition: pathutils.cpp:147
const char *const COPY
Command * registerShortcut(QShortcut *shortcut, const QString &id, const QList< int > &context)
Makes a shortcut known to the system under the specified string id.
const char *const ICON_CUT
const char *const G_WINDOW_HIDE_TOOLBAR
const char *const G_TOOLS
ActionContainer * createMenuBar(const QString &id)
Creates a new menu bar with the given string id.
virtual int priority() const =0
virtual QAction * action() const =0
Core::GlobalMessaging * globalMessaging() const
Definition: mainwindow.cpp:937
bool hasContext(int context) const
const char *const OPTIONS
virtual void setAttribute(CommandAttribute attr)=0
virtual Command * registerAction(QAction *action, const QString &id, const QList< int > &context)=0
Makes an action known to the system under the specified string id.
const char *const G_WINDOW
void contextChanged(Core::IContext *context)
Sent just after a new context became the current context (meaning that its widget got focus)...
const char *const GOTO_OTHER_SPLIT
const char *const M_TOOLS
Definition: coreconstants.h:83
const char *const ICON_OPTIONS
Core plugin system that manages the plugins, their life cycle and their registered objects...
Definition: pluginmanager.h:53
const char *const G_WINDOW_OTHER
const char *const SPLIT_SIDE_BY_SIDE
const char *const G_EDIT_ADVANCED
void addAdditionalContext(int context)
const char *const MENU_BAR
Definition: coreconstants.h:74
const char *const G_HELP_HELP
void optionsDialogRequested()
Signal that allows plugins to perform actions just before the {Tools|Options} dialog is shown...
bool hasContext(int context) const
void readSettings(QSettings *qs)
const char *const SAVEALL
for i
Definition: OPPlots.m:140
const char *const G_EDIT
const char *const REMOVE_ALL_SPLITS
IContext * currentContextObject() const
Definition: mainwindow.cpp:526
const char *const G_FILE_CLOSE
const char *const ICON_HELP
const char *const G_EDIT_OTHER
const char *const G_FILE_PROJECT
const char *const GCS_AUTHOR
Definition: coreconstants.h:39
const char *const REDO
const char *const G_FILE_SAVE
IContext * contextObject(QWidget *widget)
Definition: mainwindow.cpp:980
void saveSettings(QSettings *qs=nullptr)
const char *const ABOUT_AUTHORS
void readSettings(QSettings *settings)
virtual const char * uniqueModeName() const =0
const char *const G_EDIT_FIND
virtual void dropEvent(QDropEvent *event)
Definition: mainwindow.cpp:515
int takeLeastPriorityUavGadgetManager(const QList< Core::UAVGadgetManager * > m_uavGadgetManagers)
DataFields data
Core::ModeManager * modeManager() const
Definition: mainwindow.cpp:970
virtual void setDefaultText(const QString &text)=0
QVector< IMode * > modes() const
Definition: modemanager.h:70
const char *const M_FILE_RECENTFILES
Definition: coreconstants.h:80
virtual QMenu * menu() const =0
const int C_GLOBAL_ID
Definition: coreconstants.h:90
UAVGadgetInstanceManager * uavGadgetInstanceManager() const
Definition: mainwindow.cpp:965
virtual void dragEnterEvent(QDragEnterEvent *event)
Definition: mainwindow.cpp:506
const char *const CUT
const char *const G_WINDOW_PANES
static bool isAnyUnixHost()
Definition: hostosinfo.h:106
Parse log file
void save(QSettings *qs)
void saveSettings(QSettings *qs)
const char *const G_WINDOW_SPLIT
void coreAboutToOpen()
const char *const G_EDIT_SELECTALL
const char *const GCS_VERSION_LONG
Definition: coreconstants.h:51
const char *const G_VIEW
const char *const M_FILE
Definition: coreconstants.h:77
QStatusBar * statusBar() const
Definition: mainwindow.cpp:531
static ICore * instance()
Definition: coreimpl.cpp:46
const char *const G_FILE_OTHER
const char *const ICON_GCS
Core::BoardManager * boardManager() const
Definition: mainwindow.cpp:955
void saveSettings(QSettings *settings)
const char *const ICON_COPY
Command * registerAction(QAction *action, const QString &id, const QList< int > &context)
Makes an action known to the system under the specified string id.
const char *const G_WINDOW_NAVIGATE
virtual void appendGroup(const QString &group)=0
virtual void readConfig(QSettings *qSettings, UAVConfigInfo *configInfo)=0
const char *const G_HELP
const char *const ICON_UNDO
virtual void closeEvent(QCloseEvent *event)
Definition: mainwindow.cpp:450
const char *const ICON_EXIT
void setContext(const QList< int > &context)
static bool isMacHost()
Definition: hostosinfo.h:58
void coreAboutToClose()
Plugins can do some pre-end-of-life actions when they get this signal.
virtual void addAction(Core::Command *action, const QString &group=QString())=0
const char *const TOGGLE_FULLSCREEN
QString choosenConfig()
const char *const HIDE_TOOLBARS
bool showOptionsDialog(const QString &category=QString(), const QString &page=QString(), QWidget *parent=nullptr)
Definition: mainwindow.cpp:883
void coreOpened()
Emitted after all plugins have been loaded and the main window shown.
virtual void setDefaultKeySequence(const QKeySequence &key)=0
const char *const S_RETURNTOEDITOR
Core::ConnectionManager * connectionManager() const
Definition: mainwindow.cpp:950
Provides a hook for plugins to veto on certain events emitted from the core plugin.
Definition: icorelistener.h:59
virtual void saveConfig(QSettings *qSettings, Core::UAVConfigInfo *configInfo)=0
void splashMessages(QString)
const char *const GCS_NAME
Definition: coreconstants.h:38
const char *const G_FILE
void readSettings(QSettings *qs=nullptr, bool workspaceDiffOnly=false)
const char *const G_FILE_NEW
The Config Info is a helper-class to handle version changes in GCS configuration files.
Definition: uavconfiginfo.h:53
ActionContainer * createMenu(const QString &id)
Creates a new menu with the given string id.
The action manager is responsible for registration of menus and menu items and keyboard shortcuts...
Definition: actionmanager.h:47
const char *const SPLIT
const char *const G_WINDOW_SIZE
const char *const C_UAVGADGETMANAGER
Definition: coreconstants.h:93
virtual QList< int > context() const =0
void read(QSettings *qs)
static const QSettings::Format XmlSettingsFormat
Definition: xmlconfig.h:43
void saveSettingsRequested()
Emitted to signal that the user has requested that the global settings should be saved to disk...
ActionContainer * actionContainer(int uid) const
void setNameOfConfigurable(const QString nameOfConfigurable)
Definition: uavconfiginfo.h:69
const char *const ABOUT_GCS
Internal::GeneralSettings * generalSettings() const
Definition: mainwindow.cpp:975
Definition: icore.h:39
const char *const ICON_REDO
void loadFiles(QString path)
QSettings * settings(QSettings::Scope scope) const
Definition: mainwindow.cpp:942
virtual void addMenu(Core::ActionContainer *menu, const QString &group=QString())=0
virtual UniqueIDManager * uniqueIDManager() const =0
Returns the application's id manager.
Core::UniqueIDManager * uniqueIDManager() const
Definition: mainwindow.cpp:932
const char *const G_EDIT_COPYPASTE
virtual QWidget * widget()=0
bool init(QString *errorMessage)
Definition: mainwindow.cpp:297
void reorderModes(QMap< QString, int > priorities)
const char *const ZOOM_WINDOW
void addContextObject(IContext *contex)
Definition: mainwindow.cpp:985
void removeContextObject(IContext *contex)
Definition: mainwindow.cpp:996
void contextAboutToChange(Core::IContext *context)
Sent just before a new context becomes the current context (meaning that its widget got focus)...
const char *const EXIT
const char *const REMOVE_CURRENT_SPLIT
The class Command represents an action like a menu item, tool button, or shortcut. You don't create Command objects directly, instead use {ActionManager::registerAction()} to register an action and retrieve a Command. The Command object represents the user visible action and its properties. If multiple actions are registered with the same ID (but different contexts) the returned Command is the shared one between these actions.
Definition: command.h:43
QList< UAVGadgetManager * > uavGadgetManagers() const
Definition: mainwindow.cpp:960
const char *const G_HELP_ABOUT
const char *const ICON_PLUGIN
const char *const UNDO
virtual void changeEvent(QEvent *e)
e
Definition: OPPlots.m:99
void removeAdditionalContext(int context)
const char *const ABOUT_PLUGINS
Core::ActionManager * actionManager() const
Definition: mainwindow.cpp:927
const char *const SELECTALL
const char *const G_DEFAULT_THREE