2 ******************************************************************************
5 * @author The LibrePilot Project, http://www.librepilot.org Copyright (C) 2015.
6 * The OpenPilot Team, http://www.openpilot.org Copyright (C) 2010.
7 * Parts by Nokia Corporation (qt-info@nokia.com) Copyright (C) 2009.
8 * @addtogroup GCSPlugins GCS Plugins
10 * @addtogroup CorePlugin Core Plugin
12 * @brief The Core GCS plugin
13 *****************************************************************************/
15 * This program is free software; you can redistribute it and/or modify
16 * it under the terms of the GNU General Public License as published by
17 * the Free Software Foundation; either version 3 of the License, or
18 * (at your option) any later version.
20 * This program is distributed in the hope that it will be useful, but
21 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
22 * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
25 * You should have received a copy of the GNU General Public License along
26 * with this program; if not, write to the Free Software Foundation, Inc.,
27 * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
30 #include "mainwindow.h"
31 #include "actioncontainer.h"
32 #include "actionmanager_p.h"
34 #include "connectionmanager.h"
36 #include "coreconstants.h"
37 #include "utils/mytabwidget.h"
38 #include "generalsettings.h"
39 #include "messagemanager.h"
40 #include "modemanager.h"
41 #include "mimedatabase.h"
42 #include "outputpane.h"
43 #include "plugindialog.h"
44 #include "shortcutsettings.h"
45 #include "uavgadgetmanager.h"
46 #include "uavgadgetinstancemanager.h"
47 #include "workspacesettings.h"
49 #include "aboutdialog.h"
51 #include "ioutputpane.h"
52 #include "icorelistener.h"
53 #include "iconfigurableplugin.h"
55 #include <qstylefactory.h>
57 #include "settingsdialog.h"
58 #include "threadmanager.h"
59 #include "uniqueidmanager.h"
60 #include "variablemanager.h"
62 #include <coreplugin/settingsdatabase.h>
63 #include <extensionsystem/pluginmanager.h>
64 #include "dialogs/iwizard.h"
65 #include <utils/pathchooser.h>
66 #include <utils/pathutils.h>
67 #include <utils/stylehelper.h>
68 #include "version_info/version_info.h"
70 #include <QtCore/QDebug>
71 #include <QtCore/QFileInfo>
72 #include <QtCore/QSettings>
73 #include <QtCore/QTimer>
74 #include <QtCore/QtPlugin>
75 #include <QtCore/QUrl>
77 #include <QtWidgets/QApplication>
78 #include <QCloseEvent>
84 #include <QToolButton>
85 #include <QMessageBox>
86 #include <QDesktopServices>
87 #include <QElapsedTimer>
92 #include <QtPlatformHeaders/QWindowsWindowFunctions>
96 using namespace Core::Internal
;
98 static const char *uriListMimeFormatC
= "text/uri-list";
100 enum { debugMainWindow
= 0 };
102 MainWindow::MainWindow() :
103 EventFilteringMainWindow(),
104 m_coreImpl(new CoreImpl(this)),
105 m_uniqueIDManager(new UniqueIDManager()),
106 m_globalContext(QList
<int>() << Constants::C_GLOBAL_ID
),
107 m_additionalContexts(m_globalContext
),
108 m_dontSaveSettings(false),
109 m_actionManager(new ActionManagerPrivate(this)),
110 m_variableManager(new VariableManager(this)),
111 m_threadManager(new ThreadManager(this)),
113 m_connectionManager(0),
114 m_mimeDatabase(new MimeDatabase
),
117 m_generalSettings(new GeneralSettings
),
118 m_shortcutSettings(new ShortcutSettings
),
119 m_workspaceSettings(new WorkspaceSettings
),
131 m_toggleFullScreenAction(0)
133 setWindowTitle(QLatin1String(GCS_BIG_NAME
) + " " + VersionInfo::label());
135 qApp
->setWindowIcon(QIcon(":/core/images/librepilot_logo_128.png"));
137 qApp
->setStyle(QStyleFactory::create("Fusion"));
140 m_settingsDatabase
= new SettingsDatabase(QFileInfo(settings
.fileName()).path(),
141 QFileInfo(settings
.fileName()).baseName(),
144 setDockNestingEnabled(true);
146 setCorner(Qt::BottomLeftCorner
, Qt::LeftDockWidgetArea
);
147 setCorner(Qt::BottomRightCorner
, Qt::BottomDockWidgetArea
);
149 registerDefaultContainers();
150 registerDefaultActions();
152 m_modeStack
= new MyTabWidget(this);
153 m_modeStack
->setIconSize(QSize(24, 24));
154 m_modeStack
->setTabPosition(QTabWidget::South
);
155 m_modeStack
->setMovable(false);
156 m_modeStack
->setMinimumWidth(512);
157 m_modeStack
->setElideMode(Qt::ElideRight
);
158 m_modeManager
= new ModeManager(this, m_modeStack
);
160 m_connectionManager
= new ConnectionManager(this);
161 m_modeStack
->setCornerWidget(m_connectionManager
, Qt::TopRightCorner
);
163 m_messageManager
= new MessageManager
;
164 setCentralWidget(m_modeStack
);
166 connect(QApplication::instance(), SIGNAL(focusChanged(QWidget
*, QWidget
*)),
167 this, SLOT(updateFocusWidget(QWidget
*, QWidget
*)));
168 connect(m_workspaceSettings
, SIGNAL(tabBarSettingsApplied(QTabWidget::TabPosition
, bool)),
169 this, SLOT(applyTabBarSettings(QTabWidget::TabPosition
, bool)));
170 connect(m_modeManager
, SIGNAL(newModeOrder(QVector
<IMode
*>)), m_workspaceSettings
, SLOT(newModeOrder(QVector
<IMode
*>)));
171 statusBar()->setProperty("p_styled", true);
172 setAcceptDrops(true);
175 MainWindow::~MainWindow()
177 if (m_connectionManager
) {
179 m_connectionManager
->disconnectDevice();
180 m_connectionManager
->suspendPolling();
185 ExtensionSystem::PluginManager
*pm
= ExtensionSystem::PluginManager::instance();
186 if (m_uavGadgetManagers
.count() > 0) {
187 foreach(UAVGadgetManager
* mode
, m_uavGadgetManagers
) {
188 pm
->removeObject(mode
);
193 pm
->removeObject(m_shortcutSettings
);
194 pm
->removeObject(m_generalSettings
);
195 pm
->removeObject(m_workspaceSettings
);
196 delete m_messageManager
;
197 m_messageManager
= 0;
198 delete m_shortcutSettings
;
199 m_shortcutSettings
= 0;
200 delete m_generalSettings
;
201 m_generalSettings
= 0;
202 delete m_workspaceSettings
;
203 m_workspaceSettings
= 0;
204 delete m_uniqueIDManager
;
205 m_uniqueIDManager
= 0;
207 pm
->removeObject(m_coreImpl
);
211 delete m_modeManager
;
213 delete m_mimeDatabase
;
217 bool MainWindow::init(QString
*errorMessage
)
219 Q_UNUSED(errorMessage
)
221 ExtensionSystem::PluginManager
* pm
= ExtensionSystem::PluginManager::instance();
222 pm
->addObject(m_coreImpl
);
223 m_modeManager
->init();
224 m_connectionManager
->init();
226 pm
->addObject(m_generalSettings
);
227 pm
->addObject(m_shortcutSettings
);
228 pm
->addObject(m_workspaceSettings
);
233 void MainWindow::modeChanged(Core::IMode
* /*mode*/)
236 void MainWindow::extensionsInitialized()
240 settings
.beginGroup("General");
242 m_config_description
= settings
.value("Description", "none").toString();
243 m_config_details
= settings
.value("Details", "none").toString();
244 m_config_stylesheet
= settings
.value("StyleSheet", "none").toString();
246 qDebug() << "Configured style sheet:" << m_config_stylesheet
;
247 if (m_config_stylesheet
== "wide") {
248 // OP-869 just in case some user configuration still references the now obsolete "wide" style sheet
249 m_config_stylesheet
= "default";
252 // Load common style sheet
253 QString style
= loadStyleSheet(m_config_stylesheet
+ ".qss");
255 // Load and concatenate platform specific style sheet
256 QString fileName
= m_config_stylesheet
;
258 fileName
+= "_macos.qss";
259 #elif defined(Q_OS_LINUX)
260 fileName
+= "_linux.qss";
262 fileName
+= "_windows.qss";
264 style
+= loadStyleSheet(fileName
);
266 // We'll use qApp macro to get the QApplication pointer
267 // and set the style sheet application wide.
268 // qDebug() << "Setting application style sheet to:" << style;
269 qApp
->setStyleSheet(style
);
273 m_uavGadgetInstanceManager
= new UAVGadgetInstanceManager(this);
275 m_uavGadgetInstanceManager
->readSettings(settings
);
277 m_messageManager
->init();
278 readSettings(settings
);
282 emit m_coreImpl
->coreAboutToOpen();
284 emit m_coreImpl
->coreOpened();
287 QString
MainWindow::loadStyleSheet(QString fileName
)
290 // ...to open the file
291 QFile
file(Utils::GetDataPath() + QString("stylesheets/") + fileName
);
293 qDebug() << "Loading style sheet file" << file
.fileName();
294 if (file
.open(QFile::ReadOnly
)) {
296 QTextStream
textStream(&file
);
297 // ...read file to a string.
298 style
= textStream
.readAll();
301 qDebug() << "Failed to open style sheet file" << file
.fileName();
306 void MainWindow::closeEvent(QCloseEvent
*event
)
308 if (!m_generalSettings
->saveSettingsOnExit()) {
309 m_dontSaveSettings
= true;
311 if (!m_dontSaveSettings
) {
312 emit m_coreImpl
->saveSettingsRequested();
315 const QList
<ICoreListener
*> listeners
= ExtensionSystem::PluginManager::instance()->getObjects
<ICoreListener
>();
316 foreach(ICoreListener
* listener
, listeners
) {
317 if (!listener
->coreAboutToClose()) {
323 emit m_coreImpl
->coreAboutToClose();
325 if (!m_dontSaveSettings
) {
327 saveSettings(settings
);
328 m_uavGadgetInstanceManager
->saveSettings(settings
);
331 qApp
->closeAllWindows();
336 // Check for desktop file manager file drop events
337 static bool isDesktopFileManagerDrop(const QMimeData
*d
, QStringList
*files
= 0)
342 // Extract dropped files from Mime data.
343 if (!d
->hasFormat(QLatin1String(uriListMimeFormatC
))) {
346 const QList
<QUrl
> urls
= d
->urls();
350 // Try to find local files
351 bool hasFiles
= false;
352 const QList
<QUrl
>::const_iterator cend
= urls
.constEnd();
353 for (QList
<QUrl
>::const_iterator it
= urls
.constBegin(); it
!= cend
; ++it
) {
354 const QString fileName
= it
->toLocalFile();
355 if (!fileName
.isEmpty()) {
358 files
->push_back(fileName
);
360 break; // No result list, sufficient for checking
367 void MainWindow::dragEnterEvent(QDragEnterEvent
*event
)
369 if (isDesktopFileManagerDrop(event
->mimeData())) {
376 void MainWindow::dropEvent(QDropEvent
*event
)
380 if (isDesktopFileManagerDrop(event
->mimeData(), &files
)) {
388 IContext
*MainWindow::currentContextObject() const
390 return m_activeContext
;
393 QStatusBar
*MainWindow::statusBar() const
395 return new QStatusBar(); // m_modeStack->statusBar();
398 void MainWindow::registerDefaultContainers()
400 ActionManagerPrivate
*am
= m_actionManager
;
402 ActionContainer
*menubar
= am
->createMenuBar(Constants::MENU_BAR
);
404 #ifndef Q_WS_MAC // System menu bar on Mac
405 setMenuBar(menubar
->menuBar());
407 menubar
->appendGroup(Constants::G_FILE
);
408 menubar
->appendGroup(Constants::G_EDIT
);
409 menubar
->appendGroup(Constants::G_VIEW
);
410 menubar
->appendGroup(Constants::G_TOOLS
);
411 menubar
->appendGroup(Constants::G_WINDOW
);
412 menubar
->appendGroup(Constants::G_HELP
);
415 ActionContainer
*filemenu
= am
->createMenu(Constants::M_FILE
);
416 menubar
->addMenu(filemenu
, Constants::G_FILE
);
417 filemenu
->menu()->setTitle(tr("&File"));
418 filemenu
->appendGroup(Constants::G_FILE_NEW
);
419 filemenu
->appendGroup(Constants::G_FILE_OPEN
);
420 filemenu
->appendGroup(Constants::G_FILE_PROJECT
);
421 filemenu
->appendGroup(Constants::G_FILE_SAVE
);
422 filemenu
->appendGroup(Constants::G_FILE_CLOSE
);
423 filemenu
->appendGroup(Constants::G_FILE_OTHER
);
424 connect(filemenu
->menu(), SIGNAL(aboutToShow()), this, SLOT(aboutToShowRecentFiles()));
428 ActionContainer
*medit
= am
->createMenu(Constants::M_EDIT
);
429 menubar
->addMenu(medit
, Constants::G_EDIT
);
430 medit
->menu()->setTitle(tr("&Edit"));
431 medit
->appendGroup(Constants::G_EDIT_UNDOREDO
);
432 medit
->appendGroup(Constants::G_EDIT_COPYPASTE
);
433 medit
->appendGroup(Constants::G_EDIT_SELECTALL
);
434 medit
->appendGroup(Constants::G_EDIT_ADVANCED
);
435 medit
->appendGroup(Constants::G_EDIT_FIND
);
436 medit
->appendGroup(Constants::G_EDIT_OTHER
);
439 ActionContainer
*ac
= am
->createMenu(Constants::M_TOOLS
);
440 menubar
->addMenu(ac
, Constants::G_TOOLS
);
441 ac
->menu()->setTitle(tr("&Tools"));
444 ActionContainer
*mwindow
= am
->createMenu(Constants::M_WINDOW
);
445 menubar
->addMenu(mwindow
, Constants::G_WINDOW
);
446 mwindow
->menu()->setTitle(tr("&Window"));
447 mwindow
->appendGroup(Constants::G_WINDOW_SIZE
);
448 mwindow
->appendGroup(Constants::G_WINDOW_HIDE_TOOLBAR
);
449 mwindow
->appendGroup(Constants::G_WINDOW_PANES
);
450 mwindow
->appendGroup(Constants::G_WINDOW_SPLIT
);
451 mwindow
->appendGroup(Constants::G_WINDOW_NAVIGATE
);
452 mwindow
->appendGroup(Constants::G_WINDOW_OTHER
);
455 ac
= am
->createMenu(Constants::M_HELP
);
456 menubar
->addMenu(ac
, Constants::G_HELP
);
457 ac
->menu()->setTitle(tr("&Help"));
458 ac
->appendGroup(Constants::G_HELP_HELP
);
459 ac
->appendGroup(Constants::G_HELP_ABOUT
);
462 static Command
*createSeparator(ActionManager
*am
, QObject
*parent
, const QString
&name
, const QList
<int> &context
)
464 QAction
*tmpaction
= new QAction(parent
);
466 tmpaction
->setSeparator(true);
467 Command
*cmd
= am
->registerAction(tmpaction
, name
, context
);
471 void MainWindow::registerDefaultActions()
473 ActionManagerPrivate
*am
= m_actionManager
;
474 ActionContainer
*mfile
= am
->actionContainer(Constants::M_FILE
);
475 ActionContainer
*medit
= am
->actionContainer(Constants::M_EDIT
);
476 ActionContainer
*mtools
= am
->actionContainer(Constants::M_TOOLS
);
477 ActionContainer
*mwindow
= am
->actionContainer(Constants::M_WINDOW
);
478 ActionContainer
*mhelp
= am
->actionContainer(Constants::M_HELP
);
480 // File menu separators
481 Command
*cmd
= createSeparator(am
, this, "QtCreator.File.Sep.Save", m_globalContext
);
483 mfile
->addAction(cmd
, Constants::G_FILE_SAVE
);
485 cmd
= createSeparator(am
, this, "QtCreator.File.Sep.Close", m_globalContext
);
486 mfile
->addAction(cmd
, Constants::G_FILE_CLOSE
);
488 cmd
= createSeparator(am
, this, "QtCreator.File.Sep.Other", m_globalContext
);
489 mfile
->addAction(cmd
, Constants::G_FILE_OTHER
);
491 // Edit menu separators
492 cmd
= createSeparator(am
, this, "QtCreator.Edit.Sep.CopyPaste", m_globalContext
);
493 medit
->addAction(cmd
, Constants::G_EDIT_COPYPASTE
);
495 cmd
= createSeparator(am
, this, "QtCreator.Edit.Sep.SelectAll", m_globalContext
);
496 medit
->addAction(cmd
, Constants::G_EDIT_SELECTALL
);
498 cmd
= createSeparator(am
, this, "QtCreator.Edit.Sep.Find", m_globalContext
);
499 medit
->addAction(cmd
, Constants::G_EDIT_FIND
);
501 cmd
= createSeparator(am
, this, "QtCreator.Edit.Sep.Advanced", m_globalContext
);
502 medit
->addAction(cmd
, Constants::G_EDIT_ADVANCED
);
504 // Tools menu separators
505 cmd
= createSeparator(am
, this, "QtCreator.Tools.Sep.Options", m_globalContext
);
506 mtools
->addAction(cmd
, Constants::G_DEFAULT_THREE
);
508 // Help menu separators
510 // Return to editor shortcut: Note this requires Qt to fix up
511 // handling of shortcut overrides in menus, item views, combos....
512 m_focusToEditor
= new QShortcut(this);
513 cmd
= am
->registerShortcut(m_focusToEditor
, Constants::S_RETURNTOEDITOR
, m_globalContext
);
514 cmd
->setDefaultKeySequence(QKeySequence(Qt::Key_Escape
));
515 connect(m_focusToEditor
, SIGNAL(activated()), this, SLOT(setFocusToEditor()));
520 m_newAction = new QAction(QIcon(Constants::ICON_NEWFILE), tr("&New File or Project..."), this);
521 cmd = am->registerAction(m_newAction, Constants::NEW, m_globalContext);
522 cmd->setDefaultKeySequence(QKeySequence::New);
523 mfile->addAction(cmd, Constants::G_FILE_NEW);
524 connect(m_newAction, SIGNAL(triggered()), this, SLOT(newFile()));
529 m_openAction = new QAction(QIcon(Constants::ICON_OPENFILE), tr("&Open File or Project..."), this);
530 cmd = am->registerAction(m_openAction, Constants::OPEN, m_globalContext);
531 cmd->setDefaultKeySequence(QKeySequence::Open);
532 mfile->addAction(cmd, Constants::G_FILE_OPEN);
533 connect(m_openAction, SIGNAL(triggered()), this, SLOT(openFile()));
538 m_openWithAction = new QAction(tr("&Open File With..."), this);
539 cmd = am->registerAction(m_openWithAction, Constants::OPEN_WITH, m_globalContext);
540 mfile->addAction(cmd, Constants::G_FILE_OPEN);
541 connect(m_openWithAction, SIGNAL(triggered()), this, SLOT(openFileWith()));
544 // File->Recent Files Menu
546 ActionContainer *ac = am->createMenu(Constants::M_FILE_RECENTFILES);
547 mfile->addMenu(ac, Constants::G_FILE_OPEN);
548 ac->menu()->setTitle(tr("Recent Files"));
552 QAction *tmpaction = new QAction(QIcon(Constants::ICON_SAVEFILE), tr("&Save"), this);
553 cmd = am->registerAction(tmpaction, Constants::SAVE, m_globalContext);
554 cmd->setDefaultKeySequence(QKeySequence::Save);
555 cmd->setAttribute(Command::CA_UpdateText);
556 cmd->setDefaultText(tr("&Save"));
557 mfile->addAction(cmd, Constants::G_FILE_SAVE);
560 tmpaction = new QAction(tr("Save &As..."), this);
561 cmd = am->registerAction(tmpaction, Constants::SAVEAS, m_globalContext);
563 cmd->setDefaultKeySequence(QKeySequence(tr("Ctrl+Shift+S")));
565 cmd->setAttribute(Command::CA_UpdateText);
566 cmd->setDefaultText(tr("Save &As..."));
567 mfile->addAction(cmd, Constants::G_FILE_SAVE);
571 m_saveAllAction
= new QAction(tr("Save &GCS Default Settings"), this);
572 cmd
= am
->registerAction(m_saveAllAction
, Constants::SAVEALL
, m_globalContext
);
574 cmd
->setDefaultKeySequence(QKeySequence(tr("Ctrl+Shift+S")));
576 mfile
->addAction(cmd
, Constants::G_FILE_SAVE
);
577 connect(m_saveAllAction
, SIGNAL(triggered()), this, SLOT(saveAll()));
580 m_exitAction
= new QAction(QIcon(Constants::ICON_EXIT
), tr("E&xit"), this);
581 cmd
= am
->registerAction(m_exitAction
, Constants::EXIT
, m_globalContext
);
582 cmd
->setDefaultKeySequence(QKeySequence(tr("Ctrl+Q")));
583 mfile
->addAction(cmd
, Constants::G_FILE_OTHER
);
584 connect(m_exitAction
, SIGNAL(triggered()), this, SLOT(exit()));
587 QAction
*tmpaction
= new QAction(QIcon(Constants::ICON_UNDO
), tr("&Undo"), this);
588 cmd
= am
->registerAction(tmpaction
, Constants::UNDO
, m_globalContext
);
589 cmd
->setDefaultKeySequence(QKeySequence::Undo
);
590 cmd
->setAttribute(Command::CA_UpdateText
);
591 cmd
->setDefaultText(tr("&Undo"));
592 medit
->addAction(cmd
, Constants::G_EDIT_UNDOREDO
);
593 tmpaction
->setEnabled(false);
596 tmpaction
= new QAction(QIcon(Constants::ICON_REDO
), tr("&Redo"), this);
597 cmd
= am
->registerAction(tmpaction
, Constants::REDO
, m_globalContext
);
598 cmd
->setDefaultKeySequence(QKeySequence::Redo
);
599 cmd
->setAttribute(Command::CA_UpdateText
);
600 cmd
->setDefaultText(tr("&Redo"));
601 medit
->addAction(cmd
, Constants::G_EDIT_UNDOREDO
);
602 tmpaction
->setEnabled(false);
605 tmpaction
= new QAction(QIcon(Constants::ICON_CUT
), tr("Cu&t"), this);
606 cmd
= am
->registerAction(tmpaction
, Constants::CUT
, m_globalContext
);
607 cmd
->setDefaultKeySequence(QKeySequence::Cut
);
608 medit
->addAction(cmd
, Constants::G_EDIT_COPYPASTE
);
609 tmpaction
->setEnabled(false);
612 tmpaction
= new QAction(QIcon(Constants::ICON_COPY
), tr("&Copy"), this);
613 cmd
= am
->registerAction(tmpaction
, Constants::COPY
, m_globalContext
);
614 cmd
->setDefaultKeySequence(QKeySequence::Copy
);
615 medit
->addAction(cmd
, Constants::G_EDIT_COPYPASTE
);
616 tmpaction
->setEnabled(false);
619 tmpaction
= new QAction(QIcon(Constants::ICON_PASTE
), tr("&Paste"), this);
620 cmd
= am
->registerAction(tmpaction
, Constants::PASTE
, m_globalContext
);
621 cmd
->setDefaultKeySequence(QKeySequence::Paste
);
622 medit
->addAction(cmd
, Constants::G_EDIT_COPYPASTE
);
623 tmpaction
->setEnabled(false);
626 tmpaction
= new QAction(tr("&Select All"), this);
627 cmd
= am
->registerAction(tmpaction
, Constants::SELECTALL
, m_globalContext
);
628 cmd
->setDefaultKeySequence(QKeySequence::SelectAll
);
629 medit
->addAction(cmd
, Constants::G_EDIT_SELECTALL
);
630 tmpaction
->setEnabled(false);
633 m_optionsAction
= new QAction(QIcon(Constants::ICON_OPTIONS
), tr("&Options..."), this);
634 cmd
= am
->registerAction(m_optionsAction
, Constants::OPTIONS
, m_globalContext
);
636 cmd
->setDefaultKeySequence(QKeySequence("Ctrl+,"));
637 cmd
->action()->setMenuRole(QAction::PreferencesRole
);
639 mtools
->addAction(cmd
, Constants::G_DEFAULT_THREE
);
640 connect(m_optionsAction
, SIGNAL(triggered()), this, SLOT(showOptionsDialog()));
644 m_minimizeAction
= new QAction(tr("Minimize"), this);
645 cmd
= am
->registerAction(m_minimizeAction
, Constants::MINIMIZE_WINDOW
, m_globalContext
);
646 cmd
->setDefaultKeySequence(QKeySequence("Ctrl+M"));
647 mwindow
->addAction(cmd
, Constants::G_WINDOW_SIZE
);
648 connect(m_minimizeAction
, SIGNAL(triggered()), this, SLOT(showMinimized()));
651 m_zoomAction
= new QAction(tr("Zoom"), this);
652 cmd
= am
->registerAction(m_zoomAction
, Constants::ZOOM_WINDOW
, m_globalContext
);
653 mwindow
->addAction(cmd
, Constants::G_WINDOW_SIZE
);
654 connect(m_zoomAction
, SIGNAL(triggered()), this, SLOT(showMaximized()));
657 cmd
= createSeparator(am
, this, "QtCreator.Window.Sep.Size", m_globalContext
);
658 mwindow
->addAction(cmd
, Constants::G_WINDOW_SIZE
);
662 // Full Screen Action
663 m_toggleFullScreenAction
= new QAction(tr("Full Screen"), this);
664 m_toggleFullScreenAction
->setCheckable(true);
665 cmd
= am
->registerAction(m_toggleFullScreenAction
, Constants::TOGGLE_FULLSCREEN
, m_globalContext
);
666 cmd
->setDefaultKeySequence(QKeySequence("Ctrl+Shift+F11"));
667 mwindow
->addAction(cmd
, Constants::G_WINDOW_SIZE
);
668 connect(m_toggleFullScreenAction
, SIGNAL(triggered(bool)), this, SLOT(setFullScreen(bool)));
672 * UavGadgetManager Actions
674 const QList
<int> uavGadgetManagerContext
=
675 QList
<int>() << CoreImpl::instance()->uniqueIDManager()->uniqueIdentifier(Constants::C_UAVGADGETMANAGER
);
676 // Window menu separators
677 QAction
*tmpaction1
= new QAction(this);
678 tmpaction1
->setSeparator(true);
679 cmd
= am
->registerAction(tmpaction1
, "OpenPilot.Window.Sep.Split", uavGadgetManagerContext
);
680 mwindow
->addAction(cmd
, Constants::G_WINDOW_HIDE_TOOLBAR
);
682 m_showToolbarsAction
= new QAction(tr("Edit Gadgets Mode"), this);
683 m_showToolbarsAction
->setCheckable(true);
684 cmd
= am
->registerAction(m_showToolbarsAction
, Constants::HIDE_TOOLBARS
, uavGadgetManagerContext
);
685 cmd
->setDefaultKeySequence(QKeySequence(tr("Ctrl+Shift+F10")));
686 mwindow
->addAction(cmd
, Constants::G_WINDOW_HIDE_TOOLBAR
);
688 // Window menu separators
689 QAction
*tmpaction2
= new QAction(this);
690 tmpaction2
->setSeparator(true);
691 cmd
= am
->registerAction(tmpaction2
, "OpenPilot.Window.Sep.Split2", uavGadgetManagerContext
);
692 mwindow
->addAction(cmd
, Constants::G_WINDOW_SPLIT
);
695 QString prefix
= tr("Meta+Shift");
697 QString prefix
= tr("Ctrl+Shift");
700 m_splitAction
= new QAction(tr("Split"), this);
701 cmd
= am
->registerAction(m_splitAction
, Constants::SPLIT
, uavGadgetManagerContext
);
702 cmd
->setDefaultKeySequence(QKeySequence(tr("%1+Down").arg(prefix
)));
703 mwindow
->addAction(cmd
, Constants::G_WINDOW_SPLIT
);
705 m_splitSideBySideAction
= new QAction(tr("Split Side by Side"), this);
706 cmd
= am
->registerAction(m_splitSideBySideAction
, Constants::SPLIT_SIDE_BY_SIDE
, uavGadgetManagerContext
);
707 cmd
->setDefaultKeySequence(QKeySequence(tr("%1+Right").arg(prefix
)));
708 mwindow
->addAction(cmd
, Constants::G_WINDOW_SPLIT
);
710 m_removeCurrentSplitAction
= new QAction(tr("Close Current View"), this);
711 cmd
= am
->registerAction(m_removeCurrentSplitAction
, Constants::REMOVE_CURRENT_SPLIT
, uavGadgetManagerContext
);
712 cmd
->setDefaultKeySequence(QKeySequence(tr("%1+C").arg(prefix
)));
713 mwindow
->addAction(cmd
, Constants::G_WINDOW_SPLIT
);
715 m_removeAllSplitsAction
= new QAction(tr("Close All Other Views"), this);
716 cmd
= am
->registerAction(m_removeAllSplitsAction
, Constants::REMOVE_ALL_SPLITS
, uavGadgetManagerContext
);
717 cmd
->setDefaultKeySequence(QKeySequence(tr("%1+A").arg(prefix
)));
718 mwindow
->addAction(cmd
, Constants::G_WINDOW_SPLIT
);
720 m_gotoOtherSplitAction
= new QAction(tr("Goto Next View"), this);
721 cmd
= am
->registerAction(m_gotoOtherSplitAction
, Constants::GOTO_OTHER_SPLIT
, uavGadgetManagerContext
);
722 cmd
->setDefaultKeySequence(QKeySequence(tr("%1+N").arg(prefix
)));
723 mwindow
->addAction(cmd
, Constants::G_WINDOW_SPLIT
);
726 tmpaction
= new QAction(QIcon(Constants::ICON_HELP
), tr("&Help..."), this);
727 cmd
= am
->registerAction(tmpaction
, Constants::G_HELP_HELP
, m_globalContext
);
728 mhelp
->addAction(cmd
, Constants::G_HELP_HELP
);
729 tmpaction
->setEnabled(true);
730 connect(tmpaction
, SIGNAL(triggered()), this, SLOT(showHelp()));
733 // Mac doesn't have the "About" actions in the Help menu
735 tmpaction
= new QAction(this);
736 tmpaction
->setSeparator(true);
737 cmd
= am
->registerAction(tmpaction
, "QtCreator.Help.Sep.About", m_globalContext
);
738 mhelp
->addAction(cmd
, Constants::G_HELP_ABOUT
);
741 // About Plugins Action
742 tmpaction
= new QAction(QIcon(Constants::ICON_PLUGIN
), tr("About &Plugins..."), this);
743 cmd
= am
->registerAction(tmpaction
, Constants::ABOUT_PLUGINS
, m_globalContext
);
744 mhelp
->addAction(cmd
, Constants::G_HELP_ABOUT
);
745 tmpaction
->setEnabled(true);
747 cmd
->action()->setMenuRole(QAction::ApplicationSpecificRole
);
749 connect(tmpaction
, SIGNAL(triggered()), this, SLOT(aboutPlugins()));
752 tmpaction
= new QAction(QIcon(Constants::ICON_PLUGIN
), tr("About &%1...").arg(ORG_BIG_NAME
), this);
753 cmd
= am
->registerAction(tmpaction
, Constants::ABOUT_AUTHORS
, m_globalContext
);
754 mhelp
->addAction(cmd
, Constants::G_HELP_ABOUT
);
755 tmpaction
->setEnabled(true);
757 cmd
->action()->setMenuRole(QAction::ApplicationSpecificRole
);
759 connect(tmpaction
, SIGNAL(triggered()), this, SLOT(showAboutDialog()));
762 void MainWindow::newFile()
765 void MainWindow::openFile()
768 void MainWindow::setFocusToEditor()
771 bool MainWindow::showOptionsDialog(const QString
&category
, const QString
&page
, QWidget
*parent
)
773 emit m_coreImpl
->optionsDialogRequested();
778 SettingsDialog
dlg(parent
, category
, page
);
779 return dlg
.execDialog();
782 void MainWindow::saveAll()
784 if (m_dontSaveSettings
) {
788 emit m_coreImpl
->saveSettingsRequested();
790 saveSettings(settings
);
793 void MainWindow::exit()
795 // this function is most likely called from a user action
796 // that is from an event handler of an object
797 // since on close we are going to delete everything
798 // so to prevent the deleting of that object we
800 QTimer::singleShot(0, this, SLOT(close()));
803 void MainWindow::openFileWith()
806 void MainWindow::applyTabBarSettings(QTabWidget::TabPosition pos
, bool movable
)
808 if (m_modeStack
->tabPosition() != pos
) {
809 m_modeStack
->setTabPosition(pos
);
811 m_modeStack
->setMovable(movable
);
814 void MainWindow::showHelp()
816 QDesktopServices::openUrl(QUrl(Constants::GCS_HELP
, QUrl::StrictMode
));
819 ActionManager
*MainWindow::actionManager() const
821 return m_actionManager
;
824 UniqueIDManager
*MainWindow::uniqueIDManager() const
826 return m_uniqueIDManager
;
829 MessageManager
*MainWindow::messageManager() const
831 return m_messageManager
;
834 VariableManager
*MainWindow::variableManager() const
836 return m_variableManager
;
839 ThreadManager
*MainWindow::threadManager() const
841 return m_threadManager
;
844 ConnectionManager
*MainWindow::connectionManager() const
846 return m_connectionManager
;
849 QList
<UAVGadgetManager
*> MainWindow::uavGadgetManagers() const
851 return m_uavGadgetManagers
;
854 UAVGadgetInstanceManager
*MainWindow::uavGadgetInstanceManager() const
856 return m_uavGadgetInstanceManager
;
860 ModeManager
*MainWindow::modeManager() const
862 return m_modeManager
;
865 MimeDatabase
*MainWindow::mimeDatabase() const
867 return m_mimeDatabase
;
870 GeneralSettings
*MainWindow::generalSettings() const
872 return m_generalSettings
;
875 IContext
*MainWindow::contextObject(QWidget
*widget
)
877 return m_contextWidgets
.value(widget
, NULL
);
880 void MainWindow::addContextObject(IContext
*context
)
885 QWidget
*widget
= context
->widget();
886 if (m_contextWidgets
.contains(widget
)) {
890 m_contextWidgets
.insert(widget
, context
);
893 void MainWindow::removeContextObject(IContext
*context
)
899 QWidget
*widget
= context
->widget();
900 if (!m_contextWidgets
.contains(widget
)) {
904 m_contextWidgets
.remove(widget
);
905 if (m_activeContext
== context
) {
906 updateContextObject(0);
910 void MainWindow::changeEvent(QEvent
*e
)
912 QMainWindow::changeEvent(e
);
914 if (e
->type() == QEvent::ActivationChange
) {
915 if (isActiveWindow()) {
916 if (debugMainWindow
) {
917 qDebug() << "main window activated";
919 emit
windowActivated();
921 } else if (e
->type() == QEvent::WindowStateChange
) {
923 bool minimized
= isMinimized();
924 if (debugMainWindow
) {
925 qDebug() << "main window state changed to minimized=" << minimized
;
927 m_minimizeAction
->setEnabled(!minimized
);
928 m_zoomAction
->setEnabled(!minimized
);
930 bool isFullScreen
= (windowState() & Qt::WindowFullScreen
) != 0;
931 m_toggleFullScreenAction
->setChecked(isFullScreen
);
936 void MainWindow::updateFocusWidget(QWidget
*old
, QWidget
*now
)
940 // Prevent changing the context object just because the menu is activated
941 if (qobject_cast
<QMenuBar
*>(now
)) {
945 IContext
*newContext
= 0;
947 IContext
*context
= 0;
948 QWidget
*p
= focusWidget();
950 context
= m_contextWidgets
.value(p
, NULL
);
952 newContext
= context
;
955 p
= p
->parentWidget();
958 updateContextObject(newContext
);
961 void MainWindow::updateContextObject(IContext
*context
)
963 if (context
== m_activeContext
) {
966 IContext
*oldContext
= m_activeContext
;
967 m_activeContext
= context
;
968 if (!context
|| oldContext
!= m_activeContext
) {
969 emit m_coreImpl
->contextAboutToChange(context
);
971 if (debugMainWindow
) {
972 qDebug() << "new context object =" << context
<< (context
? context
->widget() : 0)
973 << (context
? context
->widget()->metaObject()->className() : 0);
975 emit m_coreImpl
->contextChanged(context
);
979 void MainWindow::resetContext()
981 updateContextObject(0);
984 void MainWindow::shutdown()
986 disconnect(QApplication::instance(), SIGNAL(focusChanged(QWidget
*, QWidget
*)),
987 this, SLOT(updateFocusWidget(QWidget
*, QWidget
*)));
990 // We have to remove all the existing gagdets at his point, not
992 uavGadgetInstanceManager()->removeAllGadgets();
995 /* Enable/disable menus for uavgadgets */
996 void MainWindow::showUavGadgetMenus(bool show
, bool hasSplitter
)
998 m_showToolbarsAction
->setChecked(show
);
999 m_splitAction
->setEnabled(show
);
1000 m_splitSideBySideAction
->setEnabled(show
);
1001 m_removeCurrentSplitAction
->setEnabled(show
&& hasSplitter
);
1002 m_removeAllSplitsAction
->setEnabled(show
&& hasSplitter
);
1003 m_gotoOtherSplitAction
->setEnabled(show
&& hasSplitter
);
1006 inline int takeLeastPriorityUavGadgetManager(const QList
<Core::UAVGadgetManager
*> m_uavGadgetManagers
)
1009 int prio
= m_uavGadgetManagers
.at(0)->priority();
1011 for (int i
= 0; i
< m_uavGadgetManagers
.count(); i
++) {
1012 int prio2
= m_uavGadgetManagers
.at(i
)->priority();
1021 void MainWindow::createWorkspaces(QSettings
&settings
, bool diffOnly
)
1023 ExtensionSystem::PluginManager
*pm
= ExtensionSystem::PluginManager::instance();
1025 Core::UAVGadgetManager
*uavGadgetManager
;
1027 // If diffOnly is true, we only add/remove the number of workspaces
1028 // that has changed,
1029 // otherwise a complete reload of workspaces is done
1030 int toRemoveFirst
= m_uavGadgetManagers
.count();
1031 int newWorkspacesNo
= m_workspaceSettings
->numberOfWorkspaces();
1033 if (diffOnly
&& m_uavGadgetManagers
.count() > newWorkspacesNo
) {
1034 toRemoveFirst
= m_uavGadgetManagers
.count() - newWorkspacesNo
;
1041 while (!m_uavGadgetManagers
.isEmpty() && (toRemoveFirst
> removed
)) {
1042 int index
= takeLeastPriorityUavGadgetManager(m_uavGadgetManagers
);
1043 uavGadgetManager
= m_uavGadgetManagers
.takeAt(index
);
1044 uavGadgetManager
->removeAllSplits();
1045 pm
->removeObject(uavGadgetManager
);
1046 delete uavGadgetManager
;
1052 start
= m_uavGadgetManagers
.count();
1054 m_uavGadgetManagers
.clear();
1057 QElapsedTimer totalTimer
;
1059 for (int i
= start
; i
< newWorkspacesNo
; ++i
) {
1060 QElapsedTimer timer
;
1063 const QString name
= m_workspaceSettings
->name(i
);
1064 const QString iconName
= m_workspaceSettings
->iconName(i
);
1065 const QString modeName
= m_workspaceSettings
->modeName(i
);
1066 uavGadgetManager
= new Core::UAVGadgetManager(CoreImpl::instance(), name
, QIcon(iconName
), 90 - i
+ 1, modeName
,
1069 connect(uavGadgetManager
, SIGNAL(showUavGadgetMenus(bool, bool)), this, SLOT(showUavGadgetMenus(bool, bool)));
1071 connect(m_showToolbarsAction
, SIGNAL(triggered(bool)), uavGadgetManager
, SLOT(showToolbars(bool)));
1072 connect(m_splitAction
, SIGNAL(triggered()), uavGadgetManager
, SLOT(split()));
1073 connect(m_splitSideBySideAction
, SIGNAL(triggered()), uavGadgetManager
, SLOT(splitSideBySide()));
1074 connect(m_removeCurrentSplitAction
, SIGNAL(triggered()), uavGadgetManager
, SLOT(removeCurrentSplit()));
1075 connect(m_removeAllSplitsAction
, SIGNAL(triggered()), uavGadgetManager
, SLOT(removeAllSplits()));
1076 connect(m_gotoOtherSplitAction
, SIGNAL(triggered()), uavGadgetManager
, SLOT(gotoOtherSplit()));
1078 pm
->addObject(uavGadgetManager
);
1079 m_uavGadgetManagers
.append(uavGadgetManager
);
1080 uavGadgetManager
->readSettings(settings
);
1081 qDebug() << "MainWindow::createWorkspaces - creating workspace" << name
<< "took" << timer
.elapsed() << "ms";
1083 qDebug() << "MainWindow::createWorkspaces - creating workspaces took" << totalTimer
.elapsed() << "ms";
1086 static const QString settingsGroup
= "MainWindow";
1087 static const QString geometryKey
= "Geometry";
1088 static const QString colorKey
= "Color";
1089 static const QString maxKey
= "Maximized";
1090 static const QString fullScreenKey
= "FullScreen";
1091 static const QString modePriorities
= "ModePriorities";
1093 void MainWindow::readSettings(QSettings
&settings
, bool workspaceDiffOnly
)
1095 if (workspaceDiffOnly
) {
1096 createWorkspaces(settings
, workspaceDiffOnly
);
1100 m_generalSettings
->readSettings(settings
);
1101 m_actionManager
->readSettings(settings
);
1103 settings
.beginGroup(settingsGroup
);
1105 Utils::StyleHelper::setBaseColor(settings
.value(colorKey
).value
<QColor
>());
1107 const QVariant geom
= settings
.value(geometryKey
);
1108 if (geom
.isValid()) {
1109 setGeometry(geom
.toRect());
1113 if (settings
.value(maxKey
, false).toBool()) {
1114 setWindowState(Qt::WindowMaximized
);
1116 setFullScreen(settings
.value(fullScreenKey
, false).toBool());
1118 settings
.endGroup();
1120 m_workspaceSettings
->readSettings(settings
);
1122 createWorkspaces(settings
);
1124 // Restore tab ordering
1125 settings
.beginGroup(modePriorities
);
1127 QStringList modeNames
= settings
.childKeys();
1128 QMap
<QString
, int> map
;
1129 foreach(QString modeName
, modeNames
) {
1130 map
.insert(modeName
, settings
.value(modeName
).toInt());
1132 m_modeManager
->reorderModes(map
);
1134 settings
.endGroup();
1136 // Restore selected tab
1137 if (m_workspaceSettings
->restoreSelectedOnStartup()) {
1138 int index
= settings
.value("SelectedWorkspace").toInt();
1139 m_modeStack
->setCurrentIndex(index
);
1144 void MainWindow::saveSettings(QSettings
&settings
) const
1146 if (m_dontSaveSettings
) {
1150 m_workspaceSettings
->saveSettings(settings
);
1152 settings
.beginGroup(settingsGroup
);
1154 settings
.setValue(colorKey
, Utils::StyleHelper::baseColor());
1156 if (windowState() & (Qt::WindowMaximized
| Qt::WindowFullScreen
)) {
1157 settings
.setValue(maxKey
, (bool)(windowState() & Qt::WindowMaximized
));
1158 settings
.setValue(fullScreenKey
, (bool)(windowState() & Qt::WindowFullScreen
));
1160 settings
.setValue(maxKey
, false);
1161 settings
.setValue(fullScreenKey
, false);
1162 settings
.setValue(geometryKey
, geometry());
1165 settings
.endGroup();
1167 // Write tab ordering
1168 settings
.beginGroup(modePriorities
);
1169 QVector
<IMode
*> modes
= m_modeManager
->modes();
1170 foreach(IMode
* mode
, modes
) {
1171 settings
.setValue(mode
->uniqueModeName(), mode
->priority());
1173 settings
.endGroup();
1175 // Write selected tab
1176 settings
.setValue("SelectedWorkspace", m_modeStack
->currentIndex());
1178 foreach(UAVGadgetManager
* manager
, m_uavGadgetManagers
) {
1179 manager
->saveSettings(settings
);
1182 m_actionManager
->saveSettings(settings
);
1183 m_generalSettings
->saveSettings(settings
);
1185 settings
.beginGroup("General");
1186 settings
.setValue("Description", m_config_description
);
1187 settings
.setValue("Details", m_config_details
);
1188 settings
.setValue("StyleSheet", m_config_stylesheet
);
1189 settings
.endGroup();
1192 void MainWindow::readSettings(IConfigurablePlugin
*plugin
, QSettings
&settings
)
1194 UAVConfigInfo configInfo
;
1195 QObject
*qo
= reinterpret_cast<QObject
*>(plugin
);
1196 QString configName
= qo
->metaObject()->className();
1198 settings
.beginGroup("Plugins");
1199 settings
.beginGroup(configName
);
1200 configInfo
.read(settings
);
1201 configInfo
.setNameOfConfigurable("Plugin-" + configName
);
1202 settings
.beginGroup("data");
1203 plugin
->readConfig(settings
, &configInfo
);
1205 settings
.endGroup();
1206 settings
.endGroup();
1207 settings
.endGroup();
1210 void MainWindow::saveSettings(IConfigurablePlugin
*plugin
, QSettings
&settings
) const
1212 if (m_dontSaveSettings
) {
1216 UAVConfigInfo configInfo
;
1217 QString configName
= plugin
->metaObject()->className();
1219 settings
.beginGroup("Plugins");
1220 settings
.beginGroup(configName
);
1221 settings
.beginGroup("data");
1222 plugin
->saveConfig(settings
, &configInfo
);
1223 settings
.endGroup();
1224 configInfo
.save(settings
);
1225 settings
.endGroup();
1226 settings
.endGroup();
1229 void MainWindow::deleteSettings()
1235 m_dontSaveSettings
= true;
1238 void MainWindow::addAdditionalContext(int context
)
1244 if (!m_additionalContexts
.contains(context
)) {
1245 m_additionalContexts
.prepend(context
);
1249 void MainWindow::removeAdditionalContext(int context
)
1255 int index
= m_additionalContexts
.indexOf(context
);
1257 m_additionalContexts
.removeAt(index
);
1261 bool MainWindow::hasContext(int context
) const
1263 return m_actionManager
->hasContext(context
);
1266 void MainWindow::updateContext()
1268 QList
<int> contexts
;
1270 if (m_activeContext
) {
1271 contexts
+= m_activeContext
->context();
1274 contexts
+= m_additionalContexts
;
1276 QList
<int> uniquecontexts
;
1277 for (int i
= 0; i
< contexts
.size(); ++i
) {
1278 const int c
= contexts
.at(i
);
1279 if (!uniquecontexts
.contains(c
)) {
1280 uniquecontexts
<< c
;
1284 m_actionManager
->setContext(uniquecontexts
);
1287 void MainWindow::aboutToShowRecentFiles()
1289 ActionContainer
*aci
=
1290 m_actionManager
->actionContainer(Constants::M_FILE_RECENTFILES
);
1293 aci
->menu()->clear();
1295 bool hasRecentFiles
= false;
1297 aci
->menu()->setEnabled(hasRecentFiles
);
1301 void MainWindow::openRecentFile()
1303 QAction
*action
= qobject_cast
<QAction
*>(sender());
1308 QString fileName
= action
->data().toString();
1309 if (!fileName
.isEmpty()) {}
1312 void MainWindow::showAboutDialog()
1314 if (!m_aboutDialog
) {
1315 m_aboutDialog
= new AboutDialog(this);
1316 connect(m_aboutDialog
, SIGNAL(finished(int)),
1317 this, SLOT(destroyAboutDialog()));
1319 m_aboutDialog
->show();
1322 void MainWindow::destroyAboutDialog()
1324 if (m_aboutDialog
) {
1325 m_aboutDialog
->deleteLater();
1330 void MainWindow::aboutPlugins()
1332 PluginDialog
dialog(this);
1337 void MainWindow::setFullScreen(bool on
)
1339 if (bool(windowState() & Qt::WindowFullScreen
) == on
) {
1345 QWindowsWindowFunctions::setHasBorderInFullScreen(windowHandle(), true);
1347 setWindowState(windowState() | Qt::WindowFullScreen
);
1349 setWindowState(windowState() & ~Qt::WindowFullScreen
);
1353 // Display a warning with an additional button to open
1354 // the debugger settings dialog if settingsId is nonempty.
1356 bool MainWindow::showWarningWithOptions(const QString
&title
,
1357 const QString
&text
,
1358 const QString
&details
,
1359 const QString
&settingsCategory
,
1360 const QString
&settingsId
,
1366 QMessageBox
msgBox(QMessageBox::Warning
, title
, text
,
1367 QMessageBox::Ok
, parent
);
1368 if (details
.isEmpty()) {
1369 msgBox
.setDetailedText(details
);
1371 QAbstractButton
*settingsButton
= 0;
1372 if (!settingsId
.isEmpty() || !settingsCategory
.isEmpty()) {
1373 settingsButton
= msgBox
.addButton(tr("Settings..."), QMessageBox::AcceptRole
);
1376 if (settingsButton
&& msgBox
.clickedButton() == settingsButton
) {
1377 return showOptionsDialog(settingsCategory
, settingsId
);