editormanager.cpp 79.3 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
****************************************************************************/
hjk's avatar
hjk committed
29

con's avatar
con committed
30
#include "editormanager.h"
31
#include "editorview.h"
con's avatar
con committed
32
#include "openeditorswindow.h"
mae's avatar
mae committed
33
#include "openeditorsview.h"
34
#include "openeditorsmodel.h"
con's avatar
con committed
35
#include "openwithdialog.h"
36
#include "documentmanager.h"
37
#include "icore.h"
Friedemann Kleint's avatar
Friedemann Kleint committed
38
#include "ieditor.h"
con's avatar
con committed
39
40
#include "iversioncontrol.h"
#include "mimedatabase.h"
41
#include "vcsmanager.h"
con's avatar
con committed
42

43
#include <coreplugin/actionmanager/actioncontainer.h>
hjk's avatar
hjk committed
44
45
#include <coreplugin/actionmanager/actionmanager.h>
#include <coreplugin/coreconstants.h>
con's avatar
con committed
46
#include <coreplugin/editormanager/ieditorfactory.h>
47
#include <coreplugin/editormanager/iexternaleditor.h>
hjk's avatar
hjk committed
48
49
#include <coreplugin/editortoolbar.h>
#include <coreplugin/fileutils.h>
50
#include <coreplugin/icorelistener.h>
hjk's avatar
hjk committed
51
52
#include <coreplugin/infobar.h>
#include <coreplugin/modemanager.h>
53
#include <coreplugin/settingsdatabase.h>
54
#include <coreplugin/variablemanager.h>
con's avatar
con committed
55

56
57
#include <extensionsystem/pluginmanager.h>

58
#include <utils/hostosinfo.h>
hjk's avatar
hjk committed
59
60
#include <utils/qtcassert.h>

61
62
63
64
65
66
67
68
#include <QDateTime>
#include <QDebug>
#include <QFileInfo>
#include <QMap>
#include <QSet>
#include <QSettings>
#include <QTextCodec>
#include <QTimer>
con's avatar
con committed
69

70
71
72
73
74
75
76
77
#include <QAction>
#include <QShortcut>
#include <QApplication>
#include <QFileDialog>
#include <QMenu>
#include <QMessageBox>
#include <QPushButton>
#include <QSplitter>
con's avatar
con committed
78
79
80

enum { debugEditorManager=0 };

81
static const char kCurrentDocumentPrefix[] = "CurrentDocument";
Friedemann Kleint's avatar
Friedemann Kleint committed
82
83
static const char kCurrentDocumentXPos[] = "CurrentDocument:XPos";
static const char kCurrentDocumentYPos[] = "CurrentDocument:YPos";
84
static const char kMakeWritableWarning[] = "Core.EditorManager.MakeWritable";
con's avatar
con committed
85

86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
//===================EditorClosingCoreListener======================

namespace Core {
namespace Internal {

class EditorClosingCoreListener : public ICoreListener
{
public:
    EditorClosingCoreListener(EditorManager *em);
    bool editorAboutToClose(IEditor *editor);
    bool coreAboutToClose();

private:
    EditorManager *m_em;
};

EditorClosingCoreListener::EditorClosingCoreListener(EditorManager *em)
        : m_em(em)
{
}

bool EditorClosingCoreListener::editorAboutToClose(IEditor *)
{
    return true;
}

bool EditorClosingCoreListener::coreAboutToClose()
{
    // Do not ask for files to save.
    // MainWindow::closeEvent has already done that.
    return m_em->closeAllEditors(false);
}

} // namespace Internal
} // namespace Core

using namespace Core;
using namespace Core::Internal;
using namespace Utils;

con's avatar
con committed
126
127
128
129
130
131
132
133
134
//===================EditorManager=====================

EditorManagerPlaceHolder *EditorManagerPlaceHolder::m_current = 0;

EditorManagerPlaceHolder::EditorManagerPlaceHolder(Core::IMode *mode, QWidget *parent)
    : QWidget(parent), m_mode(mode)
{
    setLayout(new QVBoxLayout);
    layout()->setMargin(0);
Robert Loehning's avatar
Robert Loehning committed
135
136
    connect(Core::ModeManager::instance(), SIGNAL(currentModeChanged(Core::IMode*)),
            this, SLOT(currentModeChanged(Core::IMode*)));
137

138
    currentModeChanged(ModeManager::currentMode());
con's avatar
con committed
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
}

EditorManagerPlaceHolder::~EditorManagerPlaceHolder()
{
    if (m_current == this) {
        EditorManager::instance()->setParent(0);
        EditorManager::instance()->hide();
    }
}

void EditorManagerPlaceHolder::currentModeChanged(Core::IMode *mode)
{
    if (m_current == this) {
        m_current = 0;
        EditorManager::instance()->setParent(0);
        EditorManager::instance()->hide();
    }
    if (m_mode == mode) {
        m_current = this;
        layout()->addWidget(EditorManager::instance());
        EditorManager::instance()->show();
    }
}

EditorManagerPlaceHolder* EditorManagerPlaceHolder::current()
{
    return m_current;
}

// ---------------- EditorManager

