mainwindow.cpp 46.7 KB
Newer Older
1
/**************************************************************************
con's avatar
con committed
2 3 4
**
** This file is part of Qt Creator
**
con's avatar
con committed
5
** Copyright (c) 2011 Nokia Corporation and/or its subsidiary(-ies).
con's avatar
con committed
6
**
hjk's avatar
hjk committed
7
** Contact: Nokia Corporation (info@qt.nokia.com)
con's avatar
con committed
8
**
9
**
10
** GNU Lesser General Public License Usage
11
**
hjk's avatar
hjk committed
12 13 14 15 16 17
** 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.
18
**
con's avatar
con committed
19
** In addition, as a special exception, Nokia gives you certain additional
hjk's avatar
hjk committed
20
** rights. These rights are described in the Nokia Qt LGPL Exception
con's avatar
con committed
21 22
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
**
hjk's avatar
hjk committed
23 24 25 26 27
** Other Usage
**
** Alternatively, this file may be used in accordance with the terms and
** conditions contained in a signed written agreement between you and Nokia.
**
con's avatar
con committed
28
** If you have questions regarding the use of this file, please contact
Tobias Hunger's avatar
Tobias Hunger committed
29
** Nokia at info@qt.nokia.com.
con's avatar
con committed
30
**
31
**************************************************************************/
con's avatar
con committed
32 33

#include "mainwindow.h"
34
#include "actioncontainer.h"
35
#include "command.h"
36
#include "actionmanager_p.h"
con's avatar
con committed
37 38 39
#include "coreimpl.h"
#include "coreconstants.h"
#include "editormanager.h"
40
#include "externaltool.h"
41
#include "toolsettings.h"
42
#include "mimetypesettings.h"
con's avatar
con committed
43 44 45
#include "fancytabwidget.h"
#include "filemanager.h"
#include "generalsettings.h"
kh1's avatar
kh1 committed
46
#include "helpmanager.h"
47
#include "ieditor.h"
con's avatar
con committed
48 49 50 51 52
#include "ifilefactory.h"
#include "messagemanager.h"
#include "modemanager.h"
#include "mimedatabase.h"
#include "newdialog.h"
53
#include "outputpanemanager.h"
con's avatar
con committed
54 55
#include "outputpane.h"
#include "plugindialog.h"
56
#include "progressmanager_p.h"
con's avatar
con committed
57 58 59
#include "progressview.h"
#include "shortcutsettings.h"
#include "vcsmanager.h"
con's avatar
con committed
60
#include "variablechooser.h"
hjk's avatar
hjk committed
61

62
#include "scriptmanager_p.h"
con's avatar
con committed
63 64 65
#include "settingsdialog.h"
#include "variablemanager.h"
#include "versiondialog.h"
con's avatar
con committed
66
#include "statusbarmanager.h"
67
#include "id.h"
con's avatar
con committed
68 69 70 71
#include "manhattanstyle.h"
#include "navigationwidget.h"
#include "rightpane.h"
#include "editormanager/ieditorfactory.h"
72
#include "statusbarwidget.h"
con's avatar
con committed
73
#include "basefilewizard.h"
74
#include "ioutputpane.h"
75
#include "externaltoolmanager.h"
76
#include "editormanager/systemeditor.h"
con's avatar
con committed
77

78
#include <app/app_version.h>
con's avatar
con committed
79
#include <coreplugin/findplaceholder.h>
80
#include <coreplugin/icorelistener.h>
81
#include <coreplugin/inavigationwidgetfactory.h>
82
#include <coreplugin/settingsdatabase.h>
83
#include <utils/pathchooser.h>
84
#include <utils/stylehelper.h>
85
#include <utils/stringutils.h>
86
#include <extensionsystem/pluginmanager.h>
con's avatar
con committed
87 88

#include <QtCore/QDebug>
89
#include <QtCore/QFileInfo>
con's avatar
con committed
90 91
#include <QtCore/QSettings>
#include <QtCore/QTimer>
92
#include <QtCore/QtPlugin>
93
#include <QtCore/QUrl>
94
#include <QtCore/QDir>
95
#include <QtCore/QFile>
con's avatar
con committed
96 97 98

