mainwindow.cpp 46.4 KB
Newer Older
hjk's avatar
hjk committed
1
/****************************************************************************
con's avatar
con committed
2
**
3
** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
hjk's avatar
hjk committed
4
** Contact: http://www.qt-project.org/legal
con's avatar
con committed
5
**
hjk's avatar
hjk committed
6
** This file is part of Qt Creator.
con's avatar
con committed
7
**
hjk's avatar
hjk committed
8 9 10 11 12 13 14
** Commercial License Usage
** Licensees holding valid commercial Qt licenses may use this file in
** accordance with the commercial license agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
** a written agreement between you and Digia.  For licensing terms and
** conditions see http://qt.digia.com/licensing.  For further information
** use the contact form at http://qt.digia.com/contact-us.
15
**
16
** GNU Lesser General Public License Usage
hjk's avatar
hjk committed
17 18 19 20 21 22 23 24 25
** 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.
**
** In addition, as a special exception, Digia gives you certain additional
** rights.  These rights are described in the Digia Qt LGPL Exception
con's avatar
con committed
26 27
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
**
hjk's avatar
hjk committed
28
****************************************************************************/
con's avatar
con committed
29 30

#include "mainwindow.h"
31
#include "actioncontainer.h"
32
#include "command.h"
Eike Ziller's avatar
Eike Ziller committed
33
#include "actionmanager.h"
34
#include "actionmanager_p.h"
hjk's avatar
hjk committed
35
#include "icore.h"
con's avatar
con committed
36 37
#include "coreconstants.h"
#include "editormanager.h"
38
#include "toolsettings.h"
39
#include "mimetypesettings.h"
con's avatar
con committed
40
#include "fancytabwidget.h"
41
#include "documentmanager.h"
con's avatar
con committed
42
#include "generalsettings.h"
kh1's avatar
kh1 committed
43
#include "helpmanager.h"
44
#include "ieditor.h"
45
#include "idocumentfactory.h"
con's avatar
con committed
46 47 48 49
#include "messagemanager.h"
#include "modemanager.h"
#include "mimedatabase.h"
#include "newdialog.h"
50
#include "outputpanemanager.h"
con's avatar
con committed
51
#include "plugindialog.h"
52
#include "progressmanager_p.h"
53
#include "progressview.h"
con's avatar
con committed
54 55
#include "shortcutsettings.h"
#include "vcsmanager.h"
56
#include "scriptmanager_p.h"
con's avatar
con committed
57 58 59
#include "settingsdialog.h"
#include "variablemanager.h"
#include "versiondialog.h"
con's avatar
con committed
60
#include "statusbarmanager.h"
61
#include "id.h"
con's avatar
con committed
62 63 64 65
#include "manhattanstyle.h"
#include "navigationwidget.h"
#include "rightpane.h"
#include "editormanager/ieditorfactory.h"
66
#include "statusbarwidget.h"
67
#include "externaltoolmanager.h"
68
#include "editormanager/systemeditor.h"
con's avatar
con committed
69

70 71 72 73
#if defined(Q_OS_MAC)
#include "macfullscreen.h"
#endif

74
#include <app/app_version.h>
75
#include <coreplugin/icorelistener.h>
76
#include <coreplugin/inavigationwidgetfactory.h>
77
#include <coreplugin/settingsdatabase.h>
hjk's avatar
hjk committed
78
#include <utils/historycompleter.h>
79
#include <utils/hostosinfo.h>
80
#include <utils/stylehelper.h>
81
#include <utils/stringutils.h>
82
#include <extensionsystem/pluginmanager.h>
con's avatar
con committed
83

84 85 86 87 88 89 90
#include <QDebug>
#include <QFileInfo>
#include <QSettings>
#include <QTimer>
#include <QUrl>
#include <QDir>
#include <QMimeData>
con's avatar
con committed
91

92 93 94 95 96 97 98 99 100 101
#include <QApplication>
#include <QCloseEvent>
#include <QMenu>
#include <QPrinter>
#include <QShortcut>
#include <QStatusBar>
#include <QToolButton>
#include <QMessageBox>
#include <QMenuBar>
#include <QPushButton>
102
#include <QStyleFactory>
con's avatar
con committed
103 104 105 106 107

/*
#include <signal.h>
extern "C" void handleSigInt(int sig)
{
108
    Q_UNUSED(sig)
hjk's avatar
hjk committed
109
    Core::ICore::exit();
con's avatar
con committed
110 111 112 113 114 115 116
    qDebug() << "SIGINT caught. Shutting down.";
}
*/

using namespace Core;
using namespace Core::Internal;

117
enum { debugMainWindow = 0 };
con's avatar
con committed
118 119

MainWindow::MainWindow() :
120
    Utils::AppMainWindow(),
hjk's avatar
hjk committed
121
    m_coreImpl(new ICore(this)),
122
    m_additionalContexts(Constants::C_GLOBAL),
123 124
    m_settings(ExtensionSystem::PluginManager::settings()),
    m_globalSettings(ExtensionSystem::PluginManager::globalSettings()),
125 126 127
    m_settingsDatabase(new SettingsDatabase(QFileInfo(m_settings->fileName()).path(),
                                            QLatin1String("QtCreator"),
                                            this)),
con's avatar
con committed
128
    m_printer(0),
Eike Ziller's avatar
Eike Ziller committed
129
    m_actionManager(new ActionManager(this)),
con's avatar
con committed
130
    m_editorManager(0),
131
    m_externalToolManager(0),
132
    m_progressManager(new ProgressManagerPrivate()),
133
    m_scriptManager(new ScriptManagerPrivate(this)),