170
namespace Core {
171
172


hjk's avatar
hjk committed
173
174
175
struct EditorManagerPrivate
{
    explicit EditorManagerPrivate(QWidget *parent);
con's avatar
con committed
176
    ~EditorManagerPrivate();
177
    Internal::EditorView *m_view;
mae's avatar
mae committed
178
    Internal::SplitterOrView *m_splitter;
mae's avatar
mae committed
179
    QPointer<IEditor> m_currentEditor;
mae's avatar
mae committed
180
    QPointer<SplitterOrView> m_currentView;
181
    QTimer *m_autoSaveTimer;
182

con's avatar
con committed
183
184
185
186
187
188
    // actions
    QAction *m_revertToSavedAction;
    QAction *m_saveAction;
    QAction *m_saveAsAction;
    QAction *m_closeCurrentEditorAction;
    QAction *m_closeAllEditorsAction;
con's avatar
con committed
189
    QAction *m_closeOtherEditorsAction;
con's avatar
con committed
190
191
192
193
    QAction *m_gotoNextDocHistoryAction;
    QAction *m_gotoPreviousDocHistoryAction;
    QAction *m_goBackAction;
    QAction *m_goForwardAction;
194
195
    QAction *m_splitAction;
    QAction *m_splitSideBySideAction;
196
197
198
    QAction *m_removeCurrentSplitAction;
    QAction *m_removeAllSplitsAction;
    QAction *m_gotoOtherSplitAction;
con's avatar
con committed
199

200
201
202
203
    QAction *m_saveCurrentEditorContextAction;
    QAction *m_saveAsCurrentEditorContextAction;
    QAction *m_revertToSavedCurrentEditorContextAction;

204
205
206
    QAction *m_closeCurrentEditorContextAction;
    QAction *m_closeAllEditorsContextAction;
    QAction *m_closeOtherEditorsContextAction;
Robert Loehning's avatar
Robert Loehning committed
207
208
    QAction *m_openGraphicalShellAction;
    QAction *m_openTerminalAction;
209
210
    QModelIndex m_contextMenuEditorIndex;

con's avatar
con committed
211
212
213
214
215
216
    Internal::OpenEditorsWindow *m_windowPopup;
    Internal::EditorClosingCoreListener *m_coreListener;

    QMap<QString, QVariant> m_editorStates;
    Internal::OpenEditorsViewFactory *m_openEditorsFactory;

217
    OpenEditorsModel *m_editorModel;
218

219
    IDocument::ReloadSetting m_reloadSetting;
220
221

    QString m_titleAddition;
222
223
224

    bool m_autoSaveEnabled;
    int m_autoSaveInterval;
con's avatar
con committed
225
};
226
}
con's avatar
con committed
227

hjk's avatar
hjk committed
228
EditorManagerPrivate::EditorManagerPrivate(QWidget *parent) :
229
    m_view(0),
230
    m_splitter(0),
231
    m_autoSaveTimer(0),
con's avatar
con committed
232
233
234
235
236
    m_revertToSavedAction(new QAction(EditorManager::tr("Revert to Saved"), parent)),
    m_saveAction(new QAction(parent)),
    m_saveAsAction(new QAction(parent)),
    m_closeCurrentEditorAction(new QAction(EditorManager::tr("Close"), parent)),
    m_closeAllEditorsAction(new QAction(EditorManager::tr("Close All"), parent)),
con's avatar
con committed
237
    m_closeOtherEditorsAction(new QAction(EditorManager::tr("Close Others"), parent)),
mae's avatar
mae committed
238
239
    m_gotoNextDocHistoryAction(new QAction(EditorManager::tr("Next Open Document in History"), parent)),
    m_gotoPreviousDocHistoryAction(new QAction(EditorManager::tr("Previous Open Document in History"), parent)),
240
241
    m_goBackAction(new QAction(QIcon(QLatin1String(Constants::ICON_PREV)), EditorManager::tr("Go Back"), parent)),
    m_goForwardAction(new QAction(QIcon(QLatin1String(Constants::ICON_NEXT)), EditorManager::tr("Go Forward"), parent)),
242
243
244
    m_saveCurrentEditorContextAction(new QAction(EditorManager::tr("&Save"), parent)),
    m_saveAsCurrentEditorContextAction(new QAction(EditorManager::tr("Save &As..."), parent)),
    m_revertToSavedCurrentEditorContextAction(new QAction(EditorManager::tr("Revert to Saved"), parent)),
245
246
247
    m_closeCurrentEditorContextAction(new QAction(EditorManager::tr("Close"), parent)),
    m_closeAllEditorsContextAction(new QAction(EditorManager::tr("Close All"), parent)),
    m_closeOtherEditorsContextAction(new QAction(EditorManager::tr("Close Others"), parent)),
Robert Loehning's avatar
Robert Loehning committed
248
249
    m_openGraphicalShellAction(new QAction(FileUtils::msgGraphicalShellAction(), parent)),
    m_openTerminalAction(new QAction(FileUtils::msgTerminalAction(), parent)),
con's avatar
con committed
250
    m_windowPopup(0),
251
    m_coreListener(0),
252
    m_reloadSetting(IDocument::AlwaysAsk),
253
254
    m_autoSaveEnabled(true),
    m_autoSaveInterval(5)
con's avatar
con committed
255
{
256
    m_editorModel = new OpenEditorsModel(parent);
con's avatar
con committed
257
258
259
260
}

EditorManagerPrivate::~EditorManagerPrivate()
{
261
//    clearNavigationHistory();
con's avatar
con committed
262
263
}

hjk's avatar
hjk committed
264
265
266
static EditorManager *m_instance = 0;

EditorManager *EditorManager::instance() { return m_instance; }
con's avatar
con committed
267

hjk's avatar
hjk committed
268
EditorManager::EditorManager(QWidget *parent) :
con's avatar
con committed
269
    QWidget(parent),
hjk's avatar
hjk committed
270
    d(new EditorManagerPrivate(parent))