#include <QtGui/QApplication>
#include <QtGui/QCloseEvent>
99 100
#include <QtGui/QMenu>
#include <QtGui/QPixmap>
con's avatar
con committed
101
#include <QtGui/QPrinter>
102
#include <QtGui/QShortcut>
con's avatar
con committed
103
#include <QtGui/QStatusBar>
104
#include <QtGui/QWizard>
105
#include <QtGui/QToolButton>
106
#include <QtGui/QMessageBox>
107
#include <QtGui/QMenuBar>
108
#include <QtGui/QPushButton>
con's avatar
con committed
109 110 111 112 113 114

/*
#ifdef Q_OS_UNIX
#include <signal.h>
extern "C" void handleSigInt(int sig)
{
115
    Q_UNUSED(sig)
116
    Core::ICore::instance()->exit();
con's avatar
con committed
117 118 119 120 121 122 123 124
    qDebug() << "SIGINT caught. Shutting down.";
}
#endif
*/

using namespace Core;
using namespace Core::Internal;

125
enum { debugMainWindow = 0 };
con's avatar
con committed
126 127

MainWindow::MainWindow() :
128
    EventFilteringMainWindow(),
con's avatar
con committed
129
    m_coreImpl(new CoreImpl(this)),
130
    m_additionalContexts(Constants::C_GLOBAL),
131
    m_settings(ExtensionSystem::PluginManager::instance()->settings()),
132 133
    m_globalSettings(new QSettings(QSettings::IniFormat, QSettings::SystemScope,
                             QLatin1String("Nokia"), QLatin1String("QtCreator"), this)),
134 135 136
    m_settingsDatabase(new SettingsDatabase(QFileInfo(m_settings->fileName()).path(),
                                            QLatin1String("QtCreator"),
                                            this)),
con's avatar
con committed
137
    m_printer(0),
138
    m_actionManager(new ActionManagerPrivate(this)),
con's avatar
con committed
139
    m_editorManager(0),
140
    m_externalToolManager(0),
hjk's avatar
hjk committed
141
    m_fileManager(new FileManager(this)),
142
    m_progressManager(new ProgressManagerPrivate()),
143
    m_scriptManager(new ScriptManagerPrivate(this)),
Friedemann Kleint's avatar
Friedemann Kleint committed
144
    m_variableManager(new VariableManager),
hjk's avatar
hjk committed
145
    m_vcsManager(new VcsManager),
con's avatar
con committed
146
    m_statusBarManager(0),
con's avatar
con committed
147 148
    m_modeManager(0),
    m_mimeDatabase(new MimeDatabase),
kh1's avatar
kh1 committed
149
    m_helpManager(new HelpManager),
con's avatar
con committed
150 151
    m_navigationWidget(0),
    m_rightPaneWidget(0),
152
    m_versionDialog(0),
con's avatar
con committed
153 154 155
    m_activeContext(0),
    m_generalSettings(new GeneralSettings),
    m_shortcutSettings(new ShortcutSettings),
156
    m_toolSettings(new ToolSettings),
157
    m_mimeTypeSettings(new MimeTypeSettings),
158
    m_systemEditor(new SystemEditor),
con's avatar
con committed
159 160 161 162 163 164 165 166
    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
167
    m_toggleFullScreenAction(0),
Oswald Buddenhagen's avatar
Oswald Buddenhagen committed
168
#ifdef Q_WS_MAC
con's avatar
con committed
169 170 171 172 173
    m_minimizeAction(0),
    m_zoomAction(0),
#endif
    m_toggleSideBarButton(new QToolButton)
{
174 175
    OutputPaneManager::create();

con's avatar
con committed
176
    setWindowTitle(tr("Qt Creator"));
Oswald Buddenhagen's avatar
Oswald Buddenhagen committed
177
#ifndef Q_WS_MAC
178
    QApplication::setWindowIcon(QIcon(QLatin1String(Constants::ICON_QTLOGO_128)));
179
#endif
180 181 182 183
    QCoreApplication::setApplicationName(QLatin1String("QtCreator"));
    QCoreApplication::setApplicationVersion(QLatin1String(Core::Constants::IDE_VERSION_LONG));
    QCoreApplication::setOrganizationName(QLatin1String("Nokia"));
    QSettings::setDefaultFormat(QSettings::IniFormat);
184
    QString baseName = QApplication::style()->objectName();
con's avatar
con committed
185
#ifdef Q_WS_X11
186
    if (baseName == QLatin1String("windows")) {
187 188 189 190
        // 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")
191
            baseName = QLatin1String("plastique");
192
        else
193
            baseName = QLatin1String("cleanlooks");
194 195 196 197
    }
#endif
    qApp->setStyle(new ManhattanStyle(baseName));

con's avatar
con committed
198 199 200 201 202 203 204 205 206 207 208 209 210 211
    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());