Friedemann Kleint's avatar
Friedemann Kleint committed
134
    m_variableManager(new VariableManager),
hjk's avatar
hjk committed
135
    m_vcsManager(new VcsManager),
con's avatar
con committed
136
    m_statusBarManager(0),
con's avatar
con committed
137 138
    m_modeManager(0),
    m_mimeDatabase(new MimeDatabase),
kh1's avatar
kh1 committed
139
    m_helpManager(new HelpManager),
140
    m_modeStack(new FancyTabWidget(this)),
con's avatar
con committed
141 142
    m_navigationWidget(0),
    m_rightPaneWidget(0),
143
    m_versionDialog(0),
con's avatar
con committed
144 145
    m_generalSettings(new GeneralSettings),
    m_shortcutSettings(new ShortcutSettings),
146
    m_toolSettings(new ToolSettings),
147
    m_mimeTypeSettings(new MimeTypeSettings),
148
    m_systemEditor(new SystemEditor),
con's avatar
con committed
149 150 151 152 153 154 155 156
    m_focusToEditor(0),
    m_newAction(0),
    m_openAction(0),
    m_openWithAction(0),
    m_saveAllAction(0),
    m_exitAction(0),
    m_optionsAction(0),
    m_toggleSideBarAction(0),
hjk's avatar
hjk committed
157
    m_toggleFullScreenAction(0),
con's avatar
con committed
158 159 160 161
    m_minimizeAction(0),
    m_zoomAction(0),
    m_toggleSideBarButton(new QToolButton)
{
162
    (void) new DocumentManager(this);
163 164
    OutputPaneManager::create();

hjk's avatar
hjk committed
165 166
    Utils::HistoryCompleter::setSettings(m_settings);

con's avatar
con committed
167
    setWindowTitle(tr("Qt Creator"));
168 169
    if (!Utils::HostOsInfo::isMacHost())
        QApplication::setWindowIcon(QIcon(QLatin1String(Constants::ICON_QTLOGO_128)));
170 171
    QCoreApplication::setApplicationName(QLatin1String("QtCreator"));
    QCoreApplication::setApplicationVersion(QLatin1String(Core::Constants::IDE_VERSION_LONG));
172
    QCoreApplication::setOrganizationName(QLatin1String(Constants::IDE_SETTINGSVARIANT_STR));
173
    QString baseName = QApplication::style()->objectName();
174 175 176
    if (Utils::HostOsInfo::isAnyUnixHost() && !Utils::HostOsInfo::isMacHost()) {
        if (baseName == QLatin1String("windows")) {
            // Sometimes we get the standard windows 95 style as a fallback
177
            if (QStyleFactory::keys().contains(QLatin1String("Fusion")))
178 179 180 181 182 183 184 185 186
                baseName = QLatin1String("fusion"); // Qt5
            else { // Qt4
                // 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");
            }
187
        }
188 189 190
    }
    qApp->setStyle(new ManhattanStyle(baseName));

con's avatar
con committed
191 192 193 194 195
    setDockNestingEnabled(true);

    setCorner(Qt::BottomLeftCorner, Qt::LeftDockWidgetArea);
    setCorner(Qt::BottomRightCorner, Qt::BottomDockWidgetArea);

196 197
    m_modeManager = new ModeManager(this, m_modeStack);

con's avatar
con committed
198 199 200 201 202 203
    registerDefaultContainers();
    registerDefaultActions();

    m_navigationWidget = new NavigationWidget(m_toggleSideBarAction);
    m_rightPaneWidget = new RightPaneWidget();

con's avatar
con committed
204
    m_statusBarManager = new StatusBarManager(this);
con's avatar
con committed
205
    m_messageManager = new MessageManager;
hjk's avatar
hjk committed
206
    m_editorManager = new EditorManager(this);
con's avatar
con committed
207
    m_editorManager->hide();
hjk's avatar
hjk committed
208
    m_externalToolManager = new ExternalToolManager();
con's avatar
con committed
209 210
    setCentralWidget(m_modeStack);

211 212 213
    m_progressManager->progressView()->setParent(this);
    m_progressManager->progressView()->setReferenceWidget(m_modeStack->statusBar());

con's avatar
con committed
214 215 216 217 218 219
    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);
220 221
    //if (Utils::HostOsInfo::isAnyUnixHost())
        //signal(SIGINT, handleSigInt);
con's avatar
con committed
222 223

    statusBar()->setProperty("p_styled", true);
224
    setAcceptDrops(true);
225 226 227 228

#if defined(Q_OS_MAC)
    MacFullScreen::addFullScreen(this);
#endif
con's avatar
con committed
229 230
}

231
void MainWindow::setSidebarVisible(bool visible)
con's avatar
con committed
232 233
{
    if (NavigationWidgetPlaceHolder::current()) {
234
        if (m_navigationWidget->isSuppressed() && visible) {
con's avatar
con committed
235 236 237
            m_navigationWidget->setShown(true);
            m_navigationWidget->setSuppressed(false);
        } else {
238
            m_navigationWidget->setShown(visible);
con's avatar
con committed
239 240 241 242 243 244
        }
    }
}

void MainWindow::setSuppressNavigationWidget(bool suppress)
{
hjk's avatar
hjk committed
245
    if (NavigationWidgetPlaceHolder::current())
con's avatar
con committed
246 247 248
        m_navigationWidget->setSuppressed(suppress);
}

249 250 251 252 253
void MainWindow::setOverrideColor(const QColor &color)
{
    m_overrideColor = color;
}

254 255 256 257 258 259 260 261
void MainWindow::setIsFullScreen(bool fullScreen)
{
    if (fullScreen)
        m_toggleFullScreenAction->setText(tr("Exit Full Screen"));
    else
        m_toggleFullScreenAction->setText(tr("Enter Full Screen"));
}