con's avatar
con committed
271
272
273
{
    m_instance = this;

Robert Loehning's avatar
Robert Loehning committed
274
275
    connect(ICore::instance(), SIGNAL(contextAboutToChange(Core::IContext*)),
            this, SLOT(handleContextChange(Core::IContext*)));
con's avatar
con committed
276

277
    const Context editManagerContext(Constants::C_EDITORMANAGER);
Lasse Holmstedt's avatar
Lasse Holmstedt committed
278
    // combined context for edit & design modes
279
    const Context editDesignContext(Constants::C_EDITORMANAGER, Constants::C_DESIGN_MODE);
Lasse Holmstedt's avatar
Lasse Holmstedt committed
280

Eike Ziller's avatar
Eike Ziller committed
281
    ActionContainer *mfile = ActionManager::actionContainer(Constants::M_FILE);
con's avatar
con committed
282

283
    // Revert to saved
hjk's avatar
hjk committed
284
    d->m_revertToSavedAction->setIcon(QIcon::fromTheme(QLatin1String("document-revert")));
Eike Ziller's avatar
Eike Ziller committed
285
    Command *cmd = ActionManager::registerAction(d->m_revertToSavedAction,
con's avatar
con committed
286
                                       Constants::REVERTTOSAVED, editManagerContext);
con's avatar
con committed
287
    cmd->setAttribute(Command::CA_UpdateText);
288
    cmd->setDescription(tr("Revert File to Saved"));
con's avatar
con committed
289
    mfile->addAction(cmd, Constants::G_FILE_SAVE);
hjk's avatar
hjk committed
290
    connect(d->m_revertToSavedAction, SIGNAL(triggered()), this, SLOT(revertToSaved()));
con's avatar
con committed
291

292
    // Save Action
Eike Ziller's avatar
Eike Ziller committed
293
    ActionManager::registerAction(d->m_saveAction, Constants::SAVE, editManagerContext);
294
    connect(d->m_saveAction, SIGNAL(triggered()), this, SLOT(saveDocument()));
con's avatar
con committed
295

296
    // Save As Action
Eike Ziller's avatar
Eike Ziller committed
297
    ActionManager::registerAction(d->m_saveAsAction, Constants::SAVEAS, editManagerContext);
298
    connect(d->m_saveAsAction, SIGNAL(triggered()), this, SLOT(saveDocumentAs()));
con's avatar
con committed
299

300
    // Window Menu
Eike Ziller's avatar
Eike Ziller committed
301
    ActionContainer *mwindow = ActionManager::actionContainer(Constants::M_WINDOW);
con's avatar
con committed
302

303
    // Window menu separators
304
305
    mwindow->addSeparator(editManagerContext, Constants::G_WINDOW_SPLIT);
    mwindow->addSeparator(editManagerContext, Constants::G_WINDOW_NAVIGATE);
con's avatar
con committed
306

307
    // Close Action
Eike Ziller's avatar
Eike Ziller committed
308
    cmd = ActionManager::registerAction(d->m_closeCurrentEditorAction, Constants::CLOSE, editManagerContext, true);
con's avatar
con committed
309
    cmd->setDefaultKeySequence(QKeySequence(tr("Ctrl+W")));
con's avatar
con committed
310
    cmd->setAttribute(Core::Command::CA_UpdateText);
311
    cmd->setDescription(d->m_closeCurrentEditorAction->text());
con's avatar
con committed
312
    mfile->addAction(cmd, Constants::G_FILE_CLOSE);
hjk's avatar
hjk committed
313
    connect(d->m_closeCurrentEditorAction, SIGNAL(triggered()), this, SLOT(closeEditor()));
con's avatar
con committed
314

315
316
317
318
319
320
321
322
    if (Utils::HostOsInfo::isWindowsHost()) {
        // workaround for QTCREATORBUG-72
        QShortcut *sc = new QShortcut(parent);
        cmd = ActionManager::registerShortcut(sc, Constants::CLOSE_ALTERNATIVE, editManagerContext);
        cmd->setDefaultKeySequence(QKeySequence(tr("Ctrl+F4")));
        cmd->setDescription(EditorManager::tr("Close"));
        connect(sc, SIGNAL(activated()), this, SLOT(closeEditor()));
    }
323

324
    // Close All Action
Eike Ziller's avatar
Eike Ziller committed
325
    cmd = ActionManager::registerAction(d->m_closeAllEditorsAction, Constants::CLOSEALL, editManagerContext, true);
con's avatar
con committed
326
327
    cmd->setDefaultKeySequence(QKeySequence(tr("Ctrl+Shift+W")));
    mfile->addAction(cmd, Constants::G_FILE_CLOSE);
hjk's avatar
hjk committed
328
    connect(d->m_closeAllEditorsAction, SIGNAL(triggered()), this, SLOT(closeAllEditors()));
con's avatar
con committed
329

330
    // Close All Others Action
Eike Ziller's avatar
Eike Ziller committed
331
    cmd = ActionManager::registerAction(d->m_closeOtherEditorsAction, Constants::CLOSEOTHERS, editManagerContext, true);
con's avatar
con committed
332
333
    mfile->addAction(cmd, Constants::G_FILE_CLOSE);
    cmd->setAttribute(Core::Command::CA_UpdateText);
hjk's avatar
hjk committed
334
    connect(d->m_closeOtherEditorsAction, SIGNAL(triggered()), this, SLOT(closeOtherEditors()));
con's avatar
con committed
335

336
337
338
339
340
    //Save XXX Context Actions
    connect(d->m_saveCurrentEditorContextAction, SIGNAL(triggered()), this, SLOT(saveDocumentFromContextMenu()));
    connect(d->m_saveAsCurrentEditorContextAction, SIGNAL(triggered()), this, SLOT(saveDocumentAsFromContextMenu()));
    connect(d->m_revertToSavedCurrentEditorContextAction, SIGNAL(triggered()), this, SLOT(revertToSavedFromContextMenu()));

341
    // Close XXX Context Actions
hjk's avatar
hjk committed
342
343
344
    connect(d->m_closeAllEditorsContextAction, SIGNAL(triggered()), this, SLOT(closeAllEditors()));
    connect(d->m_closeCurrentEditorContextAction, SIGNAL(triggered()), this, SLOT(closeEditorFromContextMenu()));
    connect(d->m_closeOtherEditorsContextAction, SIGNAL(triggered()), this, SLOT(closeOtherEditorsFromContextMenu()));
345

hjk's avatar
hjk committed
346
347
    connect(d->m_openGraphicalShellAction, SIGNAL(triggered()), this, SLOT(showInGraphicalShell()));
    connect(d->m_openTerminalAction, SIGNAL(triggered()), this, SLOT(openTerminal()));
Robert Loehning's avatar
Robert Loehning committed
348

con's avatar
con committed
349
    // Goto Previous In History Action
Eike Ziller's avatar
Eike Ziller committed
350
    cmd = ActionManager::registerAction(d->m_gotoPreviousDocHistoryAction, Constants::GOTOPREVINHISTORY, editDesignContext);
351
    cmd->setDefaultKeySequence(QKeySequence(UseMacShortcuts ? tr("Alt+Tab") : tr("Ctrl+Tab")));
con's avatar
con committed
352
    mwindow->addAction(cmd, Constants::G_WINDOW_NAVIGATE);
hjk's avatar
hjk committed
353
    connect(d->m_gotoPreviousDocHistoryAction, SIGNAL(triggered()), this, SLOT(gotoPreviousDocHistory()));
con's avatar
con committed
354
355

    // Goto Next In History Action
Eike Ziller's avatar
Eike Ziller committed
356
    cmd = ActionManager::registerAction(d->m_gotoNextDocHistoryAction, Constants::GOTONEXTINHISTORY, editDesignContext);
357
    cmd->setDefaultKeySequence(QKeySequence(UseMacShortcuts ? tr("Alt+Shift+Tab") : tr("Ctrl+Shift+Tab")));
con's avatar
con committed
358
    mwindow->addAction(cmd, Constants::G_WINDOW_NAVIGATE);
hjk's avatar
hjk committed
359
    connect(d->m_gotoNextDocHistoryAction, SIGNAL(triggered()), this, SLOT(gotoNextDocHistory()));
con's avatar
con committed
360
361

    // Go back in navigation history
Eike Ziller's avatar
Eike Ziller committed
362
    cmd = ActionManager::registerAction(d->m_goBackAction, Constants::GO_BACK, editDesignContext);
363
    cmd->setDefaultKeySequence(QKeySequence(UseMacShortcuts ? tr("Ctrl+Alt+Left") : tr("Alt+Left")));
con's avatar
con committed
364
    mwindow->addAction(cmd, Constants::G_WINDOW_NAVIGATE);
hjk's avatar
hjk committed
365
    connect(d->m_goBackAction, SIGNAL(triggered()), this, SLOT(goBackInNavigationHistory()));
con's avatar
con committed
366
367

    // Go forward in navigation history
Eike Ziller's avatar
Eike Ziller committed
368
    cmd = ActionManager::registerAction(d->m_goForwardAction, Constants::GO_FORWARD, editDesignContext);
369
    cmd->setDefaultKeySequence(QKeySequence(UseMacShortcuts ? tr("Ctrl+Alt+Right") : tr("Alt+Right")));
con's avatar
con committed
370
    mwindow->addAction(cmd, Constants::G_WINDOW_NAVIGATE);
hjk's avatar
hjk committed
371
    connect(d->m_goForwardAction, SIGNAL(triggered()), this, SLOT(goForwardInNavigationHistory()));
con's avatar
con committed
372

hjk's avatar
hjk committed
373
    d->m_splitAction = new QAction(tr("Split"), this);
Eike Ziller's avatar
Eike Ziller committed
374
    cmd = ActionManager::registerAction(d->m_splitAction, Constants::SPLIT, editManagerContext);
375
    cmd->setDefaultKeySequence(QKeySequence(UseMacShortcuts ? tr("Meta+E,2") : tr("Ctrl+E,2")));
376
    mwindow->addAction(cmd, Constants::G_WINDOW_SPLIT);
hjk's avatar
hjk committed
377
    connect(d->m_splitAction, SIGNAL(triggered()), this, SLOT(split()));
378

hjk's avatar
hjk committed
379
    d->m_splitSideBySideAction = new QAction(tr("Split Side by Side"), this);
Eike Ziller's avatar
Eike Ziller committed
380
    cmd = ActionManager::registerAction(d->m_splitSideBySideAction, Constants::SPLIT_SIDE_BY_SIDE, editManagerContext);
381
    cmd->setDefaultKeySequence(QKeySequence(UseMacShortcuts ? tr("Meta+E,3") : tr("Ctrl+E,3")));
382
    mwindow->addAction(cmd, Constants::G_WINDOW_SPLIT);
hjk's avatar
hjk committed
383
    connect(d->m_splitSideBySideAction, SIGNAL(triggered()), this, SLOT(splitSideBySide()));
384

hjk's avatar
hjk committed
385
    d->m_removeCurrentSplitAction = new QAction(tr("Remove Current Split"), this);
Eike Ziller's avatar
Eike Ziller committed
386
    cmd = ActionManager::registerAction(d->m_removeCurrentSplitAction, Constants::REMOVE_CURRENT_SPLIT, editManagerContext);
387
    cmd->setDefaultKeySequence(QKeySequence(UseMacShortcuts ? tr("Meta+E,0") : tr("Ctrl+E,0")));
388
    mwindow->addAction(cmd, Constants::G_WINDOW_SPLIT);
hjk's avatar
hjk committed
389
    connect(d->m_removeCurrentSplitAction, SIGNAL(triggered()), this, SLOT(removeCurrentSplit()));
390

hjk's avatar
hjk committed
391
    d->m_removeAllSplitsAction = new QAction(tr("Remove All Splits"), this);
Eike Ziller's avatar
Eike Ziller committed
392
    cmd = ActionManager::registerAction(d->m_removeAllSplitsAction, Constants::REMOVE_ALL_SPLITS, editManagerContext);
393
    cmd->setDefaultKeySequence(QKeySequence(UseMacShortcuts ? tr("Meta+E,1") : tr("Ctrl+E,1")));
394
    mwindow->addAction(cmd, Constants::G_WINDOW_SPLIT);
hjk's avatar
hjk committed
395
    connect(d->m_removeAllSplitsAction, SIGNAL(triggered()), this, SLOT(removeAllSplits()));
396

hjk's avatar
hjk committed
397
    d->m_gotoOtherSplitAction = new QAction(tr("Go to Next Split"), this);
Eike Ziller's avatar
Eike Ziller committed
398
    cmd = ActionManager::registerAction(d->m_gotoOtherSplitAction, Constants::GOTO_OTHER_SPLIT, editManagerContext);
399
    cmd->setDefaultKeySequence(QKeySequence(UseMacShortcuts ? tr("Meta+E,o") : tr("Ctrl+E,o")));
400
    mwindow->addAction(cmd, Constants::G_WINDOW_SPLIT);
hjk's avatar
hjk committed
401
    connect(d->m_gotoOtherSplitAction, SIGNAL(triggered()), this, SLOT(gotoOtherSplit()));
402

Eike Ziller's avatar
Eike Ziller committed
403
404
    ActionContainer *medit = ActionManager::actionContainer(Constants::M_EDIT);
    ActionContainer *advancedMenu = ActionManager::createMenu(Constants::M_EDIT_ADVANCED);
405
    medit->addMenu(advancedMenu, Constants::G_EDIT_ADVANCED);
con's avatar
con committed
406
    advancedMenu->menu()->setTitle(tr("Ad&vanced"));
407
408
    advancedMenu->appendGroup(Constants::G_EDIT_FORMAT);
    advancedMenu->appendGroup(Constants::G_EDIT_COLLAPSING);
mae's avatar
mae committed
409
    advancedMenu->appendGroup(Constants::G_EDIT_BLOCKS);
410
411
412
413
    advancedMenu->appendGroup(Constants::G_EDIT_FONT);
    advancedMenu->appendGroup(Constants::G_EDIT_EDITOR);

    // Advanced menu separators
414
415
416
417
    advancedMenu->addSeparator(editManagerContext, Constants::G_EDIT_COLLAPSING);
    advancedMenu->addSeparator(editManagerContext, Constants::G_EDIT_BLOCKS);
    advancedMenu->addSeparator(editManagerContext, Constants::G_EDIT_FONT);
    advancedMenu->addSeparator(editManagerContext, Constants::G_EDIT_EDITOR);
hjk's avatar
hjk committed
418

con's avatar
con committed
419
    // other setup
hjk's avatar
hjk committed
420
421
    d->m_splitter = new SplitterOrView(d->m_editorModel);
    d->m_view = d->m_splitter->view();
mae's avatar
mae committed
422

con's avatar
con committed
423

424
425
426
    QHBoxLayout *layout = new QHBoxLayout(this);
    layout->setMargin(0);
    layout->setSpacing(0);
hjk's avatar
hjk committed
427
    layout->addWidget(d->m_splitter);
con's avatar
con committed
428
429
430

    updateActions();

hjk's avatar
hjk committed
431
    d->m_windowPopup = new OpenEditorsWindow(this);
432

hjk's avatar
hjk committed
433
434
    d->m_autoSaveTimer = new QTimer(this);
    connect(d->m_autoSaveTimer, SIGNAL(timeout()), SLOT(autoSave()));
435
    updateAutoSave();
con's avatar
con committed
436
437
438
439
}