con's avatar
con committed
212
    m_statusBarManager = new StatusBarManager(this);
con's avatar
con committed
213 214 215
    m_messageManager = new MessageManager;
    m_editorManager = new EditorManager(m_coreImpl, this);
    m_editorManager->hide();
216
    m_externalToolManager = new ExternalToolManager(m_coreImpl);
con's avatar
con committed
217 218 219 220 221 222 223 224 225 226 227 228 229
    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);
230
    setAcceptDrops(true);
con's avatar
con committed
231 232
}

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

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

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

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

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

290
    // Now that the OutputPaneManager is gone, is a good time to delete the view
291
    pm->removeObject(m_outputView);
con's avatar
con committed
292 293 294 295
    delete m_outputView;

    delete m_editorManager;
    m_editorManager = 0;
con's avatar
con committed
296 297
    delete m_statusBarManager;
    m_statusBarManager = 0;
con's avatar
con committed
298 299
    delete m_progressManager;
    m_progressManager = 0;
300
    pm->removeObject(m_coreImpl);
con's avatar
con committed
301 302 303 304 305 306 307 308 309 310
    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
311 312 313

    delete m_helpManager;
    m_helpManager = 0;
con's avatar
con committed
314 315
}

316
bool MainWindow::init(QString *errorMessage)
con's avatar
con committed
317
{
318
    Q_UNUSED(errorMessage)
319

320 321 322
    if (!mimeDatabase()->addMimeTypes(QLatin1String(":/core/editormanager/BinFiles.mimetypes.xml"), errorMessage))
        return false;

323 324
    ExtensionSystem::PluginManager *pm = ExtensionSystem::PluginManager::instance();
    pm->addObject(m_coreImpl);
con's avatar
con committed
325
    m_statusBarManager->init();
con's avatar
con committed
326 327
    m_modeManager->init();
    m_progressManager->init();
con's avatar
con committed
328

329 330
    pm->addObject(m_generalSettings);
    pm->addObject(m_shortcutSettings);
331
    pm->addObject(m_toolSettings);
332
    pm->addObject(m_mimeTypeSettings);
333 334
    pm->addObject(m_systemEditor);

335
    // Add widget to the bottom, we create the view here instead of inside the
Tobias Hunger's avatar
Tobias Hunger committed
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();
con's avatar
con committed
342 343 344 345 346 347
    return true;
}

void MainWindow::extensionsInitialized()
{
    m_editorManager->init();
con's avatar
con committed
348
    m_statusBarManager->extensionsInitalized();
349
    OutputPaneManager::instance()->init();
350
    m_vcsManager->extensionsInitialized();
351 352
    m_navigationWidget->setFactories(ExtensionSystem::PluginManager::instance()->getObjects<INavigationWidgetFactory>());

353 354 355
    // reading the shortcut settings must be done after all shortcuts have been registered
    m_actionManager->initialize();

con's avatar
con committed
356 357 358
    readSettings();
    updateContext();

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

void MainWindow::closeEvent(QCloseEvent *event)
{
    emit m_coreImpl->saveSettingsRequested();

    // Save opened files
    bool cancelled;
370 371
    QList<IFile*> notSaved = fileManager()->saveModifiedFiles(fileManager()->modifiedFiles(), &cancelled);
    if (cancelled || !notSaved.isEmpty()) {
con's avatar
con committed
372 373 374 375 376
        event->ignore();
        return;
    }

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

    emit m_coreImpl->coreAboutToClose();
386

con's avatar
con committed
387
    writeSettings();
388 389 390

    m_navigationWidget->closeSubWidgets();

con's avatar
con committed
391 392 393
    event->accept();
}

394 395 396 397 398 399 400
// 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.
401
    if (!d->hasUrls())
402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424
        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;
            if (files) {
                files->push_back(fileName);
            } else {
                break; // No result list, sufficient for checking
            }
        }
    }
    return hasFiles;
}

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

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

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

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

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

