OSDN Git Service

Update license.
[qt-creator-jp/qt-creator-jp.git] / src / plugins / coreplugin / mainwindow.cpp
1 /**************************************************************************
2 **
3 ** This file is part of Qt Creator
4 **
5 ** Copyright (c) 2011 Nokia Corporation and/or its subsidiary(-ies).
6 **
7 ** Contact: Nokia Corporation (info@qt.nokia.com)
8 **
9 **
10 ** GNU Lesser General Public License Usage
11 **
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.
18 **
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.
22 **
23 ** Other Usage
24 **
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.
27 **
28 ** If you have questions regarding the use of this file, please contact
29 ** Nokia at qt-info@nokia.com.
30 **
31 **************************************************************************/
32
33 #include "mainwindow.h"
34 #include "actioncontainer.h"
35 #include "command.h"
36 #include "actionmanager_p.h"
37 #include "coreimpl.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"
47 #include "ieditor.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"
61
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"
76
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>
85
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>
94
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
107 /*
108 #ifdef Q_OS_UNIX
109 #include <signal.h>
110 extern "C" void handleSigInt(int sig)
111 {
112     Q_UNUSED(sig)
113     Core::ICore::instance()->exit();
114     qDebug() << "SIGINT caught. Shutting down.";
115 }
116 #endif
117 */
118
119 using namespace Core;
120 using namespace Core::Internal;
121
122 enum { debugMainWindow = 0 };
123
124 MainWindow::MainWindow() :
125     EventFilteringMainWindow(),
126     m_coreImpl(new CoreImpl(this)),
127     m_uniqueIDManager(new UniqueIDManager()),
128     m_additionalContexts(Constants::C_GLOBAL),
129     m_settings(ExtensionSystem::PluginManager::instance()->settings()),
130     m_globalSettings(new QSettings(QSettings::IniFormat, QSettings::SystemScope,
131                              QLatin1String("Nokia"), QLatin1String("QtCreator"), this)),
132     m_settingsDatabase(new SettingsDatabase(QFileInfo(m_settings->fileName()).path(),
133                                             QLatin1String("QtCreator"),
134                                             this)),
135     m_printer(0),
136     m_actionManager(new ActionManagerPrivate(this)),
137     m_editorManager(0),
138     m_externalToolManager(0),
139     m_fileManager(new FileManager(this)),
140     m_progressManager(new ProgressManagerPrivate()),
141     m_scriptManager(new ScriptManagerPrivate(this)),
142     m_variableManager(new VariableManager),
143     m_vcsManager(new VcsManager),
144     m_statusBarManager(0),
145     m_modeManager(0),
146     m_mimeDatabase(new MimeDatabase),
147     m_helpManager(new HelpManager),
148     m_navigationWidget(0),
149     m_rightPaneWidget(0),
150     m_versionDialog(0),
151     m_activeContext(0),
152     m_generalSettings(new GeneralSettings),
153     m_shortcutSettings(new ShortcutSettings),
154     m_toolSettings(new ToolSettings),
155     m_mimeTypeSettings(new MimeTypeSettings),
156     m_systemEditor(new SystemEditor),
157     m_focusToEditor(0),
158     m_newAction(0),
159     m_openAction(0),
160     m_openWithAction(0),
161     m_saveAllAction(0),
162     m_exitAction(0),
163     m_optionsAction(0),
164     m_toggleSideBarAction(0),
165     m_toggleFullScreenAction(0),
166 #ifdef Q_WS_MAC
167     m_minimizeAction(0),
168     m_zoomAction(0),
169 #endif
170     m_toggleSideBarButton(new QToolButton)
171 {
172     OutputPaneManager::create();
173
174     setWindowTitle(tr("Qt Creator"));
175 #ifndef Q_WS_MAC
176     QApplication::setWindowIcon(QIcon(QLatin1String(Constants::ICON_QTLOGO_128)));
177 #endif
178     QCoreApplication::setApplicationName(QLatin1String("QtCreator"));
179     QCoreApplication::setApplicationVersion(QLatin1String(Core::Constants::IDE_VERSION_LONG));
180     QCoreApplication::setOrganizationName(QLatin1String("Nokia"));
181     QSettings::setDefaultFormat(QSettings::IniFormat);
182     QString baseName = QApplication::style()->objectName();
183 #ifdef Q_WS_X11
184     if (baseName == QLatin1String("windows")) {
185         // Sometimes we get the standard windows 95 style as a fallback
186         // e.g. if we are running on a KDE4 desktop
187         QByteArray desktopEnvironment = qgetenv("DESKTOP_SESSION");
188         if (desktopEnvironment == "kde")
189             baseName = QLatin1String("plastique");
190         else
191             baseName = QLatin1String("cleanlooks");
192     }
193 #endif
194     qApp->setStyle(new ManhattanStyle(baseName));
195
196     setDockNestingEnabled(true);
197
198     setCorner(Qt::BottomLeftCorner, Qt::LeftDockWidgetArea);
199     setCorner(Qt::BottomRightCorner, Qt::BottomDockWidgetArea);
200
201     registerDefaultContainers();
202     registerDefaultActions();
203
204     m_navigationWidget = new NavigationWidget(m_toggleSideBarAction);
205     m_rightPaneWidget = new RightPaneWidget();
206
207     m_modeStack = new FancyTabWidget(this);
208     m_modeManager = new ModeManager(this, m_modeStack);
209     m_modeManager->addWidget(m_progressManager->progressView());
210     m_statusBarManager = new StatusBarManager(this);
211     m_messageManager = new MessageManager;
212     m_editorManager = new EditorManager(m_coreImpl, this);
213     m_editorManager->hide();
214     m_externalToolManager = new ExternalToolManager(m_coreImpl);
215     setCentralWidget(m_modeStack);
216
217     connect(QApplication::instance(), SIGNAL(focusChanged(QWidget*,QWidget*)),
218             this, SLOT(updateFocusWidget(QWidget*,QWidget*)));
219     // Add a small Toolbutton for toggling the navigation widget
220     statusBar()->insertPermanentWidget(0, m_toggleSideBarButton);
221
222 //    setUnifiedTitleAndToolBarOnMac(true);
223 #ifdef Q_OS_UNIX
224      //signal(SIGINT, handleSigInt);
225 #endif
226
227     statusBar()->setProperty("p_styled", true);
228     setAcceptDrops(true);
229 }
230
231 void MainWindow::setSidebarVisible(bool visible)
232 {
233     if (NavigationWidgetPlaceHolder::current()) {
234         if (m_navigationWidget->isSuppressed() && visible) {
235             m_navigationWidget->setShown(true);
236             m_navigationWidget->setSuppressed(false);
237         } else {
238             m_navigationWidget->setShown(visible);
239         }
240     }
241 }
242
243 void MainWindow::setSuppressNavigationWidget(bool suppress)
244 {
245     if (NavigationWidgetPlaceHolder::current())
246         m_navigationWidget->setSuppressed(suppress);
247 }
248
249 void MainWindow::setOverrideColor(const QColor &color)
250 {
251     m_overrideColor = color;
252 }
253
254 MainWindow::~MainWindow()
255 {
256     ExtensionSystem::PluginManager *pm = ExtensionSystem::PluginManager::instance();
257     pm->removeObject(m_shortcutSettings);
258     pm->removeObject(m_generalSettings);
259     pm->removeObject(m_toolSettings);
260     pm->removeObject(m_mimeTypeSettings);
261     pm->removeObject(m_systemEditor);
262     delete m_externalToolManager;
263     m_externalToolManager = 0;
264     delete m_messageManager;
265     m_messageManager = 0;
266     delete m_shortcutSettings;
267     m_shortcutSettings = 0;
268     delete m_generalSettings;
269     m_generalSettings = 0;
270     delete m_toolSettings;
271     m_toolSettings = 0;
272     delete m_mimeTypeSettings;
273     m_mimeTypeSettings = 0;
274     delete m_systemEditor;
275     m_systemEditor = 0;
276     delete m_settings;
277     m_settings = 0;
278     delete m_printer;
279     m_printer = 0;
280     delete m_uniqueIDManager;
281     m_uniqueIDManager = 0;
282     delete m_vcsManager;
283     m_vcsManager = 0;
284     //we need to delete editormanager and statusbarmanager explicitly before the end of the destructor,
285     //because they might trigger stuff that tries to access data from editorwindow, like removeContextWidget
286
287     // All modes are now gone
288     OutputPaneManager::destroy();
289
290     // Now that the OutputPaneManager is gone, is a good time to delete the view
291     pm->removeObject(m_outputView);
292     delete m_outputView;
293
294     delete m_editorManager;
295     m_editorManager = 0;
296     delete m_statusBarManager;
297     m_statusBarManager = 0;
298     delete m_progressManager;
299     m_progressManager = 0;
300     pm->removeObject(m_coreImpl);
301     delete m_coreImpl;
302     m_coreImpl = 0;
303
304     delete m_rightPaneWidget;
305     m_rightPaneWidget = 0;
306
307     delete m_modeManager;
308     m_modeManager = 0;
309     delete m_mimeDatabase;
310     m_mimeDatabase = 0;
311
312     delete m_helpManager;
313     m_helpManager = 0;
314 }
315
316 bool MainWindow::init(QString *errorMessage)
317 {
318     Q_UNUSED(errorMessage)
319
320     if (!mimeDatabase()->addMimeTypes(QLatin1String(":/core/editormanager/BinFiles.mimetypes.xml"), errorMessage))
321         return false;
322
323     ExtensionSystem::PluginManager *pm = ExtensionSystem::PluginManager::instance();
324     pm->addObject(m_coreImpl);
325     m_statusBarManager->init();
326     m_modeManager->init();
327     m_progressManager->init();
328
329     pm->addObject(m_generalSettings);
330     pm->addObject(m_shortcutSettings);
331     pm->addObject(m_toolSettings);
332     pm->addObject(m_mimeTypeSettings);
333     pm->addObject(m_systemEditor);
334
335     // Add widget to the bottom, we create the view here instead of inside the
336     // OutputPaneManager, since the StatusBarManager needs to be initialized before
337     m_outputView = new Core::StatusBarWidget;
338     m_outputView->setWidget(OutputPaneManager::instance()->buttonsWidget());
339     m_outputView->setPosition(Core::StatusBarWidget::Second);
340     pm->addObject(m_outputView);
341     m_messageManager->init();
342     return true;
343 }
344
345 void MainWindow::extensionsInitialized()
346 {
347     m_editorManager->init();
348     m_statusBarManager->extensionsInitalized();
349     OutputPaneManager::instance()->init();
350     m_vcsManager->extensionsInitialized();
351     m_navigationWidget->setFactories(ExtensionSystem::PluginManager::instance()->getObjects<INavigationWidgetFactory>());
352
353     // reading the shortcut settings must be done after all shortcuts have been registered
354     m_actionManager->initialize();
355
356     readSettings();
357     updateContext();
358
359     emit m_coreImpl->coreAboutToOpen();
360     show();
361     emit m_coreImpl->coreOpened();
362 }
363
364 void MainWindow::closeEvent(QCloseEvent *event)
365 {
366     emit m_coreImpl->saveSettingsRequested();
367
368     // Save opened files
369     bool cancelled;
370     QList<IFile*> notSaved = fileManager()->saveModifiedFiles(fileManager()->modifiedFiles(), &cancelled);
371     if (cancelled || !notSaved.isEmpty()) {
372         event->ignore();
373         return;
374     }
375
376     const QList<ICoreListener *> listeners =
377         ExtensionSystem::PluginManager::instance()->getObjects<ICoreListener>();
378     foreach (ICoreListener *listener, listeners) {
379         if (!listener->coreAboutToClose()) {
380             event->ignore();
381             return;
382         }
383     }
384
385     emit m_coreImpl->coreAboutToClose();
386
387     writeSettings();
388
389     m_navigationWidget->closeSubWidgets();
390
391     event->accept();
392 }
393
394 // Check for desktop file manager file drop events
395
396 static bool isDesktopFileManagerDrop(const QMimeData *d, QStringList *files = 0)
397 {
398     if (files)
399         files->clear();
400     // Extract dropped files from Mime data.
401     if (!d->hasUrls())
402         return false;
403     const QList<QUrl> urls = d->urls();
404     if (urls.empty())
405         return false;
406     // Try to find local files
407     bool hasFiles = false;
408     const QList<QUrl>::const_iterator cend = urls.constEnd();
409     for (QList<QUrl>::const_iterator it = urls.constBegin(); it != cend; ++it) {
410         const QString fileName = it->toLocalFile();
411         if (!fileName.isEmpty()) {
412             hasFiles = true;
413             if (files) {
414                 files->push_back(fileName);
415             } else {
416                 break; // No result list, sufficient for checking
417             }
418         }
419     }
420     return hasFiles;
421 }
422
423 void MainWindow::dragEnterEvent(QDragEnterEvent *event)
424 {
425     if (isDesktopFileManagerDrop(event->mimeData()) && m_filesToOpenDelayed.isEmpty()) {
426         event->accept();
427     } else {
428         event->ignore();
429     }
430 }
431
432 void MainWindow::dropEvent(QDropEvent *event)
433 {
434     QStringList files;
435     if (isDesktopFileManagerDrop(event->mimeData(), &files)) {
436         event->accept();
437         m_filesToOpenDelayed.append(files);
438         QTimer::singleShot(50, this, SLOT(openDelayedFiles()));
439     } else {
440         event->ignore();
441     }
442 }
443
444 void MainWindow::openDelayedFiles()
445 {
446     if (m_filesToOpenDelayed.isEmpty())
447         return;
448     activateWindow();
449     raise();
450     openFiles(m_filesToOpenDelayed, ICore::SwitchMode);
451     m_filesToOpenDelayed.clear();
452 }
453
454 IContext *MainWindow::currentContextObject() const
455 {
456     return m_activeContext;
457 }
458
459 QStatusBar *MainWindow::statusBar() const
460 {
461     return m_modeStack->statusBar();
462 }
463
464 void MainWindow::registerDefaultContainers()
465 {
466     ActionManagerPrivate *am = m_actionManager;
467
468     ActionContainer *menubar = am->createMenuBar(Constants::MENU_BAR);
469
470 #ifndef Q_WS_MAC // System menu bar on Mac
471     setMenuBar(menubar->menuBar());
472 #endif
473     menubar->appendGroup(Constants::G_FILE);
474     menubar->appendGroup(Constants::G_EDIT);
475     menubar->appendGroup(Constants::G_VIEW);
476     menubar->appendGroup(Constants::G_TOOLS);
477     menubar->appendGroup(Constants::G_WINDOW);
478     menubar->appendGroup(Constants::G_HELP);
479
480     // File Menu
481     ActionContainer *filemenu = am->createMenu(Constants::M_FILE);
482     menubar->addMenu(filemenu, Constants::G_FILE);
483     filemenu->menu()->setTitle(tr("&File"));
484     filemenu->appendGroup(Constants::G_FILE_NEW);
485     filemenu->appendGroup(Constants::G_FILE_OPEN);
486     filemenu->appendGroup(Constants::G_FILE_PROJECT);
487     filemenu->appendGroup(Constants::G_FILE_SAVE);
488     filemenu->appendGroup(Constants::G_FILE_CLOSE);
489     filemenu->appendGroup(Constants::G_FILE_PRINT);
490     filemenu->appendGroup(Constants::G_FILE_OTHER);
491     connect(filemenu->menu(), SIGNAL(aboutToShow()), this, SLOT(aboutToShowRecentFiles()));
492
493
494     // Edit Menu
495     ActionContainer *medit = am->createMenu(Constants::M_EDIT);
496     menubar->addMenu(medit, Constants::G_EDIT);
497     medit->menu()->setTitle(tr("&Edit"));
498     medit->appendGroup(Constants::G_EDIT_UNDOREDO);
499     medit->appendGroup(Constants::G_EDIT_COPYPASTE);
500     medit->appendGroup(Constants::G_EDIT_SELECTALL);
501     medit->appendGroup(Constants::G_EDIT_ADVANCED);
502     medit->appendGroup(Constants::G_EDIT_FIND);
503     medit->appendGroup(Constants::G_EDIT_OTHER);
504
505     // Tools Menu
506     ActionContainer *ac = am->createMenu(Constants::M_TOOLS);
507     menubar->addMenu(ac, Constants::G_TOOLS);
508     ac->menu()->setTitle(tr("&Tools"));
509
510     // Window Menu
511     ActionContainer *mwindow = am->createMenu(Constants::M_WINDOW);
512     menubar->addMenu(mwindow, Constants::G_WINDOW);
513     mwindow->menu()->setTitle(tr("&Window"));
514     mwindow->appendGroup(Constants::G_WINDOW_SIZE);
515     mwindow->appendGroup(Constants::G_WINDOW_VIEWS);
516     mwindow->appendGroup(Constants::G_WINDOW_PANES);
517     mwindow->appendGroup(Constants::G_WINDOW_SPLIT);
518     mwindow->appendGroup(Constants::G_WINDOW_NAVIGATE);
519     mwindow->appendGroup(Constants::G_WINDOW_OTHER);
520
521     // Help Menu
522     ac = am->createMenu(Constants::M_HELP);
523     menubar->addMenu(ac, Constants::G_HELP);
524     ac->menu()->setTitle(tr("&Help"));
525     ac->appendGroup(Constants::G_HELP_HELP);
526     ac->appendGroup(Constants::G_HELP_ABOUT);
527 }
528
529 static Command *createSeparator(ActionManager *am, QObject *parent,
530                                 const QString &name,
531                                 const Context &context)
532 {
533     QAction *tmpaction = new QAction(parent);
534     tmpaction->setSeparator(true);
535     Command *cmd = am->registerAction(tmpaction, name, context);
536     return cmd;
537 }
538
539 void MainWindow::registerDefaultActions()
540 {
541     ActionManagerPrivate *am = m_actionManager;
542     ActionContainer *mfile = am->actionContainer(Constants::M_FILE);
543     ActionContainer *medit = am->actionContainer(Constants::M_EDIT);
544     ActionContainer *mtools = am->actionContainer(Constants::M_TOOLS);
545     ActionContainer *mwindow = am->actionContainer(Constants::M_WINDOW);
546     ActionContainer *mhelp = am->actionContainer(Constants::M_HELP);
547
548     Context globalContext(Constants::C_GLOBAL);
549
550     // File menu separators
551     Command *cmd = createSeparator(am, this, QLatin1String("QtCreator.File.Sep.Save"), globalContext);
552     mfile->addAction(cmd, Constants::G_FILE_SAVE);
553
554     cmd =  createSeparator(am, this, QLatin1String("QtCreator.File.Sep.Print"), globalContext);
555     QIcon icon = QIcon::fromTheme(QLatin1String("edit-cut"), QIcon(Constants::ICON_CUT));
556     mfile->addAction(cmd, Constants::G_FILE_PRINT);
557
558     cmd =  createSeparator(am, this, QLatin1String("QtCreator.File.Sep.Close"), globalContext);
559     mfile->addAction(cmd, Constants::G_FILE_CLOSE);
560
561     cmd = createSeparator(am, this, QLatin1String("QtCreator.File.Sep.Other"), globalContext);
562     mfile->addAction(cmd, Constants::G_FILE_OTHER);
563
564     // Edit menu separators
565     cmd = createSeparator(am, this, QLatin1String("QtCreator.Edit.Sep.CopyPaste"), globalContext);
566     medit->addAction(cmd, Constants::G_EDIT_COPYPASTE);
567
568     cmd = createSeparator(am, this, QLatin1String("QtCreator.Edit.Sep.SelectAll"), globalContext);
569     medit->addAction(cmd, Constants::G_EDIT_SELECTALL);
570
571     cmd = createSeparator(am, this, QLatin1String("QtCreator.Edit.Sep.Find"), globalContext);
572     medit->addAction(cmd, Constants::G_EDIT_FIND);
573
574     cmd = createSeparator(am, this, QLatin1String("QtCreator.Edit.Sep.Advanced"), globalContext);
575     medit->addAction(cmd, Constants::G_EDIT_ADVANCED);
576
577     // Return to editor shortcut: Note this requires Qt to fix up
578     // handling of shortcut overrides in menus, item views, combos....
579     m_focusToEditor = new QShortcut(this);
580     cmd = am->registerShortcut(m_focusToEditor, Constants::S_RETURNTOEDITOR, globalContext);
581     cmd->setDefaultKeySequence(QKeySequence(Qt::Key_Escape));
582     connect(m_focusToEditor, SIGNAL(activated()), this, SLOT(setFocusToEditor()));
583
584     // New File Action
585     icon = QIcon::fromTheme(QLatin1String("document-new"), QIcon(Constants::ICON_NEWFILE));
586     m_newAction = new QAction(icon, tr("&New File or Project..."), this);
587     cmd = am->registerAction(m_newAction, Constants::NEW, globalContext);
588     cmd->setDefaultKeySequence(QKeySequence::New);
589     mfile->addAction(cmd, Constants::G_FILE_NEW);
590     connect(m_newAction, SIGNAL(triggered()), this, SLOT(newFile()));
591
592     // Open Action
593     icon = QIcon::fromTheme(QLatin1String("document-open"), QIcon(Constants::ICON_OPENFILE));
594     m_openAction = new QAction(icon, tr("&Open File or Project..."), this);
595     cmd = am->registerAction(m_openAction, Constants::OPEN, globalContext);
596     cmd->setDefaultKeySequence(QKeySequence::Open);
597     mfile->addAction(cmd, Constants::G_FILE_OPEN);
598     connect(m_openAction, SIGNAL(triggered()), this, SLOT(openFile()));
599
600     // Open With Action
601     m_openWithAction = new QAction(tr("Open File &With..."), this);
602     cmd = am->registerAction(m_openWithAction, Constants::OPEN_WITH, globalContext);
603     mfile->addAction(cmd, Constants::G_FILE_OPEN);
604     connect(m_openWithAction, SIGNAL(triggered()), this, SLOT(openFileWith()));
605
606     // File->Recent Files Menu
607     ActionContainer *ac = am->createMenu(Constants::M_FILE_RECENTFILES);
608     mfile->addMenu(ac, Constants::G_FILE_OPEN);
609     ac->menu()->setTitle(tr("Recent &Files"));
610     ac->setOnAllDisabledBehavior(ActionContainer::Show);
611
612     // Save Action
613     icon = QIcon::fromTheme(QLatin1String("document-save"), QIcon(Constants::ICON_SAVEFILE));
614     QAction *tmpaction = new QAction(icon, tr("&Save"), this);
615     tmpaction->setEnabled(false);
616     cmd = am->registerAction(tmpaction, Constants::SAVE, globalContext);
617     cmd->setDefaultKeySequence(QKeySequence::Save);
618     cmd->setAttribute(Command::CA_UpdateText);
619     cmd->setDefaultText(tr("&Save"));
620     mfile->addAction(cmd, Constants::G_FILE_SAVE);
621
622     // Save As Action
623     icon = QIcon::fromTheme(QLatin1String("document-save-as"));
624     tmpaction = new QAction(icon, tr("Save &As..."), this);
625     tmpaction->setEnabled(false);
626     cmd = am->registerAction(tmpaction, Constants::SAVEAS, globalContext);
627 #ifdef Q_WS_MAC
628     cmd->setDefaultKeySequence(QKeySequence(tr("Ctrl+Shift+S")));
629 #endif
630     cmd->setAttribute(Command::CA_UpdateText);
631     cmd->setDefaultText(tr("Save &As..."));
632     mfile->addAction(cmd, Constants::G_FILE_SAVE);
633
634     // SaveAll Action
635     m_saveAllAction = new QAction(tr("Save A&ll"), this);
636     cmd = am->registerAction(m_saveAllAction, Constants::SAVEALL, globalContext);
637 #ifndef Q_WS_MAC
638     cmd->setDefaultKeySequence(QKeySequence(tr("Ctrl+Shift+S")));
639 #endif
640     mfile->addAction(cmd, Constants::G_FILE_SAVE);
641     connect(m_saveAllAction, SIGNAL(triggered()), this, SLOT(saveAll()));
642
643     // Print Action
644     icon = QIcon::fromTheme(QLatin1String("document-print"));
645     tmpaction = new QAction(icon, tr("&Print..."), this);
646     tmpaction->setEnabled(false);
647     cmd = am->registerAction(tmpaction, Constants::PRINT, globalContext);
648     cmd->setDefaultKeySequence(QKeySequence::Print);
649     mfile->addAction(cmd, Constants::G_FILE_PRINT);
650
651     // Exit Action
652     icon = QIcon::fromTheme(QLatin1String("application-exit"));
653     m_exitAction = new QAction(icon, tr("E&xit"), this);
654     cmd = am->registerAction(m_exitAction, Constants::EXIT, globalContext);
655     cmd->setDefaultKeySequence(QKeySequence(tr("Ctrl+Q")));
656     mfile->addAction(cmd, Constants::G_FILE_OTHER);
657     connect(m_exitAction, SIGNAL(triggered()), this, SLOT(exit()));
658
659     // Undo Action
660     icon = QIcon::fromTheme(QLatin1String("edit-undo"), QIcon(Constants::ICON_UNDO));
661     tmpaction = new QAction(icon, tr("&Undo"), this);
662     cmd = am->registerAction(tmpaction, Constants::UNDO, globalContext);
663     cmd->setDefaultKeySequence(QKeySequence::Undo);
664     cmd->setAttribute(Command::CA_UpdateText);
665     cmd->setDefaultText(tr("&Undo"));
666     medit->addAction(cmd, Constants::G_EDIT_UNDOREDO);
667     tmpaction->setEnabled(false);
668
669     // Redo Action
670     icon = QIcon::fromTheme(QLatin1String("edit-redo"), QIcon(Constants::ICON_REDO));
671     tmpaction = new QAction(icon, tr("&Redo"), this);
672     cmd = am->registerAction(tmpaction, Constants::REDO, globalContext);
673     cmd->setDefaultKeySequence(QKeySequence::Redo);
674     cmd->setAttribute(Command::CA_UpdateText);
675     cmd->setDefaultText(tr("&Redo"));
676     medit->addAction(cmd, Constants::G_EDIT_UNDOREDO);
677     tmpaction->setEnabled(false);
678
679     // Cut Action
680     icon = QIcon::fromTheme(QLatin1String("edit-cut"), QIcon(Constants::ICON_CUT));
681     tmpaction = new QAction(icon, tr("Cu&t"), this);
682     cmd = am->registerAction(tmpaction, Constants::CUT, globalContext);
683     cmd->setDefaultKeySequence(QKeySequence::Cut);
684     medit->addAction(cmd, Constants::G_EDIT_COPYPASTE);
685     tmpaction->setEnabled(false);
686
687     // Copy Action
688     icon = QIcon::fromTheme(QLatin1String("edit-copy"), QIcon(Constants::ICON_COPY));
689     tmpaction = new QAction(icon, tr("&Copy"), this);
690     cmd = am->registerAction(tmpaction, Constants::COPY, globalContext);
691     cmd->setDefaultKeySequence(QKeySequence::Copy);
692     medit->addAction(cmd, Constants::G_EDIT_COPYPASTE);
693     tmpaction->setEnabled(false);
694
695     // Paste Action
696     icon = QIcon::fromTheme(QLatin1String("edit-paste"), QIcon(Constants::ICON_PASTE));
697     tmpaction = new QAction(icon, tr("&Paste"), this);
698     cmd = am->registerAction(tmpaction, Constants::PASTE, globalContext);
699     cmd->setDefaultKeySequence(QKeySequence::Paste);
700     medit->addAction(cmd, Constants::G_EDIT_COPYPASTE);
701     tmpaction->setEnabled(false);
702
703     // Select All
704     icon = QIcon::fromTheme(QLatin1String("edit-select-all"));
705     tmpaction = new QAction(icon, tr("Select &All"), this);
706     cmd = am->registerAction(tmpaction, Constants::SELECTALL, globalContext);
707     cmd->setDefaultKeySequence(QKeySequence::SelectAll);
708     medit->addAction(cmd, Constants::G_EDIT_SELECTALL);
709     tmpaction->setEnabled(false);
710
711     // Goto Action
712     icon = QIcon::fromTheme(QLatin1String("go-jump"));
713     tmpaction = new QAction(icon, tr("&Go To Line..."), this);
714     cmd = am->registerAction(tmpaction, Constants::GOTO, globalContext);
715     cmd->setDefaultKeySequence(QKeySequence(tr("Ctrl+L")));
716     medit->addAction(cmd, Constants::G_EDIT_OTHER);
717     tmpaction->setEnabled(false);
718
719     // Options Action
720     mtools->appendGroup(Constants::G_TOOLS_OPTIONS);
721     cmd = createSeparator(am, this, QLatin1String("QtCreator.Tools.Sep.Options"), globalContext);
722     mtools->addAction(cmd, Constants::G_TOOLS_OPTIONS);
723     m_optionsAction = new QAction(tr("&Options..."), this);
724     cmd = am->registerAction(m_optionsAction, Constants::OPTIONS, globalContext);
725 #ifdef Q_WS_MAC
726     cmd->setDefaultKeySequence(QKeySequence("Ctrl+,"));
727     cmd->action()->setMenuRole(QAction::PreferencesRole);
728 #endif
729     mtools->addAction(cmd, Constants::G_TOOLS_OPTIONS);
730     connect(m_optionsAction, SIGNAL(triggered()), this, SLOT(showOptionsDialog()));
731
732 #ifdef Q_WS_MAC
733     // Minimize Action
734     m_minimizeAction = new QAction(tr("Minimize"), this);
735     cmd = am->registerAction(m_minimizeAction, Constants::MINIMIZE_WINDOW, globalContext);
736     cmd->setDefaultKeySequence(QKeySequence("Ctrl+M"));
737     mwindow->addAction(cmd, Constants::G_WINDOW_SIZE);
738     connect(m_minimizeAction, SIGNAL(triggered()), this, SLOT(showMinimized()));
739
740     // Zoom Action
741     m_zoomAction = new QAction(tr("Zoom"), this);
742     cmd = am->registerAction(m_zoomAction, Constants::ZOOM_WINDOW, globalContext);
743     mwindow->addAction(cmd, Constants::G_WINDOW_SIZE);
744     connect(m_zoomAction, SIGNAL(triggered()), this, SLOT(showMaximized()));
745
746     // Window separator
747     cmd = createSeparator(am, this, QLatin1String("QtCreator.Window.Sep.Size"), globalContext);
748     mwindow->addAction(cmd, Constants::G_WINDOW_SIZE);
749 #endif
750
751     // Show Sidebar Action
752     m_toggleSideBarAction = new QAction(QIcon(Constants::ICON_TOGGLE_SIDEBAR),
753                                         tr("Show Sidebar"), this);
754     m_toggleSideBarAction->setCheckable(true);
755     cmd = am->registerAction(m_toggleSideBarAction, Constants::TOGGLE_SIDEBAR, globalContext);
756     cmd->setAttribute(Command::CA_UpdateText);
757 #ifdef Q_WS_MAC
758     cmd->setDefaultKeySequence(QKeySequence("Ctrl+0"));
759 #else
760     cmd->setDefaultKeySequence(QKeySequence("Alt+0"));
761 #endif
762     connect(m_toggleSideBarAction, SIGNAL(triggered(bool)), this, SLOT(setSidebarVisible(bool)));
763     m_toggleSideBarButton->setDefaultAction(cmd->action());
764     mwindow->addAction(cmd, Constants::G_WINDOW_VIEWS);
765     m_toggleSideBarAction->setEnabled(false);
766
767 #ifndef Q_WS_MAC
768     // Full Screen Action
769     m_toggleFullScreenAction = new QAction(tr("Full Screen"), this);
770     m_toggleFullScreenAction->setCheckable(true);
771     cmd = am->registerAction(m_toggleFullScreenAction, Constants::TOGGLE_FULLSCREEN, globalContext);
772     cmd->setDefaultKeySequence(QKeySequence("Ctrl+Shift+F11"));
773     mwindow->addAction(cmd, Constants::G_WINDOW_SIZE);
774     connect(m_toggleFullScreenAction, SIGNAL(triggered(bool)), this, SLOT(setFullScreen(bool)));
775 #endif
776
777     // Window->Views
778     ActionContainer *mviews = am->createMenu(Constants::M_WINDOW_VIEWS);
779     mwindow->addMenu(mviews, Constants::G_WINDOW_VIEWS);
780     mviews->menu()->setTitle(tr("&Views"));
781
782     // About IDE Action
783     icon = QIcon::fromTheme(QLatin1String("help-about"));
784 #ifdef Q_WS_MAC
785     tmpaction = new QAction(icon, tr("About &Qt Creator"), this); // it's convention not to add dots to the about menu
786 #else
787     tmpaction = new QAction(icon, tr("About &Qt Creator..."), this);
788 #endif
789     cmd = am->registerAction(tmpaction, Constants::ABOUT_QTCREATOR, globalContext);
790     mhelp->addAction(cmd, Constants::G_HELP_ABOUT);
791     tmpaction->setEnabled(true);
792 #ifdef Q_WS_MAC
793     cmd->action()->setMenuRole(QAction::ApplicationSpecificRole);
794 #endif
795     connect(tmpaction, SIGNAL(triggered()), this,  SLOT(aboutQtCreator()));
796
797     //About Plugins Action
798     tmpaction = new QAction(tr("About &Plugins..."), this);
799     cmd = am->registerAction(tmpaction, Constants::ABOUT_PLUGINS, globalContext);
800     mhelp->addAction(cmd, Constants::G_HELP_ABOUT);
801     tmpaction->setEnabled(true);
802 #ifdef Q_WS_MAC
803     cmd->action()->setMenuRole(QAction::ApplicationSpecificRole);
804 #endif
805     connect(tmpaction, SIGNAL(triggered()), this,  SLOT(aboutPlugins()));
806     // About Qt Action
807 //    tmpaction = new QAction(tr("About &Qt..."), this);
808 //    cmd = am->registerAction(tmpaction, Constants:: ABOUT_QT, globalContext);
809 //    mhelp->addAction(cmd, Constants::G_HELP_ABOUT);
810 //    tmpaction->setEnabled(true);
811 //    connect(tmpaction, SIGNAL(triggered()), qApp, SLOT(aboutQt()));
812     // About sep
813 #ifndef Q_WS_MAC // doesn't have the "About" actions in the Help menu
814     tmpaction = new QAction(this);
815     tmpaction->setSeparator(true);
816     cmd = am->registerAction(tmpaction, "QtCreator.Help.Sep.About", globalContext);
817     mhelp->addAction(cmd, Constants::G_HELP_ABOUT);
818 #endif
819 }
820
821 void MainWindow::newFile()
822 {
823     showNewItemDialog(tr("New", "Title of dialog"), IWizard::allWizards(), QString());
824 }
825
826 void MainWindow::openFile()
827 {
828     openFiles(editorManager()->getOpenFileNames(), ICore::SwitchMode);
829 }
830
831 static QList<IFileFactory*> getNonEditorFileFactories()
832 {
833     const QList<IFileFactory*> allFileFactories =
834         ExtensionSystem::PluginManager::instance()->getObjects<IFileFactory>();
835     QList<IFileFactory*> nonEditorFileFactories;
836     foreach (IFileFactory *factory, allFileFactories) {
837         if (!qobject_cast<IEditorFactory *>(factory))
838             nonEditorFileFactories.append(factory);
839     }
840     return nonEditorFileFactories;
841 }
842
843 static IFileFactory *findFileFactory(const QList<IFileFactory*> &fileFactories,
844                                      const MimeDatabase *db,
845                                      const QFileInfo &fi)
846 {
847     if (const MimeType mt = db->findByFile(fi)) {
848         const QString type = mt.type();
849         foreach (IFileFactory *factory, fileFactories) {
850             if (factory->mimeTypes().contains(type))
851                 return factory;
852         }
853     }
854     return 0;
855 }
856
857 // opens either an editor or loads a project
858 void MainWindow::openFiles(const QStringList &fileNames, ICore::OpenFilesFlags flags)
859 {
860     QList<IFileFactory*> nonEditorFileFactories = getNonEditorFileFactories();
861
862     foreach (const QString &fileName, fileNames) {
863         const QFileInfo fi(fileName);
864         const QString absoluteFilePath = fi.absoluteFilePath();
865         if (IFileFactory *fileFactory = findFileFactory(nonEditorFileFactories, mimeDatabase(), fi)) {
866             Core::IFile *file = fileFactory->open(absoluteFilePath);
867             if (!file && (flags & ICore::StopOnLoadFail))
868                 return;
869             if (file && (flags & ICore::SwitchMode))
870                 Core::ModeManager::instance()->activateMode(Core::Constants::MODE_EDIT);
871         } else {
872             QFlags<EditorManager::OpenEditorFlag> emFlags;
873             if (flags & ICore::SwitchMode)
874                 emFlags = EditorManager::ModeSwitch;
875             if (flags & ICore::CanContainLineNumbers)
876                 emFlags |=  EditorManager::CanContainLineNumber;
877             Core::IEditor *editor = editorManager()->openEditor(absoluteFilePath, QString(), emFlags);
878             if (!editor && (flags & ICore::StopOnLoadFail))
879                 return;
880         }
881     }
882 }
883
884 void MainWindow::setFocusToEditor()
885 {
886     bool focusWasMovedToEditor = false;
887
888     // give focus to the editor if we have one
889     if (IEditor *editor = m_editorManager->currentEditor()) {
890         if (qApp->focusWidget() != editor->widget()) {
891             editor->widget()->setFocus();
892             focusWasMovedToEditor = editor->widget()->hasFocus();
893         }
894     }
895
896     // check for some maximized pane which we want to unmaximize
897     if (OutputPanePlaceHolder::getCurrent()
898         && OutputPanePlaceHolder::getCurrent()->isVisible()
899         && OutputPanePlaceHolder::getCurrent()->isMaximized()) {
900         OutputPanePlaceHolder::getCurrent()->unmaximize();
901         return;
902     }
903
904     if (focusWasMovedToEditor)
905         return;
906
907
908     // check for some visible bar which we want to hide
909     bool stuffVisible =
910             (FindToolBarPlaceHolder::getCurrent() &&
911              FindToolBarPlaceHolder::getCurrent()->isVisible())
912             || (OutputPanePlaceHolder::getCurrent() &&
913                 OutputPanePlaceHolder::getCurrent()->isVisible())
914             || (RightPanePlaceHolder::current() &&
915                 RightPanePlaceHolder::current()->isVisible());
916     if (stuffVisible) {
917         if (FindToolBarPlaceHolder::getCurrent())
918             FindToolBarPlaceHolder::getCurrent()->hide();
919         OutputPaneManager::instance()->slotHide();
920         RightPaneWidget::instance()->setShown(false);
921         return;
922     }
923
924     // switch to edit mode if necessary
925     m_coreImpl->modeManager()->activateMode(QLatin1String(Constants::MODE_EDIT));
926
927 }
928
929 void MainWindow::showNewItemDialog(const QString &title,
930                                           const QList<IWizard *> &wizards,
931                                           const QString &defaultLocation)
932 {
933     // Scan for wizards matching the filter and pick one. Don't show
934     // dialog if there is only one.
935     IWizard *wizard = 0;
936     switch (wizards.size()) {
937     case 0:
938         break;
939     case 1:
940         wizard = wizards.front();
941         break;
942     default: {
943         NewDialog dlg(this);
944         dlg.setWizards(wizards);
945         dlg.setWindowTitle(title);
946         wizard = dlg.showDialog();
947     }
948         break;
949     }
950
951     if (!wizard)
952         return;
953
954     QString path = defaultLocation;
955     if (path.isEmpty()) {
956         const FileManager *fm = m_coreImpl->fileManager();
957         switch (wizard->kind()) {
958         case IWizard::ProjectWizard:
959             // Project wizards: Check for projects directory or
960             // use last visited directory of file dialog. Never start
961             // at current.
962             path = fm->useProjectsDirectory() ?
963                        fm->projectsDirectory() :
964                        fm->fileDialogLastVisitedDirectory();
965             break;
966         default:
967             path = fm->fileDialogInitialDirectory();
968             break;
969         }
970     }
971     wizard->runWizard(path, this);
972 }
973
974 bool MainWindow::showOptionsDialog(const QString &category,
975                                    const QString &page,
976                                    QWidget *parent)
977 {
978     emit m_coreImpl->optionsDialogRequested();
979     if (!parent)
980         parent = this;
981     SettingsDialog *dialog = SettingsDialog::getSettingsDialog(parent, category, page);
982     return dialog->execDialog();
983 }
984
985 void MainWindow::saveAll()
986 {
987     m_fileManager->saveModifiedFilesSilently(m_fileManager->modifiedFiles());
988     emit m_coreImpl->saveSettingsRequested();
989 }
990
991 void MainWindow::exit()
992 {
993     // this function is most likely called from a user action
994     // that is from an event handler of an object
995     // since on close we are going to delete everything
996     // so to prevent the deleting of that object we
997     // just append it
998     QTimer::singleShot(0, this,  SLOT(close()));
999 }
1000
1001 void MainWindow::openFileWith()
1002 {
1003     QStringList fileNames = editorManager()->getOpenFileNames();
1004     foreach (const QString &fileName, fileNames) {
1005         bool isExternal;
1006         const QString editorId = editorManager()->getOpenWithEditorId(fileName, &isExternal);
1007         if (editorId.isEmpty())
1008             continue;
1009         if (isExternal) {
1010             editorManager()->openExternalEditor(fileName, editorId);
1011         } else {
1012             editorManager()->openEditor(fileName, editorId, Core::EditorManager::ModeSwitch);
1013         }
1014     }
1015 }
1016
1017 ActionManager *MainWindow::actionManager() const
1018 {
1019     return m_actionManager;
1020 }
1021
1022 FileManager *MainWindow::fileManager() const
1023 {
1024     return m_fileManager;
1025 }
1026
1027 UniqueIDManager *MainWindow::uniqueIDManager() const
1028 {
1029     return m_uniqueIDManager;
1030 }
1031
1032 MessageManager *MainWindow::messageManager() const
1033 {
1034     return m_messageManager;
1035 }
1036
1037 VcsManager *MainWindow::vcsManager() const
1038 {
1039     return m_vcsManager;
1040 }
1041
1042 QSettings *MainWindow::settings(QSettings::Scope scope) const
1043 {
1044     if (scope == QSettings::UserScope)
1045         return m_settings;
1046     else
1047         return m_globalSettings;
1048 }
1049
1050 EditorManager *MainWindow::editorManager() const
1051 {
1052     return m_editorManager;
1053 }
1054
1055 ProgressManager *MainWindow::progressManager() const
1056 {
1057     return m_progressManager;
1058 }
1059
1060 ScriptManager *MainWindow::scriptManager() const
1061 {
1062      return m_scriptManager;
1063 }
1064
1065 VariableManager *MainWindow::variableManager() const
1066 {
1067      return m_variableManager.data();
1068 }
1069
1070 ModeManager *MainWindow::modeManager() const
1071 {
1072     return m_modeManager;
1073 }
1074
1075 MimeDatabase *MainWindow::mimeDatabase() const
1076 {
1077     return m_mimeDatabase;
1078 }
1079
1080 HelpManager *MainWindow::helpManager() const
1081 {
1082     return m_helpManager;
1083 }
1084
1085 IContext *MainWindow::contextObject(QWidget *widget)
1086 {
1087     return m_contextWidgets.value(widget);
1088 }
1089
1090 void MainWindow::addContextObject(IContext *context)
1091 {
1092     if (!context)
1093         return;
1094     QWidget *widget = context->widget();
1095     if (m_contextWidgets.contains(widget))
1096         return;
1097
1098     m_contextWidgets.insert(widget, context);
1099 }
1100
1101 void MainWindow::removeContextObject(IContext *context)
1102 {
1103     if (!context)
1104         return;
1105
1106     QWidget *widget = context->widget();
1107     if (!m_contextWidgets.contains(widget))
1108         return;
1109
1110     m_contextWidgets.remove(widget);
1111     if (m_activeContext == context)
1112         updateContextObject(0);
1113 }
1114
1115 void MainWindow::changeEvent(QEvent *e)
1116 {
1117     QMainWindow::changeEvent(e);
1118     if (e->type() == QEvent::ActivationChange) {
1119         if (isActiveWindow()) {
1120             if (debugMainWindow)
1121                 qDebug() << "main window activated";
1122             emit windowActivated();
1123         }
1124     } else if (e->type() == QEvent::WindowStateChange) {
1125 #ifdef Q_WS_MAC
1126         bool minimized = isMinimized();
1127         if (debugMainWindow)
1128             qDebug() << "main window state changed to minimized=" << minimized;
1129         m_minimizeAction->setEnabled(!minimized);
1130         m_zoomAction->setEnabled(!minimized);
1131 #else
1132         bool isFullScreen = (windowState() & Qt::WindowFullScreen) != 0;
1133         m_toggleFullScreenAction->setChecked(isFullScreen);
1134 #endif
1135     }
1136 }
1137
1138 void MainWindow::updateFocusWidget(QWidget *old, QWidget *now)
1139 {
1140     Q_UNUSED(old)
1141
1142     // Prevent changing the context object just because the menu or a menu item is activated
1143     if (qobject_cast<QMenuBar*>(now) || qobject_cast<QMenu*>(now))
1144         return;
1145
1146     IContext *newContext = 0;
1147     if (focusWidget()) {
1148         IContext *context = 0;
1149         QWidget *p = focusWidget();
1150         while (p) {
1151             context = m_contextWidgets.value(p);
1152             if (context) {
1153                 newContext = context;
1154                 break;
1155             }
1156             p = p->parentWidget();
1157         }
1158     }
1159     updateContextObject(newContext);
1160 }
1161
1162 void MainWindow::updateContextObject(IContext *context)
1163 {
1164     if (context == m_activeContext)
1165         return;
1166     emit m_coreImpl->contextAboutToChange(context);
1167     m_activeContext = context;
1168     updateContext();
1169     if (debugMainWindow)
1170         qDebug() << "new context object =" << context << (context ? context->widget() : 0)
1171                  << (context ? context->widget()->metaObject()->className() : 0);
1172 }
1173
1174 void MainWindow::resetContext()
1175 {
1176     updateContextObject(0);
1177 }
1178
1179 void MainWindow::aboutToShutdown()
1180 {
1181     disconnect(QApplication::instance(), SIGNAL(focusChanged(QWidget*,QWidget*)),
1182                this, SLOT(updateFocusWidget(QWidget*,QWidget*)));
1183     m_activeContext = 0;
1184     hide();
1185 }
1186
1187 static const char *settingsGroup = "MainWindow";
1188 static const char *colorKey = "Color";
1189 static const char *windowGeometryKey = "WindowGeometry";
1190 static const char *windowStateKey = "WindowState";
1191
1192 // TODO compat for <= 2.1, remove later
1193 static const char *geometryKey = "Geometry";
1194 static const char *maxKey = "Maximized";
1195 static const char *fullScreenKey = "FullScreen";
1196
1197 void MainWindow::readSettings()
1198 {
1199     m_settings->beginGroup(QLatin1String(settingsGroup));
1200
1201     if (m_overrideColor.isValid()) {
1202         Utils::StyleHelper::setBaseColor(m_overrideColor);
1203         // Get adapted base color.
1204         m_overrideColor = Utils::StyleHelper::baseColor();
1205     } else {
1206         Utils::StyleHelper::setBaseColor(
1207                 m_settings->value(QLatin1String(colorKey),
1208                                   QColor(Utils::StyleHelper::DEFAULT_BASE_COLOR)).value<QColor>());
1209     }
1210
1211     // TODO compat for <= 2.1, remove later
1212     if (m_settings->contains(QLatin1String(geometryKey))) {
1213         const QVariant geom = m_settings->value(QLatin1String(geometryKey));
1214         if (geom.isValid()) {
1215             setGeometry(geom.toRect());
1216         } else {
1217             resize(1024, 700);
1218         }
1219         if (m_settings->value(QLatin1String(maxKey), false).toBool())
1220             setWindowState(Qt::WindowMaximized);
1221         setFullScreen(m_settings->value(QLatin1String(fullScreenKey), false).toBool());
1222
1223         m_settings->remove(QLatin1String(geometryKey));
1224         m_settings->remove(QLatin1String(maxKey));
1225         m_settings->remove(QLatin1String(fullScreenKey));
1226     } else {
1227         if (!restoreGeometry(m_settings->value(QLatin1String(windowGeometryKey)).toByteArray())) {
1228             resize(1024, 700);
1229         }
1230         restoreState(m_settings->value(QLatin1String(windowStateKey)).toByteArray());
1231     }
1232
1233     m_settings->endGroup();
1234
1235     m_editorManager->readSettings();
1236     m_navigationWidget->restoreSettings(m_settings);
1237     m_rightPaneWidget->readSettings(m_settings);
1238 }
1239
1240 void MainWindow::writeSettings()
1241 {
1242     m_settings->beginGroup(QLatin1String(settingsGroup));
1243
1244     if (!(m_overrideColor.isValid() && Utils::StyleHelper::baseColor() == m_overrideColor))
1245         m_settings->setValue(QLatin1String(colorKey), Utils::StyleHelper::requestedBaseColor());
1246
1247     m_settings->setValue(QLatin1String(windowGeometryKey), saveGeometry());
1248     m_settings->setValue(QLatin1String(windowStateKey), saveState());
1249
1250     m_settings->endGroup();
1251
1252     m_fileManager->saveSettings();
1253     m_actionManager->saveSettings(m_settings);
1254     m_editorManager->saveSettings();
1255     m_navigationWidget->saveSettings(m_settings);
1256 }
1257
1258 void MainWindow::updateAdditionalContexts(const Context &remove, const Context &add)
1259 {
1260     foreach (const int context, remove) {
1261         if (context == 0)
1262             continue;
1263
1264         int index = m_additionalContexts.indexOf(context);
1265         if (index != -1)
1266             m_additionalContexts.removeAt(index);
1267     }
1268
1269     foreach (const int context, add) {
1270         if (context == 0)
1271             continue;
1272
1273         if (!m_additionalContexts.contains(context))
1274             m_additionalContexts.prepend(context);
1275     }
1276
1277     updateContext();
1278 }
1279
1280 bool MainWindow::hasContext(int context) const
1281 {
1282     return m_actionManager->hasContext(context);
1283 }
1284
1285 void MainWindow::updateContext()
1286 {
1287     Context contexts;
1288
1289     if (m_activeContext)
1290         contexts.add(m_activeContext->context());
1291
1292     contexts.add(m_additionalContexts);
1293
1294     Context uniquecontexts;
1295     for (int i = 0; i < contexts.size(); ++i) {
1296         const int c = contexts.at(i);
1297         if (!uniquecontexts.contains(c))
1298             uniquecontexts.add(c);
1299     }
1300
1301     m_actionManager->setContext(uniquecontexts);
1302     emit m_coreImpl->contextChanged(m_activeContext, m_additionalContexts);
1303 }
1304
1305 void MainWindow::aboutToShowRecentFiles()
1306 {
1307     ActionContainer *aci =
1308         m_actionManager->actionContainer(Constants::M_FILE_RECENTFILES);
1309     aci->menu()->clear();
1310
1311     bool hasRecentFiles = false;
1312     foreach (const FileManager::RecentFile &file, m_fileManager->recentFiles()) {
1313         hasRecentFiles = true;
1314         QAction *action = aci->menu()->addAction(
1315                     QDir::toNativeSeparators(Utils::withTildeHomePath(file.first)));
1316         action->setData(qVariantFromValue(file));
1317         connect(action, SIGNAL(triggered()), this, SLOT(openRecentFile()));
1318     }
1319     aci->menu()->setEnabled(hasRecentFiles);
1320 }
1321
1322 void MainWindow::openRecentFile()
1323 {
1324     if (const QAction *action = qobject_cast<const QAction*>(sender())) {
1325         const FileManager::RecentFile file = action->data().value<FileManager::RecentFile>();
1326         editorManager()->openEditor(file.first, file.second, Core::EditorManager::ModeSwitch);
1327     }
1328 }
1329
1330 void MainWindow::aboutQtCreator()
1331 {
1332     if (!m_versionDialog) {
1333         m_versionDialog = new VersionDialog(this);
1334         connect(m_versionDialog, SIGNAL(finished(int)),
1335                 this, SLOT(destroyVersionDialog()));
1336     }
1337     m_versionDialog->show();
1338 }
1339
1340 void MainWindow::destroyVersionDialog()
1341 {
1342     if (m_versionDialog) {
1343         m_versionDialog->deleteLater();
1344         m_versionDialog = 0;
1345     }
1346 }
1347
1348 void MainWindow::aboutPlugins()
1349 {
1350     PluginDialog dialog(this);
1351     dialog.exec();
1352 }
1353
1354 QPrinter *MainWindow::printer() const
1355 {
1356     if (!m_printer)
1357         m_printer = new QPrinter(QPrinter::HighResolution);
1358     return m_printer;
1359 }
1360
1361 void MainWindow::setFullScreen(bool on)
1362 {
1363     if (bool(windowState() & Qt::WindowFullScreen) == on)
1364         return;
1365
1366     if (on) {
1367         setWindowState(windowState() | Qt::WindowFullScreen);
1368         //statusBar()->hide();
1369         //menuBar()->hide();
1370     } else {
1371         setWindowState(windowState() & ~Qt::WindowFullScreen);
1372         //menuBar()->show();
1373         //statusBar()->show();
1374     }
1375 }
1376
1377 // Display a warning with an additional button to open
1378 // the debugger settings dialog if settingsId is nonempty.
1379
1380 bool MainWindow::showWarningWithOptions(const QString &title,
1381                                         const QString &text,
1382                                         const QString &details,
1383                                         const QString &settingsCategory,
1384                                         const QString &settingsId,
1385                                         QWidget *parent)
1386 {
1387     if (parent == 0)
1388         parent = this;
1389     QMessageBox msgBox(QMessageBox::Warning, title, text,
1390                        QMessageBox::Ok, parent);
1391     if (!details.isEmpty())
1392         msgBox.setDetailedText(details);
1393     QAbstractButton *settingsButton = 0;
1394     if (!settingsId.isEmpty() || !settingsCategory.isEmpty())
1395         settingsButton = msgBox.addButton(tr("Settings..."), QMessageBox::AcceptRole);
1396     msgBox.exec();
1397     if (settingsButton && msgBox.clickedButton() == settingsButton) {
1398         return showOptionsDialog(settingsCategory, settingsId);
1399     }
1400     return false;
1401 }