EditorManager::~EditorManager()
{
440
    m_instance = 0;
hjk's avatar
hjk committed
441
    if (ICore::instance()) {
hjk's avatar
hjk committed
442
        if (d->m_coreListener) {
443
            ExtensionSystem::PluginManager::removeObject(d->m_coreListener);
hjk's avatar
hjk committed
444
            delete d->m_coreListener;
con's avatar
con committed
445
        }
446
        ExtensionSystem::PluginManager::removeObject(d->m_openEditorsFactory);
hjk's avatar
hjk committed
447
        delete d->m_openEditorsFactory;
con's avatar
con committed
448
    }
hjk's avatar
hjk committed
449
    delete d;
con's avatar
con committed
450
451
452
453
}

void EditorManager::init()
{
hjk's avatar
hjk committed
454
    d->m_coreListener = new EditorClosingCoreListener(this);
455
    ExtensionSystem::PluginManager::addObject(d->m_coreListener);
con's avatar
con committed
456

hjk's avatar
hjk committed
457
    d->m_openEditorsFactory = new OpenEditorsViewFactory();
458
    ExtensionSystem::PluginManager::addObject(d->m_openEditorsFactory);
con's avatar
con committed
459

Eike Ziller's avatar
Eike Ziller committed
460
461
    VariableManager::registerFileVariables(kCurrentDocumentPrefix, tr("Current document"));
    VariableManager::registerVariable(kCurrentDocumentXPos,
con's avatar
con committed
462
        tr("X-coordinate of the current editor's upper left corner, relative to screen."));
Eike Ziller's avatar
Eike Ziller committed
463
    VariableManager::registerVariable(kCurrentDocumentYPos,
con's avatar
con committed
464
        tr("Y-coordinate of the current editor's upper left corner, relative to screen."));
Eike Ziller's avatar
Eike Ziller committed
465
    connect(VariableManager::instance(), SIGNAL(variableUpdateRequested(QByteArray)),
hjk's avatar
hjk committed
466
            this, SLOT(updateVariable(QByteArray)));
con's avatar
con committed
467
468
}