void MainWindow::registerDefaultContainers()
{
466
    ActionManagerPrivate *am = m_actionManager;
con's avatar
con committed
467

468
    ActionContainer *menubar = am->createMenuBar(Constants::MENU_BAR);
con's avatar
con committed
469 470 471 472 473 474 475 476 477 478 479

#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);

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


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

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

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

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

529 530
static Command *createSeparator(ActionManager *am, QObject *parent,
                                const QString &name,
531
                                const Context &context)
con's avatar
con committed
532 533 534
{
    QAction *tmpaction = new QAction(parent);
    tmpaction->setSeparator(true);
con's avatar
con committed
535
    Command *cmd = am->registerAction(tmpaction, name, context);
con's avatar
con committed
536 537 538 539 540
    return cmd;
}

void MainWindow::registerDefaultActions()
{
541
    ActionManagerPrivate *am = m_actionManager;
542 543 544 545 546
    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);
con's avatar
con committed
547

548 549
    Context globalContext(Constants::C_GLOBAL);

con's avatar
con committed
550
    // File menu separators
551
    Command *cmd = createSeparator(am, this, QLatin1String("QtCreator.File.Sep.Save"), globalContext);
con's avatar
con committed
552 553
    mfile->addAction(cmd, Constants::G_FILE_SAVE);

554
    cmd =  createSeparator(am, this, QLatin1String("QtCreator.File.Sep.Print"), globalContext);
555
    QIcon icon = QIcon::fromTheme(QLatin1String("edit-cut"), QIcon(Constants::ICON_CUT));
con's avatar
con committed
556 557
    mfile->addAction(cmd, Constants::G_FILE_PRINT);

558
    cmd =  createSeparator(am, this, QLatin1String("QtCreator.File.Sep.Close"), globalContext);
con's avatar
con committed
559 560
    mfile->addAction(cmd, Constants::G_FILE_CLOSE);

561
    cmd = createSeparator(am, this, QLatin1String("QtCreator.File.Sep.Other"), globalContext);
con's avatar
con committed
562 563 564
    mfile->addAction(cmd, Constants::G_FILE_OTHER);

    // Edit menu separators
565
    cmd = createSeparator(am, this, QLatin1String("QtCreator.Edit.Sep.CopyPaste"), globalContext);
con's avatar
con committed
566 567
    medit->addAction(cmd, Constants::G_EDIT_COPYPASTE);

568
    cmd = createSeparator(am, this, QLatin1String("QtCreator.Edit.Sep.SelectAll"), globalContext);
con's avatar
con committed
569 570
    medit->addAction(cmd, Constants::G_EDIT_SELECTALL);

571
    cmd = createSeparator(am, this, QLatin1String("QtCreator.Edit.Sep.Find"), globalContext);
con's avatar
con committed
572 573
    medit->addAction(cmd, Constants::G_EDIT_FIND);

574
    cmd = createSeparator(am, this, QLatin1String("QtCreator.Edit.Sep.Advanced"), globalContext);
575
    medit->addAction(cmd, Constants::G_EDIT_ADVANCED);
con's avatar
con committed
576

577
    // Return to editor shortcut: Note this requires Qt to fix up
con's avatar
con committed
578 579
    // handling of shortcut overrides in menus, item views, combos....
    m_focusToEditor = new QShortcut(this);
580
    cmd = am->registerShortcut(m_focusToEditor, Constants::S_RETURNTOEDITOR, globalContext);
con's avatar
con committed
581 582 583
    cmd->setDefaultKeySequence(QKeySequence(Qt::Key_Escape));
    connect(m_focusToEditor, SIGNAL(activated()), this, SLOT(setFocusToEditor()));

584
    // New File Action
585 586
    icon = QIcon::fromTheme(QLatin1String("document-new"), QIcon(Constants::ICON_NEWFILE));
    m_newAction = new QAction(icon, tr("&New File or Project..."), this);
587
    cmd = am->registerAction(m_newAction, Constants::NEW, globalContext);
con's avatar
con committed
588 589 590 591
    cmd->setDefaultKeySequence(QKeySequence::New);
    mfile->addAction(cmd, Constants::G_FILE_NEW);
    connect(m_newAction, SIGNAL(triggered()), this, SLOT(newFile()));

592
    // Open Action
593 594
    icon = QIcon::fromTheme(QLatin1String("document-open"), QIcon(Constants::ICON_OPENFILE));
    m_openAction = new QAction(icon, tr("&Open File or Project..."), this);
595
    cmd = am->registerAction(m_openAction, Constants::OPEN, globalContext);
con's avatar
con committed
596 597 598 599
    cmd->setDefaultKeySequence(QKeySequence::Open);
    mfile->addAction(cmd, Constants::G_FILE_OPEN);
    connect(m_openAction, SIGNAL(triggered()), this, SLOT(openFile()));

600
    // Open With Action
601
    m_openWithAction = new QAction(tr("Open File &With..."), this);
602
    cmd = am->registerAction(m_openWithAction, Constants::OPEN_WITH, globalContext);
con's avatar
con committed
603 604 605
    mfile->addAction(cmd, Constants::G_FILE_OPEN);
    connect(m_openWithAction, SIGNAL(triggered()), this, SLOT(openFileWith()));

606
    // File->Recent Files Menu
607
    ActionContainer *ac = am->createMenu(Constants::M_FILE_RECENTFILES);
con's avatar
con committed
608
    mfile->addMenu(ac, Constants::G_FILE_OPEN);
609
    ac->menu()->setTitle(tr("Recent &Files"));
610
    ac->setOnAllDisabledBehavior(ActionContainer::Show);
con's avatar
con committed
611

612
    // Save Action
613 614
    icon = QIcon::fromTheme(QLatin1String("document-save"), QIcon(Constants::ICON_SAVEFILE));
    QAction *tmpaction = new QAction(icon, tr("&Save"), this);
615
    tmpaction->setEnabled(false);
616
    cmd = am->registerAction(tmpaction, Constants::SAVE, globalContext);
con's avatar
con committed
617
    cmd->setDefaultKeySequence(QKeySequence::Save);
con's avatar
con committed
618
    cmd->setAttribute(Command::CA_UpdateText);
con's avatar
con committed
619 620 621
    cmd->setDefaultText(tr("&Save"));
    mfile->addAction(cmd, Constants::G_FILE_SAVE);

622
    // Save As Action
623 624
    icon = QIcon::fromTheme(QLatin1String("document-save-as"));
    tmpaction = new QAction(icon, tr("Save &As..."), this);
625
    tmpaction->setEnabled(false);
626
    cmd = am->registerAction(tmpaction, Constants::SAVEAS, globalContext);
Oswald Buddenhagen's avatar
Oswald Buddenhagen committed
627
#ifdef Q_WS_MAC
con's avatar
con committed
628 629
    cmd->setDefaultKeySequence(QKeySequence(tr("Ctrl+Shift+S")));
#endif
con's avatar
con committed
630
    cmd->setAttribute(Command::CA_UpdateText);
con's avatar
con committed
631 632 633
    cmd->setDefaultText(tr("Save &As..."));
    mfile->addAction(cmd, Constants::G_FILE_SAVE);

634
    // SaveAll Action
con's avatar
con committed
635
    m_saveAllAction = new QAction(tr("Save A&ll"), this);
636
    cmd = am->registerAction(m_saveAllAction, Constants::SAVEALL, globalContext);
Oswald Buddenhagen's avatar
Oswald Buddenhagen committed
637
#ifndef Q_WS_MAC
con's avatar
con committed
638 639 640 641 642
    cmd->setDefaultKeySequence(QKeySequence(tr("Ctrl+Shift+S")));
#endif
    mfile->addAction(cmd, Constants::G_FILE_SAVE);
    connect(m_saveAllAction, SIGNAL(triggered()), this, SLOT(saveAll()));

643
    // Print Action
644 645
    icon = QIcon::fromTheme(QLatin1String("document-print"));
    tmpaction = new QAction(icon, tr("&Print..."), this);
646
    tmpaction->setEnabled(false);
647
    cmd = am->registerAction(tmpaction, Constants::PRINT, globalContext);
648
    cmd->setDefaultKeySequence(QKeySequence::Print);
con's avatar
con committed
649 650
    mfile->addAction(cmd, Constants::G_FILE_PRINT);

651
    // Exit Action
652 653
    icon = QIcon::fromTheme(QLatin1String("application-exit"));
    m_exitAction = new QAction(icon, tr("E&xit"), this);
654
    cmd = am->registerAction(m_exitAction, Constants::EXIT, globalContext);
con's avatar
con committed
655 656 657 658
    cmd->setDefaultKeySequence(QKeySequence(tr("Ctrl+Q")));
    mfile->addAction(cmd, Constants::G_FILE_OTHER);
    connect(m_exitAction, SIGNAL(triggered()), this, SLOT(exit()));

659
    // Undo Action
660 661
    icon = QIcon::fromTheme(QLatin1String("edit-undo"), QIcon(Constants::ICON_UNDO));
    tmpaction = new QAction(icon, tr("&Undo"), this);
662
    cmd = am->registerAction(tmpaction, Constants::UNDO, globalContext);
con's avatar
con committed
663
    cmd->setDefaultKeySequence(QKeySequence::Undo);
con's avatar
con committed
664
    cmd->setAttribute(Command::CA_UpdateText);
con's avatar
con committed
665 666
    cmd->setDefaultText(tr("&Undo"));
    medit->addAction(cmd, Constants::G_EDIT_UNDOREDO);
667
    tmpaction->setEnabled(false);
con's avatar
con committed
668

669
    // Redo Action
670 671
    icon = QIcon::fromTheme(QLatin1String("edit-redo"), QIcon(Constants::ICON_REDO));
    tmpaction = new QAction(icon, tr("&Redo"), this);
672
    cmd = am->registerAction(tmpaction, Constants::REDO, globalContext);
con's avatar
con committed
673
    cmd->setDefaultKeySequence(QKeySequence::Redo);
con's avatar
con committed
674
    cmd->setAttribute(Command::CA_UpdateText);
con's avatar
con committed
675 676
    cmd->setDefaultText(tr("&Redo"));
    medit->addAction(cmd, Constants::G_EDIT_UNDOREDO);
677
    tmpaction->setEnabled(false);
con's avatar
con committed
678

679
    // Cut Action
680 681
    icon = QIcon::fromTheme(QLatin1String("edit-cut"), QIcon(Constants::ICON_CUT));
    tmpaction = new QAction(icon, tr("Cu&t"), this);
682
    cmd = am->registerAction(tmpaction, Constants::CUT, globalContext);
con's avatar
con committed
683 684
    cmd->setDefaultKeySequence(QKeySequence::Cut);
    medit->addAction(cmd, Constants::G_EDIT_COPYPASTE);
685
    tmpaction->setEnabled(false);
con's avatar
con committed
686

687
    // Copy Action
688 689
    icon = QIcon::fromTheme(QLatin1String("edit-copy"), QIcon(Constants::ICON_COPY));
    tmpaction = new QAction(icon, tr("&Copy"), this);
690
    cmd = am->registerAction(tmpaction, Constants::COPY, globalContext);
con's avatar
con committed
691 692
    cmd->setDefaultKeySequence(QKeySequence::Copy);
    medit->addAction(cmd, Constants::G_EDIT_COPYPASTE);
693
    tmpaction->setEnabled(false);
con's avatar
con committed
694

695
    // Paste Action
696 697
    icon = QIcon::fromTheme(QLatin1String("edit-paste"), QIcon(Constants::ICON_PASTE));
    tmpaction = new QAction(icon, tr("&Paste"), this);
698
    cmd = am->registerAction(tmpaction, Constants::PASTE, globalContext);
con's avatar
con committed
699 700
    cmd->setDefaultKeySequence(QKeySequence::Paste);
    medit->addAction(cmd, Constants::G_EDIT_COPYPASTE);
701
    tmpaction->setEnabled(false);
con's avatar
con committed
702

703
    // Select All
704
    icon = QIcon::fromTheme(QLatin1String("edit-select-all"));
con's avatar
con committed
705
    tmpaction = new QAction(icon, tr("Select &All"), this);
706
    cmd = am->registerAction(tmpaction, Constants::SELECTALL, globalContext);
con's avatar
con committed
707 708
    cmd->setDefaultKeySequence(QKeySequence::SelectAll);
    medit->addAction(cmd, Constants::G_EDIT_SELECTALL);
709
    tmpaction->setEnabled(false);
con's avatar
con committed
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);
con's avatar
con committed
715 716
    cmd->setDefaultKeySequence(QKeySequence(tr("Ctrl+L")));
    medit->addAction(cmd, Constants::G_EDIT_OTHER);