con's avatar
con committed
262 263
MainWindow::~MainWindow()
{
264 265 266 267 268
    ExtensionSystem::PluginManager::removeObject(m_shortcutSettings);
    ExtensionSystem::PluginManager::removeObject(m_generalSettings);
    ExtensionSystem::PluginManager::removeObject(m_toolSettings);
    ExtensionSystem::PluginManager::removeObject(m_mimeTypeSettings);
    ExtensionSystem::PluginManager::removeObject(m_systemEditor);
269 270
    delete m_externalToolManager;
    m_externalToolManager = 0;
con's avatar
con committed
271 272 273 274 275 276
    delete m_messageManager;
    m_messageManager = 0;
    delete m_shortcutSettings;
    m_shortcutSettings = 0;
    delete m_generalSettings;
    m_generalSettings = 0;
277 278
    delete m_toolSettings;
    m_toolSettings = 0;
279 280
    delete m_mimeTypeSettings;
    m_mimeTypeSettings = 0;
281 282
    delete m_systemEditor;
    m_systemEditor = 0;
con's avatar
con committed
283 284 285 286 287 288
    delete m_settings;
    m_settings = 0;
    delete m_printer;
    m_printer = 0;
    delete m_vcsManager;
    m_vcsManager = 0;
con's avatar
con committed
289
    //we need to delete editormanager and statusbarmanager explicitly before the end of the destructor,
con's avatar
con committed
290 291 292
    //because they might trigger stuff that tries to access data from editorwindow, like removeContextWidget

    // All modes are now gone
293
    OutputPaneManager::destroy();
con's avatar
con committed
294

295
    // Now that the OutputPaneManager is gone, is a good time to delete the view
296
    ExtensionSystem::PluginManager::removeObject(m_outputView);
con's avatar
con committed
297 298 299 300 301 302
    delete m_outputView;

    delete m_editorManager;
    m_editorManager = 0;
    delete m_progressManager;
    m_progressManager = 0;
303 304
    delete m_statusBarManager;
    m_statusBarManager = 0;
305
    ExtensionSystem::PluginManager::removeObject(m_coreImpl);
con's avatar
con committed
306 307 308 309 310 311 312 313 314 315
    delete m_coreImpl;
    m_coreImpl = 0;

    delete m_rightPaneWidget;
    m_rightPaneWidget = 0;

    delete m_modeManager;
    m_modeManager = 0;
    delete m_mimeDatabase;
    m_mimeDatabase = 0;
kh1's avatar
kh1 committed
316 317 318

    delete m_helpManager;
    m_helpManager = 0;
con's avatar
con committed
319 320
}

321
bool MainWindow::init(QString *errorMessage)
con's avatar
con committed
322
{
323
    Q_UNUSED(errorMessage)
324

325 326 327
    if (!mimeDatabase()->addMimeTypes(QLatin1String(":/core/editormanager/BinFiles.mimetypes.xml"), errorMessage))
        return false;

328
    ExtensionSystem::PluginManager::addObject(m_coreImpl);
con's avatar
con committed
329
    m_statusBarManager->init();
con's avatar
con committed
330
    m_modeManager->init();
331
    m_progressManager->init(); // needs the status bar manager
con's avatar
con committed
332

333 334 335 336 337
    ExtensionSystem::PluginManager::addObject(m_generalSettings);
    ExtensionSystem::PluginManager::addObject(m_shortcutSettings);
    ExtensionSystem::PluginManager::addObject(m_toolSettings);
    ExtensionSystem::PluginManager::addObject(m_mimeTypeSettings);
    ExtensionSystem::PluginManager::addObject(m_systemEditor);
338

339
    // Add widget to the bottom, we create the view here instead of inside the
Tobias Hunger's avatar
Tobias Hunger committed
340
    // OutputPaneManager, since the StatusBarManager needs to be initialized before
341
    m_outputView = new Core::StatusBarWidget;
342
    m_outputView->setWidget(OutputPaneManager::instance()->buttonsWidget());
343
    m_outputView->setPosition(Core::StatusBarWidget::Second);
344
    ExtensionSystem::PluginManager::addObject(m_outputView);
345
    m_messageManager->init();
con's avatar
con committed
346 347 348 349 350 351
    return true;
}

void MainWindow::extensionsInitialized()
{
    m_editorManager->init();
con's avatar
con committed
352
    m_statusBarManager->extensionsInitalized();
353
    OutputPaneManager::instance()->init();
354
    m_vcsManager->extensionsInitialized();
355
    m_navigationWidget->setFactories(ExtensionSystem::PluginManager::getObjects<INavigationWidgetFactory>());
356

357
    // reading the shortcut settings must be done after all shortcuts have been registered
Eike Ziller's avatar
Eike Ziller committed
358
    m_actionManager->d->initialize();
359

con's avatar
con committed
360 361 362
    readSettings();
    updateContext();

363 364
    emit m_coreImpl->coreAboutToOpen();
    show();
con's avatar
con committed
365 366 367 368 369
    emit m_coreImpl->coreOpened();
}