469
470
void EditorManager::updateAutoSave()
{
hjk's avatar
hjk committed
471
472
    if (d->m_autoSaveEnabled)
        d->m_autoSaveTimer->start(d->m_autoSaveInterval * (60 * 1000));
473
    else
hjk's avatar
hjk committed
474
        d->m_autoSaveTimer->stop();
475
}
Lasse Holmstedt's avatar
Lasse Holmstedt committed
476

Lasse Holmstedt's avatar
Lasse Holmstedt committed
477
EditorToolBar *EditorManager::createToolBar(QWidget *parent)
Lasse Holmstedt's avatar
Lasse Holmstedt committed
478
{
Lasse Holmstedt's avatar
Lasse Holmstedt committed
479
    return new EditorToolBar(parent);
Lasse Holmstedt's avatar
Lasse Holmstedt committed
480
481
}

mae's avatar
mae committed
482
void EditorManager::removeEditor(IEditor *editor)
con's avatar
con committed
483
{
hjk's avatar
hjk committed
484
485
    bool isDuplicate = d->m_editorModel->isDuplicate(editor);
    d->m_editorModel->removeEditor(editor);
hjk's avatar
hjk committed
486
    if (!isDuplicate)
487
        DocumentManager::removeDocument(editor->document());
hjk's avatar
hjk committed
488
    ICore::removeContextObject(editor);
con's avatar
con committed
489
490
}

491
void EditorManager::handleContextChange(Core::IContext *context)
con's avatar
con committed
492
493
494
495
{
    if (debugEditorManager)
        qDebug() << Q_FUNC_INFO;
    IEditor *editor = context ? qobject_cast<IEditor*>(context) : 0;
496
    if (editor)
497
        setCurrentEditor(editor);
498
    else
499
        updateActions();
500
501
}