717
    tmpaction->setEnabled(false);
con's avatar
con committed
718

719
    // Options Action
con's avatar
con committed
720 721 722
    mtools->appendGroup(Constants::G_TOOLS_OPTIONS);
    cmd = createSeparator(am, this, QLatin1String("QtCreator.Tools.Sep.Options"), globalContext);
    mtools->addAction(cmd, Constants::G_TOOLS_OPTIONS);
con's avatar
con committed
723
    m_optionsAction = new QAction(tr("&Options..."), this);
724
    cmd = am->registerAction(m_optionsAction, Constants::OPTIONS, globalContext);
Oswald Buddenhagen's avatar
Oswald Buddenhagen committed
725
#ifdef Q_WS_MAC
con's avatar
con committed
726
    cmd->setDefaultKeySequence(QKeySequence("Ctrl+,"));
con's avatar
con committed
727
    cmd->action()->setMenuRole(QAction::PreferencesRole);
con's avatar
con committed
728
#endif
con's avatar
con committed
729
    mtools->addAction(cmd, Constants::G_TOOLS_OPTIONS);
con's avatar
con committed
730 731
    connect(m_optionsAction, SIGNAL(triggered()), this, SLOT(showOptionsDialog()));

Oswald Buddenhagen's avatar
Oswald Buddenhagen committed
732
#ifdef Q_WS_MAC
733
    // Minimize Action
