/************************************************************************** ** ** This file is part of Qt Creator ** ** Copyright (c) 2010 Nokia Corporation and/or its subsidiary(-ies). ** ** Contact: Nokia Corporation (qt-info@nokia.com) ** ** Commercial Usage ** ** Licensees holding valid Qt Commercial licenses may use this file in ** accordance with the Qt Commercial License Agreement provided with the ** Software or, alternatively, in accordance with the terms contained in ** a written agreement between you and Nokia. ** ** GNU Lesser General Public License Usage ** ** Alternatively, this file may be used under the terms of the GNU Lesser ** General Public License version 2.1 as published by the Free Software ** Foundation and appearing in the file LICENSE.LGPL included in the ** packaging of this file. Please review the following information to ** ensure the GNU Lesser General Public License version 2.1 requirements ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. ** ** If you are unsure which license is appropriate for your use, please ** contact the sales department at http://qt.nokia.com/contact. ** **************************************************************************/ #include "mainwindow.h" #include "actioncontainer.h" #include "command.h" #include "actionmanager_p.h" #include "coreimpl.h" #include "coreconstants.h" #include "editormanager.h" #include "fancytabwidget.h" #include "filemanager.h" #include "generalsettings.h" #include "ifilefactory.h" #include "messagemanager.h" #include "modemanager.h" #include "mimedatabase.h" #include "newdialog.h" #include "outputpane.h" #include "plugindialog.h" #include "progressmanager_p.h" #include "progressview.h" #include "shortcutsettings.h" #include "vcsmanager.h" #include "scriptmanager_p.h" #include "settingsdialog.h" #include "variablemanager.h" #include "versiondialog.h" #include "statusbarmanager.h" #include "uniqueidmanager.h" #include "manhattanstyle.h" #include "navigationwidget.h" #include "rightpane.h" #include "editormanager/ieditorfactory.h" #include "statusbarwidget.h" #include "basefilewizard.h" #include "ioutputpane.h" #include "editormanager/systemeditor.h" #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include /* #ifdef Q_OS_UNIX #include extern "C" void handleSigInt(int sig) { Q_UNUSED(sig) Core::ICore::instance()->exit(); qDebug() << "SIGINT caught. Shutting down."; } #endif */ using namespace Core; using namespace Core::Internal; enum { debugMainWindow = 0 }; MainWindow::MainWindow() : EventFilteringMainWindow(), m_coreImpl(new CoreImpl(this)), m_uniqueIDManager(new UniqueIDManager()), m_globalContext(QList() << Constants::C_GLOBAL_ID), m_additionalContexts(m_globalContext), // keep this in sync with main() in app/main.cpp m_settings(new QSettings(QSettings::IniFormat, QSettings::UserScope, QLatin1String("Nokia"), QLatin1String("QtCreator"), this)), m_globalSettings(new QSettings(QSettings::IniFormat, QSettings::SystemScope, QLatin1String("Nokia"), QLatin1String("QtCreator"), this)), m_settingsDatabase(new SettingsDatabase(QFileInfo(m_settings->fileName()).path(), QLatin1String("QtCreator"), this)), m_printer(0), m_actionManager(new ActionManagerPrivate(this)), m_editorManager(0), m_fileManager(new FileManager(this)), m_progressManager(new ProgressManagerPrivate()), m_scriptManager(new ScriptManagerPrivate(this)), m_variableManager(new VariableManager(this)), m_vcsManager(new VCSManager), m_statusBarManager(0), m_modeManager(0), m_mimeDatabase(new MimeDatabase), m_navigationWidget(0), m_rightPaneWidget(0), m_versionDialog(0), m_activeContext(0), m_generalSettings(new GeneralSettings), m_shortcutSettings(new ShortcutSettings), m_systemEditor(new SystemEditor), m_focusToEditor(0), m_newAction(0), m_openAction(0), m_openWithAction(0), m_saveAllAction(0), m_exitAction(0), m_optionsAction(0), m_toggleSideBarAction(0), m_toggleFullScreenAction(0), #ifdef Q_WS_MAC m_minimizeAction(0), m_zoomAction(0), #endif m_toggleSideBarButton(new QToolButton) { OutputPaneManager::create(); setWindowTitle(tr("Qt Creator")); #ifndef Q_WS_MAC qApp->setWindowIcon(QIcon(":/core/images/qtcreator_logo_128.png")); #endif QCoreApplication::setApplicationName(QLatin1String("QtCreator")); QCoreApplication::setApplicationVersion(QLatin1String(Core::Constants::IDE_VERSION_LONG)); QCoreApplication::setOrganizationName(QLatin1String("Nokia")); QSettings::setDefaultFormat(QSettings::IniFormat); QString baseName = qApp->style()->objectName(); #ifdef Q_WS_X11 if (baseName == QLatin1String("windows")) { // Sometimes we get the standard windows 95 style as a fallback // e.g. if we are running on a KDE4 desktop QByteArray desktopEnvironment = qgetenv("DESKTOP_SESSION"); if (desktopEnvironment == "kde") baseName = QLatin1String("plastique"); else baseName = QLatin1String("cleanlooks"); } #endif qApp->setStyle(new ManhattanStyle(baseName)); setDockNestingEnabled(true); setCorner(Qt::BottomLeftCorner, Qt::LeftDockWidgetArea); setCorner(Qt::BottomRightCorner, Qt::BottomDockWidgetArea); registerDefaultContainers(); registerDefaultActions(); m_navigationWidget = new NavigationWidget(m_toggleSideBarAction); m_rightPaneWidget = new RightPaneWidget(); m_modeStack = new FancyTabWidget(this); m_modeManager = new ModeManager(this, m_modeStack); m_modeManager->addWidget(m_progressManager->progressView()); m_statusBarManager = new StatusBarManager(this); m_messageManager = new MessageManager; m_editorManager = new EditorManager(m_coreImpl, this); m_editorManager->hide(); setCentralWidget(m_modeStack); connect(QApplication::instance(), SIGNAL(focusChanged(QWidget*,QWidget*)), this, SLOT(updateFocusWidget(QWidget*,QWidget*))); // Add a small Toolbutton for toggling the navigation widget statusBar()->insertPermanentWidget(0, m_toggleSideBarButton); // setUnifiedTitleAndToolBarOnMac(true); #ifdef Q_OS_UNIX //signal(SIGINT, handleSigInt); #endif statusBar()->setProperty("p_styled", true); setAcceptDrops(true); } void MainWindow::setSidebarVisible(bool visible) { if (NavigationWidgetPlaceHolder::current()) { if (m_navigationWidget->isSuppressed() && visible) { m_navigationWidget->setShown(true); m_navigationWidget->setSuppressed(false); } else { m_navigationWidget->setShown(visible); } } } void MainWindow::setSuppressNavigationWidget(bool suppress) { if (NavigationWidgetPlaceHolder::current()) m_navigationWidget->setSuppressed(suppress); } void MainWindow::setOverrideColor(const QColor &color) { m_overrideColor = color; } MainWindow::~MainWindow() { hide(); ExtensionSystem::PluginManager *pm = ExtensionSystem::PluginManager::instance(); pm->removeObject(m_shortcutSettings); pm->removeObject(m_generalSettings); pm->removeObject(m_systemEditor); delete m_messageManager; m_messageManager = 0; delete m_shortcutSettings; m_shortcutSettings = 0; delete m_generalSettings; m_generalSettings = 0; delete m_systemEditor; m_systemEditor = 0; delete m_settings; m_settings = 0; delete m_printer; m_printer = 0; delete m_uniqueIDManager; m_uniqueIDManager = 0; delete m_vcsManager; m_vcsManager = 0; //we need to delete editormanager and statusbarmanager explicitly before the end of the destructor, //because they might trigger stuff that tries to access data from editorwindow, like removeContextWidget // All modes are now gone OutputPaneManager::destroy(); // Now that the OutputPaneManager is gone, is a good time to delete the view pm->removeObject(m_outputView); delete m_outputView; delete m_editorManager; m_editorManager = 0; delete m_statusBarManager; m_statusBarManager = 0; delete m_progressManager; m_progressManager = 0; pm->removeObject(m_coreImpl); delete m_coreImpl; m_coreImpl = 0; delete m_rightPaneWidget; m_rightPaneWidget = 0; delete m_navigationWidget; m_navigationWidget = 0; delete m_modeManager; m_modeManager = 0; delete m_mimeDatabase; m_mimeDatabase = 0; } bool MainWindow::init(QString *errorMessage) { Q_UNUSED(errorMessage) if (!mimeDatabase()->addMimeTypes(QLatin1String(":/core/editormanager/BinFiles.mimetypes.xml"), errorMessage)) return false; ExtensionSystem::PluginManager *pm = ExtensionSystem::PluginManager::instance(); pm->addObject(m_coreImpl); m_statusBarManager->init(); m_modeManager->init(); m_progressManager->init(); pm->addObject(m_generalSettings); pm->addObject(m_shortcutSettings); pm->addObject(m_systemEditor); // Add widget to the bottom, we create the view here instead of inside the // OutputPaneManager, since the StatusBarManager needs to be initialized before m_outputView = new Core::StatusBarWidget; m_outputView->setWidget(OutputPaneManager::instance()->buttonsWidget()); m_outputView->setPosition(Core::StatusBarWidget::Second); pm->addObject(m_outputView); m_messageManager->init(); return true; } void MainWindow::extensionsInitialized() { m_editorManager->init(); m_statusBarManager->extensionsInitalized(); OutputPaneManager::instance()->init(); m_actionManager->initialize(); m_vcsManager->extensionsInitialized(); readSettings(); updateContext(); emit m_coreImpl->coreAboutToOpen(); show(); emit m_coreImpl->coreOpened(); } void MainWindow::closeEvent(QCloseEvent *event) { emit m_coreImpl->saveSettingsRequested(); // Save opened files bool cancelled; QList notSaved = fileManager()->saveModifiedFiles(fileManager()->modifiedFiles(), &cancelled); if (cancelled || !notSaved.isEmpty()) { event->ignore(); return; } const QList listeners = ExtensionSystem::PluginManager::instance()->getObjects(); foreach (ICoreListener *listener, listeners) { if (!listener->coreAboutToClose()) { event->ignore(); return; } } emit m_coreImpl->coreAboutToClose(); writeSettings(); event->accept(); } // Check for desktop file manager file drop events static bool isDesktopFileManagerDrop(const QMimeData *d, QStringList *files = 0) { if (files) files->clear(); // Extract dropped files from Mime data. if (!d->hasUrls()) return false; const QList urls = d->urls(); if (urls.empty()) return false; // Try to find local files bool hasFiles = false; const QList::const_iterator cend = urls.constEnd(); for (QList::const_iterator it = urls.constBegin(); it != cend; ++it) { const QString fileName = it->toLocalFile(); if (!fileName.isEmpty()) { hasFiles = true; if (files) { files->push_back(fileName); } else { break; // No result list, sufficient for checking } } } return hasFiles; } void MainWindow::dragEnterEvent(QDragEnterEvent *event) { if (isDesktopFileManagerDrop(event->mimeData())) { event->accept(); } else { event->ignore(); } } void MainWindow::dropEvent(QDropEvent *event) { QStringList files; if (isDesktopFileManagerDrop(event->mimeData(), &files)) { event->accept(); openFiles(files); } else { event->ignore(); } } IContext *MainWindow::currentContextObject() const { return m_activeContext; } QStatusBar *MainWindow::statusBar() const { return m_modeStack->statusBar(); } void MainWindow::registerDefaultContainers() { ActionManagerPrivate *am = m_actionManager; ActionContainer *menubar = am->createMenuBar(Constants::MENU_BAR); #ifndef Q_WS_MAC // System menu bar on Mac setMenuBar(menubar->menuBar()); #endif menubar->appendGroup(Constants::G_FILE); menubar->appendGroup(Constants::G_EDIT); menubar->appendGroup(Constants::G_VIEW); menubar->appendGroup(Constants::G_TOOLS); menubar->appendGroup(Constants::G_WINDOW); menubar->appendGroup(Constants::G_HELP); // File Menu ActionContainer *filemenu = am->createMenu(Constants::M_FILE); menubar->addMenu(filemenu, Constants::G_FILE); filemenu->menu()->setTitle(tr("&File")); filemenu->appendGroup(Constants::G_FILE_NEW); filemenu->appendGroup(Constants::G_FILE_OPEN); filemenu->appendGroup(Constants::G_FILE_PROJECT); filemenu->appendGroup(Constants::G_FILE_SAVE); filemenu->appendGroup(Constants::G_FILE_CLOSE); filemenu->appendGroup(Constants::G_FILE_PRINT); filemenu->appendGroup(Constants::G_FILE_OTHER); connect(filemenu->menu(), SIGNAL(aboutToShow()), this, SLOT(aboutToShowRecentFiles())); // Edit Menu ActionContainer *medit = am->createMenu(Constants::M_EDIT); menubar->addMenu(medit, Constants::G_EDIT); medit->menu()->setTitle(tr("&Edit")); medit->appendGroup(Constants::G_EDIT_UNDOREDO); medit->appendGroup(Constants::G_EDIT_COPYPASTE); medit->appendGroup(Constants::G_EDIT_SELECTALL); medit->appendGroup(Constants::G_EDIT_ADVANCED); medit->appendGroup(Constants::G_EDIT_FIND); medit->appendGroup(Constants::G_EDIT_OTHER); // Tools Menu ActionContainer *ac = am->createMenu(Constants::M_TOOLS); menubar->addMenu(ac, Constants::G_TOOLS); ac->menu()->setTitle(tr("&Tools")); // Window Menu ActionContainer *mwindow = am->createMenu(Constants::M_WINDOW); menubar->addMenu(mwindow, Constants::G_WINDOW); mwindow->menu()->setTitle(tr("&Window")); mwindow->appendGroup(Constants::G_WINDOW_SIZE); mwindow->appendGroup(Constants::G_WINDOW_PANES); mwindow->appendGroup(Constants::G_WINDOW_SPLIT); mwindow->appendGroup(Constants::G_WINDOW_NAVIGATE); mwindow->appendGroup(Constants::G_WINDOW_OTHER); // Help Menu ac = am->createMenu(Constants::M_HELP); menubar->addMenu(ac, Constants::G_HELP); ac->menu()->setTitle(tr("&Help")); ac->appendGroup(Constants::G_HELP_HELP); ac->appendGroup(Constants::G_HELP_ABOUT); } static Command *createSeparator(ActionManager *am, QObject *parent, const QString &name, const QList &context) { QAction *tmpaction = new QAction(parent); tmpaction->setSeparator(true); Command *cmd = am->registerAction(tmpaction, name, context); return cmd; } void MainWindow::registerDefaultActions() { ActionManagerPrivate *am = m_actionManager; ActionContainer *mfile = am->actionContainer(Constants::M_FILE); ActionContainer *medit = am->actionContainer(Constants::M_EDIT); ActionContainer *mtools = am->actionContainer(Constants::M_TOOLS); ActionContainer *mwindow = am->actionContainer(Constants::M_WINDOW); ActionContainer *mhelp = am->actionContainer(Constants::M_HELP); // File menu separators Command *cmd = createSeparator(am, this, QLatin1String("QtCreator.File.Sep.Save"), m_globalContext); mfile->addAction(cmd, Constants::G_FILE_SAVE); cmd = createSeparator(am, this, QLatin1String("QtCreator.File.Sep.Print"), m_globalContext); QIcon icon = QIcon::fromTheme(QLatin1String("edit-cut"), QIcon(Constants::ICON_CUT)); mfile->addAction(cmd, Constants::G_FILE_PRINT); cmd = createSeparator(am, this, QLatin1String("QtCreator.File.Sep.Close"), m_globalContext); mfile->addAction(cmd, Constants::G_FILE_CLOSE); cmd = createSeparator(am, this, QLatin1String("QtCreator.File.Sep.Other"), m_globalContext); mfile->addAction(cmd, Constants::G_FILE_OTHER); // Edit menu separators cmd = createSeparator(am, this, QLatin1String("QtCreator.Edit.Sep.CopyPaste"), m_globalContext); medit->addAction(cmd, Constants::G_EDIT_COPYPASTE); cmd = createSeparator(am, this, QLatin1String("QtCreator.Edit.Sep.SelectAll"), m_globalContext); medit->addAction(cmd, Constants::G_EDIT_SELECTALL); cmd = createSeparator(am, this, QLatin1String("QtCreator.Edit.Sep.Find"), m_globalContext); medit->addAction(cmd, Constants::G_EDIT_FIND); cmd = createSeparator(am, this, QLatin1String("QtCreator.Edit.Sep.Advanced"), m_globalContext); medit->addAction(cmd, Constants::G_EDIT_ADVANCED); // Tools menu separators cmd = createSeparator(am, this, QLatin1String("QtCreator.Tools.Sep.Options"), m_globalContext); mtools->addAction(cmd, Constants::G_DEFAULT_THREE); // Return to editor shortcut: Note this requires Qt to fix up // handling of shortcut overrides in menus, item views, combos.... m_focusToEditor = new QShortcut(this); cmd = am->registerShortcut(m_focusToEditor, Constants::S_RETURNTOEDITOR, m_globalContext); cmd->setDefaultKeySequence(QKeySequence(Qt::Key_Escape)); connect(m_focusToEditor, SIGNAL(activated()), this, SLOT(setFocusToEditor())); // New File Action icon = QIcon::fromTheme(QLatin1String("document-new"), QIcon(Constants::ICON_NEWFILE)); m_newAction = new QAction(icon, tr("&New File or Project..."), this); cmd = am->registerAction(m_newAction, Constants::NEW, m_globalContext); cmd->setDefaultKeySequence(QKeySequence::New); mfile->addAction(cmd, Constants::G_FILE_NEW); connect(m_newAction, SIGNAL(triggered()), this, SLOT(newFile())); // Open Action icon = QIcon::fromTheme(QLatin1String("document-open"), QIcon(Constants::ICON_OPENFILE)); m_openAction = new QAction(icon, tr("&Open File or Project..."), this); cmd = am->registerAction(m_openAction, Constants::OPEN, m_globalContext); cmd->setDefaultKeySequence(QKeySequence::Open); mfile->addAction(cmd, Constants::G_FILE_OPEN); connect(m_openAction, SIGNAL(triggered()), this, SLOT(openFile())); // Open With Action m_openWithAction = new QAction(tr("Open File &With..."), this); cmd = am->registerAction(m_openWithAction, Constants::OPEN_WITH, m_globalContext); mfile->addAction(cmd, Constants::G_FILE_OPEN); connect(m_openWithAction, SIGNAL(triggered()), this, SLOT(openFileWith())); // File->Recent Files Menu ActionContainer *ac = am->createMenu(Constants::M_FILE_RECENTFILES); mfile->addMenu(ac, Constants::G_FILE_OPEN); ac->menu()->setTitle(tr("Recent &Files")); // Save Action icon = QIcon::fromTheme(QLatin1String("document-save"), QIcon(Constants::ICON_SAVEFILE)); QAction *tmpaction = new QAction(icon, tr("&Save"), this); cmd = am->registerAction(tmpaction, Constants::SAVE, m_globalContext); cmd->setDefaultKeySequence(QKeySequence::Save); cmd->setAttribute(Command::CA_UpdateText); cmd->setDefaultText(tr("&Save")); mfile->addAction(cmd, Constants::G_FILE_SAVE); // Save As Action icon = QIcon::fromTheme(QLatin1String("document-save-as")); tmpaction = new QAction(icon, tr("Save &As..."), this); cmd = am->registerAction(tmpaction, Constants::SAVEAS, m_globalContext); #ifdef Q_WS_MAC cmd->setDefaultKeySequence(QKeySequence(tr("Ctrl+Shift+S"))); #endif cmd->setAttribute(Command::CA_UpdateText); cmd->setDefaultText(tr("Save &As...")); mfile->addAction(cmd, Constants::G_FILE_SAVE); // SaveAll Action m_saveAllAction = new QAction(tr("Save A&ll"), this); cmd = am->registerAction(m_saveAllAction, Constants::SAVEALL, m_globalContext); #ifndef Q_WS_MAC cmd->setDefaultKeySequence(QKeySequence(tr("Ctrl+Shift+S"))); #endif mfile->addAction(cmd, Constants::G_FILE_SAVE); connect(m_saveAllAction, SIGNAL(triggered()), this, SLOT(saveAll())); // Print Action icon = QIcon::fromTheme(QLatin1String("document-print")); tmpaction = new QAction(icon, tr("&Print..."), this); cmd = am->registerAction(tmpaction, Constants::PRINT, m_globalContext); mfile->addAction(cmd, Constants::G_FILE_PRINT); // Exit Action icon = QIcon::fromTheme(QLatin1String("application-exit")); m_exitAction = new QAction(icon, tr("E&xit"), this); cmd = am->registerAction(m_exitAction, Constants::EXIT, m_globalContext); cmd->setDefaultKeySequence(QKeySequence(tr("Ctrl+Q"))); mfile->addAction(cmd, Constants::G_FILE_OTHER); connect(m_exitAction, SIGNAL(triggered()), this, SLOT(exit())); // Undo Action icon = QIcon::fromTheme(QLatin1String("edit-undo"), QIcon(Constants::ICON_UNDO)); tmpaction = new QAction(icon, tr("&Undo"), this); cmd = am->registerAction(tmpaction, Constants::UNDO, m_globalContext); cmd->setDefaultKeySequence(QKeySequence::Undo); cmd->setAttribute(Command::CA_UpdateText); cmd->setDefaultText(tr("&Undo")); medit->addAction(cmd, Constants::G_EDIT_UNDOREDO); tmpaction->setEnabled(false); // Redo Action icon = QIcon::fromTheme(QLatin1String("edit-redo"), QIcon(Constants::ICON_REDO)); tmpaction = new QAction(icon, tr("&Redo"), this); cmd = am->registerAction(tmpaction, Constants::REDO, m_globalContext); cmd->setDefaultKeySequence(QKeySequence::Redo); cmd->setAttribute(Command::CA_UpdateText); cmd->setDefaultText(tr("&Redo")); medit->addAction(cmd, Constants::G_EDIT_UNDOREDO); tmpaction->setEnabled(false); // Cut Action icon = QIcon::fromTheme(QLatin1String("edit-cut"), QIcon(Constants::ICON_CUT)); tmpaction = new QAction(icon, tr("Cu&t"), this); cmd = am->registerAction(tmpaction, Constants::CUT, m_globalContext); cmd->setDefaultKeySequence(QKeySequence::Cut); medit->addAction(cmd, Constants::G_EDIT_COPYPASTE); tmpaction->setEnabled(false); // Copy Action icon = QIcon::fromTheme(QLatin1String("edit-copy"), QIcon(Constants::ICON_COPY)); tmpaction = new QAction(icon, tr("&Copy"), this); cmd = am->registerAction(tmpaction, Constants::COPY, m_globalContext); cmd->setDefaultKeySequence(QKeySequence::Copy); medit->addAction(cmd, Constants::G_EDIT_COPYPASTE); tmpaction->setEnabled(false); // Paste Action icon = QIcon::fromTheme(QLatin1String("edit-paste"), QIcon(Constants::ICON_PASTE)); tmpaction = new QAction(icon, tr("&Paste"), this); cmd = am->registerAction(tmpaction, Constants::PASTE, m_globalContext); cmd->setDefaultKeySequence(QKeySequence::Paste); medit->addAction(cmd, Constants::G_EDIT_COPYPASTE); tmpaction->setEnabled(false); // Select All icon = QIcon::fromTheme(QLatin1String("edit-select-all")); tmpaction = new QAction(icon, tr("&Select All"), this); cmd = am->registerAction(tmpaction, Constants::SELECTALL, m_globalContext); cmd->setDefaultKeySequence(QKeySequence::SelectAll); medit->addAction(cmd, Constants::G_EDIT_SELECTALL); tmpaction->setEnabled(false); // Goto Action icon = QIcon::fromTheme(QLatin1String("go-jump")); tmpaction = new QAction(icon, tr("&Go To Line..."), this); cmd = am->registerAction(tmpaction, Constants::GOTO, m_globalContext); cmd->setDefaultKeySequence(QKeySequence(tr("Ctrl+L"))); medit->addAction(cmd, Constants::G_EDIT_OTHER); tmpaction->setEnabled(false); // Options Action m_optionsAction = new QAction(tr("&Options..."), this); cmd = am->registerAction(m_optionsAction, Constants::OPTIONS, m_globalContext); #ifdef Q_WS_MAC cmd->setDefaultKeySequence(QKeySequence("Ctrl+,")); cmd->action()->setMenuRole(QAction::PreferencesRole); #endif mtools->addAction(cmd, Constants::G_DEFAULT_THREE); connect(m_optionsAction, SIGNAL(triggered()), this, SLOT(showOptionsDialog())); #ifdef Q_WS_MAC // Minimize Action m_minimizeAction = new QAction(tr("Minimize"), this); cmd = am->registerAction(m_minimizeAction, Constants::MINIMIZE_WINDOW, m_globalContext); cmd->setDefaultKeySequence(QKeySequence("Ctrl+M")); mwindow->addAction(cmd, Constants::G_WINDOW_SIZE); connect(m_minimizeAction, SIGNAL(triggered()), this, SLOT(showMinimized())); // Zoom Action m_zoomAction = new QAction(tr("Zoom"), this); cmd = am->registerAction(m_zoomAction, Constants::ZOOM_WINDOW, m_globalContext); mwindow->addAction(cmd, Constants::G_WINDOW_SIZE); connect(m_zoomAction, SIGNAL(triggered()), this, SLOT(showMaximized())); // Window separator cmd = createSeparator(am, this, QLatin1String("QtCreator.Window.Sep.Size"), m_globalContext); mwindow->addAction(cmd, Constants::G_WINDOW_SIZE); #endif // Show Sidebar Action m_toggleSideBarAction = new QAction(QIcon(Constants::ICON_TOGGLE_SIDEBAR), tr("Show Sidebar"), this); m_toggleSideBarAction->setCheckable(true); cmd = am->registerAction(m_toggleSideBarAction, Constants::TOGGLE_SIDEBAR, m_globalContext); cmd->setAttribute(Command::CA_UpdateText); #ifdef Q_WS_MAC cmd->setDefaultKeySequence(QKeySequence("Ctrl+0")); #else cmd->setDefaultKeySequence(QKeySequence("Alt+0")); #endif connect(m_toggleSideBarAction, SIGNAL(triggered(bool)), this, SLOT(setSidebarVisible(bool))); m_toggleSideBarButton->setDefaultAction(cmd->action()); mwindow->addAction(cmd, Constants::G_WINDOW_PANES); m_toggleSideBarAction->setEnabled(false); #ifndef Q_WS_MAC // Full Screen Action m_toggleFullScreenAction = new QAction(tr("Full Screen"), this); m_toggleFullScreenAction->setCheckable(true); cmd = am->registerAction(m_toggleFullScreenAction, Constants::TOGGLE_FULLSCREEN, m_globalContext); cmd->setDefaultKeySequence(QKeySequence("Ctrl+Shift+F11")); mwindow->addAction(cmd, Constants::G_WINDOW_SIZE); connect(m_toggleFullScreenAction, SIGNAL(triggered(bool)), this, SLOT(setFullScreen(bool))); #endif // About IDE Action icon = QIcon::fromTheme(QLatin1String("help-about")); #ifdef Q_WS_MAC tmpaction = new QAction(icon, tr("About &Qt Creator"), this); // it's convention not to add dots to the about menu #else tmpaction = new QAction(icon, tr("About &Qt Creator..."), this); #endif cmd = am->registerAction(tmpaction, Constants::ABOUT_QTCREATOR, m_globalContext); mhelp->addAction(cmd, Constants::G_HELP_ABOUT); tmpaction->setEnabled(true); #ifdef Q_WS_MAC cmd->action()->setMenuRole(QAction::ApplicationSpecificRole); #endif connect(tmpaction, SIGNAL(triggered()), this, SLOT(aboutQtCreator())); //About Plugins Action tmpaction = new QAction(tr("About &Plugins..."), this); cmd = am->registerAction(tmpaction, Constants::ABOUT_PLUGINS, m_globalContext); mhelp->addAction(cmd, Constants::G_HELP_ABOUT); tmpaction->setEnabled(true); #ifdef Q_WS_MAC cmd->action()->setMenuRole(QAction::ApplicationSpecificRole); #endif connect(tmpaction, SIGNAL(triggered()), this, SLOT(aboutPlugins())); // About Qt Action // tmpaction = new QAction(tr("About &Qt..."), this); // cmd = am->registerAction(tmpaction, Constants:: ABOUT_QT, m_globalContext); // mhelp->addAction(cmd, Constants::G_HELP_ABOUT); // tmpaction->setEnabled(true); // connect(tmpaction, SIGNAL(triggered()), qApp, SLOT(aboutQt())); // About sep #ifndef Q_WS_MAC // doesn't have the "About" actions in the Help menu tmpaction = new QAction(this); tmpaction->setSeparator(true); cmd = am->registerAction(tmpaction, QLatin1String("QtCreator.Help.Sep.About"), m_globalContext); mhelp->addAction(cmd, Constants::G_HELP_ABOUT); #endif } void MainWindow::newFile() { showNewItemDialog(tr("New...", "Title of dialog"), IWizard::allWizards(), QString(), m_coreImpl->newItemDialogPreferredWizardKinds()); } void MainWindow::openFile() { openFiles(editorManager()->getOpenFileNames()); } static QList getNonEditorFileFactories() { const QList allFileFactories = ExtensionSystem::PluginManager::instance()->getObjects(); QList nonEditorFileFactories; foreach (IFileFactory *factory, allFileFactories) { if (!qobject_cast(factory)) nonEditorFileFactories.append(factory); } return nonEditorFileFactories; } static IFileFactory *findFileFactory(const QList &fileFactories, const MimeDatabase *db, const QFileInfo &fi) { if (const MimeType mt = db->findByFile(fi)) { const QString type = mt.type(); foreach (IFileFactory *factory, fileFactories) { if (factory->mimeTypes().contains(type)) return factory; } } return 0; } // opens either an editor or loads a project void MainWindow::openFiles(const QStringList &fileNames) { QList nonEditorFileFactories = getNonEditorFileFactories(); foreach (const QString &fileName, fileNames) { const QFileInfo fi(fileName); const QString absoluteFilePath = fi.absoluteFilePath(); if (IFileFactory *fileFactory = findFileFactory(nonEditorFileFactories, mimeDatabase(), fi)) { fileFactory->open(absoluteFilePath); } else { editorManager()->openEditor(absoluteFilePath); } } } void MainWindow::setFocusToEditor() { QWidget *focusWidget = qApp->focusWidget(); if (!EditorManager::instance()->isVisible()) { m_coreImpl->modeManager()->activateMode(QLatin1String(Constants::MODE_EDIT)); } if (IEditor *editor = m_editorManager->currentEditor()) editor->widget()->setFocus(); bool focusWasAlreadyInEditor = (focusWidget && focusWidget == qApp->focusWidget()); if (!focusWasAlreadyInEditor) { if (OutputPanePlaceHolder::getCurrent() && OutputPanePlaceHolder::getCurrent()->isVisible()) OutputPanePlaceHolder::getCurrent()->unmaximize(); } else { bool stuffVisible = (FindToolBarPlaceHolder::getCurrent() && FindToolBarPlaceHolder::getCurrent()->isVisible()) || (OutputPanePlaceHolder::getCurrent() && OutputPanePlaceHolder::getCurrent()->isVisible()) || (RightPanePlaceHolder::current() && RightPanePlaceHolder::current()->isVisible()); if (stuffVisible) { if (FindToolBarPlaceHolder::getCurrent()) FindToolBarPlaceHolder::getCurrent()->hide(); OutputPaneManager::instance()->slotHide(); RightPaneWidget::instance()->setShown(false); } else { m_coreImpl->modeManager()->activateMode(QLatin1String(Constants::MODE_EDIT)); } } } QStringList MainWindow::showNewItemDialog(const QString &title, const QList &wizards, const QString &defaultLocation, IWizard::WizardKinds preferredWizardKinds) { // Scan for wizards matching the filter and pick one. Don't show // dialog if there is only one. IWizard *wizard = 0; switch (wizards.size()) { case 0: break; case 1: wizard = wizards.front(); break; default: { NewDialog dlg(this); dlg.setWizards(wizards); dlg.setWindowTitle(title); dlg.setPreferredWizardKinds(preferredWizardKinds); wizard = dlg.showDialog(); } break; } if (!wizard) return QStringList(); QString path = defaultLocation; if (path.isEmpty()) { const FileManager *fm = m_coreImpl->fileManager(); switch (wizard->kind()) { case IWizard::ProjectWizard: // Project wizards: Check for projects directory or // use last visited directory of file dialog. Never start // at current. path = fm->useProjectsDirectory() ? fm->projectsDirectory() : fm->fileDialogLastVisitedDirectory(); break; default: path = fm->fileDialogInitialDirectory(); break; } } return wizard->runWizard(path, this); } bool MainWindow::showOptionsDialog(const QString &category, const QString &page, QWidget *parent) { emit m_coreImpl->optionsDialogRequested(); if (!parent) parent = this; SettingsDialog dlg(parent, category, page); return dlg.execDialog(); } void MainWindow::saveAll() { m_fileManager->saveModifiedFilesSilently(m_fileManager->modifiedFiles()); emit m_coreImpl->saveSettingsRequested(); } void MainWindow::exit() { // this function is most likely called from a user action // that is from an event handler of an object // since on close we are going to delete everything // so to prevent the deleting of that object we // just append it QTimer::singleShot(0, this, SLOT(close())); } void MainWindow::openFileWith() { QStringList fileNames = editorManager()->getOpenFileNames(); foreach (const QString &fileName, fileNames) { bool isExternal; const QString editorId = editorManager()->getOpenWithEditorId(fileName, &isExternal); if (editorId.isEmpty()) continue; if (isExternal) { editorManager()->openExternalEditor(fileName, editorId); } else { editorManager()->openEditor(fileName, editorId); } } } ActionManager *MainWindow::actionManager() const { return m_actionManager; } FileManager *MainWindow::fileManager() const { return m_fileManager; } UniqueIDManager *MainWindow::uniqueIDManager() const { return m_uniqueIDManager; } MessageManager *MainWindow::messageManager() const { return m_messageManager; } VCSManager *MainWindow::vcsManager() const { return m_vcsManager; } QSettings *MainWindow::settings(QSettings::Scope scope) const { if (scope == QSettings::UserScope) return m_settings; else return m_globalSettings; } EditorManager *MainWindow::editorManager() const { return m_editorManager; } ProgressManager *MainWindow::progressManager() const { return m_progressManager; } ScriptManager *MainWindow::scriptManager() const { return m_scriptManager; } VariableManager *MainWindow::variableManager() const { return m_variableManager; } ModeManager *MainWindow::modeManager() const { return m_modeManager; } MimeDatabase *MainWindow::mimeDatabase() const { return m_mimeDatabase; } IContext *MainWindow::contextObject(QWidget *widget) { return m_contextWidgets.value(widget); } void MainWindow::addContextObject(IContext *context) { if (!context) return; QWidget *widget = context->widget(); if (m_contextWidgets.contains(widget)) return; m_contextWidgets.insert(widget, context); } void MainWindow::removeContextObject(IContext *context) { if (!context) return; QWidget *widget = context->widget(); if (!m_contextWidgets.contains(widget)) return; m_contextWidgets.remove(widget); if (m_activeContext == context) updateContextObject(0); } void MainWindow::changeEvent(QEvent *e) { QMainWindow::changeEvent(e); if (e->type() == QEvent::ActivationChange) { if (isActiveWindow()) { if (debugMainWindow) qDebug() << "main window activated"; emit windowActivated(); } } else if (e->type() == QEvent::WindowStateChange) { #ifdef Q_WS_MAC bool minimized = isMinimized(); if (debugMainWindow) qDebug() << "main window state changed to minimized=" << minimized; m_minimizeAction->setEnabled(!minimized); m_zoomAction->setEnabled(!minimized); #else bool isFullScreen = (windowState() & Qt::WindowFullScreen) != 0; m_toggleFullScreenAction->setChecked(isFullScreen); #endif } } void MainWindow::updateFocusWidget(QWidget *old, QWidget *now) { Q_UNUSED(old) // Prevent changing the context object just because the menu is activated if (qobject_cast(now)) return; IContext *newContext = 0; if (focusWidget()) { IContext *context = 0; QWidget *p = focusWidget(); while (p) { context = m_contextWidgets.value(p); if (context) { newContext = context; break; } p = p->parentWidget(); } } updateContextObject(newContext); } void MainWindow::updateContextObject(IContext *context) { if (context == m_activeContext) return; IContext *oldContext = m_activeContext; m_activeContext = context; if (!context || oldContext != m_activeContext) { emit m_coreImpl->contextAboutToChange(context); updateContext(); if (debugMainWindow) qDebug() << "new context object =" << context << (context ? context->widget() : 0) << (context ? context->widget()->metaObject()->className() : 0); } } void MainWindow::resetContext() { updateContextObject(0); } void MainWindow::shutdown() { disconnect(QApplication::instance(), SIGNAL(focusChanged(QWidget*,QWidget*)), this, SLOT(updateFocusWidget(QWidget*,QWidget*))); m_activeContext = 0; } static const char *settingsGroup = "MainWindow"; static const char *geometryKey = "Geometry"; static const char *colorKey = "Color"; static const char *maxKey = "Maximized"; static const char *fullScreenKey = "FullScreen"; void MainWindow::readSettings() { m_settings->beginGroup(QLatin1String(settingsGroup)); if (m_overrideColor.isValid()) { Utils::StyleHelper::setBaseColor(m_overrideColor); // Get adapted base color. m_overrideColor = Utils::StyleHelper::baseColor(); } else { Utils::StyleHelper::setBaseColor(m_settings->value(QLatin1String(colorKey)).value()); } const QVariant geom = m_settings->value(QLatin1String(geometryKey)); if (geom.isValid()) { setGeometry(geom.toRect()); } else { resize(1024, 700); } if (m_settings->value(QLatin1String(maxKey), false).toBool()) setWindowState(Qt::WindowMaximized); setFullScreen(m_settings->value(QLatin1String(fullScreenKey), false).toBool()); m_settings->endGroup(); m_editorManager->readSettings(); m_navigationWidget->restoreSettings(m_settings); m_rightPaneWidget->readSettings(m_settings); } void MainWindow::writeSettings() { m_settings->beginGroup(QLatin1String(settingsGroup)); if (!(m_overrideColor.isValid() && Utils::StyleHelper::baseColor() == m_overrideColor)) m_settings->setValue(QLatin1String(colorKey), Utils::StyleHelper::requestedBaseColor()); if (windowState() & (Qt::WindowMaximized | Qt::WindowFullScreen)) { m_settings->setValue(QLatin1String(maxKey), (bool) (windowState() & Qt::WindowMaximized)); m_settings->setValue(QLatin1String(fullScreenKey), (bool) (windowState() & Qt::WindowFullScreen)); } else { m_settings->setValue(QLatin1String(maxKey), false); m_settings->setValue(QLatin1String(fullScreenKey), false); m_settings->setValue(QLatin1String(geometryKey), geometry()); } m_settings->endGroup(); m_fileManager->saveRecentFiles(); m_actionManager->saveSettings(m_settings); m_editorManager->saveSettings(); m_navigationWidget->saveSettings(m_settings); } void MainWindow::updateAdditionalContexts(const QList &remove, const QList &add) { foreach (const int context, remove) { if (context == 0) continue; int index = m_additionalContexts.indexOf(context); if (index != -1) m_additionalContexts.removeAt(index); } foreach (const int context, add) { if (context == 0) continue; if (!m_additionalContexts.contains(context)) m_additionalContexts.prepend(context); } updateContext(); } bool MainWindow::hasContext(int context) const { return m_actionManager->hasContext(context); } void MainWindow::updateContext() { QList contexts; if (m_activeContext) contexts += m_activeContext->context(); contexts += m_additionalContexts; QList uniquecontexts; for (int i = 0; i < contexts.size(); ++i) { const int c = contexts.at(i); if (!uniquecontexts.contains(c)) uniquecontexts << c; } m_actionManager->setContext(uniquecontexts); emit m_coreImpl->contextChanged(m_activeContext, m_additionalContexts); } void MainWindow::aboutToShowRecentFiles() { ActionContainer *aci = m_actionManager->actionContainer(Constants::M_FILE_RECENTFILES); aci->menu()->clear(); bool hasRecentFiles = false; foreach (const QString &fileName, m_fileManager->recentFiles()) { hasRecentFiles = true; QAction *action = aci->menu()->addAction(fileName); action->setData(fileName); connect(action, SIGNAL(triggered()), this, SLOT(openRecentFile())); } aci->menu()->setEnabled(hasRecentFiles); } void MainWindow::openRecentFile() { QAction *action = qobject_cast(sender()); if (!action) return; QString fileName = action->data().toString(); if (!fileName.isEmpty()) { editorManager()->openEditor(fileName); editorManager()->ensureEditorManagerVisible(); } } void MainWindow::aboutQtCreator() { if (!m_versionDialog) { m_versionDialog = new VersionDialog(this); connect(m_versionDialog, SIGNAL(finished(int)), this, SLOT(destroyVersionDialog())); } m_versionDialog->show(); } void MainWindow::destroyVersionDialog() { if (m_versionDialog) { m_versionDialog->deleteLater(); m_versionDialog = 0; } } void MainWindow::aboutPlugins() { PluginDialog dialog(this); dialog.exec(); } QPrinter *MainWindow::printer() const { if (!m_printer) m_printer = new QPrinter(QPrinter::HighResolution); return m_printer; } void MainWindow::setFullScreen(bool on) { if (bool(windowState() & Qt::WindowFullScreen) == on) return; if (on) { setWindowState(windowState() | Qt::WindowFullScreen); //statusBar()->hide(); //menuBar()->hide(); } else { setWindowState(windowState() & ~Qt::WindowFullScreen); //menuBar()->show(); //statusBar()->show(); } } // Display a warning with an additional button to open // the debugger settings dialog if settingsId is nonempty. bool MainWindow::showWarningWithOptions(const QString &title, const QString &text, const QString &details, const QString &settingsCategory, const QString &settingsId, QWidget *parent) { if (parent == 0) parent = this; QMessageBox msgBox(QMessageBox::Warning, title, text, QMessageBox::Ok, parent); if (details.isEmpty()) msgBox.setDetailedText(details); QAbstractButton *settingsButton = 0; if (!settingsId.isEmpty() || !settingsCategory.isEmpty()) settingsButton = msgBox.addButton(tr("Settings..."), QMessageBox::AcceptRole); msgBox.exec(); if (settingsButton && msgBox.clickedButton() == settingsButton) { return showOptionsDialog(settingsCategory, settingsId); } return false; }