con's avatar
con committed
502
503
void EditorManager::setCurrentEditor(IEditor *editor, bool ignoreNavigationHistory)
{
504
505
506
    if (editor)
        setCurrentView(0);

hjk's avatar
hjk committed
507
    if (d->m_currentEditor == editor)
con's avatar
con committed
508
        return;
hjk's avatar
hjk committed
509
    if (d->m_currentEditor && !ignoreNavigationHistory)
510
        addCurrentPositionToNavigationHistory();
mae's avatar
mae committed
511

hjk's avatar
hjk committed
512
    d->m_currentEditor = editor;
con's avatar
con committed
513
    if (editor) {
hjk's avatar
hjk committed
514
        if (SplitterOrView *splitterOrView = d->m_splitter->findView(editor))
515
            splitterOrView->view()->setCurrentEditor(editor);
hjk's avatar
hjk committed
516
        d->m_view->updateEditorHistory(editor); // the global view should have a complete history
con's avatar
con committed
517
    }
mae's avatar
mae committed
518
    updateActions();
519
    updateWindowTitle();
mae's avatar
mae committed
520
    emit currentEditorChanged(editor);
con's avatar
con committed
521
522
}

mae's avatar
mae committed
523
524
525

void EditorManager::setCurrentView(Core::Internal::SplitterOrView *view)
{
hjk's avatar
hjk committed
526
    if (view == d->m_currentView)
mae's avatar
mae committed
527
528
        return;

hjk's avatar
hjk committed
529
530
    SplitterOrView *old = d->m_currentView;
    d->m_currentView = view;
mae's avatar
mae committed
531
532
533
534
535

    if (old)
        old->update();
    if (view)
        view->update();
536
537
538

    if (view && !view->editor())
        view->setFocus();
mae's avatar
mae committed
539
540
}

mae's avatar
mae committed
541
Core::Internal::SplitterOrView *EditorManager::currentSplitterOrView() const
mae's avatar
mae committed
542
{
hjk's avatar
hjk committed
543
    SplitterOrView *view = d->m_currentView;
544
    if (!view)
hjk's avatar
hjk committed
545
546
547
        view = d->m_currentEditor?
               d->m_splitter->findView(d->m_currentEditor):
               d->m_splitter->findFirstView();
mae's avatar
mae committed
548
    if (!view)
hjk's avatar
hjk committed
549
        return d->m_splitter;
550
    return view;
mae's avatar
mae committed
551
552
}

553
554
555
556
557
Core::Internal::SplitterOrView *EditorManager::topSplitterOrView() const
{
    return d->m_splitter;
}

mae's avatar
mae committed
558
559
560
561
562
Core::Internal::EditorView *EditorManager::currentEditorView() const
{
    return currentSplitterOrView()->view();
}

con's avatar
con committed
563
564
565
QList<IEditor *> EditorManager::editorsForFileName(const QString &filename) const
{
    QList<IEditor *> found;
566
    QString fixedname = DocumentManager::fixFileName(filename, DocumentManager::KeepLinks);
con's avatar
con committed
567
    foreach (IEditor *editor, openedEditors()) {
568
        if (fixedname == DocumentManager::fixFileName(editor->document()->fileName(), DocumentManager::KeepLinks))
con's avatar
con committed
569
570
571
572
573
            found << editor;
    }
    return found;
}

574
QList<IEditor *> EditorManager::editorsForDocument(IDocument *document) const
575
576
577
{
    QList<IEditor *> found;
    foreach (IEditor *editor, openedEditors()) {
578
        if (editor->document() == document)
579
580
581
582
583
            found << editor;
    }
    return found;
}

hjk's avatar
hjk committed
584
IEditor *EditorManager::currentEditor()
con's avatar
con committed
585
{
hjk's avatar
hjk committed
586
    return m_instance->d->m_currentEditor;
con's avatar
con committed
587
588
}

mae's avatar
mae committed
589
590
591
592
593
594
595
void EditorManager::emptyView(Core::Internal::EditorView *view)
{
    if (!view)
        return;

    QList<IEditor *> editors = view->editors();
    foreach (IEditor *editor, editors) {
hjk's avatar
hjk committed
596
        if (!d->m_editorModel->isDuplicate(editor)) {
mae's avatar
mae committed
597
598
599
600
601
602
603
604
605
606
607
608
609
610
            editors.removeAll(editor);
            view->removeEditor(editor);
            continue;
        }
        emit editorAboutToClose(editor);
        removeEditor(editor);
        view->removeEditor(editor);
    }
    emit editorsClosed(editors);
    foreach (IEditor *editor, editors) {
        delete editor;
    }
}

mae's avatar
mae committed
611
void EditorManager::closeView(Core::Internal::EditorView *view)
con's avatar
con committed
612
{
mae's avatar
mae committed
613
    if (!view)
con's avatar
con committed
614
        return;
mae's avatar
mae committed
615

hjk's avatar
hjk committed
616
    if (view == d->m_view) {
617
618
        if (IEditor *e = view->currentEditor())
            closeEditors(QList<IEditor *>() << e);
mae's avatar
mae committed
619
620
621
        return;
    }

622
623
624
625
626
627
628
629
630
631
    if (IEditor *e = view->currentEditor()) {
        /*
           when we are closing a view with an original editor which has
           duplicates, then make one of the duplicates the original.
           Otherwise the original would be kept around and the user might
           experience jumping to a missleading position within the file when
           visiting the file again. With the code below, the position within
           the file will be the position of the first duplicate which is still
           around.
        */
hjk's avatar
hjk committed
632
633
        if (!d->m_editorModel->isDuplicate(e)) {
            QList<IEditor *> duplicates = d->m_editorModel->duplicatesFor(e);
634
            if (!duplicates.isEmpty())
hjk's avatar
hjk committed
635
                d->m_editorModel->makeOriginal(duplicates.first());
636
637
638
        }
    }

mae's avatar
mae committed
639
640
    emptyView(view);

hjk's avatar
hjk committed
641
    SplitterOrView *splitterOrView = d->m_splitter->findView(view);
642
    Q_ASSERT(splitterOrView);
mae's avatar
mae committed
643
    Q_ASSERT(splitterOrView->view() == view);
hjk's avatar
hjk committed
644
    SplitterOrView *splitter = d->m_splitter->findSplitter(splitterOrView);
mae's avatar
mae committed
645
    Q_ASSERT(splitterOrView->hasEditors() == false);
646
    splitterOrView->hide();
mae's avatar
mae committed
647
648
649
650
651
652
    delete splitterOrView;

    splitter->unsplit();

    SplitterOrView *newCurrent = splitter->findFirstView();
    if (newCurrent) {
653
        if (IEditor *e = newCurrent->editor())
654
            activateEditor(newCurrent->view(), e);
655
        else
mae's avatar
mae committed
656
            setCurrentView(newCurrent);
mae's avatar
mae committed
657
    }
mae's avatar
mae committed
658
}
mae's avatar
mae committed
659