con's avatar
con committed
734
    m_minimizeAction = new QAction(tr("Minimize"), this);
hjk's avatar
hjk committed
735
    cmd = am->registerAction(m_minimizeAction, Constants::MINIMIZE_WINDOW, globalContext);
con's avatar
con committed
736 737 738 739
    cmd->setDefaultKeySequence(QKeySequence("Ctrl+M"));
    mwindow->addAction(cmd, Constants::G_WINDOW_SIZE);
    connect(m_minimizeAction, SIGNAL(triggered()), this, SLOT(showMinimized()));

740
    // Zoom Action
con's avatar
con committed
741
    m_zoomAction = new QAction(tr("Zoom"), this);
hjk's avatar
hjk committed
742
    cmd = am->registerAction(m_zoomAction, Constants::ZOOM_WINDOW, globalContext);
con's avatar
con committed
743 744 745
    mwindow->addAction(cmd, Constants::G_WINDOW_SIZE);
    connect(m_zoomAction, SIGNAL(triggered()), this, SLOT(showMaximized()));

746
    // Window separator
hjk's avatar
hjk committed
747
    cmd = createSeparator(am, this, QLatin1String("QtCreator.Window.Sep.Size"), globalContext);
con's avatar
con committed
748 749 750
    mwindow->addAction(cmd, Constants::G_WINDOW_SIZE);