void MainWindow::closeEvent(QCloseEvent *event)
{
Tobias Hunger's avatar
Tobias Hunger committed
370
    ICore::saveSettings();
con's avatar
con committed
371 372 373

    // Save opened files
    bool cancelled;
374
    QList<IDocument*> notSaved = DocumentManager::saveModifiedDocuments(DocumentManager::modifiedDocuments(), &cancelled);
375
    if (cancelled || !notSaved.isEmpty()) {
con's avatar
con committed
376 377 378 379 380
        event->ignore();
        return;
    }

    const QList<ICoreListener *> listeners =
381
        ExtensionSystem::PluginManager::getObjects<ICoreListener>();
con's avatar
con committed
382 383 384 385 386 387 388 389
    foreach (ICoreListener *listener, listeners) {
        if (!listener->coreAboutToClose()) {
            event->ignore();
            return;
        }
    }

    emit m_coreImpl->coreAboutToClose();
390

con's avatar
con committed
391
    writeSettings();
392 393 394

    m_navigationWidget->closeSubWidgets();

con's avatar
con committed
395 396 397
    event->accept();
}

398 399 400 401 402 403 404
// 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.
405
    if (!d->hasUrls())
406 407 408 409 410 411 412 413 414 415 416
        return false;
    const QList<QUrl> urls = d->urls();
    if (urls.empty())
        return false;
    // Try to find local files
    bool hasFiles = false;
    const QList<QUrl>::const_iterator cend = urls.constEnd();
    for (QList<QUrl>::const_iterator it = urls.constBegin(); it != cend; ++it) {
        const QString fileName = it->toLocalFile();
        if (!fileName.isEmpty()) {
            hasFiles = true;
417
            if (files)
418
                files->push_back(fileName);
419
            else
420 421 422 423 424 425 426 427
                break; // No result list, sufficient for checking
        }
    }
    return hasFiles;
}

void MainWindow::dragEnterEvent(QDragEnterEvent *event)
{
428
    if (isDesktopFileManagerDrop(event->mimeData()) && m_filesToOpenDelayed.isEmpty())
429
        event->accept();
430
    else
431 432 433 434 435 436 437 438
        event->ignore();
}

void MainWindow::dropEvent(QDropEvent *event)
{
    QStringList files;
    if (isDesktopFileManagerDrop(event->mimeData(), &files)) {
        event->accept();
439 440
        m_filesToOpenDelayed.append(files);
        QTimer::singleShot(50, this, SLOT(openDelayedFiles()));
441 442 443 444 445
    } else {
        event->ignore();
    }
}

446 447 448 449
void MainWindow::openDelayedFiles()
{
    if (m_filesToOpenDelayed.isEmpty())
        return;
450
    raiseWindow();
451 452 453 454
    openFiles(m_filesToOpenDelayed, ICore::SwitchMode);
    m_filesToOpenDelayed.clear();
}

con's avatar
con committed
455 456
IContext *MainWindow::currentContextObject() const
{
457
    return m_activeContext.isEmpty() ? 0 : m_activeContext.first();
con's avatar
con committed
458 459 460 461 462 463 464 465 466
}

QStatusBar *MainWindow::statusBar() const
{
    return m_modeStack->statusBar();
}

void MainWindow::registerDefaultContainers()
{
Eike Ziller's avatar
Eike Ziller committed
467
    ActionContainer *menubar = ActionManager::createMenuBar(Constants::MENU_BAR);
con's avatar
con committed
468

469 470
    if (!Utils::HostOsInfo::isMacHost()) // System menu bar on Mac
        setMenuBar(menubar->menuBar());
con's avatar
con committed
471 472 473 474 475 476 477
    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);

478
    // File Menu
Eike Ziller's avatar
Eike Ziller committed
479
    ActionContainer *filemenu = ActionManager::createMenu(Constants::M_FILE);
con's avatar
con committed
480 481 482 483 484 485 486 487 488 489 490 491
    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()));


492
    // Edit Menu
Eike Ziller's avatar
Eike Ziller committed
493
    ActionContainer *medit = ActionManager::createMenu(Constants::M_EDIT);
con's avatar
con committed
494 495 496 497 498
    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);
499
    medit->appendGroup(Constants::G_EDIT_ADVANCED);
500
    medit->appendGroup(Constants::G_EDIT_FIND);
con's avatar
con committed
501 502
    medit->appendGroup(Constants::G_EDIT_OTHER);

503
    // Tools Menu
Eike Ziller's avatar
Eike Ziller committed
504
    ActionContainer *ac = ActionManager::createMenu(Constants::M_TOOLS);
con's avatar
con committed
505 506 507
    menubar->addMenu(ac, Constants::G_TOOLS);
    ac->menu()->setTitle(tr("&Tools"));

508
    // Window Menu
Eike Ziller's avatar
Eike Ziller committed
509
    ActionContainer *mwindow = ActionManager::createMenu(Constants::M_WINDOW);
con's avatar
con committed
510 511 512
    menubar->addMenu(mwindow, Constants::G_WINDOW);
    mwindow->menu()->setTitle(tr("&Window"));
    mwindow->appendGroup(Constants::G_WINDOW_SIZE);
513
    mwindow->appendGroup(Constants::G_WINDOW_VIEWS);
con's avatar
con committed
514 515 516 517 518
    mwindow->appendGroup(Constants::G_WINDOW_PANES);
    mwindow->appendGroup(Constants::G_WINDOW_SPLIT);
    mwindow->appendGroup(Constants::G_WINDOW_NAVIGATE);
    mwindow->appendGroup(Constants::G_WINDOW_OTHER);

519
    // Help Menu
Eike Ziller's avatar
Eike Ziller committed
520
    ac = ActionManager::createMenu(Constants::M_HELP);
con's avatar
con committed
521 522
    menubar->addMenu(ac, Constants::G_HELP);
    ac->menu()->setTitle(tr("&Help"));
523 524
    ac->appendGroup(Constants::G_HELP_HELP);
    ac->appendGroup(Constants::G_HELP_ABOUT);
con's avatar
con committed
525 526 527 528
}