con's avatar
con committed
660
QList<IEditor*>
661
    EditorManager::editorsForDocuments(QList<IDocument*> documents) const
con's avatar
con committed
662
663
664
{
    const QList<IEditor *> editors = openedEditors();
    QSet<IEditor *> found;
665
    foreach (IDocument *document, documents) {
con's avatar
con committed
666
        foreach (IEditor *editor, editors) {
667
            if (editor->document() == document && !found.contains(editor))
con's avatar
con committed
668
669
670
671
672
673
                    found << editor;
        }
    }
    return found.toList();
}

674
QList<IDocument *> EditorManager::documentsForEditors(QList<IEditor *> editors) const
con's avatar
con committed
675
676
{
    QSet<IEditor *> handledEditors;
677
    QList<IDocument *> documents;
con's avatar
con committed
678
679
    foreach (IEditor *editor, editors) {
        if (!handledEditors.contains(editor)) {
680
            documents << editor->document();
681
            handledEditors.insert(editor);
con's avatar
con committed
682
683
        }
    }
684
    return documents;
con's avatar
con committed
685
686
687
688
}

bool EditorManager::closeAllEditors(bool askAboutModifiedEditors)
{
hjk's avatar
hjk committed
689
    d->m_editorModel->removeAllRestoredEditors();
690
    if (closeEditors(openedEditors(), askAboutModifiedEditors)) {
hjk's avatar
hjk committed
691
//        d->clearNavigationHistory();
692
693
694
        return true;
    }
    return false;
con's avatar
con committed
695
696
}

697
void EditorManager::closeOtherEditors(IEditor *editor)
con's avatar
con committed
698
{
hjk's avatar
hjk committed
699
    d->m_editorModel->removeAllRestoredEditors();
con's avatar
con committed
700
    QList<IEditor*> editors = openedEditors();
701
    editors.removeAll(editor);
con's avatar
con committed
702
703
704
    closeEditors(editors, true);
}

705
706
707
708
709
710
711
void EditorManager::closeOtherEditors()
{
    IEditor *current = currentEditor();
    QTC_ASSERT(current, return);
    closeOtherEditors(current);
}

712
713
714
// SLOT connected to action
void EditorManager::closeEditor()
{
hjk's avatar
hjk committed
715
    if (!d->m_currentEditor)
716
        return;
717
    addCurrentPositionToNavigationHistory();
hjk's avatar
hjk committed
718
    closeEditor(d->m_currentEditor);
719
720
}

721
722
723
724
725
726
static void assignAction(QAction *self, QAction *other)
{
    self->setText(other->text());
    self->setIcon(other->icon());
    self->setShortcut(other->shortcut());
    self->setEnabled(other->isEnabled());
727
    self->setIconVisibleInMenu(other->isIconVisibleInMenu());
728
729
730
}

void EditorManager::addSaveAndCloseEditorActions(QMenu *contextMenu, const QModelIndex &editorIndex)
731
732
{
    QTC_ASSERT(contextMenu, return);
hjk's avatar
hjk committed
733
    d->m_contextMenuEditorIndex = editorIndex;
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752

    assignAction(d->m_saveCurrentEditorContextAction, ActionManager::command(Constants::SAVE)->action());
    assignAction(d->m_saveAsCurrentEditorContextAction, ActionManager::command(Constants::SAVEAS)->action());
    assignAction(d->m_revertToSavedCurrentEditorContextAction, ActionManager::command(Constants::REVERTTOSAVED)->action());

    IEditor *editor = d->m_contextMenuEditorIndex.data(Qt::UserRole).value<Core::IEditor*>();

    setupSaveActions(editor,
                     d->m_saveCurrentEditorContextAction,
                     d->m_saveAsCurrentEditorContextAction,
                     d->m_revertToSavedCurrentEditorContextAction);

    contextMenu->addAction(d->m_saveCurrentEditorContextAction);
    contextMenu->addAction(d->m_saveAsCurrentEditorContextAction);
    contextMenu->addAction(ActionManager::command(Constants::SAVEALL)->action());
    contextMenu->addAction(d->m_revertToSavedCurrentEditorContextAction);

    contextMenu->addSeparator();

hjk's avatar
hjk committed
753
    d->m_closeCurrentEditorContextAction->setText(editorIndex.isValid()
754
755
                                                    ? tr("Close \"%1\"").arg(editorIndex.data().toString())
                                                    : tr("Close Editor"));
hjk's avatar
hjk committed
756
    d->m_closeOtherEditorsContextAction->setText(editorIndex.isValid()
757
758
                                                   ? tr("Close All Except \"%1\"").arg(editorIndex.data().toString())
                                                   : tr("Close Other Editors"));
hjk's avatar
hjk committed
759
760
761
762
763
764
    d->m_closeCurrentEditorContextAction->setEnabled(editorIndex.isValid());
    d->m_closeOtherEditorsContextAction->setEnabled(editorIndex.isValid());
    d->m_closeAllEditorsContextAction->setEnabled(!openedEditors().isEmpty());
    contextMenu->addAction(d->m_closeCurrentEditorContextAction);
    contextMenu->addAction(d->m_closeAllEditorsContextAction);
    contextMenu->addAction(d->m_closeOtherEditorsContextAction);
765
766
}

Robert Loehning's avatar
Robert Loehning committed
767
768
769
void EditorManager::addNativeDirActions(QMenu *contextMenu, const QModelIndex &editorIndex)
{
    QTC_ASSERT(contextMenu, return);
hjk's avatar
hjk committed
770
771
772
773
    d->m_openGraphicalShellAction->setEnabled(editorIndex.isValid());
    d->m_openTerminalAction->setEnabled(editorIndex.isValid());
    contextMenu->addAction(d->m_openGraphicalShellAction);
    contextMenu->addAction(d->m_openTerminalAction);
Robert Loehning's avatar
Robert Loehning committed
774
775
}