#endif

751
    // Show Sidebar Action
con's avatar
con committed
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);
Oswald Buddenhagen's avatar
Oswald Buddenhagen committed
757
#ifdef Q_WS_MAC
con's avatar
con committed
758 759 760 761
    cmd->setDefaultKeySequence(QKeySequence("Ctrl+0"));
#else
    cmd->setDefaultKeySequence(QKeySequence("Alt+0"));
#endif
762
    connect(m_toggleSideBarAction, SIGNAL(triggered(bool)), this, SLOT(setSidebarVisible(bool)));
con's avatar
con committed
763
    m_toggleSideBarButton->setDefaultAction(cmd->action());
764
    mwindow->addAction(cmd, Constants::G_WINDOW_VIEWS);
con's avatar
con committed
765 766
    m_toggleSideBarAction->setEnabled(false);

Oswald Buddenhagen's avatar
Oswald Buddenhagen committed
767
#ifndef Q_WS_MAC
768 769
    // Full Screen Action
    m_toggleFullScreenAction = new QAction(tr("Full Screen"), this);
hjk's avatar
hjk committed
770
    m_toggleFullScreenAction->setCheckable(true);
771
    cmd = am->registerAction(m_toggleFullScreenAction, Constants::TOGGLE_FULLSCREEN, globalContext);
hjk's avatar
hjk committed
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
hjk's avatar
hjk committed
776

777 778 779 780 781
    // Window->Views
    ActionContainer *mviews = am->createMenu(Constants::M_WINDOW_VIEWS);
    mwindow->addMenu(mviews, Constants::G_WINDOW_VIEWS);
    mviews->menu()->setTitle(tr("&Views"));

782
    // About IDE Action
783
    icon = QIcon::fromTheme(QLatin1String("help-about"));
Oswald Buddenhagen's avatar
Oswald Buddenhagen committed
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
con's avatar
con committed
786
#else
787
    tmpaction = new QAction(icon, tr("About &Qt Creator..."), this);
con's avatar
con committed
788
#endif
789
    cmd = am->registerAction(tmpaction, Constants::ABOUT_QTCREATOR, globalContext);
con's avatar
con committed
790 791
    mhelp->addAction(cmd, Constants::G_HELP_ABOUT);
    tmpaction->setEnabled(true);
con's avatar
con committed
792 793 794
#ifdef Q_WS_MAC
    cmd->action()->setMenuRole(QAction::ApplicationSpecificRole);
#endif
con's avatar
con committed
795
    connect(tmpaction, SIGNAL(triggered()), this,  SLOT(aboutQtCreator()));
