1 /**************************************************************************
3 ** This file is part of Qt Creator
5 ** Copyright (c) 2011 Nokia Corporation and/or its subsidiary(-ies).
7 ** Contact: Nokia Corporation (info@qt.nokia.com)
10 ** GNU Lesser General Public License Usage
12 ** This file may be used under the terms of the GNU Lesser General Public
13 ** License version 2.1 as published by the Free Software Foundation and
14 ** appearing in the file LICENSE.LGPL included in the packaging of this file.
15 ** Please review the following information to ensure the GNU Lesser General
16 ** Public License version 2.1 requirements will be met:
17 ** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
19 ** In addition, as a special exception, Nokia gives you certain additional
20 ** rights. These rights are described in the Nokia Qt LGPL Exception
21 ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
25 ** Alternatively, this file may be used in accordance with the terms and
26 ** conditions contained in a signed written agreement between you and Nokia.
28 ** If you have questions regarding the use of this file, please contact
29 ** Nokia at info@qt.nokia.com.
31 **************************************************************************/
33 #include "mainwindow.h"
34 #include "actioncontainer.h"
36 #include "actionmanager_p.h"
38 #include "coreconstants.h"
39 #include "editormanager.h"
40 #include "externaltool.h"
41 #include "toolsettings.h"
42 #include "mimetypesettings.h"
43 #include "fancytabwidget.h"
44 #include "filemanager.h"
45 #include "generalsettings.h"
46 #include "helpmanager.h"
48 #include "ifilefactory.h"
49 #include "messagemanager.h"
50 #include "modemanager.h"
51 #include "mimedatabase.h"
52 #include "newdialog.h"
53 #include "outputpanemanager.h"
54 #include "outputpane.h"
55 #include "plugindialog.h"
56 #include "progressmanager_p.h"
57 #include "progressview.h"
58 #include "shortcutsettings.h"
59 #include "vcsmanager.h"
60 #include "variablechooser.h"
62 #include "scriptmanager_p.h"
63 #include "settingsdialog.h"
64 #include "variablemanager.h"
65 #include "versiondialog.h"
66 #include "statusbarmanager.h"
67 #include "uniqueidmanager.h"
68 #include "manhattanstyle.h"
69 #include "navigationwidget.h"
70 #include "rightpane.h"
71 #include "editormanager/ieditorfactory.h"
72 #include "statusbarwidget.h"
73 #include "basefilewizard.h"
74 #include "ioutputpane.h"
75 #include "editormanager/systemeditor.h"
77 #include <coreplugin/findplaceholder.h>
78 #include <coreplugin/icorelistener.h>
79 #include <coreplugin/inavigationwidgetfactory.h>
80 #include <coreplugin/settingsdatabase.h>
81 #include <utils/pathchooser.h>
82 #include <utils/stylehelper.h>
83 #include <utils/stringutils.h>
84 #include <extensionsystem/pluginmanager.h>
86 #include <QtCore/QDebug>
87 #include <QtCore/QFileInfo>
88 #include <QtCore/QSettings>
89 #include <QtCore/QTimer>
90 #include <QtCore/QtPlugin>
91 #include <QtCore/QUrl>
92 #include <QtCore/QDir>
93 #include <QtCore/QFile>
95 #include <QtGui/QApplication>
96 #include <QtGui/QCloseEvent>
97 #include <QtGui/QMenu>
98 #include <QtGui/QPixmap>
99 #include <QtGui/QPrinter>
100 #include <QtGui/QShortcut>
101 #include <QtGui/QStatusBar>
102 #include <QtGui/QWizard>
103 #include <QtGui/QToolButton>
104 #include <QtGui/QMessageBox>
105 #include <QtGui/QMenuBar>
106 #include <QtGui/QPushButton>
111 extern "C" void handleSigInt(int sig)
114 Core::ICore::instance()->exit();
115 qDebug() << "SIGINT caught. Shutting down.";
120 using namespace Core;
121 using namespace Core::Internal;
123 enum { debugMainWindow = 0 };
125 MainWindow::MainWindow() :
126 EventFilteringMainWindow(),
127 m_coreImpl(new CoreImpl(this)),
128 m_uniqueIDManager(new UniqueIDManager()),
129 m_additionalContexts(Constants::C_GLOBAL),
130 m_settings(ExtensionSystem::PluginManager::instance()->settings()),
131 m_globalSettings(new QSettings(QSettings::IniFormat, QSettings::SystemScope,
132 QLatin1String("Nokia"), QLatin1String("QtCreator"), this)),
133 m_settingsDatabase(new SettingsDatabase(QFileInfo(m_settings->fileName()).path(),
134 QLatin1String("QtCreator"),
137 m_actionManager(new ActionManagerPrivate(this)),
139 m_externalToolManager(0),
140 m_fileManager(new FileManager(this)),
141 m_progressManager(new ProgressManagerPrivate()),
142 m_scriptManager(new ScriptManagerPrivate(this)),
143 m_variableManager(new VariableManager),
144 m_vcsManager(new VcsManager),
145 m_statusBarManager(0),
147 m_mimeDatabase(new MimeDatabase),
148 m_helpManager(new HelpManager),
149 m_navigationWidget(0),
150 m_rightPaneWidget(0),
153 m_generalSettings(new GeneralSettings),
154 m_shortcutSettings(new ShortcutSettings),
155 m_toolSettings(new ToolSettings),
156 m_mimeTypeSettings(new MimeTypeSettings),
157 m_systemEditor(new SystemEditor),
165 m_toggleSideBarAction(0),
166 m_toggleFullScreenAction(0),
171 m_toggleSideBarButton(new QToolButton)
173 OutputPaneManager::create();
175 setWindowTitle(tr("Qt Creator"));
177 QApplication::setWindowIcon(QIcon(QLatin1String(Constants::ICON_QTLOGO_128)));
179 QCoreApplication::setApplicationName(QLatin1String("QtCreator"));
180 QCoreApplication::setApplicationVersion(QLatin1String(Core::Constants::IDE_VERSION_LONG));
181 QCoreApplication::setOrganizationName(QLatin1String("Nokia"));
182 QSettings::setDefaultFormat(QSettings::IniFormat);
183 QString baseName = QApplication::style()->objectName();
185 if (baseName == QLatin1String("windows")) {
186 // Sometimes we get the standard windows 95 style as a fallback
187 // e.g. if we are running on a KDE4 desktop
188 QByteArray desktopEnvironment = qgetenv("DESKTOP_SESSION");
189 if (desktopEnvironment == "kde")
190 baseName = QLatin1String("plastique");
192 baseName = QLatin1String("cleanlooks");
195 qApp->setStyle(new ManhattanStyle(baseName));
197 setDockNestingEnabled(true);
199 setCorner(Qt::BottomLeftCorner, Qt::LeftDockWidgetArea);
200 setCorner(Qt::BottomRightCorner, Qt::BottomDockWidgetArea);
202 registerDefaultContainers();
203 registerDefaultActions();
205 m_navigationWidget = new NavigationWidget(m_toggleSideBarAction);
206 m_rightPaneWidget = new RightPaneWidget();
208 m_modeStack = new FancyTabWidget(this);
209 m_modeManager = new ModeManager(this, m_modeStack);
210 m_modeManager->addWidget(m_progressManager->progressView());
211 m_statusBarManager = new StatusBarManager(this);
212 m_messageManager = new MessageManager;
213 m_editorManager = new EditorManager(m_coreImpl, this);
214 m_editorManager->hide();
215 m_externalToolManager = new ExternalToolManager(m_coreImpl);
216 setCentralWidget(m_modeStack);
218 connect(QApplication::instance(), SIGNAL(focusChanged(QWidget*,QWidget*)),
219 this, SLOT(updateFocusWidget(QWidget*,QWidget*)));
220 // Add a small Toolbutton for toggling the navigation widget
221 statusBar()->insertPermanentWidget(0, m_toggleSideBarButton);
223 // setUnifiedTitleAndToolBarOnMac(true);
225 //signal(SIGINT, handleSigInt);
228 statusBar()->setProperty("p_styled", true);
229 setAcceptDrops(true);
232 void MainWindow::setSidebarVisible(bool visible)
234 if (NavigationWidgetPlaceHolder::current()) {
235 if (m_navigationWidget->isSuppressed() && visible) {
236 m_navigationWidget->setShown(true);
237 m_navigationWidget->setSuppressed(false);
239 m_navigationWidget->setShown(visible);
244 void MainWindow::setSuppressNavigationWidget(bool suppress)
246 if (NavigationWidgetPlaceHolder::current())
247 m_navigationWidget->setSuppressed(suppress);
250 void MainWindow::setOverrideColor(const QColor &color)
252 m_overrideColor = color;
255 MainWindow::~MainWindow()
257 ExtensionSystem::PluginManager *pm = ExtensionSystem::PluginManager::instance();
258 pm->removeObject(m_shortcutSettings);
259 pm->removeObject(m_generalSettings);
260 pm->removeObject(m_toolSettings);
261 pm->removeObject(m_mimeTypeSettings);
262 pm->removeObject(m_systemEditor);
263 delete m_externalToolManager;
264 m_externalToolManager = 0;
265 delete m_messageManager;
266 m_messageManager = 0;
267 delete m_shortcutSettings;
268 m_shortcutSettings = 0;
269 delete m_generalSettings;
270 m_generalSettings = 0;
271 delete m_toolSettings;
273 delete m_mimeTypeSettings;
274 m_mimeTypeSettings = 0;
275 delete m_systemEditor;
281 delete m_uniqueIDManager;
282 m_uniqueIDManager = 0;
285 //we need to delete editormanager and statusbarmanager explicitly before the end of the destructor,
286 //because they might trigger stuff that tries to access data from editorwindow, like removeContextWidget
288 // All modes are now gone
289 OutputPaneManager::destroy();
291 // Now that the OutputPaneManager is gone, is a good time to delete the view
292 pm->removeObject(m_outputView);
295 delete m_editorManager;
297 delete m_statusBarManager;
298 m_statusBarManager = 0;
299 delete m_progressManager;
300 m_progressManager = 0;
301 pm->removeObject(m_coreImpl);
305 delete m_rightPaneWidget;
306 m_rightPaneWidget = 0;
308 delete m_modeManager;
310 delete m_mimeDatabase;
313 delete m_helpManager;
317 bool MainWindow::init(QString *errorMessage)
319 Q_UNUSED(errorMessage)
321 if (!mimeDatabase()->addMimeTypes(QLatin1String(":/core/editormanager/BinFiles.mimetypes.xml"), errorMessage))
324 ExtensionSystem::PluginManager *pm = ExtensionSystem::PluginManager::instance();
325 pm->addObject(m_coreImpl);
326 m_statusBarManager->init();
327 m_modeManager->init();
328 m_progressManager->init();
330 pm->addObject(m_generalSettings);
331 pm->addObject(m_shortcutSettings);
332 pm->addObject(m_toolSettings);
333 pm->addObject(m_mimeTypeSettings);
334 pm->addObject(m_systemEditor);
336 // Add widget to the bottom, we create the view here instead of inside the
337 // OutputPaneManager, since the StatusBarManager needs to be initialized before
338 m_outputView = new Core::StatusBarWidget;
339 m_outputView->setWidget(OutputPaneManager::instance()->buttonsWidget());
340 m_outputView->setPosition(Core::StatusBarWidget::Second);
341 pm->addObject(m_outputView);
342 m_messageManager->init();
346 void MainWindow::extensionsInitialized()
348 m_editorManager->init();
349 m_statusBarManager->extensionsInitalized();
350 OutputPaneManager::instance()->init();
351 m_vcsManager->extensionsInitialized();
352 m_navigationWidget->setFactories(ExtensionSystem::PluginManager::instance()->getObjects<INavigationWidgetFactory>());
354 // reading the shortcut settings must be done after all shortcuts have been registered
355 m_actionManager->initialize();
360 emit m_coreImpl->coreAboutToOpen();
362 emit m_coreImpl->coreOpened();
365 void MainWindow::closeEvent(QCloseEvent *event)
367 emit m_coreImpl->saveSettingsRequested();
371 QList<IFile*> notSaved = fileManager()->saveModifiedFiles(fileManager()->modifiedFiles(), &cancelled);
372 if (cancelled || !notSaved.isEmpty()) {
377 const QList<ICoreListener *> listeners =
378 ExtensionSystem::PluginManager::instance()->getObjects<ICoreListener>();
379 foreach (ICoreListener *listener, listeners) {
380 if (!listener->coreAboutToClose()) {
386 emit m_coreImpl->coreAboutToClose();
390 m_navigationWidget->closeSubWidgets();
395 // Check for desktop file manager file drop events
397 static bool isDesktopFileManagerDrop(const QMimeData *d, QStringList *files = 0)
401 // Extract dropped files from Mime data.
404 const QList<QUrl> urls = d->urls();
407 // Try to find local files
408 bool hasFiles = false;
409 const QList<QUrl>::const_iterator cend = urls.constEnd();
410 for (QList<QUrl>::const_iterator it = urls.constBegin(); it != cend; ++it) {
411 const QString fileName = it->toLocalFile();
412 if (!fileName.isEmpty()) {
415 files->push_back(fileName);
417 break; // No result list, sufficient for checking
424 void MainWindow::dragEnterEvent(QDragEnterEvent *event)
426 if (isDesktopFileManagerDrop(event->mimeData()) && m_filesToOpenDelayed.isEmpty()) {
433 void MainWindow::dropEvent(QDropEvent *event)
436 if (isDesktopFileManagerDrop(event->mimeData(), &files)) {
438 m_filesToOpenDelayed.append(files);
439 QTimer::singleShot(50, this, SLOT(openDelayedFiles()));
445 void MainWindow::openDelayedFiles()
447 if (m_filesToOpenDelayed.isEmpty())
451 openFiles(m_filesToOpenDelayed, ICore::SwitchMode);
452 m_filesToOpenDelayed.clear();
455 IContext *MainWindow::currentContextObject() const
457 return m_activeContext;
460 QStatusBar *MainWindow::statusBar() const
462 return m_modeStack->statusBar();
465 void MainWindow::registerDefaultContainers()
467 ActionManagerPrivate *am = m_actionManager;
469 ActionContainer *menubar = am->createMenuBar(Constants::MENU_BAR);
471 #ifndef Q_WS_MAC // System menu bar on Mac
472 setMenuBar(menubar->menuBar());
474 menubar->appendGroup(Constants::G_FILE);
475 menubar->appendGroup(Constants::G_EDIT);
476 menubar->appendGroup(Constants::G_VIEW);
477 menubar->appendGroup(Constants::G_TOOLS);
478 menubar->appendGroup(Constants::G_WINDOW);
479 menubar->appendGroup(Constants::G_HELP);
482 ActionContainer *filemenu = am->createMenu(Constants::M_FILE);
483 menubar->addMenu(filemenu, Constants::G_FILE);
484 filemenu->menu()->setTitle(tr("&File"));
485 filemenu->appendGroup(Constants::G_FILE_NEW);
486 filemenu->appendGroup(Constants::G_FILE_OPEN);
487 filemenu->appendGroup(Constants::G_FILE_PROJECT);
488 filemenu->appendGroup(Constants::G_FILE_SAVE);
489 filemenu->appendGroup(Constants::G_FILE_CLOSE);
490 filemenu->appendGroup(Constants::G_FILE_PRINT);
491 filemenu->appendGroup(Constants::G_FILE_OTHER);
492 connect(filemenu->menu(), SIGNAL(aboutToShow()), this, SLOT(aboutToShowRecentFiles()));
496 ActionContainer *medit = am->createMenu(Constants::M_EDIT);
497 menubar->addMenu(medit, Constants::G_EDIT);
498 medit->menu()->setTitle(tr("&Edit"));
499 medit->appendGroup(Constants::G_EDIT_UNDOREDO);
500 medit->appendGroup(Constants::G_EDIT_COPYPASTE);
501 medit->appendGroup(Constants::G_EDIT_SELECTALL);
502 medit->appendGroup(Constants::G_EDIT_ADVANCED);
503 medit->appendGroup(Constants::G_EDIT_FIND);
504 medit->appendGroup(Constants::G_EDIT_OTHER);
507 ActionContainer *ac = am->createMenu(Constants::M_TOOLS);
508 menubar->addMenu(ac, Constants::G_TOOLS);
509 ac->menu()->setTitle(tr("&Tools"));
512 ActionContainer *mwindow = am->createMenu(Constants::M_WINDOW);
513 menubar->addMenu(mwindow, Constants::G_WINDOW);
514 mwindow->menu()->setTitle(tr("&Window"));
515 mwindow->appendGroup(Constants::G_WINDOW_SIZE);
516 mwindow->appendGroup(Constants::G_WINDOW_VIEWS);
517 mwindow->appendGroup(Constants::G_WINDOW_PANES);
518 mwindow->appendGroup(Constants::G_WINDOW_SPLIT);
519 mwindow->appendGroup(Constants::G_WINDOW_NAVIGATE);
520 mwindow->appendGroup(Constants::G_WINDOW_OTHER);
523 ac = am->createMenu(Constants::M_HELP);
524 menubar->addMenu(ac, Constants::G_HELP);
525 ac->menu()->setTitle(tr("&Help"));
526 ac->appendGroup(Constants::G_HELP_HELP);
527 ac->appendGroup(Constants::G_HELP_ABOUT);
530 static Command *createSeparator(ActionManager *am, QObject *parent,
532 const Context &context)
534 QAction *tmpaction = new QAction(parent);
535 tmpaction->setSeparator(true);
536 Command *cmd = am->registerAction(tmpaction, name, context);
540 void MainWindow::registerDefaultActions()
542 ActionManagerPrivate *am = m_actionManager;
543 ActionContainer *mfile = am->actionContainer(Constants::M_FILE);
544 ActionContainer *medit = am->actionContainer(Constants::M_EDIT);
545 ActionContainer *mtools = am->actionContainer(Constants::M_TOOLS);
546 ActionContainer *mwindow = am->actionContainer(Constants::M_WINDOW);
547 ActionContainer *mhelp = am->actionContainer(Constants::M_HELP);
549 Context globalContext(Constants::C_GLOBAL);
551 // File menu separators
552 Command *cmd = createSeparator(am, this, QLatin1String("QtCreator.File.Sep.Save"), globalContext);
553 mfile->addAction(cmd, Constants::G_FILE_SAVE);
555 cmd = createSeparator(am, this, QLatin1String("QtCreator.File.Sep.Print"), globalContext);
556 QIcon icon = QIcon::fromTheme(QLatin1String("edit-cut"), QIcon(Constants::ICON_CUT));
557 mfile->addAction(cmd, Constants::G_FILE_PRINT);
559 cmd = createSeparator(am, this, QLatin1String("QtCreator.File.Sep.Close"), globalContext);
560 mfile->addAction(cmd, Constants::G_FILE_CLOSE);
562 cmd = createSeparator(am, this, QLatin1String("QtCreator.File.Sep.Other"), globalContext);
563 mfile->addAction(cmd, Constants::G_FILE_OTHER);
565 // Edit menu separators
566 cmd = createSeparator(am, this, QLatin1String("QtCreator.Edit.Sep.CopyPaste"), globalContext);
567 medit->addAction(cmd, Constants::G_EDIT_COPYPASTE);
569 cmd = createSeparator(am, this, QLatin1String("QtCreator.Edit.Sep.SelectAll"), globalContext);
570 medit->addAction(cmd, Constants::G_EDIT_SELECTALL);
572 cmd = createSeparator(am, this, QLatin1String("QtCreator.Edit.Sep.Find"), globalContext);
573 medit->addAction(cmd, Constants::G_EDIT_FIND);
575 cmd = createSeparator(am, this, QLatin1String("QtCreator.Edit.Sep.Advanced"), globalContext);
576 medit->addAction(cmd, Constants::G_EDIT_ADVANCED);
578 // Return to editor shortcut: Note this requires Qt to fix up
579 // handling of shortcut overrides in menus, item views, combos....
580 m_focusToEditor = new QShortcut(this);
581 cmd = am->registerShortcut(m_focusToEditor, Constants::S_RETURNTOEDITOR, globalContext);
582 cmd->setDefaultKeySequence(QKeySequence(Qt::Key_Escape));
583 connect(m_focusToEditor, SIGNAL(activated()), this, SLOT(setFocusToEditor()));
586 icon = QIcon::fromTheme(QLatin1String("document-new"), QIcon(Constants::ICON_NEWFILE));
587 m_newAction = new QAction(icon, tr("&New File or Project..."), this);
588 cmd = am->registerAction(m_newAction, Constants::NEW, globalContext);
589 cmd->setDefaultKeySequence(QKeySequence::New);
590 mfile->addAction(cmd, Constants::G_FILE_NEW);
591 connect(m_newAction, SIGNAL(triggered()), this, SLOT(newFile()));
594 icon = QIcon::fromTheme(QLatin1String("document-open"), QIcon(Constants::ICON_OPENFILE));
595 m_openAction = new QAction(icon, tr("&Open File or Project..."), this);
596 cmd = am->registerAction(m_openAction, Constants::OPEN, globalContext);
597 cmd->setDefaultKeySequence(QKeySequence::Open);
598 mfile->addAction(cmd, Constants::G_FILE_OPEN);
599 connect(m_openAction, SIGNAL(triggered()), this, SLOT(openFile()));
602 m_openWithAction = new QAction(tr("Open File &With..."), this);
603 cmd = am->registerAction(m_openWithAction, Constants::OPEN_WITH, globalContext);
604 mfile->addAction(cmd, Constants::G_FILE_OPEN);
605 connect(m_openWithAction, SIGNAL(triggered()), this, SLOT(openFileWith()));
607 // File->Recent Files Menu
608 ActionContainer *ac = am->createMenu(Constants::M_FILE_RECENTFILES);
609 mfile->addMenu(ac, Constants::G_FILE_OPEN);
610 ac->menu()->setTitle(tr("Recent &Files"));
611 ac->setOnAllDisabledBehavior(ActionContainer::Show);
614 icon = QIcon::fromTheme(QLatin1String("document-save"), QIcon(Constants::ICON_SAVEFILE));
615 QAction *tmpaction = new QAction(icon, tr("&Save"), this);
616 tmpaction->setEnabled(false);
617 cmd = am->registerAction(tmpaction, Constants::SAVE, globalContext);
618 cmd->setDefaultKeySequence(QKeySequence::Save);
619 cmd->setAttribute(Command::CA_UpdateText);
620 cmd->setDefaultText(tr("&Save"));
621 mfile->addAction(cmd, Constants::G_FILE_SAVE);
624 icon = QIcon::fromTheme(QLatin1String("document-save-as"));
625 tmpaction = new QAction(icon, tr("Save &As..."), this);
626 tmpaction->setEnabled(false);
627 cmd = am->registerAction(tmpaction, Constants::SAVEAS, globalContext);
629 cmd->setDefaultKeySequence(QKeySequence(tr("Ctrl+Shift+S")));
631 cmd->setAttribute(Command::CA_UpdateText);
632 cmd->setDefaultText(tr("Save &As..."));
633 mfile->addAction(cmd, Constants::G_FILE_SAVE);
636 m_saveAllAction = new QAction(tr("Save A&ll"), this);
637 cmd = am->registerAction(m_saveAllAction, Constants::SAVEALL, globalContext);
639 cmd->setDefaultKeySequence(QKeySequence(tr("Ctrl+Shift+S")));
641 mfile->addAction(cmd, Constants::G_FILE_SAVE);
642 connect(m_saveAllAction, SIGNAL(triggered()), this, SLOT(saveAll()));
645 icon = QIcon::fromTheme(QLatin1String("document-print"));
646 tmpaction = new QAction(icon, tr("&Print..."), this);
647 tmpaction->setEnabled(false);
648 cmd = am->registerAction(tmpaction, Constants::PRINT, globalContext);
649 cmd->setDefaultKeySequence(QKeySequence::Print);
650 mfile->addAction(cmd, Constants::G_FILE_PRINT);
653 icon = QIcon::fromTheme(QLatin1String("application-exit"));
654 m_exitAction = new QAction(icon, tr("E&xit"), this);
655 cmd = am->registerAction(m_exitAction, Constants::EXIT, globalContext);
656 cmd->setDefaultKeySequence(QKeySequence(tr("Ctrl+Q")));
657 mfile->addAction(cmd, Constants::G_FILE_OTHER);
658 connect(m_exitAction, SIGNAL(triggered()), this, SLOT(exit()));
661 icon = QIcon::fromTheme(QLatin1String("edit-undo"), QIcon(Constants::ICON_UNDO));
662 tmpaction = new QAction(icon, tr("&Undo"), this);
663 cmd = am->registerAction(tmpaction, Constants::UNDO, globalContext);
664 cmd->setDefaultKeySequence(QKeySequence::Undo);
665 cmd->setAttribute(Command::CA_UpdateText);
666 cmd->setDefaultText(tr("&Undo"));
667 medit->addAction(cmd, Constants::G_EDIT_UNDOREDO);
668 tmpaction->setEnabled(false);
671 icon = QIcon::fromTheme(QLatin1String("edit-redo"), QIcon(Constants::ICON_REDO));
672 tmpaction = new QAction(icon, tr("&Redo"), this);
673 cmd = am->registerAction(tmpaction, Constants::REDO, globalContext);
674 cmd->setDefaultKeySequence(QKeySequence::Redo);
675 cmd->setAttribute(Command::CA_UpdateText);
676 cmd->setDefaultText(tr("&Redo"));
677 medit->addAction(cmd, Constants::G_EDIT_UNDOREDO);
678 tmpaction->setEnabled(false);
681 icon = QIcon::fromTheme(QLatin1String("edit-cut"), QIcon(Constants::ICON_CUT));
682 tmpaction = new QAction(icon, tr("Cu&t"), this);
683 cmd = am->registerAction(tmpaction, Constants::CUT, globalContext);
684 cmd->setDefaultKeySequence(QKeySequence::Cut);
685 medit->addAction(cmd, Constants::G_EDIT_COPYPASTE);
686 tmpaction->setEnabled(false);
689 icon = QIcon::fromTheme(QLatin1String("edit-copy"), QIcon(Constants::ICON_COPY));
690 tmpaction = new QAction(icon, tr("&Copy"), this);
691 cmd = am->registerAction(tmpaction, Constants::COPY, globalContext);
692 cmd->setDefaultKeySequence(QKeySequence::Copy);
693 medit->addAction(cmd, Constants::G_EDIT_COPYPASTE);
694 tmpaction->setEnabled(false);
697 icon = QIcon::fromTheme(QLatin1String("edit-paste"), QIcon(Constants::ICON_PASTE));
698 tmpaction = new QAction(icon, tr("&Paste"), this);
699 cmd = am->registerAction(tmpaction, Constants::PASTE, globalContext);
700 cmd->setDefaultKeySequence(QKeySequence::Paste);
701 medit->addAction(cmd, Constants::G_EDIT_COPYPASTE);
702 tmpaction->setEnabled(false);
705 icon = QIcon::fromTheme(QLatin1String("edit-select-all"));
706 tmpaction = new QAction(icon, tr("Select &All"), this);
707 cmd = am->registerAction(tmpaction, Constants::SELECTALL, globalContext);
708 cmd->setDefaultKeySequence(QKeySequence::SelectAll);
709 medit->addAction(cmd, Constants::G_EDIT_SELECTALL);
710 tmpaction->setEnabled(false);
713 icon = QIcon::fromTheme(QLatin1String("go-jump"));
714 tmpaction = new QAction(icon, tr("&Go to Line..."), this);
715 cmd = am->registerAction(tmpaction, Constants::GOTO, globalContext);
716 cmd->setDefaultKeySequence(QKeySequence(tr("Ctrl+L")));
717 medit->addAction(cmd, Constants::G_EDIT_OTHER);
718 tmpaction->setEnabled(false);
721 mtools->appendGroup(Constants::G_TOOLS_OPTIONS);
722 cmd = createSeparator(am, this, QLatin1String("QtCreator.Tools.Sep.Options"), globalContext);
723 mtools->addAction(cmd, Constants::G_TOOLS_OPTIONS);
724 m_optionsAction = new QAction(tr("&Options..."), this);
725 cmd = am->registerAction(m_optionsAction, Constants::OPTIONS, globalContext);
727 cmd->setDefaultKeySequence(QKeySequence("Ctrl+,"));
728 cmd->action()->setMenuRole(QAction::PreferencesRole);
730 mtools->addAction(cmd, Constants::G_TOOLS_OPTIONS);
731 connect(m_optionsAction, SIGNAL(triggered()), this, SLOT(showOptionsDialog()));
735 m_minimizeAction = new QAction(tr("Minimize"), this);
736 cmd = am->registerAction(m_minimizeAction, Constants::MINIMIZE_WINDOW, globalContext);
737 cmd->setDefaultKeySequence(QKeySequence("Ctrl+M"));
738 mwindow->addAction(cmd, Constants::G_WINDOW_SIZE);
739 connect(m_minimizeAction, SIGNAL(triggered()), this, SLOT(showMinimized()));
742 m_zoomAction = new QAction(tr("Zoom"), this);
743 cmd = am->registerAction(m_zoomAction, Constants::ZOOM_WINDOW, globalContext);
744 mwindow->addAction(cmd, Constants::G_WINDOW_SIZE);
745 connect(m_zoomAction, SIGNAL(triggered()), this, SLOT(showMaximized()));
748 cmd = createSeparator(am, this, QLatin1String("QtCreator.Window.Sep.Size"), globalContext);
749 mwindow->addAction(cmd, Constants::G_WINDOW_SIZE);
752 // Show Sidebar Action
753 m_toggleSideBarAction = new QAction(QIcon(Constants::ICON_TOGGLE_SIDEBAR),
754 tr("Show Sidebar"), this);
755 m_toggleSideBarAction->setCheckable(true);
756 cmd = am->registerAction(m_toggleSideBarAction, Constants::TOGGLE_SIDEBAR, globalContext);
757 cmd->setAttribute(Command::CA_UpdateText);
759 cmd->setDefaultKeySequence(QKeySequence("Ctrl+0"));
761 cmd->setDefaultKeySequence(QKeySequence("Alt+0"));
763 connect(m_toggleSideBarAction, SIGNAL(triggered(bool)), this, SLOT(setSidebarVisible(bool)));
764 m_toggleSideBarButton->setDefaultAction(cmd->action());
765 mwindow->addAction(cmd, Constants::G_WINDOW_VIEWS);
766 m_toggleSideBarAction->setEnabled(false);
769 // Full Screen Action
770 m_toggleFullScreenAction = new QAction(tr("Full Screen"), this);
771 m_toggleFullScreenAction->setCheckable(true);
772 cmd = am->registerAction(m_toggleFullScreenAction, Constants::TOGGLE_FULLSCREEN, globalContext);
773 cmd->setDefaultKeySequence(QKeySequence("Ctrl+Shift+F11"));
774 mwindow->addAction(cmd, Constants::G_WINDOW_SIZE);
775 connect(m_toggleFullScreenAction, SIGNAL(triggered(bool)), this, SLOT(setFullScreen(bool)));
779 ActionContainer *mviews = am->createMenu(Constants::M_WINDOW_VIEWS);
780 mwindow->addMenu(mviews, Constants::G_WINDOW_VIEWS);
781 mviews->menu()->setTitle(tr("&Views"));
784 icon = QIcon::fromTheme(QLatin1String("help-about"));
786 tmpaction = new QAction(icon, tr("About &Qt Creator"), this); // it's convention not to add dots to the about menu
788 tmpaction = new QAction(icon, tr("About &Qt Creator..."), this);
790 cmd = am->registerAction(tmpaction, Constants::ABOUT_QTCREATOR, globalContext);
791 mhelp->addAction(cmd, Constants::G_HELP_ABOUT);
792 tmpaction->setEnabled(true);
794 cmd->action()->setMenuRole(QAction::ApplicationSpecificRole);
796 connect(tmpaction, SIGNAL(triggered()), this, SLOT(aboutQtCreator()));
798 //About Plugins Action
799 tmpaction = new QAction(tr("About &Plugins..."), this);
800 cmd = am->registerAction(tmpaction, Constants::ABOUT_PLUGINS, globalContext);
801 mhelp->addAction(cmd, Constants::G_HELP_ABOUT);
802 tmpaction->setEnabled(true);
804 cmd->action()->setMenuRole(QAction::ApplicationSpecificRole);
806 connect(tmpaction, SIGNAL(triggered()), this, SLOT(aboutPlugins()));
808 // tmpaction = new QAction(tr("About &Qt..."), this);
809 // cmd = am->registerAction(tmpaction, Constants:: ABOUT_QT, globalContext);
810 // mhelp->addAction(cmd, Constants::G_HELP_ABOUT);
811 // tmpaction->setEnabled(true);
812 // connect(tmpaction, SIGNAL(triggered()), qApp, SLOT(aboutQt()));
814 #ifndef Q_WS_MAC // doesn't have the "About" actions in the Help menu
815 tmpaction = new QAction(this);
816 tmpaction->setSeparator(true);
817 cmd = am->registerAction(tmpaction, "QtCreator.Help.Sep.About", globalContext);
818 mhelp->addAction(cmd, Constants::G_HELP_ABOUT);
822 void MainWindow::newFile()
824 showNewItemDialog(tr("New", "Title of dialog"), IWizard::allWizards(), QString());
827 void MainWindow::openFile()
829 openFiles(editorManager()->getOpenFileNames(), ICore::SwitchMode);
832 static QList<IFileFactory*> getNonEditorFileFactories()
834 const QList<IFileFactory*> allFileFactories =
835 ExtensionSystem::PluginManager::instance()->getObjects<IFileFactory>();
836 QList<IFileFactory*> nonEditorFileFactories;
837 foreach (IFileFactory *factory, allFileFactories) {
838 if (!qobject_cast<IEditorFactory *>(factory))
839 nonEditorFileFactories.append(factory);
841 return nonEditorFileFactories;
844 static IFileFactory *findFileFactory(const QList<IFileFactory*> &fileFactories,
845 const MimeDatabase *db,
848 if (const MimeType mt = db->findByFile(fi)) {
849 const QString type = mt.type();
850 foreach (IFileFactory *factory, fileFactories) {
851 if (factory->mimeTypes().contains(type))
858 // opens either an editor or loads a project
859 void MainWindow::openFiles(const QStringList &fileNames, ICore::OpenFilesFlags flags)
861 QList<IFileFactory*> nonEditorFileFactories = getNonEditorFileFactories();
863 foreach (const QString &fileName, fileNames) {
864 const QFileInfo fi(fileName);
865 const QString absoluteFilePath = fi.absoluteFilePath();
866 if (IFileFactory *fileFactory = findFileFactory(nonEditorFileFactories, mimeDatabase(), fi)) {
867 Core::IFile *file = fileFactory->open(absoluteFilePath);
868 if (!file && (flags & ICore::StopOnLoadFail))
870 if (file && (flags & ICore::SwitchMode))
871 Core::ModeManager::instance()->activateMode(Core::Constants::MODE_EDIT);
873 QFlags<EditorManager::OpenEditorFlag> emFlags;
874 if (flags & ICore::SwitchMode)
875 emFlags = EditorManager::ModeSwitch;
876 if (flags & ICore::CanContainLineNumbers)
877 emFlags |= EditorManager::CanContainLineNumber;
878 Core::IEditor *editor = editorManager()->openEditor(absoluteFilePath, QString(), emFlags);
879 if (!editor && (flags & ICore::StopOnLoadFail))
885 void MainWindow::setFocusToEditor()
887 bool focusWasMovedToEditor = false;
889 // give focus to the editor if we have one
890 if (IEditor *editor = m_editorManager->currentEditor()) {
891 if (qApp->focusWidget() != editor->widget()) {
892 editor->widget()->setFocus();
893 focusWasMovedToEditor = editor->widget()->hasFocus();
897 // check for some maximized pane which we want to unmaximize
898 if (OutputPanePlaceHolder::getCurrent()
899 && OutputPanePlaceHolder::getCurrent()->isVisible()
900 && OutputPanePlaceHolder::getCurrent()->isMaximized()) {
901 OutputPanePlaceHolder::getCurrent()->unmaximize();
905 if (focusWasMovedToEditor)
909 // check for some visible bar which we want to hide
911 (FindToolBarPlaceHolder::getCurrent() &&
912 FindToolBarPlaceHolder::getCurrent()->isVisible())
913 || (OutputPanePlaceHolder::getCurrent() &&
914 OutputPanePlaceHolder::getCurrent()->isVisible())
915 || (RightPanePlaceHolder::current() &&
916 RightPanePlaceHolder::current()->isVisible());
918 if (FindToolBarPlaceHolder::getCurrent())
919 FindToolBarPlaceHolder::getCurrent()->hide();
920 OutputPaneManager::instance()->slotHide();
921 RightPaneWidget::instance()->setShown(false);
925 // switch to edit mode if necessary
926 m_coreImpl->modeManager()->activateMode(QLatin1String(Constants::MODE_EDIT));
930 void MainWindow::showNewItemDialog(const QString &title,
931 const QList<IWizard *> &wizards,
932 const QString &defaultLocation)
934 // Scan for wizards matching the filter and pick one. Don't show
935 // dialog if there is only one.
937 switch (wizards.size()) {
941 wizard = wizards.front();
945 dlg.setWizards(wizards);
946 dlg.setWindowTitle(title);
947 wizard = dlg.showDialog();
955 QString path = defaultLocation;
956 if (path.isEmpty()) {
957 const FileManager *fm = m_coreImpl->fileManager();
958 switch (wizard->kind()) {
959 case IWizard::ProjectWizard:
960 // Project wizards: Check for projects directory or
961 // use last visited directory of file dialog. Never start
963 path = fm->useProjectsDirectory() ?
964 fm->projectsDirectory() :
965 fm->fileDialogLastVisitedDirectory();
968 path = fm->fileDialogInitialDirectory();
972 wizard->runWizard(path, this);
975 bool MainWindow::showOptionsDialog(const QString &category,
979 emit m_coreImpl->optionsDialogRequested();
982 SettingsDialog *dialog = SettingsDialog::getSettingsDialog(parent, category, page);
983 return dialog->execDialog();
986 void MainWindow::saveAll()
988 m_fileManager->saveModifiedFilesSilently(m_fileManager->modifiedFiles());
989 emit m_coreImpl->saveSettingsRequested();
992 void MainWindow::exit()
994 // this function is most likely called from a user action
995 // that is from an event handler of an object
996 // since on close we are going to delete everything
997 // so to prevent the deleting of that object we
999 QTimer::singleShot(0, this, SLOT(close()));
1002 void MainWindow::openFileWith()
1004 QStringList fileNames = editorManager()->getOpenFileNames();
1005 foreach (const QString &fileName, fileNames) {
1007 const QString editorId = editorManager()->getOpenWithEditorId(fileName, &isExternal);
1008 if (editorId.isEmpty())
1011 editorManager()->openExternalEditor(fileName, editorId);
1013 editorManager()->openEditor(fileName, editorId, Core::EditorManager::ModeSwitch);
1018 ActionManager *MainWindow::actionManager() const
1020 return m_actionManager;
1023 FileManager *MainWindow::fileManager() const
1025 return m_fileManager;
1028 UniqueIDManager *MainWindow::uniqueIDManager() const
1030 return m_uniqueIDManager;
1033 MessageManager *MainWindow::messageManager() const
1035 return m_messageManager;
1038 VcsManager *MainWindow::vcsManager() const
1040 return m_vcsManager;
1043 QSettings *MainWindow::settings(QSettings::Scope scope) const
1045 if (scope == QSettings::UserScope)
1048 return m_globalSettings;
1051 EditorManager *MainWindow::editorManager() const
1053 return m_editorManager;
1056 ProgressManager *MainWindow::progressManager() const
1058 return m_progressManager;
1061 ScriptManager *MainWindow::scriptManager() const
1063 return m_scriptManager;
1066 VariableManager *MainWindow::variableManager() const
1068 return m_variableManager.data();
1071 ModeManager *MainWindow::modeManager() const
1073 return m_modeManager;
1076 MimeDatabase *MainWindow::mimeDatabase() const
1078 return m_mimeDatabase;
1081 HelpManager *MainWindow::helpManager() const
1083 return m_helpManager;
1086 IContext *MainWindow::contextObject(QWidget *widget)
1088 return m_contextWidgets.value(widget);
1091 void MainWindow::addContextObject(IContext *context)
1095 QWidget *widget = context->widget();
1096 if (m_contextWidgets.contains(widget))
1099 m_contextWidgets.insert(widget, context);
1102 void MainWindow::removeContextObject(IContext *context)
1107 QWidget *widget = context->widget();
1108 if (!m_contextWidgets.contains(widget))
1111 m_contextWidgets.remove(widget);
1112 if (m_activeContext == context)
1113 updateContextObject(0);
1116 void MainWindow::changeEvent(QEvent *e)
1118 QMainWindow::changeEvent(e);
1119 if (e->type() == QEvent::ActivationChange) {
1120 if (isActiveWindow()) {
1121 if (debugMainWindow)
1122 qDebug() << "main window activated";
1123 emit windowActivated();
1125 } else if (e->type() == QEvent::WindowStateChange) {
1127 bool minimized = isMinimized();
1128 if (debugMainWindow)
1129 qDebug() << "main window state changed to minimized=" << minimized;
1130 m_minimizeAction->setEnabled(!minimized);
1131 m_zoomAction->setEnabled(!minimized);
1133 bool isFullScreen = (windowState() & Qt::WindowFullScreen) != 0;
1134 m_toggleFullScreenAction->setChecked(isFullScreen);
1139 void MainWindow::updateFocusWidget(QWidget *old, QWidget *now)
1143 // Prevent changing the context object just because the menu or a menu item is activated
1144 if (qobject_cast<QMenuBar*>(now) || qobject_cast<QMenu*>(now))
1147 IContext *newContext = 0;
1148 if (focusWidget()) {
1149 IContext *context = 0;
1150 QWidget *p = focusWidget();
1152 context = m_contextWidgets.value(p);
1154 newContext = context;
1157 p = p->parentWidget();
1160 updateContextObject(newContext);
1163 void MainWindow::updateContextObject(IContext *context)
1165 if (context == m_activeContext)
1167 emit m_coreImpl->contextAboutToChange(context);
1168 m_activeContext = context;
1170 if (debugMainWindow)
1171 qDebug() << "new context object =" << context << (context ? context->widget() : 0)
1172 << (context ? context->widget()->metaObject()->className() : 0);
1175 void MainWindow::resetContext()
1177 updateContextObject(0);
1180 void MainWindow::aboutToShutdown()
1182 disconnect(QApplication::instance(), SIGNAL(focusChanged(QWidget*,QWidget*)),
1183 this, SLOT(updateFocusWidget(QWidget*,QWidget*)));
1184 m_activeContext = 0;
1188 static const char settingsGroup[] = "MainWindow";
1189 static const char colorKey[] = "Color";
1190 static const char windowGeometryKey[] = "WindowGeometry";
1191 static const char windowStateKey[] = "WindowState";
1193 // TODO compat for <= 2.1, remove later
1194 static const char geometryKey[] = "Geometry";
1195 static const char maxKey[] = "Maximized";
1196 static const char fullScreenKey[] = "FullScreen";
1198 void MainWindow::readSettings()
1200 m_settings->beginGroup(QLatin1String(settingsGroup));
1202 if (m_overrideColor.isValid()) {
1203 Utils::StyleHelper::setBaseColor(m_overrideColor);
1204 // Get adapted base color.
1205 m_overrideColor = Utils::StyleHelper::baseColor();
1207 Utils::StyleHelper::setBaseColor(
1208 m_settings->value(QLatin1String(colorKey),
1209 QColor(Utils::StyleHelper::DEFAULT_BASE_COLOR)).value<QColor>());
1212 // TODO compat for <= 2.1, remove later
1213 if (m_settings->contains(QLatin1String(geometryKey))) {
1214 const QVariant geom = m_settings->value(QLatin1String(geometryKey));
1215 if (geom.isValid()) {
1216 setGeometry(geom.toRect());
1220 if (m_settings->value(QLatin1String(maxKey), false).toBool())
1221 setWindowState(Qt::WindowMaximized);
1222 setFullScreen(m_settings->value(QLatin1String(fullScreenKey), false).toBool());
1224 m_settings->remove(QLatin1String(geometryKey));
1225 m_settings->remove(QLatin1String(maxKey));
1226 m_settings->remove(QLatin1String(fullScreenKey));
1228 if (!restoreGeometry(m_settings->value(QLatin1String(windowGeometryKey)).toByteArray())) {
1231 restoreState(m_settings->value(QLatin1String(windowStateKey)).toByteArray());
1234 m_settings->endGroup();
1236 m_editorManager->readSettings();
1237 m_navigationWidget->restoreSettings(m_settings);
1238 m_rightPaneWidget->readSettings(m_settings);
1241 void MainWindow::writeSettings()
1243 m_settings->beginGroup(QLatin1String(settingsGroup));
1245 if (!(m_overrideColor.isValid() && Utils::StyleHelper::baseColor() == m_overrideColor))
1246 m_settings->setValue(QLatin1String(colorKey), Utils::StyleHelper::requestedBaseColor());
1248 m_settings->setValue(QLatin1String(windowGeometryKey), saveGeometry());
1249 m_settings->setValue(QLatin1String(windowStateKey), saveState());
1251 m_settings->endGroup();
1253 m_fileManager->saveSettings();
1254 m_actionManager->saveSettings(m_settings);
1255 m_editorManager->saveSettings();
1256 m_navigationWidget->saveSettings(m_settings);
1259 void MainWindow::updateAdditionalContexts(const Context &remove, const Context &add)
1261 foreach (const int context, remove) {
1265 int index = m_additionalContexts.indexOf(context);
1267 m_additionalContexts.removeAt(index);
1270 foreach (const int context, add) {
1274 if (!m_additionalContexts.contains(context))
1275 m_additionalContexts.prepend(context);
1281 bool MainWindow::hasContext(int context) const
1283 return m_actionManager->hasContext(context);
1286 void MainWindow::updateContext()
1290 if (m_activeContext)
1291 contexts.add(m_activeContext->context());
1293 contexts.add(m_additionalContexts);
1295 Context uniquecontexts;
1296 for (int i = 0; i < contexts.size(); ++i) {
1297 const int c = contexts.at(i);
1298 if (!uniquecontexts.contains(c))
1299 uniquecontexts.add(c);
1302 m_actionManager->setContext(uniquecontexts);
1303 emit m_coreImpl->contextChanged(m_activeContext, m_additionalContexts);
1306 void MainWindow::aboutToShowRecentFiles()
1308 ActionContainer *aci =
1309 m_actionManager->actionContainer(Constants::M_FILE_RECENTFILES);
1310 aci->menu()->clear();
1312 bool hasRecentFiles = false;
1313 foreach (const FileManager::RecentFile &file, m_fileManager->recentFiles()) {
1314 hasRecentFiles = true;
1315 QAction *action = aci->menu()->addAction(
1316 QDir::toNativeSeparators(Utils::withTildeHomePath(file.first)));
1317 action->setData(qVariantFromValue(file));
1318 connect(action, SIGNAL(triggered()), this, SLOT(openRecentFile()));
1320 aci->menu()->setEnabled(hasRecentFiles);
1322 // add the Clear Menu item
1323 if (hasRecentFiles) {
1324 aci->menu()->addSeparator();
1325 QAction *action = aci->menu()->addAction(QCoreApplication::translate(
1326 "Core", Core::Constants::TR_CLEAR_MENU));
1327 connect(action, SIGNAL(triggered()), m_fileManager, SLOT(clearRecentFiles()));
1331 void MainWindow::openRecentFile()
1333 if (const QAction *action = qobject_cast<const QAction*>(sender())) {
1334 const FileManager::RecentFile file = action->data().value<FileManager::RecentFile>();
1335 editorManager()->openEditor(file.first, file.second, Core::EditorManager::ModeSwitch);
1339 void MainWindow::aboutQtCreator()
1341 if (!m_versionDialog) {
1342 m_versionDialog = new VersionDialog(this);
1343 connect(m_versionDialog, SIGNAL(finished(int)),
1344 this, SLOT(destroyVersionDialog()));
1346 m_versionDialog->show();
1349 void MainWindow::destroyVersionDialog()
1351 if (m_versionDialog) {
1352 m_versionDialog->deleteLater();
1353 m_versionDialog = 0;
1357 void MainWindow::aboutPlugins()
1359 PluginDialog dialog(this);
1363 QPrinter *MainWindow::printer() const
1366 m_printer = new QPrinter(QPrinter::HighResolution);
1370 void MainWindow::setFullScreen(bool on)
1372 if (bool(windowState() & Qt::WindowFullScreen) == on)
1376 setWindowState(windowState() | Qt::WindowFullScreen);
1377 //statusBar()->hide();
1378 //menuBar()->hide();
1380 setWindowState(windowState() & ~Qt::WindowFullScreen);
1381 //menuBar()->show();
1382 //statusBar()->show();
1386 // Display a warning with an additional button to open
1387 // the debugger settings dialog if settingsId is nonempty.
1389 bool MainWindow::showWarningWithOptions(const QString &title,
1390 const QString &text,
1391 const QString &details,
1392 const QString &settingsCategory,
1393 const QString &settingsId,
1398 QMessageBox msgBox(QMessageBox::Warning, title, text,
1399 QMessageBox::Ok, parent);
1400 if (!details.isEmpty())
1401 msgBox.setDetailedText(details);
1402 QAbstractButton *settingsButton = 0;
1403 if (!settingsId.isEmpty() || !settingsCategory.isEmpty())
1404 settingsButton = msgBox.addButton(tr("Settings..."), QMessageBox::AcceptRole);
1406 if (settingsButton && msgBox.clickedButton() == settingsButton) {
1407 return showOptionsDialog(settingsCategory, settingsId);