776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
void EditorManager::saveDocumentFromContextMenu()
{
    IEditor *editor = d->m_contextMenuEditorIndex.data(Qt::UserRole).value<Core::IEditor*>();
    if (editor)
        saveDocument(editor->document());
}

void EditorManager::saveDocumentAsFromContextMenu()
{
    IEditor *editor = d->m_contextMenuEditorIndex.data(Qt::UserRole).value<Core::IEditor*>();
    if (editor)
        saveDocumentAs(editor->document());
}

void EditorManager::revertToSavedFromContextMenu()
{
    IEditor *editor = d->m_contextMenuEditorIndex.data(Qt::UserRole).value<Core::IEditor*>();
    if (editor)
        revertToSaved(editor);
}

797
798
void EditorManager::closeEditorFromContextMenu()
{
hjk's avatar
hjk committed
799
    closeEditor(d->m_contextMenuEditorIndex);
800
801
802
803
}

void EditorManager::closeOtherEditorsFromContextMenu()
{
hjk's avatar
hjk committed
804
    closeOtherEditors(d->m_contextMenuEditorIndex.data(Qt::UserRole).value<IEditor *>());
805
806
}

Robert Loehning's avatar
Robert Loehning committed
807
808
void EditorManager::showInGraphicalShell()
{
hjk's avatar
hjk committed
809
    const QString path = d->m_contextMenuEditorIndex.data(Qt::UserRole + 1).toString();
hjk's avatar
hjk committed
810
    Core::FileUtils::showInGraphicalShell(ICore::mainWindow(), path);
Robert Loehning's avatar
Robert Loehning committed
811
812
813
814
}

void EditorManager::openTerminal()
{
hjk's avatar
hjk committed
815
    const QString path = QFileInfo(d->m_contextMenuEditorIndex.data(Qt::UserRole + 1).toString()).path();
816
    Core::FileUtils::openTerminal(path);
Robert Loehning's avatar
Robert Loehning committed
817
818
}

819
820
821
822
823
824
825
826
827
828
829
830
831
void EditorManager::closeEditor(Core::IEditor *editor)
{
    if (!editor)
        return;
    closeEditors(QList<IEditor *>() << editor);
}

void EditorManager::closeEditor(const QModelIndex &index)
{
    IEditor *editor = index.data(Qt::UserRole).value<Core::IEditor*>();
    if (editor)
        closeEditor(editor);
    else
hjk's avatar
hjk committed
832
        d->m_editorModel->removeEditor(index);
833
834
}

835
bool EditorManager::closeEditors(const QList<IEditor*> &editorsToClose, bool askAboutModifiedEditors)
con's avatar
con committed
836
837
838
{
    if (editorsToClose.isEmpty())
        return true;
839

mae's avatar
mae committed
840
    SplitterOrView *currentSplitterOrView = this->currentSplitterOrView();
841

con's avatar
con committed
842
843
844
845
    bool closingFailed = false;
    QList<IEditor*> acceptedEditors;
    //ask all core listeners to check whether the editor can be closed
    const QList<ICoreListener *> listeners =
846
        ExtensionSystem::PluginManager::getObjects<ICoreListener>();
con's avatar
con committed
847
848
    foreach (IEditor *editor, editorsToClose) {
        bool editorAccepted = true;
hjk's avatar
hjk committed
849
850
        if (d->m_editorModel->isDuplicate(editor))
            editor = d->m_editorModel->originalForDuplicate(editor);
con's avatar
con committed
851
852
853
        foreach (ICoreListener *listener, listeners) {
            if (!listener->editorAboutToClose(editor)) {
                editorAccepted = false;
854
                closingFailed = true;
con's avatar
con committed
855
856
857
858
859
860
861
862
863
864
865
                break;
            }
        }
        if (editorAccepted)
            acceptedEditors.append(editor);
    }
    if (acceptedEditors.isEmpty())
        return false;
    //ask whether to save modified files
    if (askAboutModifiedEditors) {
        bool cancelled = false;
866
        QList<IDocument*> list = DocumentManager::saveModifiedDocuments(documentsForEditors(acceptedEditors), &cancelled);
con's avatar
con committed
867
868
869
        if (cancelled)
            return false;
        if (!list.isEmpty()) {
870
            closingFailed = true;
871
            QSet<IEditor*> skipSet = editorsForDocuments(list).toSet();
con's avatar
con committed
872
873
874
875
876
            acceptedEditors = acceptedEditors.toSet().subtract(skipSet).toList();
        }
    }
    if (acceptedEditors.isEmpty())
        return false;
mae's avatar
mae committed
877

878
879
880
    // close Editor History list
    windowPopup()->setVisible(false);

mae's avatar
mae committed
881
    // add duplicates
882
    QList<IEditor *> duplicates;
883
    foreach (IEditor *editor, acceptedEditors)
884
885
        duplicates += d->m_editorModel->duplicatesFor(editor);
    acceptedEditors += duplicates;
mae's avatar
mae committed
886

887
    QList<EditorView*> closedViews;
mae's avatar
mae committed
888

con's avatar
con committed
889
890
891
    // remove the editors
    foreach (IEditor *editor, acceptedEditors) {
        emit editorAboutToClose(editor);
892
        if (!editor->document()->fileName().isEmpty()
893
                && !editor->isTemporary()) {
con's avatar
con committed
894
895
            QByteArray state = editor->saveState();
            if (!state.isEmpty())
896
                d->m_editorStates.insert(editor->document()->fileName(), QVariant(state));
con's avatar
con committed
897
        }
mae's avatar
mae committed
898

mae's avatar
mae committed
899
        removeEditor(editor);
hjk's avatar
hjk committed
900
        if (SplitterOrView *view = d->m_splitter->findView(editor)) {
901
902
            if (editor == view->view()->currentEditor())
                closedViews += view->view();
mae's avatar
mae committed
903
            view->view()->removeEditor(editor);
mae's avatar
mae committed
904
        }
con's avatar
con committed
905
    }
mae's avatar
mae committed
906

907
    foreach (EditorView *view, closedViews) {
mae's avatar
mae committed
908
909
910
        IEditor *newCurrent = view->currentEditor();
        if (!newCurrent)
            newCurrent = pickUnusedEditor();