con's avatar
con committed
796

con's avatar
con committed
797 798
    //About Plugins Action
    tmpaction = new QAction(tr("About &Plugins..."), this);
799
    cmd = am->registerAction(tmpaction, Constants::ABOUT_PLUGINS, globalContext);
con's avatar
con committed
800 801
    mhelp->addAction(cmd, Constants::G_HELP_ABOUT);
    tmpaction->setEnabled(true);
Oswald Buddenhagen's avatar
Oswald Buddenhagen committed
802
#ifdef Q_WS_MAC
con's avatar
con committed
803 804 805
    cmd->action()->setMenuRole(QAction::ApplicationSpecificRole);
#endif
    connect(tmpaction, SIGNAL(triggered()), this,  SLOT(aboutPlugins()));
806
    // About Qt Action
con's avatar
con committed
807
//    tmpaction = new QAction(tr("About &Qt..."), this);
hjk's avatar
hjk committed
808
//    cmd = am->registerAction(tmpaction, Constants:: ABOUT_QT, globalContext);
con's avatar
con committed
809 810 811 812
//    mhelp->addAction(cmd, Constants::G_HELP_ABOUT);
//    tmpaction->setEnabled(true);
//    connect(tmpaction, SIGNAL(triggered()), qApp, SLOT(aboutQt()));
    // About sep
con's avatar
con committed
813
#ifndef Q_WS_MAC // doesn't have the "About" actions in the Help menu
con's avatar
con committed
814 815
    tmpaction = new QAction(this);
    tmpaction->setSeparator(true);
hjk's avatar
hjk committed
816
    cmd = am->registerAction(tmpaction, "QtCreator.Help.Sep.About", globalContext);
con's avatar
con committed
817
    mhelp->addAction(cmd, Constants::G_HELP_ABOUT);
con's avatar
con committed
818
#endif
con's avatar
con committed
819 820 821 822
}

void MainWindow::newFile()
{
823
    showNewItemDialog(tr("New", "Title of dialog"), IWizard::allWizards(), QString());
con's avatar
con committed
824 825 826 827
}

void MainWindow::openFile()
{
828
    openFiles(editorManager()->getOpenFileNames(), ICore::SwitchMode);
con's avatar
con committed
829 830 831 832
}

static QList<IFileFactory*> getNonEditorFileFactories()
{
833 834
    const QList<IFileFactory*> allFileFactories =
        ExtensionSystem::PluginManager::instance()->getObjects<IFileFactory>();
con's avatar
con committed
835 836 837 838 839 840 841 842 843 844 845 846 847 848 849 850 851 852 853 854 855 856 857
    QList<IFileFactory*> nonEditorFileFactories;
    foreach (IFileFactory *factory, allFileFactories) {
        if (!qobject_cast<IEditorFactory *>(factory))
            nonEditorFileFactories.append(factory);
    }
    return nonEditorFileFactories;
}

static IFileFactory *findFileFactory(const QList<IFileFactory*> &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
858
void MainWindow::openFiles(const QStringList &fileNames, ICore::OpenFilesFlags flags)
con's avatar
con committed
859 860 861 862 863 864 865
{
    QList<IFileFactory*> nonEditorFileFactories = getNonEditorFileFactories();

    foreach (const QString &fileName, fileNames) {
        const QFileInfo fi(fileName);
        const QString absoluteFilePath = fi.absoluteFilePath();
        if (IFileFactory *fileFactory = findFileFactory(nonEditorFileFactories, mimeDatabase(), fi)) {
866 867 868 869
            Core::IFile *file = fileFactory->open(absoluteFilePath);
            if (!file && (flags & ICore::StopOnLoadFail))
                return;
            if (file && (flags & ICore::SwitchMode))
870
                Core::ModeManager::instance()->activateMode(Core::Constants::MODE_EDIT);
con's avatar
con committed
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 878 879
            Core::IEditor *editor = editorManager()->openEditor(absoluteFilePath, QString(), emFlags);
            if (!editor && (flags & ICore::StopOnLoadFail))
                return;
con's avatar
con committed
880 881 882 883 884 885
        }
    }
}

void MainWindow::setFocusToEditor()
{
mae's avatar
mae committed
886
    bool focusWasMovedToEditor = false;
con's avatar
con committed
887

mae's avatar
mae committed
888 889 890
    // give focus to the editor if we have one
    if (IEditor *editor = m_editorManager->currentEditor()) {
        if (qApp->focusWidget() != editor->widget()) {