void MainWindow::registerDefaultActions()
{
Eike Ziller's avatar
Eike Ziller committed
529 530 531 532 533
    ActionContainer *mfile = ActionManager::actionContainer(Constants::M_FILE);
    ActionContainer *medit = ActionManager::actionContainer(Constants::M_EDIT);
    ActionContainer *mtools = ActionManager::actionContainer(Constants::M_TOOLS);
    ActionContainer *mwindow = ActionManager::actionContainer(Constants::M_WINDOW);
    ActionContainer *mhelp = ActionManager::actionContainer(Constants::M_HELP);
con's avatar
con committed
534

535 536
    Context globalContext(Constants::C_GLOBAL);

con's avatar
con committed
537
    // File menu separators
538 539 540 541
    mfile->addSeparator(globalContext, Constants::G_FILE_SAVE);
    mfile->addSeparator(globalContext, Constants::G_FILE_PRINT);
    mfile->addSeparator(globalContext, Constants::G_FILE_CLOSE);
    mfile->addSeparator(globalContext, Constants::G_FILE_OTHER);
con's avatar
con committed
542
    // Edit menu separators
543 544 545 546
    medit->addSeparator(globalContext, Constants::G_EDIT_COPYPASTE);
    medit->addSeparator(globalContext, Constants::G_EDIT_SELECTALL);
    medit->addSeparator(globalContext, Constants::G_EDIT_FIND);
    medit->addSeparator(globalContext, Constants::G_EDIT_ADVANCED);
con's avatar
con committed
547

548
    // Return to editor shortcut: Note this requires Qt to fix up
con's avatar
con committed
549 550
    // handling of shortcut overrides in menus, item views, combos....
    m_focusToEditor = new QShortcut(this);
551
    Command *cmd = ActionManager::registerShortcut(m_focusToEditor, Constants::S_RETURNTOEDITOR, globalContext);
con's avatar
con committed
552 553 554
    cmd->setDefaultKeySequence(QKeySequence(Qt::Key_Escape));
    connect(m_focusToEditor, SIGNAL(activated()), this, SLOT(setFocusToEditor()));

555
    // New File Action
556
    QIcon icon = QIcon::fromTheme(QLatin1String("document-new"), QIcon(QLatin1String(Constants::ICON_NEWFILE)));
557
    m_newAction = new QAction(icon, tr("&New File or Project..."), this);
Eike Ziller's avatar
Eike Ziller committed
558
    cmd = ActionManager::registerAction(m_newAction, Constants::NEW, globalContext);
con's avatar
con committed
559 560 561 562
    cmd->setDefaultKeySequence(QKeySequence::New);
    mfile->addAction(cmd, Constants::G_FILE_NEW);
    connect(m_newAction, SIGNAL(triggered()), this, SLOT(newFile()));

563
    // Open Action
564
    icon = QIcon::fromTheme(QLatin1String("document-open"), QIcon(QLatin1String(Constants::ICON_OPENFILE)));
565
    m_openAction = new QAction(icon, tr("&Open File or Project..."), this);
Eike Ziller's avatar
Eike Ziller committed
566
    cmd = ActionManager::registerAction(m_openAction, Constants::OPEN, globalContext);
con's avatar
con committed
567 568 569 570
    cmd->setDefaultKeySequence(QKeySequence::Open);
    mfile->addAction(cmd, Constants::G_FILE_OPEN);
    connect(m_openAction, SIGNAL(triggered()), this, SLOT(openFile()));

571
    // Open With Action
572
    m_openWithAction = new QAction(tr("Open File &With..."), this);
Eike Ziller's avatar
Eike Ziller committed
573
    cmd = ActionManager::registerAction(m_openWithAction, Constants::OPEN_WITH, globalContext);
con's avatar
con committed
574 575 576
    mfile->addAction(cmd, Constants::G_FILE_OPEN);
    connect(m_openWithAction, SIGNAL(triggered()), this, SLOT(openFileWith()));

577
    // File->Recent Files Menu
Eike Ziller's avatar
Eike Ziller committed
578
    ActionContainer *ac = ActionManager::createMenu(Constants::M_FILE_RECENTFILES);
con's avatar
con committed
579
    mfile->addMenu(ac, Constants::G_FILE_OPEN);
580
    ac->menu()->setTitle(tr("Recent &Files"));
581
    ac->setOnAllDisabledBehavior(ActionContainer::Show);
con's avatar
con committed
582

583
    // Save Action
584
    icon = QIcon::fromTheme(QLatin1String("document-save"), QIcon(QLatin1String(Constants::ICON_SAVEFILE)));
585
    QAction *tmpaction = new QAction(icon, tr("&Save"), this);
586
    tmpaction->setEnabled(false);
Eike Ziller's avatar
Eike Ziller committed
587
    cmd = ActionManager::registerAction(tmpaction, Constants::SAVE, globalContext);
con's avatar
con committed
588
    cmd->setDefaultKeySequence(QKeySequence::Save);
con's avatar
con committed
589
    cmd->setAttribute(Command::CA_UpdateText);
590
    cmd->setDescription(tr("Save"));
con's avatar
con committed
591 592
    mfile->addAction(cmd, Constants::G_FILE_SAVE);

593
    // Save As Action
594 595
    icon = QIcon::fromTheme(QLatin1String("document-save-as"));
    tmpaction = new QAction(icon, tr("Save &As..."), this);
596
    tmpaction->setEnabled(false);
Eike Ziller's avatar
Eike Ziller committed
597
    cmd = ActionManager::registerAction(tmpaction, Constants::SAVEAS, globalContext);
598
    cmd->setDefaultKeySequence(QKeySequence(UseMacShortcuts ? tr("Ctrl+Shift+S") : QString()));
con's avatar
con committed
599
    cmd->setAttribute(Command::CA_UpdateText);
600
    cmd->setDescription(tr("Save As..."));
con's avatar
con committed
601 602
    mfile->addAction(cmd, Constants::G_FILE_SAVE);

603
    // SaveAll Action
con's avatar
con committed
604
    m_saveAllAction = new QAction(tr("Save A&ll"), this);
Eike Ziller's avatar
Eike Ziller committed
605
    cmd = ActionManager::registerAction(m_saveAllAction, Constants::SAVEALL, globalContext);
606
    cmd->setDefaultKeySequence(QKeySequence(UseMacShortcuts ? QString() : tr("Ctrl+Shift+S")));
con's avatar
con committed
607 608 609
    mfile->addAction(cmd, Constants::G_FILE_SAVE);
    connect(m_saveAllAction, SIGNAL(triggered()), this, SLOT(saveAll()));

610
    // Print Action
611 612
    icon = QIcon::fromTheme(QLatin1String("document-print"));
    tmpaction = new QAction(icon, tr("&Print..."), this);
613
    tmpaction->setEnabled(false);
Eike Ziller's avatar
Eike Ziller committed
614
    cmd = ActionManager::registerAction(tmpaction, Constants::PRINT, globalContext);
615
    cmd->setDefaultKeySequence(QKeySequence::Print);
con's avatar
con committed
616 617
    mfile->addAction(cmd, Constants::G_FILE_PRINT);

618
    // Exit Action
619 620
    icon = QIcon::fromTheme(QLatin1String("application-exit"));
    m_exitAction = new QAction(icon, tr("E&xit"), this);
Eike Ziller's avatar
Eike Ziller committed
621
    cmd = ActionManager::registerAction(m_exitAction, Constants::EXIT, globalContext);
con's avatar
con committed
622 623 624 625
    cmd->setDefaultKeySequence(QKeySequence(tr("Ctrl+Q")));
    mfile->addAction(cmd, Constants::G_FILE_OTHER);
    connect(m_exitAction, SIGNAL(triggered()), this, SLOT(exit()));

626
    // Undo Action
627
    icon = QIcon::fromTheme(QLatin1String("edit-undo"), QIcon(QLatin1String(Constants::ICON_UNDO)));
628
    tmpaction = new QAction(icon, tr("&Undo"), this);
Eike Ziller's avatar
Eike Ziller committed
629
    cmd = ActionManager::registerAction(tmpaction, Constants::UNDO, globalContext);
con's avatar
con committed
630
    cmd->setDefaultKeySequence(QKeySequence::Undo);
con's avatar
con committed
631
    cmd->setAttribute(Command::CA_UpdateText);
632
    cmd->setDescription(tr("Undo"));
con's avatar
con committed
633
    medit->addAction(cmd, Constants::G_EDIT_UNDOREDO);
634
    tmpaction->setEnabled(false);
con's avatar
con committed
635

636
    // Redo Action
637
    icon = QIcon::fromTheme(QLatin1String("edit-redo"), QIcon(QLatin1String(Constants::ICON_REDO)));
638
    tmpaction = new QAction(icon, tr("&Redo"), this);
Eike Ziller's avatar
Eike Ziller committed
639
    cmd = ActionManager::registerAction(tmpaction, Constants::REDO, globalContext);
con's avatar
con committed
640
    cmd->setDefaultKeySequence(QKeySequence::Redo);
con's avatar
con committed
641
    cmd->setAttribute(Command::CA_UpdateText);
642
    cmd->setDescription(tr("Redo"));
con's avatar
con committed
643
    medit->addAction(cmd, Constants::G_EDIT_UNDOREDO);
644
    tmpaction->setEnabled(false);
con's avatar
con committed
645

646
    // Cut Action
647
    icon = QIcon::fromTheme(QLatin1String("edit-cut"), QIcon(QLatin1String(Constants::ICON_CUT)));
648
    tmpaction = new QAction(icon, tr("Cu&t"), this);
Eike Ziller's avatar
Eike Ziller committed
649
    cmd = ActionManager::registerAction(tmpaction, Constants::CUT, globalContext);
con's avatar
con committed
650 651
    cmd->setDefaultKeySequence(QKeySequence::Cut);
    medit->addAction(cmd, Constants::G_EDIT_COPYPASTE);
652
    tmpaction->setEnabled(false);
con's avatar
con committed
653

654
    // Copy Action
655
    icon = QIcon::fromTheme(QLatin1String("edit-copy"), QIcon(QLatin1String(Constants::ICON_COPY)));
656
    tmpaction = new QAction(icon, tr("&Copy"), this);
Eike Ziller's avatar
Eike Ziller committed
657
    cmd = ActionManager::registerAction(tmpaction, Constants::COPY, globalContext);
con's avatar
con committed
658 659
    cmd->setDefaultKeySequence(QKeySequence::Copy);
    medit->addAction(cmd, Constants::G_EDIT_COPYPASTE);
660
    tmpaction->setEnabled(false);
con's avatar
con committed
661

662
    // Paste Action
663
    icon = QIcon::fromTheme(QLatin1String("edit-paste"), QIcon(QLatin1String(Constants::ICON_PASTE)));
664
    tmpaction = new QAction(icon, tr("&Paste"), this);
Eike Ziller's avatar
Eike Ziller committed
665
    cmd = ActionManager::registerAction(tmpaction, Constants::PASTE, globalContext);
con's avatar
con committed
666 667
    cmd->setDefaultKeySequence(QKeySequence::Paste);
    medit->addAction(cmd, Constants::G_EDIT_COPYPASTE);
668
    tmpaction->setEnabled(false);
con's avatar
con committed
669

670
    // Select All
671
    icon = QIcon::fromTheme(QLatin1String("edit-select-all"));
con's avatar
con committed
672
    tmpaction = new QAction(icon, tr("Select &All"), this);
Eike Ziller's avatar
Eike Ziller committed
673
    cmd = ActionManager::registerAction(tmpaction, Constants::SELECTALL, globalContext);
con's avatar
con committed
674 675
    cmd->setDefaultKeySequence(QKeySequence::SelectAll);
    medit->addAction(cmd, Constants::G_EDIT_SELECTALL);
676
    tmpaction->setEnabled(false);
con's avatar
con committed
677

678
    // Goto Action
679
    icon = QIcon::fromTheme(QLatin1String("go-jump"));
680
    tmpaction = new QAction(icon, tr("&Go to Line..."), this);
Eike Ziller's avatar
Eike Ziller committed
681
    cmd = ActionManager::registerAction(tmpaction, Constants::GOTO, globalContext);
con's avatar
con committed
682 683
    cmd->setDefaultKeySequence(QKeySequence(tr("Ctrl+L")));
    medit->addAction(cmd, Constants::G_EDIT_OTHER);
684
    tmpaction->setEnabled(false);
con's avatar
con committed
685

686
    // Options Action
con's avatar
con committed
687
    mtools->appendGroup(Constants::G_TOOLS_OPTIONS);
688
    mtools->addSeparator(globalContext, Constants::G_TOOLS_OPTIONS);
con's avatar
con committed
689
    m_optionsAction = new QAction(tr("&Options..."), this);
Eike Ziller's avatar
Eike Ziller committed
690
    cmd = ActionManager::registerAction(m_optionsAction, Constants::OPTIONS, globalContext);
691 692 693 694
    if (UseMacShortcuts) {
        cmd->setDefaultKeySequence(QKeySequence(tr("Ctrl+,")));
        cmd->action()->setMenuRole(QAction::PreferencesRole);
    }
con's avatar
con committed
695
    mtools->addAction(cmd, Constants::G_TOOLS_OPTIONS);
con's avatar
con committed
696 697
    connect(m_optionsAction, SIGNAL(triggered()), this, SLOT(showOptionsDialog()));

698 699 700
    if (UseMacShortcuts) {
        // Minimize Action
        m_minimizeAction = new QAction(tr("Minimize"), this);
Eike Ziller's avatar
Eike Ziller committed
701
        cmd = ActionManager::registerAction(m_minimizeAction, Constants::MINIMIZE_WINDOW, globalContext);
702 703 704 705 706 707
        cmd->setDefaultKeySequence(QKeySequence(tr("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);
Eike Ziller's avatar
Eike Ziller committed
708
        cmd = ActionManager::registerAction(m_zoomAction, Constants::ZOOM_WINDOW, globalContext);
709 710 711 712
        mwindow->addAction(cmd, Constants::G_WINDOW_SIZE);
        connect(m_zoomAction, SIGNAL(triggered()), this, SLOT(showMaximized()));

        // Window separator
713
        mwindow->addSeparator(globalContext, Constants::G_WINDOW_SIZE);
714
    }
con's avatar
con committed
715

716
    // Show Sidebar Action
717
    m_toggleSideBarAction = new QAction(QIcon(QLatin1String(Constants::ICON_TOGGLE_SIDEBAR)),
718
                                        tr("Show Sidebar"), this);
719
    m_toggleSideBarAction->setCheckable(true);
Eike Ziller's avatar
Eike Ziller committed
720
    cmd = ActionManager::registerAction(m_toggleSideBarAction, Constants::TOGGLE_SIDEBAR, globalContext);
721
    cmd->setAttribute(Command::CA_UpdateText);
722
    cmd->setDefaultKeySequence(QKeySequence(UseMacShortcuts ? tr("Ctrl+0") : tr("Alt+0")));
723
    connect(m_toggleSideBarAction, SIGNAL(triggered(bool)), this, SLOT(setSidebarVisible(bool)));
con's avatar
con committed
724
    m_toggleSideBarButton->setDefaultAction(cmd->action());
725
    mwindow->addAction(cmd, Constants::G_WINDOW_VIEWS);
con's avatar
con committed
726 727
    m_toggleSideBarAction->setEnabled(false);

728 729 730 731 732 733
    // Show Mode Selector Action
    m_toggleModeSelectorAction = new QAction(tr("Show Mode Selector"), this);
    m_toggleModeSelectorAction->setCheckable(true);
    cmd = ActionManager::registerAction(m_toggleModeSelectorAction, Constants::TOGGLE_MODE_SELECTOR, globalContext);
    connect(m_toggleModeSelectorAction, SIGNAL(triggered(bool)), ModeManager::instance(), SLOT(setModeSelectorVisible(bool)));
    mwindow->addAction(cmd, Constants::G_WINDOW_VIEWS);
734

735 736
#if defined(Q_OS_MAC)
    const QString fullScreenActionText(tr("Enter Full Screen"));
737
    bool supportsFullScreen = MacFullScreen::supportsFullScreen();
738 739
#else
    const QString fullScreenActionText(tr("Full Screen"));
740
    bool supportsFullScreen = true;
741
#endif
742 743 744
    if (supportsFullScreen) {
        // Full Screen Action
        m_toggleFullScreenAction = new QAction(fullScreenActionText, this);
745
        m_toggleFullScreenAction->setMenuRole(QAction::NoRole);
746
        m_toggleFullScreenAction->setCheckable(!Utils::HostOsInfo::isMacHost());
Eike Ziller's avatar
Eike Ziller committed
747
        cmd = ActionManager::registerAction(m_toggleFullScreenAction, Constants::TOGGLE_FULLSCREEN, globalContext);
748 749 750 751
        cmd->setDefaultKeySequence(QKeySequence(UseMacShortcuts ? tr("Ctrl+Meta+F") : tr("Ctrl+Shift+F11")));
        cmd->setAttribute(Command::CA_UpdateText); /* for Mac */
        mwindow->addAction(cmd, Constants::G_WINDOW_SIZE);
        connect(m_toggleFullScreenAction, SIGNAL(triggered(bool)), this, SLOT(setFullScreen(bool)));
752
    }
hjk's avatar
hjk committed
753

754
    // Window->Views
Eike Ziller's avatar
Eike Ziller committed
755
    ActionContainer *mviews = ActionManager::createMenu(Constants::M_WINDOW_VIEWS);
756 757 758
    mwindow->addMenu(mviews, Constants::G_WINDOW_VIEWS);
    mviews->menu()->setTitle(tr("&Views"));

759
    // About IDE Action
760
    icon = QIcon::fromTheme(QLatin1String("help-about"));
761 762 763 764
    if (Utils::HostOsInfo::isMacHost())
        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);
Eike Ziller's avatar
Eike Ziller committed
765
    cmd = ActionManager::registerAction(tmpaction, Constants::ABOUT_QTCREATOR, globalContext);
766 767
    if (Utils::HostOsInfo::isMacHost())
        cmd->action()->setMenuRole(QAction::ApplicationSpecificRole);
768 769
    mhelp->addAction(cmd, Constants::G_HELP_ABOUT);
    tmpaction->setEnabled(true);
con's avatar
con committed
770
    connect(tmpaction, SIGNAL(triggered()), this,  SLOT(aboutQtCreator()));
con's avatar
con committed
771

con's avatar
con committed
772 773
    //About Plugins Action
    tmpaction = new QAction(tr("About &Plugins..."), this);
Eike Ziller's avatar
Eike Ziller committed
774
    cmd = ActionManager::registerAction(tmpaction, Constants::ABOUT_PLUGINS, globalContext);
775 776
    if (Utils::HostOsInfo::isMacHost())
        cmd->action()->setMenuRole(QAction::ApplicationSpecificRole);
777 778
    mhelp->addAction(cmd, Constants::G_HELP_ABOUT);
    tmpaction->setEnabled(true);
con's avatar
con committed
779
    connect(tmpaction, SIGNAL(triggered()), this,  SLOT(aboutPlugins()));
780
    // About Qt Action
con's avatar
con committed
781
//    tmpaction = new QAction(tr("About &Qt..."), this);
Eike Ziller's avatar
Eike Ziller committed
782
//    cmd = ActionManager::registerAction(tmpaction, Constants:: ABOUT_QT, globalContext);
con's avatar
con committed
783 784 785 786
//    mhelp->addAction(cmd, Constants::G_HELP_ABOUT);
//    tmpaction->setEnabled(true);
//    connect(tmpaction, SIGNAL(triggered()), qApp, SLOT(aboutQt()));
    // About sep
787 788 789 790 791 792
    if (!Utils::HostOsInfo::isMacHost()) { // doesn't have the "About" actions in the Help menu
        tmpaction = new QAction(this);
        tmpaction->setSeparator(true);
        cmd = ActionManager::registerAction(tmpaction, "QtCreator.Help.Sep.About", globalContext);
        mhelp->addAction(cmd, Constants::G_HELP_ABOUT);
    }
con's avatar
con committed
793 794 795 796
}

void MainWindow::newFile()
{
797
    showNewItemDialog(tr("New", "Title of dialog"), IWizard::allWizards(), QString());
con's avatar
con committed
798 799 800 801
}

void MainWindow::openFile()
{
802
    openFiles(editorManager()->getOpenFileNames(), ICore::SwitchMode);
con's avatar
con committed
803 804
}

805
static QList<IDocumentFactory*> getNonEditorDocumentFactories()
con's avatar
con committed
806
{
807
    const QList<IDocumentFactory*> allFileFactories =
808
        ExtensionSystem::PluginManager::getObjects<IDocumentFactory>();
809 810
    QList<IDocumentFactory*> nonEditorFileFactories;
    foreach (IDocumentFactory *factory, allFileFactories) {
con's avatar
con committed
811 812 813 814 815 816
        if (!qobject_cast<IEditorFactory *>(factory))
            nonEditorFileFactories.append(factory);
    }
    return nonEditorFileFactories;
}

817
static IDocumentFactory *findDocumentFactory(const QList<IDocumentFactory*> &fileFactories,
con's avatar
con committed
818 819 820 821 822
                                     const MimeDatabase *db,
                                     const QFileInfo &fi)
{
    if (const MimeType mt = db->findByFile(fi)) {
        const QString type = mt.type();
823
        foreach (IDocumentFactory *factory, fileFactories) {
con's avatar
con committed
824 825 826 827 828 829 830
            if (factory->mimeTypes().contains(type))
                return factory;
        }
    }
    return 0;
}

831 832 833 834 835 836 837 838 839 840 841
/*! Either opens \a fileNames with editors or loads a project.
 *
 *  \a flags can be used to stop on first failure, indicate that a file name
 *  might include line numbers and/or switch mode to edit mode.
 *
 *  \returns the first opened document. Required to support the -block flag
 *  for client mode.
 *
 *  \sa IPlugin::remoteArguments()
 */
IDocument *MainWindow::openFiles(const QStringList &fileNames, ICore::OpenFilesFlags flags)
con's avatar
con committed
842
{
Eike Ziller's avatar