From 690f4cced597e19a12e05be8f63cf02f91d8d054 Mon Sep 17 00:00:00 2001 From: dankers Date: Thu, 4 Feb 2010 06:12:53 +0000 Subject: [PATCH] Branding again.... git-svn-id: svn://svn.openpilot.org/OpenPilot/trunk@169 ebee16cc-31ac-478f-84a7-5cbb03baadba --- ground/src/plugins/coreplugin/core.qrc | 99 +- ground/src/plugins/coreplugin/coreconstants.h | 2 +- .../editormanager/editormanager.cpp | 3874 ++++++++--------- .../coreplugin/images/openpilot_logo_256.png | Bin 0 -> 15596 bytes .../coreplugin/images/openpilot_logo_64.png | Bin 0 -> 3523 bytes ground/src/plugins/coreplugin/mainwindow.cpp | 6 +- .../src/plugins/coreplugin/versiondialog.cpp | 2 +- 7 files changed, 1993 insertions(+), 1990 deletions(-) create mode 100644 ground/src/plugins/coreplugin/images/openpilot_logo_256.png create mode 100644 ground/src/plugins/coreplugin/images/openpilot_logo_64.png diff --git a/ground/src/plugins/coreplugin/core.qrc b/ground/src/plugins/coreplugin/core.qrc index 42f59f6c1..84f9047a9 100644 --- a/ground/src/plugins/coreplugin/core.qrc +++ b/ground/src/plugins/coreplugin/core.qrc @@ -1,48 +1,51 @@ - - - images/clean_pane_small.png - images/clear.png - images/closebutton.png - images/dir.png - images/editcopy.png - images/editcut.png - images/editpaste.png - images/empty14.png - images/filenew.png - images/fileopen.png - images/filesave.png - images/find.png - images/findnext.png - images/qtcreator_logo_128.png - images/qtcreator_logo_32.png - images/inputfield.png - images/inputfield_disabled.png - images/linkicon.png - images/locked.png - images/magnifier.png - images/minus.png - images/next.png - images/panel_button.png - images/panel_button_checked.png - images/panel_button_checked_hover.png - images/panel_button_hover.png - images/panel_button_pressed.png - images/plus.png - images/prev.png - images/pushbutton.png - images/pushbutton_hover.png - images/pushbutton_pressed.png - images/qtwatermark.png - images/redo.png - images/replace.png - images/reset.png - images/sidebaricon.png - images/splitbutton_horizontal.png - images/statusbar.png - images/undo.png - images/unknownfile.png - images/unlocked.png - images/extension.png - images/darkclosebutton.png - - + + + images/openpilot_logo_256.png + images/openpilot_logo_128.png + images/openpilot_logo_64.png + images/clean_pane_small.png + images/clear.png + images/closebutton.png + images/dir.png + images/editcopy.png + images/editcut.png + images/editpaste.png + images/empty14.png + images/filenew.png + images/fileopen.png + images/filesave.png + images/find.png + images/findnext.png + images/qtcreator_logo_128.png + images/qtcreator_logo_32.png + images/inputfield.png + images/inputfield_disabled.png + images/linkicon.png + images/locked.png + images/magnifier.png + images/minus.png + images/next.png + images/panel_button.png + images/panel_button_checked.png + images/panel_button_checked_hover.png + images/panel_button_hover.png + images/panel_button_pressed.png + images/plus.png + images/prev.png + images/pushbutton.png + images/pushbutton_hover.png + images/pushbutton_pressed.png + images/qtwatermark.png + images/redo.png + images/replace.png + images/reset.png + images/sidebaricon.png + images/splitbutton_horizontal.png + images/statusbar.png + images/undo.png + images/unknownfile.png + images/unlocked.png + images/extension.png + images/darkclosebutton.png + + diff --git a/ground/src/plugins/coreplugin/coreconstants.h b/ground/src/plugins/coreplugin/coreconstants.h index a917dc047..bf6ac57a1 100644 --- a/ground/src/plugins/coreplugin/coreconstants.h +++ b/ground/src/plugins/coreplugin/coreconstants.h @@ -122,7 +122,7 @@ const char * const MINIMIZE_WINDOW = "QtCreator.MinimizeWindow"; const char * const ZOOM_WINDOW = "QtCreator.ZoomWindow"; const char * const SPLIT = "QtCreator.Split"; -const char * const SPLIT_SGCS_BY_SIDE = "QtCreator.SplitSideBySide"; +const char * const SPLIT_SIDE_BY_SIDE = "QtCreator.SplitSideBySide"; const char * const REMOVE_CURRENT_SPLIT = "QtCreator.RemoveCurrentSplit"; const char * const REMOVE_ALL_SPLITS = "QtCreator.RemoveAllSplits"; const char * const GOTO_OTHER_SPLIT = "QtCreator.GotoOtherSplit"; diff --git a/ground/src/plugins/coreplugin/editormanager/editormanager.cpp b/ground/src/plugins/coreplugin/editormanager/editormanager.cpp index 610ef1047..21f032904 100644 --- a/ground/src/plugins/coreplugin/editormanager/editormanager.cpp +++ b/ground/src/plugins/coreplugin/editormanager/editormanager.cpp @@ -1,1937 +1,1937 @@ -/************************************************************************** -** -** This file is part of Qt Creator -** -** Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies). -** -** Contact: Nokia Corporation (qt-info@nokia.com) -** -** Commercial Usage -** -** Licensees holding valid Qt Commercial licenses may use this file in -** accordance with the Qt Commercial License Agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and Nokia. -** -** GNU Lesser General Public License Usage -** -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 2.1 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 2.1 requirements -** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** If you are unsure which license is appropriate for your use, please -** contact the sales department at http://qt.nokia.com/contact. -** -**************************************************************************/ - -#include "editormanager.h" -#include "editorview.h" -#include "openeditorswindow.h" -#include "openeditorsview.h" -#include "openeditorsmodel.h" -#include "openwithdialog.h" -#include "filemanager.h" -#include "icore.h" -#include "iversioncontrol.h" -#include "mimedatabase.h" -#include "tabpositionindicator.h" -#include "vcsmanager.h" - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include - -#include -#include - -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -Q_DECLARE_METATYPE(Core::IEditor*) - -using namespace Core; -using namespace Core::Internal; -using namespace Utils; - -enum { debugEditorManager=0 }; - -static inline ExtensionSystem::PluginManager *pluginManager() -{ - return ExtensionSystem::PluginManager::instance(); -} - -//===================EditorManager===================== - -EditorManagerPlaceHolder *EditorManagerPlaceHolder::m_current = 0; - -EditorManagerPlaceHolder::EditorManagerPlaceHolder(Core::IMode *mode, QWidget *parent) - : QWidget(parent), m_mode(mode) -{ - setLayout(new QVBoxLayout); - layout()->setMargin(0); - connect(Core::ModeManager::instance(), SIGNAL(currentModeChanged(Core::IMode *)), - this, SLOT(currentModeChanged(Core::IMode *))); - - currentModeChanged(Core::ModeManager::instance()->currentMode()); -} - -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 - -namespace Core { - - -struct EditorManagerPrivate { - explicit EditorManagerPrivate(ICore *core, QWidget *parent); - ~EditorManagerPrivate(); - Internal::EditorView *m_view; - Internal::SplitterOrView *m_splitter; - QPointer m_currentEditor; - QPointer m_currentView; - - ICore *m_core; - - - // actions - QAction *m_revertToSavedAction; - QAction *m_saveAction; - QAction *m_saveAsAction; - QAction *m_closeCurrentEditorAction; - QAction *m_closeAllEditorsAction; - QAction *m_closeOtherEditorsAction; - QAction *m_gotoNextDocHistoryAction; - QAction *m_gotoPreviousDocHistoryAction; - QAction *m_goBackAction; - QAction *m_goForwardAction; - QAction *m_openInExternalEditorAction; - QAction *m_splitAction; - QAction *m_splitSideBySideAction; - QAction *m_removeCurrentSplitAction; - QAction *m_removeAllSplitsAction; - QAction *m_gotoOtherSplitAction; - - Internal::OpenEditorsWindow *m_windowPopup; - Core::BaseView *m_openEditorsView; - Internal::EditorClosingCoreListener *m_coreListener; - - QMap m_editorStates; - Internal::OpenEditorsViewFactory *m_openEditorsFactory; - - QString fileFilters; - QString selectedFilter; - - OpenEditorsModel *m_editorModel; - QString m_externalEditor; - - IFile::ReloadBehavior m_reloadBehavior; -}; -} - -EditorManagerPrivate::EditorManagerPrivate(ICore *core, QWidget *parent) : - m_view(0), - m_splitter(0), - m_core(core), - 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)), - m_closeOtherEditorsAction(new QAction(EditorManager::tr("Close Others"), parent)), - m_gotoNextDocHistoryAction(new QAction(EditorManager::tr("Next Open Document in History"), parent)), - m_gotoPreviousDocHistoryAction(new QAction(EditorManager::tr("Previous Open Document in History"), parent)), - m_goBackAction(new QAction(QIcon(QLatin1String(":/help/images/previous.png")), EditorManager::tr("Go Back"), parent)), - m_goForwardAction(new QAction(QIcon(QLatin1String(":/help/images/next.png")), EditorManager::tr("Go Forward"), parent)), - m_openInExternalEditorAction(new QAction(EditorManager::tr("Open in External Editor"), parent)), - m_windowPopup(0), - m_coreListener(0), - m_reloadBehavior(IFile::AskForReload) -{ - m_editorModel = new OpenEditorsModel(parent); -} - -EditorManagerPrivate::~EditorManagerPrivate() -{ -// clearNavigationHistory(); -} - -EditorManager *EditorManager::m_instance = 0; - -static Command *createSeparator(ActionManager *am, QObject *parent, - const QString &name, - const QList &context) -{ - QAction *tmpaction = new QAction(parent); - tmpaction->setSeparator(true); - Command *cmd = am->registerAction(tmpaction, name, context); - return cmd; -} - -EditorManager::EditorManager(ICore *core, QWidget *parent) : - QWidget(parent), - m_d(new EditorManagerPrivate(core, parent)) -{ - m_instance = this; - - connect(m_d->m_core, SIGNAL(contextAboutToChange(Core::IContext *)), - this, SLOT(handleContextChange(Core::IContext *))); - - const QList gc = QList() << Constants::C_GLOBAL_ID; - const QList editManagerContext = - QList() << m_d->m_core->uniqueIDManager()->uniqueIdentifier(Constants::C_EDITORMANAGER); - - ActionManager *am = m_d->m_core->actionManager(); - ActionContainer *mfile = am->actionContainer(Constants::M_FILE); - - //Revert to saved - Command *cmd = am->registerAction(m_d->m_revertToSavedAction, - Constants::REVERTTOSAVED, editManagerContext); - cmd->setAttribute(Command::CA_UpdateText); - cmd->setDefaultText(tr("Revert File to Saved")); - mfile->addAction(cmd, Constants::G_FILE_SAVE); - connect(m_d->m_revertToSavedAction, SIGNAL(triggered()), this, SLOT(revertToSaved())); - - //Save Action - am->registerAction(m_d->m_saveAction, Constants::SAVE, editManagerContext); - connect(m_d->m_saveAction, SIGNAL(triggered()), this, SLOT(saveFile())); - - //Save As Action - am->registerAction(m_d->m_saveAsAction, Constants::SAVEAS, editManagerContext); - connect(m_d->m_saveAsAction, SIGNAL(triggered()), this, SLOT(saveFileAs())); - - //Window Menu - ActionContainer *mwindow = am->actionContainer(Constants::M_WINDOW); - - //Window menu separators - QAction *tmpaction = new QAction(this); - tmpaction->setSeparator(true); - cmd = am->registerAction(tmpaction, QLatin1String("QtCreator.Window.Sep.Split"), editManagerContext); - mwindow->addAction(cmd, Constants::G_WINDOW_SPLIT); - - tmpaction = new QAction(this); - tmpaction->setSeparator(true); - cmd = am->registerAction(tmpaction, QLatin1String("QtCreator.Window.Sep.Navigate"), editManagerContext); - mwindow->addAction(cmd, Constants::G_WINDOW_NAVIGATE); - - //Close Action - cmd = am->registerAction(m_d->m_closeCurrentEditorAction, Constants::CLOSE, editManagerContext); - cmd->setDefaultKeySequence(QKeySequence(tr("Ctrl+W"))); - cmd->setAttribute(Core::Command::CA_UpdateText); - cmd->setDefaultText(m_d->m_closeCurrentEditorAction->text()); - mfile->addAction(cmd, Constants::G_FILE_CLOSE); - connect(m_d->m_closeCurrentEditorAction, SIGNAL(triggered()), this, SLOT(closeEditor())); - - //Close All Action - cmd = am->registerAction(m_d->m_closeAllEditorsAction, Constants::CLOSEALL, editManagerContext); - cmd->setDefaultKeySequence(QKeySequence(tr("Ctrl+Shift+W"))); - mfile->addAction(cmd, Constants::G_FILE_CLOSE); - connect(m_d->m_closeAllEditorsAction, SIGNAL(triggered()), this, SLOT(closeAllEditors())); - - //Close All Others Action - cmd = am->registerAction(m_d->m_closeOtherEditorsAction, Constants::CLOSEOTHERS, editManagerContext); - mfile->addAction(cmd, Constants::G_FILE_CLOSE); - cmd->setAttribute(Core::Command::CA_UpdateText); - connect(m_d->m_closeOtherEditorsAction, SIGNAL(triggered()), this, SLOT(closeOtherEditors())); - - // Goto Previous In History Action - cmd = am->registerAction(m_d->m_gotoPreviousDocHistoryAction, Constants::GOTOPREVINHISTORY, editManagerContext); -#ifdef Q_WS_MAC - cmd->setDefaultKeySequence(QKeySequence(tr("Alt+Tab"))); -#else - cmd->setDefaultKeySequence(QKeySequence(tr("Ctrl+Tab"))); -#endif - mwindow->addAction(cmd, Constants::G_WINDOW_NAVIGATE); - connect(m_d->m_gotoPreviousDocHistoryAction, SIGNAL(triggered()), this, SLOT(gotoPreviousDocHistory())); - - // Goto Next In History Action - cmd = am->registerAction(m_d->m_gotoNextDocHistoryAction, Constants::GOTONEXTINHISTORY, editManagerContext); -#ifdef Q_WS_MAC - cmd->setDefaultKeySequence(QKeySequence(tr("Alt+Shift+Tab"))); -#else - cmd->setDefaultKeySequence(QKeySequence(tr("Ctrl+Shift+Tab"))); -#endif - mwindow->addAction(cmd, Constants::G_WINDOW_NAVIGATE); - connect(m_d->m_gotoNextDocHistoryAction, SIGNAL(triggered()), this, SLOT(gotoNextDocHistory())); - - // Go back in navigation history - cmd = am->registerAction(m_d->m_goBackAction, Constants::GO_BACK, editManagerContext); -#ifdef Q_WS_MAC - cmd->setDefaultKeySequence(QKeySequence(tr("Ctrl+Alt+Left"))); -#else - cmd->setDefaultKeySequence(QKeySequence(tr("Alt+Left"))); -#endif - mwindow->addAction(cmd, Constants::G_WINDOW_NAVIGATE); - connect(m_d->m_goBackAction, SIGNAL(triggered()), this, SLOT(goBackInNavigationHistory())); - - // Go forward in navigation history - cmd = am->registerAction(m_d->m_goForwardAction, Constants::GO_FORWARD, editManagerContext); -#ifdef Q_WS_MAC - cmd->setDefaultKeySequence(QKeySequence(tr("Ctrl+Alt+Right"))); -#else - cmd->setDefaultKeySequence(QKeySequence(tr("Alt+Right"))); -#endif - mwindow->addAction(cmd, Constants::G_WINDOW_NAVIGATE); - connect(m_d->m_goForwardAction, SIGNAL(triggered()), this, SLOT(goForwardInNavigationHistory())); - -#ifdef Q_WS_MAC - QString prefix = tr("Meta+E"); -#else - QString prefix = tr("Ctrl+E"); -#endif - - m_d->m_splitAction = new QAction(tr("Split"), this); - cmd = am->registerAction(m_d->m_splitAction, Constants::SPLIT, editManagerContext); - cmd->setDefaultKeySequence(QKeySequence(tr("%1,2").arg(prefix))); - mwindow->addAction(cmd, Constants::G_WINDOW_SPLIT); - connect(m_d->m_splitAction, SIGNAL(triggered()), this, SLOT(split())); - - m_d->m_splitSideBySideAction = new QAction(tr("Split Side by Side"), this); - cmd = am->registerAction(m_d->m_splitSideBySideAction, Constants::SPLIT_SIDE_BY_SIDE, editManagerContext); - cmd->setDefaultKeySequence(QKeySequence(tr("%1,3").arg(prefix))); - mwindow->addAction(cmd, Constants::G_WINDOW_SPLIT); - connect(m_d->m_splitSideBySideAction, SIGNAL(triggered()), this, SLOT(splitSideBySide())); - - m_d->m_removeCurrentSplitAction = new QAction(tr("Remove Current Split"), this); - cmd = am->registerAction(m_d->m_removeCurrentSplitAction, Constants::REMOVE_CURRENT_SPLIT, editManagerContext); - cmd->setDefaultKeySequence(QKeySequence(tr("%1,0").arg(prefix))); - mwindow->addAction(cmd, Constants::G_WINDOW_SPLIT); - connect(m_d->m_removeCurrentSplitAction, SIGNAL(triggered()), this, SLOT(removeCurrentSplit())); - - m_d->m_removeAllSplitsAction = new QAction(tr("Remove All Splits"), this); - cmd = am->registerAction(m_d->m_removeAllSplitsAction, Constants::REMOVE_ALL_SPLITS, editManagerContext); - cmd->setDefaultKeySequence(QKeySequence(tr("%1,1").arg(prefix))); - mwindow->addAction(cmd, Constants::G_WINDOW_SPLIT); - connect(m_d->m_removeAllSplitsAction, SIGNAL(triggered()), this, SLOT(removeAllSplits())); - - m_d->m_gotoOtherSplitAction = new QAction(tr("Goto Other Split"), this); - cmd = am->registerAction(m_d->m_gotoOtherSplitAction, Constants::GOTO_OTHER_SPLIT, editManagerContext); - cmd->setDefaultKeySequence(QKeySequence(tr("%1,o").arg(prefix))); - mwindow->addAction(cmd, Constants::G_WINDOW_SPLIT); - connect(m_d->m_gotoOtherSplitAction, SIGNAL(triggered()), this, SLOT(gotoOtherSplit())); - - ActionContainer *medit = am->actionContainer(Constants::M_EDIT); - ActionContainer *advancedMenu = am->createMenu(Constants::M_EDIT_ADVANCED); - medit->addMenu(advancedMenu, Constants::G_EDIT_ADVANCED); - advancedMenu->menu()->setTitle(tr("&Advanced")); - advancedMenu->appendGroup(Constants::G_EDIT_FORMAT); - advancedMenu->appendGroup(Constants::G_EDIT_COLLAPSING); - advancedMenu->appendGroup(Constants::G_EDIT_BLOCKS); - advancedMenu->appendGroup(Constants::G_EDIT_FONT); - advancedMenu->appendGroup(Constants::G_EDIT_EDITOR); - - // Advanced menu separators - cmd = createSeparator(am, this, QLatin1String("QtCreator.Edit.Sep.Collapsing"), editManagerContext); - advancedMenu->addAction(cmd, Constants::G_EDIT_COLLAPSING); - cmd = createSeparator(am, this, QLatin1String("QtCreator.Edit.Sep.Blocks"), editManagerContext); - advancedMenu->addAction(cmd, Constants::G_EDIT_BLOCKS); - cmd = createSeparator(am, this, QLatin1String("QtCreator.Edit.Sep.Font"), editManagerContext); - advancedMenu->addAction(cmd, Constants::G_EDIT_FONT); - cmd = createSeparator(am, this, QLatin1String("QtCreator.Edit.Sep.Editor"), editManagerContext); - advancedMenu->addAction(cmd, Constants::G_EDIT_EDITOR); - - cmd = am->registerAction(m_d->m_openInExternalEditorAction, Constants::OPEN_IN_EXTERNAL_EDITOR, editManagerContext); - cmd->setDefaultKeySequence(QKeySequence(tr("Alt+V,Alt+I"))); - advancedMenu->addAction(cmd, Constants::G_EDIT_EDITOR); - connect(m_d->m_openInExternalEditorAction, SIGNAL(triggered()), this, SLOT(openInExternalEditor())); - - // Connect to VariableManager for CURRENT_DOCUMENT variable setting - VariableManager *vm = VariableManager::instance(); - connect(this, SIGNAL(currentEditorChanged(Core::IEditor *)), - vm, SLOT(updateCurrentDocument(Core::IEditor *))); - - - // other setup - m_d->m_splitter = new SplitterOrView(m_d->m_editorModel); - m_d->m_view = m_d->m_splitter->view(); - - - QHBoxLayout *layout = new QHBoxLayout(this); - layout->setMargin(0); - layout->setSpacing(0); - layout->addWidget(m_d->m_splitter); - - updateActions(); - - m_d->m_windowPopup = new OpenEditorsWindow(this); -} - -EditorManager::~EditorManager() -{ - if (m_d->m_core) { - ExtensionSystem::PluginManager *pm = ExtensionSystem::PluginManager::instance(); - if (m_d->m_coreListener) { - pm->removeObject(m_d->m_coreListener); - delete m_d->m_coreListener; - } - pm->removeObject(m_d->m_openEditorsFactory); - delete m_d->m_openEditorsFactory; - } - delete m_d; -} - -void EditorManager::init() -{ - QList context; - context << m_d->m_core->uniqueIDManager()->uniqueIdentifier("QtCreator.OpenDocumentsView"); - - m_d->m_coreListener = new EditorClosingCoreListener(this); - - pluginManager()->addObject(m_d->m_coreListener); - - m_d->m_openEditorsFactory = new OpenEditorsViewFactory(); - pluginManager()->addObject(m_d->m_openEditorsFactory); -} - -QString EditorManager::defaultExternalEditor() const -{ -#ifdef Q_OS_UNIX - return ConsoleProcess::defaultTerminalEmulator() + QLatin1String( -# ifdef Q_OS_MAC - " -async" -# endif - " -geom %Wx%H+%x+%y -e vi %f +%l +\"normal %c|\""); -#else - return QLatin1String("notepad %f"); -#endif -} - -void EditorManager::removeEditor(IEditor *editor) -{ - bool isDuplicate = m_d->m_editorModel->isDuplicate(editor); - m_d->m_editorModel->removeEditor(editor); - if (!isDuplicate) { - m_d->m_core->fileManager()->removeFile(editor->file()); - } - m_d->m_core->removeContextObject(editor); -} - -void EditorManager::handleContextChange(Core::IContext *context) -{ - if (debugEditorManager) - qDebug() << Q_FUNC_INFO; - IEditor *editor = context ? qobject_cast(context) : 0; - if (editor) { - setCurrentEditor(editor); - } else { - updateActions(); - } -} - -void EditorManager::setCurrentEditor(IEditor *editor, bool ignoreNavigationHistory) -{ - if (editor) - setCurrentView(0); - - if (m_d->m_currentEditor == editor) - return; - if (m_d->m_currentEditor && !ignoreNavigationHistory) - addCurrentPositionToNavigationHistory(); - - m_d->m_currentEditor = editor; - if (editor) { - if (SplitterOrView *splitterOrView = m_d->m_splitter->findView(editor)) - splitterOrView->view()->setCurrentEditor(editor); - m_d->m_view->updateEditorHistory(editor); // the global view should have a complete history - } - updateActions(); - emit currentEditorChanged(editor); -} - - -void EditorManager::setCurrentView(Core::Internal::SplitterOrView *view) -{ - if (view == m_d->m_currentView) - return; - - SplitterOrView *old = m_d->m_currentView; - m_d->m_currentView = view; - - if (old) - old->update(); - if (view) - view->update(); - - if (view && !view->editor()) - view->setFocus(); -} - -Core::Internal::SplitterOrView *EditorManager::currentSplitterOrView() const -{ - SplitterOrView *view = m_d->m_currentView; - if (!view) - view = m_d->m_currentEditor? - m_d->m_splitter->findView(m_d->m_currentEditor): - m_d->m_splitter->findFirstView(); - if (!view) - return m_d->m_splitter; - return view; -} - -Core::Internal::EditorView *EditorManager::currentEditorView() const -{ - return currentSplitterOrView()->view(); -} - - - -QList EditorManager::editorsForFileName(const QString &filename) const -{ - QList found; - QString fixedname = FileManager::fixFileName(filename); - foreach (IEditor *editor, openedEditors()) { - if (fixedname == FileManager::fixFileName(editor->file()->fileName())) - found << editor; - } - return found; -} - -QList EditorManager::editorsForFile(IFile *file) const -{ - QList found; - foreach (IEditor *editor, openedEditors()) { - if (editor->file() == file) - found << editor; - } - return found; -} - -IEditor *EditorManager::currentEditor() const -{ - return m_d->m_currentEditor; -} - -void EditorManager::emptyView(Core::Internal::EditorView *view) -{ - if (!view) - return; - - QList editors = view->editors(); - foreach (IEditor *editor, editors) { - if (!m_d->m_editorModel->isDuplicate(editor)) { - editors.removeAll(editor); - view->removeEditor(editor); - continue; - } - emit editorAboutToClose(editor); - removeEditor(editor); - view->removeEditor(editor); - } - emit editorsClosed(editors); - foreach (IEditor *editor, editors) { - delete editor; - } -} - -void EditorManager::closeView(Core::Internal::EditorView *view) -{ - if (!view) - return; - - if (view == m_d->m_view) { - if (IEditor *e = view->currentEditor()) - closeEditors(QList() << e); - return; - } - - emptyView(view); - - SplitterOrView *splitterOrView = m_d->m_splitter->findView(view); - Q_ASSERT(splitterOrView); - Q_ASSERT(splitterOrView->view() == view); - SplitterOrView *splitter = m_d->m_splitter->findSplitter(splitterOrView); - Q_ASSERT(splitterOrView->hasEditors() == false); - splitterOrView->hide(); - delete splitterOrView; - - splitter->unsplit(); - - SplitterOrView *newCurrent = splitter->findFirstView(); - if (newCurrent) { - if (newCurrent->editor()) - activateEditor(newCurrent->view(), newCurrent->editor()); - else - setCurrentView(newCurrent); - } -} - -QList - EditorManager::editorsForFiles(QList files) const -{ - const QList editors = openedEditors(); - QSet found; - foreach (IFile *file, files) { - foreach (IEditor *editor, editors) { - if (editor->file() == file && !found.contains(editor)) { - found << editor; - } - } - } - return found.toList(); -} - -QList EditorManager::filesForEditors(QList editors) const -{ - QSet handledEditors; - QList files; - foreach (IEditor *editor, editors) { - if (!handledEditors.contains(editor)) { - files << editor->file(); - handledEditors.insert(editor); - } - } - return files; -} - -bool EditorManager::closeAllEditors(bool askAboutModifiedEditors) -{ - m_d->m_editorModel->removeAllRestoredEditors(); - if (closeEditors(openedEditors(), askAboutModifiedEditors)) { -// m_d->clearNavigationHistory(); - return true; - } - return false; -} - -void EditorManager::closeOtherEditors(IEditor *editor) -{ - m_d->m_editorModel->removeAllRestoredEditors(); - QList editors = openedEditors(); - editors.removeAll(editor); - closeEditors(editors, true); -} - - -void EditorManager::closeOtherEditors() -{ - IEditor *current = currentEditor(); - QTC_ASSERT(current, return); - closeOtherEditors(current); -} - - -// SLOT connected to action -// since this is potentially called in the event handler of the editor -// we simply postpone it with a single shot timer -void EditorManager::closeEditor() -{ - closeEditor(m_d->m_currentEditor); -} - -void EditorManager::closeEditor(Core::IEditor *editor) -{ - if (!editor) - return; - closeEditors(QList() << editor); -} - -void EditorManager::closeEditor(const QModelIndex &index) -{ - IEditor *editor = index.data(Qt::UserRole).value(); - if (editor) - closeEditor(editor); - else - m_d->m_editorModel->removeEditor(index); -} - -bool EditorManager::closeEditors(const QList editorsToClose, bool askAboutModifiedEditors) -{ - if (editorsToClose.isEmpty()) - return true; - - SplitterOrView *currentSplitterOrView = this->currentSplitterOrView(); - - bool closingFailed = false; - QList acceptedEditors; - //ask all core listeners to check whether the editor can be closed - const QList listeners = - pluginManager()->getObjects(); - foreach (IEditor *editor, editorsToClose) { - bool editorAccepted = true; - if (m_d->m_editorModel->isDuplicate(editor)) - editor = m_d->m_editorModel->originalForDuplicate(editor); - foreach (ICoreListener *listener, listeners) { - if (!listener->editorAboutToClose(editor)) { - editorAccepted = false; - closingFailed = false; - break; - } - } - if (editorAccepted) - acceptedEditors.append(editor); - } - if (acceptedEditors.isEmpty()) - return false; - //ask whether to save modified files - if (askAboutModifiedEditors) { - bool cancelled = false; - QList list = m_d->m_core->fileManager()-> - saveModifiedFiles(filesForEditors(acceptedEditors), &cancelled); - if (cancelled) - return false; - if (!list.isEmpty()) { - closingFailed = true; - QSet skipSet = editorsForFiles(list).toSet(); - acceptedEditors = acceptedEditors.toSet().subtract(skipSet).toList(); - } - } - if (acceptedEditors.isEmpty()) - return false; - - // add duplicates - foreach(IEditor *editor, acceptedEditors) - acceptedEditors += m_d->m_editorModel->duplicatesFor(editor); - - QList closedViews; - - // remove the editors - foreach (IEditor *editor, acceptedEditors) { - emit editorAboutToClose(editor); - if (!editor->file()->fileName().isEmpty()) { - QByteArray state = editor->saveState(); - if (!state.isEmpty()) - m_d->m_editorStates.insert(editor->file()->fileName(), QVariant(state)); - } - - removeEditor(editor); - if (SplitterOrView *view = m_d->m_splitter->findView(editor)) { - if (editor == view->view()->currentEditor()) - closedViews += view->view(); - view->view()->removeEditor(editor); - } - } - - foreach (EditorView *view, closedViews) { - IEditor *newCurrent = view->currentEditor(); - if (!newCurrent) - newCurrent = pickUnusedEditor(); - if (newCurrent) { - activateEditor(view, newCurrent, NoActivate); - } else { - QModelIndex idx = m_d->m_editorModel->firstRestoredEditor(); - if (idx.isValid()) - activateEditor(idx, view, NoActivate); - } - } - - emit editorsClosed(acceptedEditors); - - foreach (IEditor *editor, acceptedEditors) { - delete editor; - } - - if (currentSplitterOrView) { - if (IEditor *editor = currentSplitterOrView->editor()) - activateEditor(currentSplitterOrView->view(), editor); - } - - if (!currentEditor()) - emit currentEditorChanged(0); - - return !closingFailed; -} - -void EditorManager::closeDuplicate(Core::IEditor *editor) -{ - - IEditor *original = editor; - if (m_d->m_editorModel->isDuplicate(editor)) - original= m_d->m_editorModel->originalForDuplicate(editor); - QList duplicates = m_d->m_editorModel->duplicatesFor(original); - - if (duplicates.isEmpty()) { - closeEditor(editor); - return; - } - - if (original== editor) - m_d->m_editorModel->makeOriginal(duplicates.first()); - - SplitterOrView *currentSplitterOrView = this->currentSplitterOrView(); - - emit editorAboutToClose(editor); - - EditorView *view = m_d->m_splitter->findView(editor)->view(); - removeEditor(editor); - view->removeEditor(editor); - - IEditor *newCurrent = view->currentEditor(); - if (!newCurrent) - newCurrent = pickUnusedEditor(); - if (newCurrent) { - activateEditor(view, newCurrent, NoActivate); - } else { - QModelIndex idx = m_d->m_editorModel->firstRestoredEditor(); - if (idx.isValid()) - activateEditor(idx, view, NoActivate); - } - - emit editorsClosed(QList() << editor); - delete editor; - if (currentSplitterOrView) { - if (IEditor *currentEditor = currentSplitterOrView->editor()) - activateEditor(currentSplitterOrView->view(), currentEditor); - } -} - -Core::IEditor *EditorManager::pickUnusedEditor() const -{ - foreach (IEditor *editor, openedEditors()) { - SplitterOrView *view = m_d->m_splitter->findView(editor); - if (!view || view->editor() != editor) - return editor; - } - return 0; -} - -Core::IEditor *EditorManager::activateEditor(const QModelIndex &index, Internal::EditorView *view, OpenEditorFlags flags) -{ - IEditor *editor = index.data(Qt::UserRole).value(); - if (editor) { - return activateEditor(view, editor, flags); - } - - QString fileName = index.data(Qt::UserRole + 1).toString(); - QByteArray kind = index.data(Qt::UserRole + 2).toByteArray(); - return openEditor(view, fileName, kind, flags); -} - -Core::IEditor *EditorManager::placeEditor(Core::Internal::EditorView *view, Core::IEditor *editor) -{ - Q_ASSERT(view && editor); - - if (view->currentEditor() && view->currentEditor()->file() == editor->file()) - editor = view->currentEditor(); - - if (!view->hasEditor(editor)) { - bool duplicateSupported = editor->duplicateSupported(); - if (SplitterOrView *sourceView = m_d->m_splitter->findView(editor)) { - if (editor != sourceView->editor() || !duplicateSupported) { - sourceView->view()->removeEditor(editor); - view->addEditor(editor); - view->setCurrentEditor(editor); - if (!sourceView->editor()) { - if (IEditor *replacement = pickUnusedEditor()) { - sourceView->view()->addEditor(replacement); - } - } - return editor; - } else if (duplicateSupported) { - editor = duplicateEditor(editor); - Q_ASSERT(editor); - m_d->m_editorModel->makeOriginal(editor); - } - } - view->addEditor(editor); - } - return editor; -} - -Core::IEditor *EditorManager::activateEditor(Core::IEditor *editor, OpenEditorFlags flags) -{ - return activateEditor(0, editor, flags); -} - -Core::IEditor *EditorManager::activateEditor(Core::Internal::EditorView *view, Core::IEditor *editor, OpenEditorFlags flags) -{ - if (!view) - view = currentEditorView(); - - Q_ASSERT(view); - - if (!editor) { - if (!m_d->m_currentEditor) - setCurrentEditor(0, (flags & IgnoreNavigationHistory)); - return 0; - } - - editor = placeEditor(view, editor); - - if (!(flags & NoActivate)) { - setCurrentEditor(editor, (flags & IgnoreNavigationHistory)); - if (!(flags & NoModeSwitch)) - ensureEditorManagerVisible(); - if (isVisible()) - editor->widget()->setFocus(); - } - return editor; -} - -Core::IEditor *EditorManager::activateEditor(Core::Internal::EditorView *view, Core::IFile *file, OpenEditorFlags flags) -{ - QList editors = editorsForFile(file); - Q_ASSERT(!editors.isEmpty()); - return activateEditor(view, editors.first(), flags); -} - -/* For something that has a 'QStringList mimeTypes' (IEditorFactory - * or IExternalEditor), find the one best matching the mimetype passed in. - * Recurse over the parent classes of the mimetype to find them. */ -template -static void mimeTypeFactoryRecursion(const MimeDatabase *db, - const MimeType &mimeType, - const QList &allFactories, - bool firstMatchOnly, - QList *list) -{ - typedef typename QList::const_iterator EditorFactoryLikeListConstIterator; - // Loop factories to find type - const QString type = mimeType.type(); - const EditorFactoryLikeListConstIterator fcend = allFactories.constEnd(); - for (EditorFactoryLikeListConstIterator fit = allFactories.constBegin(); fit != fcend; ++fit) { - // Exclude duplicates when recursing over xml or C++ -> C -> text. - EditorFactoryLike *factory = *fit; - if (!list->contains(factory) && factory->mimeTypes().contains(type)) { - list->push_back(*fit); - if (firstMatchOnly) - return; - break; - } - } - // Any parent mime type classes? -> recurse - QStringList parentTypes = mimeType.subClassesOf(); - if (parentTypes.empty()) - return; - const QStringList::const_iterator pcend = parentTypes .constEnd(); - for (QStringList::const_iterator pit = parentTypes .constBegin(); pit != pcend; ++pit) { - if (const MimeType parent = db->findByType(*pit)) - mimeTypeFactoryRecursion(db, parent, allFactories, firstMatchOnly, list); - } -} - -EditorManager::EditorFactoryList - EditorManager::editorFactories(const MimeType &mimeType, bool bestMatchOnly) const -{ - EditorFactoryList rc; - const EditorFactoryList allFactories = pluginManager()->getObjects(); - mimeTypeFactoryRecursion(m_d->m_core->mimeDatabase(), mimeType, allFactories, bestMatchOnly, &rc); - if (debugEditorManager) - qDebug() << Q_FUNC_INFO << mimeType.type() << " returns " << rc; - return rc; -} - -EditorManager::ExternalEditorList - EditorManager::externalEditors(const MimeType &mimeType, bool bestMatchOnly) const -{ - ExternalEditorList rc; - const ExternalEditorList allEditors = pluginManager()->getObjects(); - mimeTypeFactoryRecursion(m_d->m_core->mimeDatabase(), mimeType, allEditors, bestMatchOnly, &rc); - if (debugEditorManager) - qDebug() << Q_FUNC_INFO << mimeType.type() << " returns " << rc; - return rc; -} - -/* For something that has a 'QString kind' (IEditorFactory - * or IExternalEditor), find the one matching a kind. */ -template - inline EditorFactoryLike *findByKind(ExtensionSystem::PluginManager *pm, - const QString &kind) -{ - const QList factories = pm->template getObjects(); - foreach(EditorFactoryLike *efl, factories) - if (kind == efl->kind()) - return efl; - return 0; -} - -IEditor *EditorManager::createEditor(const QString &editorKind, - const QString &fileName) -{ - typedef QList FactoryList; - if (debugEditorManager) - qDebug() << Q_FUNC_INFO << editorKind << fileName; - - - EditorFactoryList factories; - if (editorKind.isEmpty()) { - // Find by mime type - MimeType mimeType = m_d->m_core->mimeDatabase()->findByFile(QFileInfo(fileName)); - if (!mimeType) { - qWarning("%s unable to determine mime type of %s/%s. Falling back to text/plain", - Q_FUNC_INFO, fileName.toUtf8().constData(), editorKind.toUtf8().constData()); - mimeType = m_d->m_core->mimeDatabase()->findByType(QLatin1String("text/plain")); - } - factories = editorFactories(mimeType, true); - } else { - // Find by editor kind - if (IEditorFactory *factory = findByKind(pluginManager(), editorKind)) - factories.push_back(factory); - } - if (factories.empty()) { - qWarning("%s: unable to find an editor factory for the file '%s', editor kind '%s'.", - Q_FUNC_INFO, fileName.toUtf8().constData(), editorKind.toUtf8().constData()); - return 0; - } - - IEditor *editor = factories.front()->createEditor(this); - if (editor) - connect(editor, SIGNAL(changed()), this, SLOT(updateActions())); - if (editor) - emit editorCreated(editor, fileName); - return editor; -} - -void EditorManager::addEditor(IEditor *editor, bool isDuplicate) -{ - if (!editor) - return; - m_d->m_core->addContextObject(editor); - - m_d->m_editorModel->addEditor(editor, isDuplicate); - if (!isDuplicate) { - m_d->m_core->fileManager()->addFile(editor->file()); - if (!editor->isTemporary()) { - m_d->m_core->fileManager()->addToRecentFiles(editor->file()->fileName()); - } - } - emit editorOpened(editor); -} - -// Run the OpenWithDialog and return the editor kind -// selected by the user. -QString EditorManager::getOpenWithEditorKind(const QString &fileName, - bool *isExternalEditor) const -{ - // Collect editors that can open the file - const MimeType mt = m_d->m_core->mimeDatabase()->findByFile(fileName); - if (!mt) - return QString(); - QStringList allEditorKinds; - QStringList externalEditorKinds; - // Built-in - const EditorFactoryList editors = editorFactories(mt, false); - const int size = editors.size(); - for (int i = 0; i < size; i++) { - allEditorKinds.push_back(editors.at(i)->kind()); - } - // External editors - const ExternalEditorList exEditors = externalEditors(mt, false); - const int esize = exEditors.size(); - for (int i = 0; i < esize; i++) { - externalEditorKinds.push_back(exEditors.at(i)->kind()); - allEditorKinds.push_back(exEditors.at(i)->kind()); - } - if (allEditorKinds.empty()) - return QString(); - // Run dialog. - OpenWithDialog dialog(fileName, m_d->m_core->mainWindow()); - dialog.setEditors(allEditorKinds); - dialog.setCurrentEditor(0); - if (dialog.exec() != QDialog::Accepted) - return QString(); - const QString selectedKind = dialog.editor(); - if (isExternalEditor) - *isExternalEditor = externalEditorKinds.contains(selectedKind); - return selectedKind; -} - -static QString formatFileFilters(const Core::ICore *core, QString *selectedFilter) -{ - QString rc; - // Compile list of filter strings. If we find a glob matching all files, - // put it last and set it as default selectedFilter. - QStringList filters = core->mimeDatabase()->filterStrings(); - filters.sort(); - selectedFilter->clear(); - if (filters.empty()) - return rc; - const QString filterSeparator = QLatin1String(";;"); - bool hasAllFilter = false; - const int size = filters.size(); - for (int i = 0; i < size; i++) { - const QString &filterString = filters.at(i); - if (filterString.isEmpty()) { // binary editor - hasAllFilter = true; - } else { - if (!rc.isEmpty()) - rc += filterSeparator; - rc += filterString; - } - } - if (hasAllFilter) { - // prepend all files filter - // prepending instead of appending to work around a but in Qt/Mac - QString allFilesFilter = EditorManager::tr("All Files (*)"); - if (!rc.isEmpty()) - allFilesFilter += filterSeparator; - rc.prepend(allFilesFilter); - *selectedFilter = allFilesFilter; - } else { - *selectedFilter = filters.front(); - } - return rc; -} - -IEditor *EditorManager::openEditor(const QString &fileName, const QString &editorKind, - EditorManager::OpenEditorFlags flags) -{ - return openEditor(0, fileName, editorKind, flags); -} - -IEditor *EditorManager::openEditor(Core::Internal::EditorView *view, const QString &fileName, - const QString &editorKind, EditorManager::OpenEditorFlags flags) -{ - if (debugEditorManager) - qDebug() << Q_FUNC_INFO << fileName << editorKind; - - if (fileName.isEmpty()) - return 0; - - const QList editors = editorsForFileName(fileName); - if (!editors.isEmpty()) { - return activateEditor(view, editors.first(), flags); - } - QApplication::setOverrideCursor(QCursor(Qt::WaitCursor)); - IEditor *editor = createEditor(editorKind, fileName); - if (!editor || !editor->open(fileName)) { - QApplication::restoreOverrideCursor(); - QMessageBox::critical(m_d->m_core->mainWindow(), tr("Opening File"), tr("Cannot open file %1!").arg(QDir::toNativeSeparators(fileName))); - delete editor; - editor = 0; - return 0; - } - addEditor(editor); - - IEditor *result= activateEditor(view, editor, flags); - if (editor == result) - restoreEditorState(editor); - QApplication::restoreOverrideCursor(); - return result; -} - -bool EditorManager::openExternalEditor(const QString &fileName, const QString &editorKind) -{ - IExternalEditor *ee = findByKind(pluginManager(), editorKind); - if (!ee) - return false; - QString errorMessage; - QApplication::setOverrideCursor(QCursor(Qt::WaitCursor)); - const bool ok = ee->startEditor(fileName, &errorMessage); - QApplication::restoreOverrideCursor(); - if (!ok) - QMessageBox::critical(m_d->m_core->mainWindow(), tr("Opening File"), errorMessage); - return ok; -} - -QStringList EditorManager::getOpenFileNames() const -{ - static QString dir = QDir::homePath(); - if (m_d->fileFilters.isEmpty()) - m_d->fileFilters = formatFileFilters(m_d->m_core, &m_d->selectedFilter); - - QString currentFile = ICore::instance()->fileManager()->currentFile(); - if (!currentFile.isEmpty()) { - const QFileInfo fi(currentFile); - dir = fi.absolutePath(); - } - - QStringList files = QFileDialog::getOpenFileNames(m_d->m_core->mainWindow(), tr("Open File"), - dir, m_d->fileFilters, &m_d->selectedFilter); - if (!files.isEmpty()) - dir = QFileInfo(files.at(0)).absolutePath(); - return files; -} - -void EditorManager::ensureEditorManagerVisible() -{ - if (!isVisible()) - m_d->m_core->modeManager()->activateMode(Constants::MODE_EDIT); -} - -IEditor *EditorManager::openEditorWithContents(const QString &editorKind, - QString *titlePattern, - const QString &contents) -{ - if (debugEditorManager) - qDebug() << Q_FUNC_INFO << editorKind << titlePattern << contents; - - if (editorKind.isEmpty()) - return 0; - - QApplication::setOverrideCursor(QCursor(Qt::WaitCursor)); - IEditor *edt = createEditor(editorKind); - if (!edt) { - QApplication::restoreOverrideCursor(); - return 0; - } - - if (!edt->createNew(contents)) { - QApplication::restoreOverrideCursor(); - delete edt; - edt = 0; - return 0; - } - - QString title = edt->displayName(); - - if (title.isEmpty() && titlePattern) { - const QChar dollar = QLatin1Char('$'); - const QChar dot = QLatin1Char('.'); - - QString base = *titlePattern; - if (base.isEmpty()) - base = QLatin1String("unnamed$"); - if (base.contains(dollar)) { - int i = 1; - QSet docnames; - foreach (IEditor *editor, openedEditors()) { - QString name = editor->file()->fileName(); - if (name.isEmpty()) { - name = editor->displayName(); - name.remove(QLatin1Char('*')); - } else { - name = QFileInfo(name).completeBaseName(); - } - docnames << name; - } - - do { - title = base; - title.replace(QString(dollar), QString::number(i++)); - } while (docnames.contains(title)); - } else { - title = *titlePattern; - } - } - *titlePattern = title; - edt->setDisplayName(title); - addEditor(edt); - QApplication::restoreOverrideCursor(); - return edt; -} - -bool EditorManager::hasEditor(const QString &fileName) const -{ - return !editorsForFileName(fileName).isEmpty(); -} - -void EditorManager::restoreEditorState(IEditor *editor) -{ - QTC_ASSERT(editor, return); - QString fileName = editor->file()->fileName(); - if (m_d->m_editorStates.contains(fileName)) - editor->restoreState(m_d->m_editorStates.value(fileName).toByteArray()); -} - -bool EditorManager::saveEditor(IEditor *editor) -{ - return saveFile(editor); -} - -bool EditorManager::saveFile(IEditor *editor) -{ - if (!editor) - editor = currentEditor(); - if (!editor) - return false; - - IFile *file = editor->file(); - file->checkPermissions(); - - const QString &fileName = file->fileName(); - - if (fileName.isEmpty()) - return saveFileAs(editor); - - bool success = false; - - // try saving, no matter what isReadOnly tells us - m_d->m_core->fileManager()->blockFileChange(file); - success = file->save(fileName); - m_d->m_core->fileManager()->unblockFileChange(file); - - if (!success) { - MakeWritableResult answer = - makeEditorWritable(editor); - if (answer == Failed) - return false; - if (answer == SavedAs) - return true; - - file->checkPermissions(); - - m_d->m_core->fileManager()->blockFileChange(file); - success = file->save(fileName); - m_d->m_core->fileManager()->unblockFileChange(file); - } - - if (success && !editor->isTemporary()) - m_d->m_core->fileManager()->addToRecentFiles(editor->file()->fileName()); - - return success; -} - -EditorManager::ReadOnlyAction - EditorManager::promptReadOnlyFile(const QString &fileName, - const IVersionControl *versionControl, - QWidget *parent, - bool displaySaveAsButton) -{ - QMessageBox msgBox(QMessageBox::Question, tr("File is Read Only"), - tr("The file %1 is read only.").arg(QDir::toNativeSeparators(fileName)), - QMessageBox::Cancel, parent); - - QPushButton *sccButton = 0; - if (versionControl && versionControl->supportsOperation(IVersionControl::OpenOperation)) - sccButton = msgBox.addButton(tr("Open with VCS (%1)").arg(versionControl->name()), QMessageBox::AcceptRole); - - QPushButton *makeWritableButton = msgBox.addButton(tr("Make writable"), QMessageBox::AcceptRole); - - QPushButton *saveAsButton = 0; - if (displaySaveAsButton) - saveAsButton = msgBox.addButton(tr("Save as ..."), QMessageBox::ActionRole); - - msgBox.setDefaultButton(sccButton ? sccButton : makeWritableButton); - msgBox.exec(); - - QAbstractButton *clickedButton = msgBox.clickedButton(); - if (clickedButton == sccButton) - return RO_OpenVCS; - if (clickedButton == makeWritableButton) - return RO_MakeWriteable; - if (clickedButton == saveAsButton) - return RO_SaveAs; - return RO_Cancel; -} - - -MakeWritableResult -EditorManager::makeEditorWritable(IEditor *editor) -{ - if (!editor || !editor->file()) - return Failed; - QString directory = QFileInfo(editor->file()->fileName()).absolutePath(); - IVersionControl *versionControl = m_d->m_core->vcsManager()->findVersionControlForDirectory(directory); - IFile *file = editor->file(); - const QString &fileName = file->fileName(); - - switch (promptReadOnlyFile(fileName, versionControl, m_d->m_core->mainWindow(), true)) { - case RO_OpenVCS: - if (!versionControl->vcsOpen(fileName)) { - QMessageBox::warning(m_d->m_core->mainWindow(), tr("Failed!"), tr("Could not open the file for editing with SCC.")); - return Failed; - } - file->checkPermissions(); - return OpenedWithVersionControl; - case RO_MakeWriteable: { - const bool permsOk = QFile::setPermissions(fileName, QFile::permissions(fileName) | QFile::WriteUser); - if (!permsOk) { - QMessageBox::warning(m_d->m_core->mainWindow(), tr("Failed!"), tr("Could not set permissions to writable.")); - return Failed; - } - } - file->checkPermissions(); - return MadeWritable; - case RO_SaveAs : - return saveFileAs(editor) ? SavedAs : Failed; - case RO_Cancel: - break; - } - return Failed; -} - -bool EditorManager::saveFileAs(IEditor *editor) -{ - if (!editor) - editor = currentEditor(); - if (!editor) - return false; - - QString absoluteFilePath = m_d->m_core->fileManager()->getSaveAsFileName(editor->file()); - if (absoluteFilePath.isEmpty()) - return false; - if (absoluteFilePath != editor->file()->fileName()) { - const QList existList = editorsForFileName(absoluteFilePath); - if (!existList.isEmpty()) { - closeEditors(existList, false); - } - } - - m_d->m_core->fileManager()->blockFileChange(editor->file()); - const bool success = editor->file()->save(absoluteFilePath); - m_d->m_core->fileManager()->unblockFileChange(editor->file()); - editor->file()->checkPermissions(); - - if (success && !editor->isTemporary()) - m_d->m_core->fileManager()->addToRecentFiles(editor->file()->fileName()); - - updateActions(); - return success; -} - -void EditorManager::gotoNextDocHistory() -{ - OpenEditorsWindow *dialog = windowPopup(); - if (dialog->isVisible()) { - dialog->selectNextEditor(); - } else { - EditorView *view = currentEditorView(); - dialog->setEditors(m_d->m_view, view, m_d->m_editorModel); - dialog->selectNextEditor(); - showWindowPopup(); - } -} - -void EditorManager::gotoPreviousDocHistory() -{ - OpenEditorsWindow *dialog = windowPopup(); - if (dialog->isVisible()) { - dialog->selectPreviousEditor(); - } else { - EditorView *view = currentEditorView(); - dialog->setEditors(m_d->m_view, view, m_d->m_editorModel); - dialog->selectPreviousEditor(); - showWindowPopup(); - } -} - -void EditorManager::makeCurrentEditorWritable() -{ - if (IEditor* curEditor = currentEditor()) - makeEditorWritable(curEditor); -} - -void EditorManager::updateActions() -{ - QString fName; - IEditor *curEditor = currentEditor(); - int openedCount = openedEditors().count() + m_d->m_editorModel->restoredEditorCount(); - if (curEditor) { - if (!curEditor->file()->fileName().isEmpty()) { - QFileInfo fi(curEditor->file()->fileName()); - fName = fi.fileName(); - } else { - fName = curEditor->displayName(); - } - - - if (curEditor->file()->isModified() && curEditor->file()->isReadOnly()) { - // we are about to change a read-only file, warn user - showEditorInfoBar(QLatin1String("Core.EditorManager.MakeWritable"), - tr("Warning: You are changing a read-only file."), - tr("Make writable"), this, SLOT(makeCurrentEditorWritable())); - } else { - hideEditorInfoBar(QLatin1String("Core.EditorManager.MakeWritable")); - } - } - - m_d->m_saveAction->setEnabled(curEditor != 0 && curEditor->file()->isModified()); - m_d->m_saveAsAction->setEnabled(curEditor != 0 && curEditor->file()->isSaveAsAllowed()); - m_d->m_revertToSavedAction->setEnabled(curEditor != 0 - && !curEditor->file()->fileName().isEmpty() && curEditor->file()->isModified()); - - QString quotedName; - if (!fName.isEmpty()) - quotedName = '"' + fName + '"'; - m_d->m_saveAsAction->setText(tr("Save %1 As...").arg(quotedName)); - m_d->m_saveAction->setText(tr("&Save %1").arg(quotedName)); - m_d->m_revertToSavedAction->setText(tr("Revert %1 to Saved").arg(quotedName)); - - - m_d->m_closeCurrentEditorAction->setEnabled(curEditor != 0); - m_d->m_closeCurrentEditorAction->setText(tr("Close %1").arg(quotedName)); - m_d->m_closeAllEditorsAction->setEnabled(openedCount > 0); - m_d->m_closeOtherEditorsAction->setEnabled(openedCount > 1); - m_d->m_closeOtherEditorsAction->setText((openedCount > 1 ? tr("Close All Except %1").arg(quotedName) : tr("Close Others"))); - - m_d->m_gotoNextDocHistoryAction->setEnabled(m_d->m_editorModel->rowCount() != 0); - m_d->m_gotoPreviousDocHistoryAction->setEnabled(m_d->m_editorModel->rowCount() != 0); - EditorView *view = currentEditorView(); - m_d->m_goBackAction->setEnabled(view ? view->canGoBack() : false); - m_d->m_goForwardAction->setEnabled(view ? view->canGoForward() : false); - - bool hasSplitter = m_d->m_splitter->isSplitter(); - m_d->m_removeCurrentSplitAction->setEnabled(hasSplitter); - m_d->m_removeAllSplitsAction->setEnabled(hasSplitter); - m_d->m_gotoOtherSplitAction->setEnabled(hasSplitter); - - m_d->m_openInExternalEditorAction->setEnabled(curEditor != 0); -} - -QList EditorManager::openedEditors() const -{ - return m_d->m_editorModel->editors(); -} - -OpenEditorsModel *EditorManager::openedEditorsModel() const -{ - return m_d->m_editorModel; -} - -void EditorManager::addCurrentPositionToNavigationHistory(IEditor *editor, const QByteArray &saveState) -{ - currentEditorView()->addCurrentPositionToNavigationHistory(editor, saveState); - updateActions(); -} - -void EditorManager::goBackInNavigationHistory() -{ - currentEditorView()->goBackInNavigationHistory(); - updateActions(); - ensureEditorManagerVisible(); - return; -} - -void EditorManager::goForwardInNavigationHistory() -{ - currentEditorView()->goForwardInNavigationHistory(); - updateActions(); - ensureEditorManagerVisible(); -} - -OpenEditorsWindow *EditorManager::windowPopup() const -{ - return m_d->m_windowPopup; -} - -void EditorManager::showWindowPopup() const -{ - const QPoint p(mapToGlobal(QPoint(0, 0))); - m_d->m_windowPopup->move((width()-m_d->m_windowPopup->width())/2 + p.x(), - (height()-m_d->m_windowPopup->height())/2 + p.y()); - m_d->m_windowPopup->setVisible(true); -} - -QByteArray EditorManager::saveState() const -{ - QByteArray bytes; - QDataStream stream(&bytes, QIODevice::WriteOnly); - - stream << QByteArray("EditorManagerV4"); - - QList editors = openedEditors(); - foreach (IEditor *editor, editors) { - if (!editor->file()->fileName().isEmpty()) { - QByteArray state = editor->saveState(); - if (!state.isEmpty()) - m_d->m_editorStates.insert(editor->file()->fileName(), QVariant(state)); - } - } - - stream << m_d->m_editorStates; - - QList entries = m_d->m_editorModel->entries(); - stream << entries.count(); - - foreach (OpenEditorsModel::Entry entry, entries) { - stream << entry.fileName() << entry.displayName() << entry.kind(); - } - - stream << m_d->m_splitter->saveState(); - - return bytes; -} - -bool EditorManager::restoreState(const QByteArray &state) -{ - closeAllEditors(true); - removeAllSplits(); - QDataStream stream(state); - - QByteArray version; - stream >> version; - - if (version != "EditorManagerV4") - return false; - - QMap editorstates; - - QApplication::setOverrideCursor(Qt::WaitCursor); - - stream >> editorstates; - - QMapIterator i(editorstates); - while (i.hasNext()) { - i.next(); - m_d->m_editorStates.insert(i.key(), i.value()); - } - - int editorCount = 0; - stream >> editorCount; - while (--editorCount >= 0) { - QString fileName; - stream >> fileName; - QString displayName; - stream >> displayName; - QByteArray kind; - stream >> kind; - - if (!fileName.isEmpty() && !displayName.isEmpty()){ - m_d->m_editorModel->addRestoredEditor(fileName, displayName, kind); - } - } - - QByteArray splitterstates; - stream >> splitterstates; - m_d->m_splitter->restoreState(splitterstates); - - // splitting and stuff results in focus trouble, that's why we set the focus again after restoration - ensureEditorManagerVisible(); - if (m_d->m_currentEditor) { - m_d->m_currentEditor->widget()->setFocus(); - } else if (Core::Internal::SplitterOrView *view = currentSplitterOrView()) { - if (IEditor *e = view->editor()) - e->widget()->setFocus(); - else if (view->view()) - view->view()->setFocus(); - } - - QApplication::restoreOverrideCursor(); - - return true; -} - -static const char * const documentStatesKey = "EditorManager/DocumentStates"; -static const char * const externalEditorKey = "EditorManager/ExternalEditorCommand"; -static const char * const reloadBehaviorKey = "EditorManager/ReloadBehavior"; - -void EditorManager::saveSettings() -{ - SettingsDatabase *settings = m_d->m_core->settingsDatabase(); - settings->setValue(QLatin1String(documentStatesKey), m_d->m_editorStates); - settings->setValue(QLatin1String(externalEditorKey), m_d->m_externalEditor); - settings->setValue(QLatin1String(reloadBehaviorKey), m_d->m_reloadBehavior); -} - -void EditorManager::readSettings() -{ - // Backward compatibility to old locations for these settings - QSettings *qs = m_d->m_core->settings(); - if (qs->contains(QLatin1String(documentStatesKey))) { - m_d->m_editorStates = qs->value(QLatin1String(documentStatesKey)) - .value >(); - qs->remove(QLatin1String(documentStatesKey)); - } - if (qs->contains(QLatin1String(externalEditorKey))) { - m_d->m_externalEditor = qs->value(QLatin1String(externalEditorKey)).toString(); - qs->remove(QLatin1String(externalEditorKey)); - } - - SettingsDatabase *settings = m_d->m_core->settingsDatabase(); - if (settings->contains(QLatin1String(documentStatesKey))) - m_d->m_editorStates = settings->value(QLatin1String(documentStatesKey)) - .value >(); - if (settings->contains(QLatin1String(externalEditorKey))) - m_d->m_externalEditor = settings->value(QLatin1String(externalEditorKey)).toString(); - - if (settings->contains(QLatin1String(reloadBehaviorKey))) - m_d->m_reloadBehavior = (IFile::ReloadBehavior)settings->value(QLatin1String(reloadBehaviorKey)).toInt(); -} - - -void EditorManager::revertToSaved() -{ - IEditor *currEditor = currentEditor(); - if (!currEditor) - return; - const QString fileName = currEditor->file()->fileName(); - if (fileName.isEmpty()) - return; - if (currEditor->file()->isModified()) { - QMessageBox msgBox(QMessageBox::Question, tr("Revert to Saved"), - tr("You will lose your current changes if you proceed reverting %1.").arg(QDir::toNativeSeparators(fileName)), - QMessageBox::Yes|QMessageBox::No, m_d->m_core->mainWindow()); - msgBox.button(QMessageBox::Yes)->setText(tr("Proceed")); - msgBox.button(QMessageBox::No)->setText(tr("Cancel")); - msgBox.setDefaultButton(QMessageBox::No); - msgBox.setEscapeButton(QMessageBox::No); - if (msgBox.exec() == QMessageBox::No) - return; - - } - IFile::ReloadBehavior temp = IFile::ReloadAll; - currEditor->file()->modified(&temp); -} - -void EditorManager::showEditorInfoBar(const QString &kind, - const QString &infoText, - const QString &buttonText, - QObject *object, const char *member) -{ - - currentEditorView()->showEditorInfoBar(kind, infoText, buttonText, object, member); -} - - -void EditorManager::hideEditorInfoBar(const QString &kind) -{ - Core::Internal::EditorView *cev = currentEditorView(); - if (cev) - cev->hideEditorInfoBar(kind); -} - -void EditorManager::showEditorStatusBar(const QString &kind, - const QString &infoText, - const QString &buttonText, - QObject *object, const char *member) -{ - - currentEditorView()->showEditorStatusBar(kind, infoText, buttonText, object, member); -} - -void EditorManager::hideEditorStatusBar(const QString &kind) -{ - currentEditorView()->hideEditorStatusBar(kind); -} - -QString EditorManager::externalEditorHelpText() const -{ - QString help = tr( - "" - "" - "" - "" - "" - "" - "" - "" - "" - "" - "" - "" - "
VariableExpands to
%ffile name
%lcurrent line number
%ccurrent column number
%xeditor's x position on screen
%yeditor's y position on screen
%weditor's width in pixels
%heditor's height in pixels
%Weditor's width in characters
%Heditor's height in characters
%%%
"); - return help; -} - -void EditorManager::openInExternalEditor() -{ - QString command = m_d->m_externalEditor; - if (command.isEmpty()) - command = defaultExternalEditor(); - - if (command.isEmpty()) - return; - - IEditor *editor = currentEditor(); - if (!editor) - return; - if (editor->file()->isModified()) { - bool cancelled = false; - QList list = m_d->m_core->fileManager()-> - saveModifiedFiles(QList() << editor->file(), &cancelled); - if (cancelled) - return; - } - - QRect rect = editor->widget()->rect(); - QFont font = editor->widget()->font(); - QFontMetrics fm(font); - rect.moveTo(editor->widget()->mapToGlobal(QPoint(0,0))); - - QString pre = command; - QString cmd; - for (int i = 0; i < pre.size(); ++i) { - QChar c = pre.at(i); - if (c == QLatin1Char('%') && i < pre.size()-1) { - c = pre.at(++i); - QString s; - if (c == QLatin1Char('f')) - s = editor->file()->fileName(); - else if (c == QLatin1Char('l')) - s = QString::number(editor->currentLine()); - else if (c == QLatin1Char('c')) - s = QString::number(editor->currentColumn()); - else if (c == QLatin1Char('x')) - s = QString::number(rect.x()); - else if (c == QLatin1Char('y')) - s = QString::number(rect.y()); - else if (c == QLatin1Char('w')) - s = QString::number(rect.width()); - else if (c == QLatin1Char('h')) - s = QString::number(rect.height()); - else if (c == QLatin1Char('W')) - s = QString::number(rect.width() / fm.width(QLatin1Char('x'))); - else if (c == QLatin1Char('H')) - s = QString::number(rect.height() / fm.lineSpacing()); - else if (c == QLatin1Char('%')) - s = c; - else { - s = QLatin1Char('%'); - cmd += c; - } - cmd += s; - continue; - - } - cmd += c; - } - - QProcess::startDetached(cmd); -} - -void EditorManager::setExternalEditor(const QString &editor) -{ - if (editor.isEmpty() || editor == defaultExternalEditor()) - m_d->m_externalEditor = defaultExternalEditor(); - else - m_d->m_externalEditor = editor; -} - -QString EditorManager::externalEditor() const -{ - if (m_d->m_externalEditor.isEmpty()) - return defaultExternalEditor(); - return m_d->m_externalEditor; -} - -void EditorManager::setReloadBehavior(IFile::ReloadBehavior behavior) -{ - m_d->m_reloadBehavior = behavior; -} - -IFile::ReloadBehavior EditorManager::reloadBehavior() const -{ - return m_d->m_reloadBehavior; -} - -Core::IEditor *EditorManager::duplicateEditor(Core::IEditor *editor) -{ - if (!editor->duplicateSupported()) - return 0; - - IEditor *duplicate = editor->duplicate(0); - duplicate->restoreState(editor->saveState()); - emit editorCreated(duplicate, duplicate->file()->fileName()); - addEditor(duplicate, true); - return duplicate; -} - -void EditorManager::split(Qt::Orientation orientation) -{ - SplitterOrView *view = m_d->m_currentView; - if (!view) - view = m_d->m_currentEditor ? m_d->m_splitter->findView(m_d->m_currentEditor) - : m_d->m_splitter->findFirstView(); - if (view && !view->splitter()) { - view->split(orientation); - } - updateActions(); -} - -void EditorManager::split() -{ - split(Qt::Vertical); -} - -void EditorManager::splitSideBySide() -{ - split(Qt::Horizontal); -} - -void EditorManager::removeCurrentSplit() -{ - SplitterOrView *viewToClose = m_d->m_currentView; - if (!viewToClose && m_d->m_currentEditor) - viewToClose = m_d->m_splitter->findView(m_d->m_currentEditor); - - if (!viewToClose || viewToClose->isSplitter() || viewToClose == m_d->m_splitter) - return; - - closeView(viewToClose->view()); - updateActions(); -} - -void EditorManager::removeAllSplits() -{ - if (!m_d->m_splitter->isSplitter()) - return; - IEditor *editor = m_d->m_currentEditor; - m_d->m_currentEditor = 0; // trigger update below - if (editor && m_d->m_editorModel->isDuplicate(editor)) - editor = m_d->m_editorModel->originalForDuplicate(editor); - m_d->m_splitter->unsplitAll(); - if (!editor) - editor = pickUnusedEditor(); - activateEditor(editor); -} - -void EditorManager::gotoOtherSplit() -{ - if (m_d->m_splitter->isSplitter()) { - SplitterOrView *currentView = m_d->m_currentView; - if (!currentView && m_d->m_currentEditor) - currentView = m_d->m_splitter->findView(m_d->m_currentEditor); - if (!currentView) - currentView = m_d->m_splitter->findFirstView(); - SplitterOrView *view = m_d->m_splitter->findNextView(currentView); - if (!view) - view = m_d->m_splitter->findFirstView(); - if (view) { - if (IEditor *editor = view->editor()) { - setCurrentEditor(editor, true); - editor->widget()->setFocus(); - } else { - setCurrentView(view); - } - } - } -} -//===================EditorClosingCoreListener====================== - -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); -} +/************************************************************************** +** +** This file is part of Qt Creator +** +** Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies). +** +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** Commercial Usage +** +** Licensees holding valid Qt Commercial licenses may use this file in +** accordance with the Qt Commercial License Agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and Nokia. +** +** GNU Lesser General Public License Usage +** +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at http://qt.nokia.com/contact. +** +**************************************************************************/ + +#include "editormanager.h" +#include "editorview.h" +#include "openeditorswindow.h" +#include "openeditorsview.h" +#include "openeditorsmodel.h" +#include "openwithdialog.h" +#include "filemanager.h" +#include "icore.h" +#include "iversioncontrol.h" +#include "mimedatabase.h" +#include "tabpositionindicator.h" +#include "vcsmanager.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +#include +#include + +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +Q_DECLARE_METATYPE(Core::IEditor*) + +using namespace Core; +using namespace Core::Internal; +using namespace Utils; + +enum { debugEditorManager=0 }; + +static inline ExtensionSystem::PluginManager *pluginManager() +{ + return ExtensionSystem::PluginManager::instance(); +} + +//===================EditorManager===================== + +EditorManagerPlaceHolder *EditorManagerPlaceHolder::m_current = 0; + +EditorManagerPlaceHolder::EditorManagerPlaceHolder(Core::IMode *mode, QWidget *parent) + : QWidget(parent), m_mode(mode) +{ + setLayout(new QVBoxLayout); + layout()->setMargin(0); + connect(Core::ModeManager::instance(), SIGNAL(currentModeChanged(Core::IMode *)), + this, SLOT(currentModeChanged(Core::IMode *))); + + currentModeChanged(Core::ModeManager::instance()->currentMode()); +} + +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 + +namespace Core { + + +struct EditorManagerPrivate { + explicit EditorManagerPrivate(ICore *core, QWidget *parent); + ~EditorManagerPrivate(); + Internal::EditorView *m_view; + Internal::SplitterOrView *m_splitter; + QPointer m_currentEditor; + QPointer m_currentView; + + ICore *m_core; + + + // actions + QAction *m_revertToSavedAction; + QAction *m_saveAction; + QAction *m_saveAsAction; + QAction *m_closeCurrentEditorAction; + QAction *m_closeAllEditorsAction; + QAction *m_closeOtherEditorsAction; + QAction *m_gotoNextDocHistoryAction; + QAction *m_gotoPreviousDocHistoryAction; + QAction *m_goBackAction; + QAction *m_goForwardAction; + QAction *m_openInExternalEditorAction; + QAction *m_splitAction; + QAction *m_splitSideBySideAction; + QAction *m_removeCurrentSplitAction; + QAction *m_removeAllSplitsAction; + QAction *m_gotoOtherSplitAction; + + Internal::OpenEditorsWindow *m_windowPopup; + Core::BaseView *m_openEditorsView; + Internal::EditorClosingCoreListener *m_coreListener; + + QMap m_editorStates; + Internal::OpenEditorsViewFactory *m_openEditorsFactory; + + QString fileFilters; + QString selectedFilter; + + OpenEditorsModel *m_editorModel; + QString m_externalEditor; + + IFile::ReloadBehavior m_reloadBehavior; +}; +} + +EditorManagerPrivate::EditorManagerPrivate(ICore *core, QWidget *parent) : + m_view(0), + m_splitter(0), + m_core(core), + 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)), + m_closeOtherEditorsAction(new QAction(EditorManager::tr("Close Others"), parent)), + m_gotoNextDocHistoryAction(new QAction(EditorManager::tr("Next Open Document in History"), parent)), + m_gotoPreviousDocHistoryAction(new QAction(EditorManager::tr("Previous Open Document in History"), parent)), + m_goBackAction(new QAction(QIcon(QLatin1String(":/help/images/previous.png")), EditorManager::tr("Go Back"), parent)), + m_goForwardAction(new QAction(QIcon(QLatin1String(":/help/images/next.png")), EditorManager::tr("Go Forward"), parent)), + m_openInExternalEditorAction(new QAction(EditorManager::tr("Open in External Editor"), parent)), + m_windowPopup(0), + m_coreListener(0), + m_reloadBehavior(IFile::AskForReload) +{ + m_editorModel = new OpenEditorsModel(parent); +} + +EditorManagerPrivate::~EditorManagerPrivate() +{ +// clearNavigationHistory(); +} + +EditorManager *EditorManager::m_instance = 0; + +static Command *createSeparator(ActionManager *am, QObject *parent, + const QString &name, + const QList &context) +{ + QAction *tmpaction = new QAction(parent); + tmpaction->setSeparator(true); + Command *cmd = am->registerAction(tmpaction, name, context); + return cmd; +} + +EditorManager::EditorManager(ICore *core, QWidget *parent) : + QWidget(parent), + m_d(new EditorManagerPrivate(core, parent)) +{ + m_instance = this; + + connect(m_d->m_core, SIGNAL(contextAboutToChange(Core::IContext *)), + this, SLOT(handleContextChange(Core::IContext *))); + + const QList gc = QList() << Constants::C_GLOBAL_ID; + const QList editManagerContext = + QList() << m_d->m_core->uniqueIDManager()->uniqueIdentifier(Constants::C_EDITORMANAGER); + + ActionManager *am = m_d->m_core->actionManager(); + ActionContainer *mfile = am->actionContainer(Constants::M_FILE); + + //Revert to saved + Command *cmd = am->registerAction(m_d->m_revertToSavedAction, + Constants::REVERTTOSAVED, editManagerContext); + cmd->setAttribute(Command::CA_UpdateText); + cmd->setDefaultText(tr("Revert File to Saved")); + mfile->addAction(cmd, Constants::G_FILE_SAVE); + connect(m_d->m_revertToSavedAction, SIGNAL(triggered()), this, SLOT(revertToSaved())); + + //Save Action + am->registerAction(m_d->m_saveAction, Constants::SAVE, editManagerContext); + connect(m_d->m_saveAction, SIGNAL(triggered()), this, SLOT(saveFile())); + + //Save As Action + am->registerAction(m_d->m_saveAsAction, Constants::SAVEAS, editManagerContext); + connect(m_d->m_saveAsAction, SIGNAL(triggered()), this, SLOT(saveFileAs())); + + //Window Menu + ActionContainer *mwindow = am->actionContainer(Constants::M_WINDOW); + + //Window menu separators + QAction *tmpaction = new QAction(this); + tmpaction->setSeparator(true); + cmd = am->registerAction(tmpaction, QLatin1String("QtCreator.Window.Sep.Split"), editManagerContext); + mwindow->addAction(cmd, Constants::G_WINDOW_SPLIT); + + tmpaction = new QAction(this); + tmpaction->setSeparator(true); + cmd = am->registerAction(tmpaction, QLatin1String("QtCreator.Window.Sep.Navigate"), editManagerContext); + mwindow->addAction(cmd, Constants::G_WINDOW_NAVIGATE); + + //Close Action + cmd = am->registerAction(m_d->m_closeCurrentEditorAction, Constants::CLOSE, editManagerContext); + cmd->setDefaultKeySequence(QKeySequence(tr("Ctrl+W"))); + cmd->setAttribute(Core::Command::CA_UpdateText); + cmd->setDefaultText(m_d->m_closeCurrentEditorAction->text()); + mfile->addAction(cmd, Constants::G_FILE_CLOSE); + connect(m_d->m_closeCurrentEditorAction, SIGNAL(triggered()), this, SLOT(closeEditor())); + + //Close All Action + cmd = am->registerAction(m_d->m_closeAllEditorsAction, Constants::CLOSEALL, editManagerContext); + cmd->setDefaultKeySequence(QKeySequence(tr("Ctrl+Shift+W"))); + mfile->addAction(cmd, Constants::G_FILE_CLOSE); + connect(m_d->m_closeAllEditorsAction, SIGNAL(triggered()), this, SLOT(closeAllEditors())); + + //Close All Others Action + cmd = am->registerAction(m_d->m_closeOtherEditorsAction, Constants::CLOSEOTHERS, editManagerContext); + mfile->addAction(cmd, Constants::G_FILE_CLOSE); + cmd->setAttribute(Core::Command::CA_UpdateText); + connect(m_d->m_closeOtherEditorsAction, SIGNAL(triggered()), this, SLOT(closeOtherEditors())); + + // Goto Previous In History Action + cmd = am->registerAction(m_d->m_gotoPreviousDocHistoryAction, Constants::GOTOPREVINHISTORY, editManagerContext); +#ifdef Q_WS_MAC + cmd->setDefaultKeySequence(QKeySequence(tr("Alt+Tab"))); +#else + cmd->setDefaultKeySequence(QKeySequence(tr("Ctrl+Tab"))); +#endif + mwindow->addAction(cmd, Constants::G_WINDOW_NAVIGATE); + connect(m_d->m_gotoPreviousDocHistoryAction, SIGNAL(triggered()), this, SLOT(gotoPreviousDocHistory())); + + // Goto Next In History Action + cmd = am->registerAction(m_d->m_gotoNextDocHistoryAction, Constants::GOTONEXTINHISTORY, editManagerContext); +#ifdef Q_WS_MAC + cmd->setDefaultKeySequence(QKeySequence(tr("Alt+Shift+Tab"))); +#else + cmd->setDefaultKeySequence(QKeySequence(tr("Ctrl+Shift+Tab"))); +#endif + mwindow->addAction(cmd, Constants::G_WINDOW_NAVIGATE); + connect(m_d->m_gotoNextDocHistoryAction, SIGNAL(triggered()), this, SLOT(gotoNextDocHistory())); + + // Go back in navigation history + cmd = am->registerAction(m_d->m_goBackAction, Constants::GO_BACK, editManagerContext); +#ifdef Q_WS_MAC + cmd->setDefaultKeySequence(QKeySequence(tr("Ctrl+Alt+Left"))); +#else + cmd->setDefaultKeySequence(QKeySequence(tr("Alt+Left"))); +#endif + mwindow->addAction(cmd, Constants::G_WINDOW_NAVIGATE); + connect(m_d->m_goBackAction, SIGNAL(triggered()), this, SLOT(goBackInNavigationHistory())); + + // Go forward in navigation history + cmd = am->registerAction(m_d->m_goForwardAction, Constants::GO_FORWARD, editManagerContext); +#ifdef Q_WS_MAC + cmd->setDefaultKeySequence(QKeySequence(tr("Ctrl+Alt+Right"))); +#else + cmd->setDefaultKeySequence(QKeySequence(tr("Alt+Right"))); +#endif + mwindow->addAction(cmd, Constants::G_WINDOW_NAVIGATE); + connect(m_d->m_goForwardAction, SIGNAL(triggered()), this, SLOT(goForwardInNavigationHistory())); + +#ifdef Q_WS_MAC + QString prefix = tr("Meta+E"); +#else + QString prefix = tr("Ctrl+E"); +#endif + + m_d->m_splitAction = new QAction(tr("Split"), this); + cmd = am->registerAction(m_d->m_splitAction, Constants::SPLIT, editManagerContext); + cmd->setDefaultKeySequence(QKeySequence(tr("%1,2").arg(prefix))); + mwindow->addAction(cmd, Constants::G_WINDOW_SPLIT); + connect(m_d->m_splitAction, SIGNAL(triggered()), this, SLOT(split())); + + m_d->m_splitSideBySideAction = new QAction(tr("Split Side by Side"), this); + cmd = am->registerAction(m_d->m_splitSideBySideAction, Constants::SPLIT_SIDE_BY_SIDE, editManagerContext); + cmd->setDefaultKeySequence(QKeySequence(tr("%1,3").arg(prefix))); + mwindow->addAction(cmd, Constants::G_WINDOW_SPLIT); + connect(m_d->m_splitSideBySideAction, SIGNAL(triggered()), this, SLOT(splitSideBySide())); + + m_d->m_removeCurrentSplitAction = new QAction(tr("Remove Current Split"), this); + cmd = am->registerAction(m_d->m_removeCurrentSplitAction, Constants::REMOVE_CURRENT_SPLIT, editManagerContext); + cmd->setDefaultKeySequence(QKeySequence(tr("%1,0").arg(prefix))); + mwindow->addAction(cmd, Constants::G_WINDOW_SPLIT); + connect(m_d->m_removeCurrentSplitAction, SIGNAL(triggered()), this, SLOT(removeCurrentSplit())); + + m_d->m_removeAllSplitsAction = new QAction(tr("Remove All Splits"), this); + cmd = am->registerAction(m_d->m_removeAllSplitsAction, Constants::REMOVE_ALL_SPLITS, editManagerContext); + cmd->setDefaultKeySequence(QKeySequence(tr("%1,1").arg(prefix))); + mwindow->addAction(cmd, Constants::G_WINDOW_SPLIT); + connect(m_d->m_removeAllSplitsAction, SIGNAL(triggered()), this, SLOT(removeAllSplits())); + + m_d->m_gotoOtherSplitAction = new QAction(tr("Goto Other Split"), this); + cmd = am->registerAction(m_d->m_gotoOtherSplitAction, Constants::GOTO_OTHER_SPLIT, editManagerContext); + cmd->setDefaultKeySequence(QKeySequence(tr("%1,o").arg(prefix))); + mwindow->addAction(cmd, Constants::G_WINDOW_SPLIT); + connect(m_d->m_gotoOtherSplitAction, SIGNAL(triggered()), this, SLOT(gotoOtherSplit())); + + ActionContainer *medit = am->actionContainer(Constants::M_EDIT); + ActionContainer *advancedMenu = am->createMenu(Constants::M_EDIT_ADVANCED); + medit->addMenu(advancedMenu, Constants::G_EDIT_ADVANCED); + advancedMenu->menu()->setTitle(tr("&Advanced")); + advancedMenu->appendGroup(Constants::G_EDIT_FORMAT); + advancedMenu->appendGroup(Constants::G_EDIT_COLLAPSING); + advancedMenu->appendGroup(Constants::G_EDIT_BLOCKS); + advancedMenu->appendGroup(Constants::G_EDIT_FONT); + advancedMenu->appendGroup(Constants::G_EDIT_EDITOR); + + // Advanced menu separators + cmd = createSeparator(am, this, QLatin1String("QtCreator.Edit.Sep.Collapsing"), editManagerContext); + advancedMenu->addAction(cmd, Constants::G_EDIT_COLLAPSING); + cmd = createSeparator(am, this, QLatin1String("QtCreator.Edit.Sep.Blocks"), editManagerContext); + advancedMenu->addAction(cmd, Constants::G_EDIT_BLOCKS); + cmd = createSeparator(am, this, QLatin1String("QtCreator.Edit.Sep.Font"), editManagerContext); + advancedMenu->addAction(cmd, Constants::G_EDIT_FONT); + cmd = createSeparator(am, this, QLatin1String("QtCreator.Edit.Sep.Editor"), editManagerContext); + advancedMenu->addAction(cmd, Constants::G_EDIT_EDITOR); + + cmd = am->registerAction(m_d->m_openInExternalEditorAction, Constants::OPEN_IN_EXTERNAL_EDITOR, editManagerContext); + cmd->setDefaultKeySequence(QKeySequence(tr("Alt+V,Alt+I"))); + advancedMenu->addAction(cmd, Constants::G_EDIT_EDITOR); + connect(m_d->m_openInExternalEditorAction, SIGNAL(triggered()), this, SLOT(openInExternalEditor())); + + // Connect to VariableManager for CURRENT_DOCUMENT variable setting + VariableManager *vm = VariableManager::instance(); + connect(this, SIGNAL(currentEditorChanged(Core::IEditor *)), + vm, SLOT(updateCurrentDocument(Core::IEditor *))); + + + // other setup + m_d->m_splitter = new SplitterOrView(m_d->m_editorModel); + m_d->m_view = m_d->m_splitter->view(); + + + QHBoxLayout *layout = new QHBoxLayout(this); + layout->setMargin(0); + layout->setSpacing(0); + layout->addWidget(m_d->m_splitter); + + updateActions(); + + m_d->m_windowPopup = new OpenEditorsWindow(this); +} + +EditorManager::~EditorManager() +{ + if (m_d->m_core) { + ExtensionSystem::PluginManager *pm = ExtensionSystem::PluginManager::instance(); + if (m_d->m_coreListener) { + pm->removeObject(m_d->m_coreListener); + delete m_d->m_coreListener; + } + pm->removeObject(m_d->m_openEditorsFactory); + delete m_d->m_openEditorsFactory; + } + delete m_d; +} + +void EditorManager::init() +{ + QList context; + context << m_d->m_core->uniqueIDManager()->uniqueIdentifier("QtCreator.OpenDocumentsView"); + + m_d->m_coreListener = new EditorClosingCoreListener(this); + + pluginManager()->addObject(m_d->m_coreListener); + + m_d->m_openEditorsFactory = new OpenEditorsViewFactory(); + pluginManager()->addObject(m_d->m_openEditorsFactory); +} + +QString EditorManager::defaultExternalEditor() const +{ +#ifdef Q_OS_UNIX + return ConsoleProcess::defaultTerminalEmulator() + QLatin1String( +# ifdef Q_OS_MAC + " -async" +# endif + " -geom %Wx%H+%x+%y -e vi %f +%l +\"normal %c|\""); +#else + return QLatin1String("notepad %f"); +#endif +} + +void EditorManager::removeEditor(IEditor *editor) +{ + bool isDuplicate = m_d->m_editorModel->isDuplicate(editor); + m_d->m_editorModel->removeEditor(editor); + if (!isDuplicate) { + m_d->m_core->fileManager()->removeFile(editor->file()); + } + m_d->m_core->removeContextObject(editor); +} + +void EditorManager::handleContextChange(Core::IContext *context) +{ + if (debugEditorManager) + qDebug() << Q_FUNC_INFO; + IEditor *editor = context ? qobject_cast(context) : 0; + if (editor) { + setCurrentEditor(editor); + } else { + updateActions(); + } +} + +void EditorManager::setCurrentEditor(IEditor *editor, bool ignoreNavigationHistory) +{ + if (editor) + setCurrentView(0); + + if (m_d->m_currentEditor == editor) + return; + if (m_d->m_currentEditor && !ignoreNavigationHistory) + addCurrentPositionToNavigationHistory(); + + m_d->m_currentEditor = editor; + if (editor) { + if (SplitterOrView *splitterOrView = m_d->m_splitter->findView(editor)) + splitterOrView->view()->setCurrentEditor(editor); + m_d->m_view->updateEditorHistory(editor); // the global view should have a complete history + } + updateActions(); + emit currentEditorChanged(editor); +} + + +void EditorManager::setCurrentView(Core::Internal::SplitterOrView *view) +{ + if (view == m_d->m_currentView) + return; + + SplitterOrView *old = m_d->m_currentView; + m_d->m_currentView = view; + + if (old) + old->update(); + if (view) + view->update(); + + if (view && !view->editor()) + view->setFocus(); +} + +Core::Internal::SplitterOrView *EditorManager::currentSplitterOrView() const +{ + SplitterOrView *view = m_d->m_currentView; + if (!view) + view = m_d->m_currentEditor? + m_d->m_splitter->findView(m_d->m_currentEditor): + m_d->m_splitter->findFirstView(); + if (!view) + return m_d->m_splitter; + return view; +} + +Core::Internal::EditorView *EditorManager::currentEditorView() const +{ + return currentSplitterOrView()->view(); +} + + + +QList EditorManager::editorsForFileName(const QString &filename) const +{ + QList found; + QString fixedname = FileManager::fixFileName(filename); + foreach (IEditor *editor, openedEditors()) { + if (fixedname == FileManager::fixFileName(editor->file()->fileName())) + found << editor; + } + return found; +} + +QList EditorManager::editorsForFile(IFile *file) const +{ + QList found; + foreach (IEditor *editor, openedEditors()) { + if (editor->file() == file) + found << editor; + } + return found; +} + +IEditor *EditorManager::currentEditor() const +{ + return m_d->m_currentEditor; +} + +void EditorManager::emptyView(Core::Internal::EditorView *view) +{ + if (!view) + return; + + QList editors = view->editors(); + foreach (IEditor *editor, editors) { + if (!m_d->m_editorModel->isDuplicate(editor)) { + editors.removeAll(editor); + view->removeEditor(editor); + continue; + } + emit editorAboutToClose(editor); + removeEditor(editor); + view->removeEditor(editor); + } + emit editorsClosed(editors); + foreach (IEditor *editor, editors) { + delete editor; + } +} + +void EditorManager::closeView(Core::Internal::EditorView *view) +{ + if (!view) + return; + + if (view == m_d->m_view) { + if (IEditor *e = view->currentEditor()) + closeEditors(QList() << e); + return; + } + + emptyView(view); + + SplitterOrView *splitterOrView = m_d->m_splitter->findView(view); + Q_ASSERT(splitterOrView); + Q_ASSERT(splitterOrView->view() == view); + SplitterOrView *splitter = m_d->m_splitter->findSplitter(splitterOrView); + Q_ASSERT(splitterOrView->hasEditors() == false); + splitterOrView->hide(); + delete splitterOrView; + + splitter->unsplit(); + + SplitterOrView *newCurrent = splitter->findFirstView(); + if (newCurrent) { + if (newCurrent->editor()) + activateEditor(newCurrent->view(), newCurrent->editor()); + else + setCurrentView(newCurrent); + } +} + +QList + EditorManager::editorsForFiles(QList files) const +{ + const QList editors = openedEditors(); + QSet found; + foreach (IFile *file, files) { + foreach (IEditor *editor, editors) { + if (editor->file() == file && !found.contains(editor)) { + found << editor; + } + } + } + return found.toList(); +} + +QList EditorManager::filesForEditors(QList editors) const +{ + QSet handledEditors; + QList files; + foreach (IEditor *editor, editors) { + if (!handledEditors.contains(editor)) { + files << editor->file(); + handledEditors.insert(editor); + } + } + return files; +} + +bool EditorManager::closeAllEditors(bool askAboutModifiedEditors) +{ + m_d->m_editorModel->removeAllRestoredEditors(); + if (closeEditors(openedEditors(), askAboutModifiedEditors)) { +// m_d->clearNavigationHistory(); + return true; + } + return false; +} + +void EditorManager::closeOtherEditors(IEditor *editor) +{ + m_d->m_editorModel->removeAllRestoredEditors(); + QList editors = openedEditors(); + editors.removeAll(editor); + closeEditors(editors, true); +} + + +void EditorManager::closeOtherEditors() +{ + IEditor *current = currentEditor(); + QTC_ASSERT(current, return); + closeOtherEditors(current); +} + + +// SLOT connected to action +// since this is potentially called in the event handler of the editor +// we simply postpone it with a single shot timer +void EditorManager::closeEditor() +{ + closeEditor(m_d->m_currentEditor); +} + +void EditorManager::closeEditor(Core::IEditor *editor) +{ + if (!editor) + return; + closeEditors(QList() << editor); +} + +void EditorManager::closeEditor(const QModelIndex &index) +{ + IEditor *editor = index.data(Qt::UserRole).value(); + if (editor) + closeEditor(editor); + else + m_d->m_editorModel->removeEditor(index); +} + +bool EditorManager::closeEditors(const QList editorsToClose, bool askAboutModifiedEditors) +{ + if (editorsToClose.isEmpty()) + return true; + + SplitterOrView *currentSplitterOrView = this->currentSplitterOrView(); + + bool closingFailed = false; + QList acceptedEditors; + //ask all core listeners to check whether the editor can be closed + const QList listeners = + pluginManager()->getObjects(); + foreach (IEditor *editor, editorsToClose) { + bool editorAccepted = true; + if (m_d->m_editorModel->isDuplicate(editor)) + editor = m_d->m_editorModel->originalForDuplicate(editor); + foreach (ICoreListener *listener, listeners) { + if (!listener->editorAboutToClose(editor)) { + editorAccepted = false; + closingFailed = false; + break; + } + } + if (editorAccepted) + acceptedEditors.append(editor); + } + if (acceptedEditors.isEmpty()) + return false; + //ask whether to save modified files + if (askAboutModifiedEditors) { + bool cancelled = false; + QList list = m_d->m_core->fileManager()-> + saveModifiedFiles(filesForEditors(acceptedEditors), &cancelled); + if (cancelled) + return false; + if (!list.isEmpty()) { + closingFailed = true; + QSet skipSet = editorsForFiles(list).toSet(); + acceptedEditors = acceptedEditors.toSet().subtract(skipSet).toList(); + } + } + if (acceptedEditors.isEmpty()) + return false; + + // add duplicates + foreach(IEditor *editor, acceptedEditors) + acceptedEditors += m_d->m_editorModel->duplicatesFor(editor); + + QList closedViews; + + // remove the editors + foreach (IEditor *editor, acceptedEditors) { + emit editorAboutToClose(editor); + if (!editor->file()->fileName().isEmpty()) { + QByteArray state = editor->saveState(); + if (!state.isEmpty()) + m_d->m_editorStates.insert(editor->file()->fileName(), QVariant(state)); + } + + removeEditor(editor); + if (SplitterOrView *view = m_d->m_splitter->findView(editor)) { + if (editor == view->view()->currentEditor()) + closedViews += view->view(); + view->view()->removeEditor(editor); + } + } + + foreach (EditorView *view, closedViews) { + IEditor *newCurrent = view->currentEditor(); + if (!newCurrent) + newCurrent = pickUnusedEditor(); + if (newCurrent) { + activateEditor(view, newCurrent, NoActivate); + } else { + QModelIndex idx = m_d->m_editorModel->firstRestoredEditor(); + if (idx.isValid()) + activateEditor(idx, view, NoActivate); + } + } + + emit editorsClosed(acceptedEditors); + + foreach (IEditor *editor, acceptedEditors) { + delete editor; + } + + if (currentSplitterOrView) { + if (IEditor *editor = currentSplitterOrView->editor()) + activateEditor(currentSplitterOrView->view(), editor); + } + + if (!currentEditor()) + emit currentEditorChanged(0); + + return !closingFailed; +} + +void EditorManager::closeDuplicate(Core::IEditor *editor) +{ + + IEditor *original = editor; + if (m_d->m_editorModel->isDuplicate(editor)) + original= m_d->m_editorModel->originalForDuplicate(editor); + QList duplicates = m_d->m_editorModel->duplicatesFor(original); + + if (duplicates.isEmpty()) { + closeEditor(editor); + return; + } + + if (original== editor) + m_d->m_editorModel->makeOriginal(duplicates.first()); + + SplitterOrView *currentSplitterOrView = this->currentSplitterOrView(); + + emit editorAboutToClose(editor); + + EditorView *view = m_d->m_splitter->findView(editor)->view(); + removeEditor(editor); + view->removeEditor(editor); + + IEditor *newCurrent = view->currentEditor(); + if (!newCurrent) + newCurrent = pickUnusedEditor(); + if (newCurrent) { + activateEditor(view, newCurrent, NoActivate); + } else { + QModelIndex idx = m_d->m_editorModel->firstRestoredEditor(); + if (idx.isValid()) + activateEditor(idx, view, NoActivate); + } + + emit editorsClosed(QList() << editor); + delete editor; + if (currentSplitterOrView) { + if (IEditor *currentEditor = currentSplitterOrView->editor()) + activateEditor(currentSplitterOrView->view(), currentEditor); + } +} + +Core::IEditor *EditorManager::pickUnusedEditor() const +{ + foreach (IEditor *editor, openedEditors()) { + SplitterOrView *view = m_d->m_splitter->findView(editor); + if (!view || view->editor() != editor) + return editor; + } + return 0; +} + +Core::IEditor *EditorManager::activateEditor(const QModelIndex &index, Internal::EditorView *view, OpenEditorFlags flags) +{ + IEditor *editor = index.data(Qt::UserRole).value(); + if (editor) { + return activateEditor(view, editor, flags); + } + + QString fileName = index.data(Qt::UserRole + 1).toString(); + QByteArray kind = index.data(Qt::UserRole + 2).toByteArray(); + return openEditor(view, fileName, kind, flags); +} + +Core::IEditor *EditorManager::placeEditor(Core::Internal::EditorView *view, Core::IEditor *editor) +{ + Q_ASSERT(view && editor); + + if (view->currentEditor() && view->currentEditor()->file() == editor->file()) + editor = view->currentEditor(); + + if (!view->hasEditor(editor)) { + bool duplicateSupported = editor->duplicateSupported(); + if (SplitterOrView *sourceView = m_d->m_splitter->findView(editor)) { + if (editor != sourceView->editor() || !duplicateSupported) { + sourceView->view()->removeEditor(editor); + view->addEditor(editor); + view->setCurrentEditor(editor); + if (!sourceView->editor()) { + if (IEditor *replacement = pickUnusedEditor()) { + sourceView->view()->addEditor(replacement); + } + } + return editor; + } else if (duplicateSupported) { + editor = duplicateEditor(editor); + Q_ASSERT(editor); + m_d->m_editorModel->makeOriginal(editor); + } + } + view->addEditor(editor); + } + return editor; +} + +Core::IEditor *EditorManager::activateEditor(Core::IEditor *editor, OpenEditorFlags flags) +{ + return activateEditor(0, editor, flags); +} + +Core::IEditor *EditorManager::activateEditor(Core::Internal::EditorView *view, Core::IEditor *editor, OpenEditorFlags flags) +{ + if (!view) + view = currentEditorView(); + + Q_ASSERT(view); + + if (!editor) { + if (!m_d->m_currentEditor) + setCurrentEditor(0, (flags & IgnoreNavigationHistory)); + return 0; + } + + editor = placeEditor(view, editor); + + if (!(flags & NoActivate)) { + setCurrentEditor(editor, (flags & IgnoreNavigationHistory)); + if (!(flags & NoModeSwitch)) + ensureEditorManagerVisible(); + if (isVisible()) + editor->widget()->setFocus(); + } + return editor; +} + +Core::IEditor *EditorManager::activateEditor(Core::Internal::EditorView *view, Core::IFile *file, OpenEditorFlags flags) +{ + QList editors = editorsForFile(file); + Q_ASSERT(!editors.isEmpty()); + return activateEditor(view, editors.first(), flags); +} + +/* For something that has a 'QStringList mimeTypes' (IEditorFactory + * or IExternalEditor), find the one best matching the mimetype passed in. + * Recurse over the parent classes of the mimetype to find them. */ +template +static void mimeTypeFactoryRecursion(const MimeDatabase *db, + const MimeType &mimeType, + const QList &allFactories, + bool firstMatchOnly, + QList *list) +{ + typedef typename QList::const_iterator EditorFactoryLikeListConstIterator; + // Loop factories to find type + const QString type = mimeType.type(); + const EditorFactoryLikeListConstIterator fcend = allFactories.constEnd(); + for (EditorFactoryLikeListConstIterator fit = allFactories.constBegin(); fit != fcend; ++fit) { + // Exclude duplicates when recursing over xml or C++ -> C -> text. + EditorFactoryLike *factory = *fit; + if (!list->contains(factory) && factory->mimeTypes().contains(type)) { + list->push_back(*fit); + if (firstMatchOnly) + return; + break; + } + } + // Any parent mime type classes? -> recurse + QStringList parentTypes = mimeType.subClassesOf(); + if (parentTypes.empty()) + return; + const QStringList::const_iterator pcend = parentTypes .constEnd(); + for (QStringList::const_iterator pit = parentTypes .constBegin(); pit != pcend; ++pit) { + if (const MimeType parent = db->findByType(*pit)) + mimeTypeFactoryRecursion(db, parent, allFactories, firstMatchOnly, list); + } +} + +EditorManager::EditorFactoryList + EditorManager::editorFactories(const MimeType &mimeType, bool bestMatchOnly) const +{ + EditorFactoryList rc; + const EditorFactoryList allFactories = pluginManager()->getObjects(); + mimeTypeFactoryRecursion(m_d->m_core->mimeDatabase(), mimeType, allFactories, bestMatchOnly, &rc); + if (debugEditorManager) + qDebug() << Q_FUNC_INFO << mimeType.type() << " returns " << rc; + return rc; +} + +EditorManager::ExternalEditorList + EditorManager::externalEditors(const MimeType &mimeType, bool bestMatchOnly) const +{ + ExternalEditorList rc; + const ExternalEditorList allEditors = pluginManager()->getObjects(); + mimeTypeFactoryRecursion(m_d->m_core->mimeDatabase(), mimeType, allEditors, bestMatchOnly, &rc); + if (debugEditorManager) + qDebug() << Q_FUNC_INFO << mimeType.type() << " returns " << rc; + return rc; +} + +/* For something that has a 'QString kind' (IEditorFactory + * or IExternalEditor), find the one matching a kind. */ +template + inline EditorFactoryLike *findByKind(ExtensionSystem::PluginManager *pm, + const QString &kind) +{ + const QList factories = pm->template getObjects(); + foreach(EditorFactoryLike *efl, factories) + if (kind == efl->kind()) + return efl; + return 0; +} + +IEditor *EditorManager::createEditor(const QString &editorKind, + const QString &fileName) +{ + typedef QList FactoryList; + if (debugEditorManager) + qDebug() << Q_FUNC_INFO << editorKind << fileName; + + + EditorFactoryList factories; + if (editorKind.isEmpty()) { + // Find by mime type + MimeType mimeType = m_d->m_core->mimeDatabase()->findByFile(QFileInfo(fileName)); + if (!mimeType) { + qWarning("%s unable to determine mime type of %s/%s. Falling back to text/plain", + Q_FUNC_INFO, fileName.toUtf8().constData(), editorKind.toUtf8().constData()); + mimeType = m_d->m_core->mimeDatabase()->findByType(QLatin1String("text/plain")); + } + factories = editorFactories(mimeType, true); + } else { + // Find by editor kind + if (IEditorFactory *factory = findByKind(pluginManager(), editorKind)) + factories.push_back(factory); + } + if (factories.empty()) { + qWarning("%s: unable to find an editor factory for the file '%s', editor kind '%s'.", + Q_FUNC_INFO, fileName.toUtf8().constData(), editorKind.toUtf8().constData()); + return 0; + } + + IEditor *editor = factories.front()->createEditor(this); + if (editor) + connect(editor, SIGNAL(changed()), this, SLOT(updateActions())); + if (editor) + emit editorCreated(editor, fileName); + return editor; +} + +void EditorManager::addEditor(IEditor *editor, bool isDuplicate) +{ + if (!editor) + return; + m_d->m_core->addContextObject(editor); + + m_d->m_editorModel->addEditor(editor, isDuplicate); + if (!isDuplicate) { + m_d->m_core->fileManager()->addFile(editor->file()); + if (!editor->isTemporary()) { + m_d->m_core->fileManager()->addToRecentFiles(editor->file()->fileName()); + } + } + emit editorOpened(editor); +} + +// Run the OpenWithDialog and return the editor kind +// selected by the user. +QString EditorManager::getOpenWithEditorKind(const QString &fileName, + bool *isExternalEditor) const +{ + // Collect editors that can open the file + const MimeType mt = m_d->m_core->mimeDatabase()->findByFile(fileName); + if (!mt) + return QString(); + QStringList allEditorKinds; + QStringList externalEditorKinds; + // Built-in + const EditorFactoryList editors = editorFactories(mt, false); + const int size = editors.size(); + for (int i = 0; i < size; i++) { + allEditorKinds.push_back(editors.at(i)->kind()); + } + // External editors + const ExternalEditorList exEditors = externalEditors(mt, false); + const int esize = exEditors.size(); + for (int i = 0; i < esize; i++) { + externalEditorKinds.push_back(exEditors.at(i)->kind()); + allEditorKinds.push_back(exEditors.at(i)->kind()); + } + if (allEditorKinds.empty()) + return QString(); + // Run dialog. + OpenWithDialog dialog(fileName, m_d->m_core->mainWindow()); + dialog.setEditors(allEditorKinds); + dialog.setCurrentEditor(0); + if (dialog.exec() != QDialog::Accepted) + return QString(); + const QString selectedKind = dialog.editor(); + if (isExternalEditor) + *isExternalEditor = externalEditorKinds.contains(selectedKind); + return selectedKind; +} + +static QString formatFileFilters(const Core::ICore *core, QString *selectedFilter) +{ + QString rc; + // Compile list of filter strings. If we find a glob matching all files, + // put it last and set it as default selectedFilter. + QStringList filters = core->mimeDatabase()->filterStrings(); + filters.sort(); + selectedFilter->clear(); + if (filters.empty()) + return rc; + const QString filterSeparator = QLatin1String(";;"); + bool hasAllFilter = false; + const int size = filters.size(); + for (int i = 0; i < size; i++) { + const QString &filterString = filters.at(i); + if (filterString.isEmpty()) { // binary editor + hasAllFilter = true; + } else { + if (!rc.isEmpty()) + rc += filterSeparator; + rc += filterString; + } + } + if (hasAllFilter) { + // prepend all files filter + // prepending instead of appending to work around a but in Qt/Mac + QString allFilesFilter = EditorManager::tr("All Files (*)"); + if (!rc.isEmpty()) + allFilesFilter += filterSeparator; + rc.prepend(allFilesFilter); + *selectedFilter = allFilesFilter; + } else { + *selectedFilter = filters.front(); + } + return rc; +} + +IEditor *EditorManager::openEditor(const QString &fileName, const QString &editorKind, + EditorManager::OpenEditorFlags flags) +{ + return openEditor(0, fileName, editorKind, flags); +} + +IEditor *EditorManager::openEditor(Core::Internal::EditorView *view, const QString &fileName, + const QString &editorKind, EditorManager::OpenEditorFlags flags) +{ + if (debugEditorManager) + qDebug() << Q_FUNC_INFO << fileName << editorKind; + + if (fileName.isEmpty()) + return 0; + + const QList editors = editorsForFileName(fileName); + if (!editors.isEmpty()) { + return activateEditor(view, editors.first(), flags); + } + QApplication::setOverrideCursor(QCursor(Qt::WaitCursor)); + IEditor *editor = createEditor(editorKind, fileName); + if (!editor || !editor->open(fileName)) { + QApplication::restoreOverrideCursor(); + QMessageBox::critical(m_d->m_core->mainWindow(), tr("Opening File"), tr("Cannot open file %1!").arg(QDir::toNativeSeparators(fileName))); + delete editor; + editor = 0; + return 0; + } + addEditor(editor); + + IEditor *result= activateEditor(view, editor, flags); + if (editor == result) + restoreEditorState(editor); + QApplication::restoreOverrideCursor(); + return result; +} + +bool EditorManager::openExternalEditor(const QString &fileName, const QString &editorKind) +{ + IExternalEditor *ee = findByKind(pluginManager(), editorKind); + if (!ee) + return false; + QString errorMessage; + QApplication::setOverrideCursor(QCursor(Qt::WaitCursor)); + const bool ok = ee->startEditor(fileName, &errorMessage); + QApplication::restoreOverrideCursor(); + if (!ok) + QMessageBox::critical(m_d->m_core->mainWindow(), tr("Opening File"), errorMessage); + return ok; +} + +QStringList EditorManager::getOpenFileNames() const +{ + static QString dir = QDir::homePath(); + if (m_d->fileFilters.isEmpty()) + m_d->fileFilters = formatFileFilters(m_d->m_core, &m_d->selectedFilter); + + QString currentFile = ICore::instance()->fileManager()->currentFile(); + if (!currentFile.isEmpty()) { + const QFileInfo fi(currentFile); + dir = fi.absolutePath(); + } + + QStringList files = QFileDialog::getOpenFileNames(m_d->m_core->mainWindow(), tr("Open File"), + dir, m_d->fileFilters, &m_d->selectedFilter); + if (!files.isEmpty()) + dir = QFileInfo(files.at(0)).absolutePath(); + return files; +} + +void EditorManager::ensureEditorManagerVisible() +{ + if (!isVisible()) + m_d->m_core->modeManager()->activateMode(Constants::MODE_EDIT); +} + +IEditor *EditorManager::openEditorWithContents(const QString &editorKind, + QString *titlePattern, + const QString &contents) +{ + if (debugEditorManager) + qDebug() << Q_FUNC_INFO << editorKind << titlePattern << contents; + + if (editorKind.isEmpty()) + return 0; + + QApplication::setOverrideCursor(QCursor(Qt::WaitCursor)); + IEditor *edt = createEditor(editorKind); + if (!edt) { + QApplication::restoreOverrideCursor(); + return 0; + } + + if (!edt->createNew(contents)) { + QApplication::restoreOverrideCursor(); + delete edt; + edt = 0; + return 0; + } + + QString title = edt->displayName(); + + if (title.isEmpty() && titlePattern) { + const QChar dollar = QLatin1Char('$'); + const QChar dot = QLatin1Char('.'); + + QString base = *titlePattern; + if (base.isEmpty()) + base = QLatin1String("unnamed$"); + if (base.contains(dollar)) { + int i = 1; + QSet docnames; + foreach (IEditor *editor, openedEditors()) { + QString name = editor->file()->fileName(); + if (name.isEmpty()) { + name = editor->displayName(); + name.remove(QLatin1Char('*')); + } else { + name = QFileInfo(name).completeBaseName(); + } + docnames << name; + } + + do { + title = base; + title.replace(QString(dollar), QString::number(i++)); + } while (docnames.contains(title)); + } else { + title = *titlePattern; + } + } + *titlePattern = title; + edt->setDisplayName(title); + addEditor(edt); + QApplication::restoreOverrideCursor(); + return edt; +} + +bool EditorManager::hasEditor(const QString &fileName) const +{ + return !editorsForFileName(fileName).isEmpty(); +} + +void EditorManager::restoreEditorState(IEditor *editor) +{ + QTC_ASSERT(editor, return); + QString fileName = editor->file()->fileName(); + if (m_d->m_editorStates.contains(fileName)) + editor->restoreState(m_d->m_editorStates.value(fileName).toByteArray()); +} + +bool EditorManager::saveEditor(IEditor *editor) +{ + return saveFile(editor); +} + +bool EditorManager::saveFile(IEditor *editor) +{ + if (!editor) + editor = currentEditor(); + if (!editor) + return false; + + IFile *file = editor->file(); + file->checkPermissions(); + + const QString &fileName = file->fileName(); + + if (fileName.isEmpty()) + return saveFileAs(editor); + + bool success = false; + + // try saving, no matter what isReadOnly tells us + m_d->m_core->fileManager()->blockFileChange(file); + success = file->save(fileName); + m_d->m_core->fileManager()->unblockFileChange(file); + + if (!success) { + MakeWritableResult answer = + makeEditorWritable(editor); + if (answer == Failed) + return false; + if (answer == SavedAs) + return true; + + file->checkPermissions(); + + m_d->m_core->fileManager()->blockFileChange(file); + success = file->save(fileName); + m_d->m_core->fileManager()->unblockFileChange(file); + } + + if (success && !editor->isTemporary()) + m_d->m_core->fileManager()->addToRecentFiles(editor->file()->fileName()); + + return success; +} + +EditorManager::ReadOnlyAction + EditorManager::promptReadOnlyFile(const QString &fileName, + const IVersionControl *versionControl, + QWidget *parent, + bool displaySaveAsButton) +{ + QMessageBox msgBox(QMessageBox::Question, tr("File is Read Only"), + tr("The file %1 is read only.").arg(QDir::toNativeSeparators(fileName)), + QMessageBox::Cancel, parent); + + QPushButton *sccButton = 0; + if (versionControl && versionControl->supportsOperation(IVersionControl::OpenOperation)) + sccButton = msgBox.addButton(tr("Open with VCS (%1)").arg(versionControl->name()), QMessageBox::AcceptRole); + + QPushButton *makeWritableButton = msgBox.addButton(tr("Make writable"), QMessageBox::AcceptRole); + + QPushButton *saveAsButton = 0; + if (displaySaveAsButton) + saveAsButton = msgBox.addButton(tr("Save as ..."), QMessageBox::ActionRole); + + msgBox.setDefaultButton(sccButton ? sccButton : makeWritableButton); + msgBox.exec(); + + QAbstractButton *clickedButton = msgBox.clickedButton(); + if (clickedButton == sccButton) + return RO_OpenVCS; + if (clickedButton == makeWritableButton) + return RO_MakeWriteable; + if (clickedButton == saveAsButton) + return RO_SaveAs; + return RO_Cancel; +} + + +MakeWritableResult +EditorManager::makeEditorWritable(IEditor *editor) +{ + if (!editor || !editor->file()) + return Failed; + QString directory = QFileInfo(editor->file()->fileName()).absolutePath(); + IVersionControl *versionControl = m_d->m_core->vcsManager()->findVersionControlForDirectory(directory); + IFile *file = editor->file(); + const QString &fileName = file->fileName(); + + switch (promptReadOnlyFile(fileName, versionControl, m_d->m_core->mainWindow(), true)) { + case RO_OpenVCS: + if (!versionControl->vcsOpen(fileName)) { + QMessageBox::warning(m_d->m_core->mainWindow(), tr("Failed!"), tr("Could not open the file for editing with SCC.")); + return Failed; + } + file->checkPermissions(); + return OpenedWithVersionControl; + case RO_MakeWriteable: { + const bool permsOk = QFile::setPermissions(fileName, QFile::permissions(fileName) | QFile::WriteUser); + if (!permsOk) { + QMessageBox::warning(m_d->m_core->mainWindow(), tr("Failed!"), tr("Could not set permissions to writable.")); + return Failed; + } + } + file->checkPermissions(); + return MadeWritable; + case RO_SaveAs : + return saveFileAs(editor) ? SavedAs : Failed; + case RO_Cancel: + break; + } + return Failed; +} + +bool EditorManager::saveFileAs(IEditor *editor) +{ + if (!editor) + editor = currentEditor(); + if (!editor) + return false; + + QString absoluteFilePath = m_d->m_core->fileManager()->getSaveAsFileName(editor->file()); + if (absoluteFilePath.isEmpty()) + return false; + if (absoluteFilePath != editor->file()->fileName()) { + const QList existList = editorsForFileName(absoluteFilePath); + if (!existList.isEmpty()) { + closeEditors(existList, false); + } + } + + m_d->m_core->fileManager()->blockFileChange(editor->file()); + const bool success = editor->file()->save(absoluteFilePath); + m_d->m_core->fileManager()->unblockFileChange(editor->file()); + editor->file()->checkPermissions(); + + if (success && !editor->isTemporary()) + m_d->m_core->fileManager()->addToRecentFiles(editor->file()->fileName()); + + updateActions(); + return success; +} + +void EditorManager::gotoNextDocHistory() +{ + OpenEditorsWindow *dialog = windowPopup(); + if (dialog->isVisible()) { + dialog->selectNextEditor(); + } else { + EditorView *view = currentEditorView(); + dialog->setEditors(m_d->m_view, view, m_d->m_editorModel); + dialog->selectNextEditor(); + showWindowPopup(); + } +} + +void EditorManager::gotoPreviousDocHistory() +{ + OpenEditorsWindow *dialog = windowPopup(); + if (dialog->isVisible()) { + dialog->selectPreviousEditor(); + } else { + EditorView *view = currentEditorView(); + dialog->setEditors(m_d->m_view, view, m_d->m_editorModel); + dialog->selectPreviousEditor(); + showWindowPopup(); + } +} + +void EditorManager::makeCurrentEditorWritable() +{ + if (IEditor* curEditor = currentEditor()) + makeEditorWritable(curEditor); +} + +void EditorManager::updateActions() +{ + QString fName; + IEditor *curEditor = currentEditor(); + int openedCount = openedEditors().count() + m_d->m_editorModel->restoredEditorCount(); + if (curEditor) { + if (!curEditor->file()->fileName().isEmpty()) { + QFileInfo fi(curEditor->file()->fileName()); + fName = fi.fileName(); + } else { + fName = curEditor->displayName(); + } + + + if (curEditor->file()->isModified() && curEditor->file()->isReadOnly()) { + // we are about to change a read-only file, warn user + showEditorInfoBar(QLatin1String("Core.EditorManager.MakeWritable"), + tr("Warning: You are changing a read-only file."), + tr("Make writable"), this, SLOT(makeCurrentEditorWritable())); + } else { + hideEditorInfoBar(QLatin1String("Core.EditorManager.MakeWritable")); + } + } + + m_d->m_saveAction->setEnabled(curEditor != 0 && curEditor->file()->isModified()); + m_d->m_saveAsAction->setEnabled(curEditor != 0 && curEditor->file()->isSaveAsAllowed()); + m_d->m_revertToSavedAction->setEnabled(curEditor != 0 + && !curEditor->file()->fileName().isEmpty() && curEditor->file()->isModified()); + + QString quotedName; + if (!fName.isEmpty()) + quotedName = '"' + fName + '"'; + m_d->m_saveAsAction->setText(tr("Save %1 As...").arg(quotedName)); + m_d->m_saveAction->setText(tr("&Save %1").arg(quotedName)); + m_d->m_revertToSavedAction->setText(tr("Revert %1 to Saved").arg(quotedName)); + + + m_d->m_closeCurrentEditorAction->setEnabled(curEditor != 0); + m_d->m_closeCurrentEditorAction->setText(tr("Close %1").arg(quotedName)); + m_d->m_closeAllEditorsAction->setEnabled(openedCount > 0); + m_d->m_closeOtherEditorsAction->setEnabled(openedCount > 1); + m_d->m_closeOtherEditorsAction->setText((openedCount > 1 ? tr("Close All Except %1").arg(quotedName) : tr("Close Others"))); + + m_d->m_gotoNextDocHistoryAction->setEnabled(m_d->m_editorModel->rowCount() != 0); + m_d->m_gotoPreviousDocHistoryAction->setEnabled(m_d->m_editorModel->rowCount() != 0); + EditorView *view = currentEditorView(); + m_d->m_goBackAction->setEnabled(view ? view->canGoBack() : false); + m_d->m_goForwardAction->setEnabled(view ? view->canGoForward() : false); + + bool hasSplitter = m_d->m_splitter->isSplitter(); + m_d->m_removeCurrentSplitAction->setEnabled(hasSplitter); + m_d->m_removeAllSplitsAction->setEnabled(hasSplitter); + m_d->m_gotoOtherSplitAction->setEnabled(hasSplitter); + + m_d->m_openInExternalEditorAction->setEnabled(curEditor != 0); +} + +QList EditorManager::openedEditors() const +{ + return m_d->m_editorModel->editors(); +} + +OpenEditorsModel *EditorManager::openedEditorsModel() const +{ + return m_d->m_editorModel; +} + +void EditorManager::addCurrentPositionToNavigationHistory(IEditor *editor, const QByteArray &saveState) +{ + currentEditorView()->addCurrentPositionToNavigationHistory(editor, saveState); + updateActions(); +} + +void EditorManager::goBackInNavigationHistory() +{ + currentEditorView()->goBackInNavigationHistory(); + updateActions(); + ensureEditorManagerVisible(); + return; +} + +void EditorManager::goForwardInNavigationHistory() +{ + currentEditorView()->goForwardInNavigationHistory(); + updateActions(); + ensureEditorManagerVisible(); +} + +OpenEditorsWindow *EditorManager::windowPopup() const +{ + return m_d->m_windowPopup; +} + +void EditorManager::showWindowPopup() const +{ + const QPoint p(mapToGlobal(QPoint(0, 0))); + m_d->m_windowPopup->move((width()-m_d->m_windowPopup->width())/2 + p.x(), + (height()-m_d->m_windowPopup->height())/2 + p.y()); + m_d->m_windowPopup->setVisible(true); +} + +QByteArray EditorManager::saveState() const +{ + QByteArray bytes; + QDataStream stream(&bytes, QIODevice::WriteOnly); + + stream << QByteArray("EditorManagerV4"); + + QList editors = openedEditors(); + foreach (IEditor *editor, editors) { + if (!editor->file()->fileName().isEmpty()) { + QByteArray state = editor->saveState(); + if (!state.isEmpty()) + m_d->m_editorStates.insert(editor->file()->fileName(), QVariant(state)); + } + } + + stream << m_d->m_editorStates; + + QList entries = m_d->m_editorModel->entries(); + stream << entries.count(); + + foreach (OpenEditorsModel::Entry entry, entries) { + stream << entry.fileName() << entry.displayName() << entry.kind(); + } + + stream << m_d->m_splitter->saveState(); + + return bytes; +} + +bool EditorManager::restoreState(const QByteArray &state) +{ + closeAllEditors(true); + removeAllSplits(); + QDataStream stream(state); + + QByteArray version; + stream >> version; + + if (version != "EditorManagerV4") + return false; + + QMap editorstates; + + QApplication::setOverrideCursor(Qt::WaitCursor); + + stream >> editorstates; + + QMapIterator i(editorstates); + while (i.hasNext()) { + i.next(); + m_d->m_editorStates.insert(i.key(), i.value()); + } + + int editorCount = 0; + stream >> editorCount; + while (--editorCount >= 0) { + QString fileName; + stream >> fileName; + QString displayName; + stream >> displayName; + QByteArray kind; + stream >> kind; + + if (!fileName.isEmpty() && !displayName.isEmpty()){ + m_d->m_editorModel->addRestoredEditor(fileName, displayName, kind); + } + } + + QByteArray splitterstates; + stream >> splitterstates; + m_d->m_splitter->restoreState(splitterstates); + + // splitting and stuff results in focus trouble, that's why we set the focus again after restoration + ensureEditorManagerVisible(); + if (m_d->m_currentEditor) { + m_d->m_currentEditor->widget()->setFocus(); + } else if (Core::Internal::SplitterOrView *view = currentSplitterOrView()) { + if (IEditor *e = view->editor()) + e->widget()->setFocus(); + else if (view->view()) + view->view()->setFocus(); + } + + QApplication::restoreOverrideCursor(); + + return true; +} + +static const char * const documentStatesKey = "EditorManager/DocumentStates"; +static const char * const externalEditorKey = "EditorManager/ExternalEditorCommand"; +static const char * const reloadBehaviorKey = "EditorManager/ReloadBehavior"; + +void EditorManager::saveSettings() +{ + SettingsDatabase *settings = m_d->m_core->settingsDatabase(); + settings->setValue(QLatin1String(documentStatesKey), m_d->m_editorStates); + settings->setValue(QLatin1String(externalEditorKey), m_d->m_externalEditor); + settings->setValue(QLatin1String(reloadBehaviorKey), m_d->m_reloadBehavior); +} + +void EditorManager::readSettings() +{ + // Backward compatibility to old locations for these settings + QSettings *qs = m_d->m_core->settings(); + if (qs->contains(QLatin1String(documentStatesKey))) { + m_d->m_editorStates = qs->value(QLatin1String(documentStatesKey)) + .value >(); + qs->remove(QLatin1String(documentStatesKey)); + } + if (qs->contains(QLatin1String(externalEditorKey))) { + m_d->m_externalEditor = qs->value(QLatin1String(externalEditorKey)).toString(); + qs->remove(QLatin1String(externalEditorKey)); + } + + SettingsDatabase *settings = m_d->m_core->settingsDatabase(); + if (settings->contains(QLatin1String(documentStatesKey))) + m_d->m_editorStates = settings->value(QLatin1String(documentStatesKey)) + .value >(); + if (settings->contains(QLatin1String(externalEditorKey))) + m_d->m_externalEditor = settings->value(QLatin1String(externalEditorKey)).toString(); + + if (settings->contains(QLatin1String(reloadBehaviorKey))) + m_d->m_reloadBehavior = (IFile::ReloadBehavior)settings->value(QLatin1String(reloadBehaviorKey)).toInt(); +} + + +void EditorManager::revertToSaved() +{ + IEditor *currEditor = currentEditor(); + if (!currEditor) + return; + const QString fileName = currEditor->file()->fileName(); + if (fileName.isEmpty()) + return; + if (currEditor->file()->isModified()) { + QMessageBox msgBox(QMessageBox::Question, tr("Revert to Saved"), + tr("You will lose your current changes if you proceed reverting %1.").arg(QDir::toNativeSeparators(fileName)), + QMessageBox::Yes|QMessageBox::No, m_d->m_core->mainWindow()); + msgBox.button(QMessageBox::Yes)->setText(tr("Proceed")); + msgBox.button(QMessageBox::No)->setText(tr("Cancel")); + msgBox.setDefaultButton(QMessageBox::No); + msgBox.setEscapeButton(QMessageBox::No); + if (msgBox.exec() == QMessageBox::No) + return; + + } + IFile::ReloadBehavior temp = IFile::ReloadAll; + currEditor->file()->modified(&temp); +} + +void EditorManager::showEditorInfoBar(const QString &kind, + const QString &infoText, + const QString &buttonText, + QObject *object, const char *member) +{ + + currentEditorView()->showEditorInfoBar(kind, infoText, buttonText, object, member); +} + + +void EditorManager::hideEditorInfoBar(const QString &kind) +{ + Core::Internal::EditorView *cev = currentEditorView(); + if (cev) + cev->hideEditorInfoBar(kind); +} + +void EditorManager::showEditorStatusBar(const QString &kind, + const QString &infoText, + const QString &buttonText, + QObject *object, const char *member) +{ + + currentEditorView()->showEditorStatusBar(kind, infoText, buttonText, object, member); +} + +void EditorManager::hideEditorStatusBar(const QString &kind) +{ + currentEditorView()->hideEditorStatusBar(kind); +} + +QString EditorManager::externalEditorHelpText() const +{ + QString help = tr( + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "
VariableExpands to
%ffile name
%lcurrent line number
%ccurrent column number
%xeditor's x position on screen
%yeditor's y position on screen
%weditor's width in pixels
%heditor's height in pixels
%Weditor's width in characters
%Heditor's height in characters
%%%
"); + return help; +} + +void EditorManager::openInExternalEditor() +{ + QString command = m_d->m_externalEditor; + if (command.isEmpty()) + command = defaultExternalEditor(); + + if (command.isEmpty()) + return; + + IEditor *editor = currentEditor(); + if (!editor) + return; + if (editor->file()->isModified()) { + bool cancelled = false; + QList list = m_d->m_core->fileManager()-> + saveModifiedFiles(QList() << editor->file(), &cancelled); + if (cancelled) + return; + } + + QRect rect = editor->widget()->rect(); + QFont font = editor->widget()->font(); + QFontMetrics fm(font); + rect.moveTo(editor->widget()->mapToGlobal(QPoint(0,0))); + + QString pre = command; + QString cmd; + for (int i = 0; i < pre.size(); ++i) { + QChar c = pre.at(i); + if (c == QLatin1Char('%') && i < pre.size()-1) { + c = pre.at(++i); + QString s; + if (c == QLatin1Char('f')) + s = editor->file()->fileName(); + else if (c == QLatin1Char('l')) + s = QString::number(editor->currentLine()); + else if (c == QLatin1Char('c')) + s = QString::number(editor->currentColumn()); + else if (c == QLatin1Char('x')) + s = QString::number(rect.x()); + else if (c == QLatin1Char('y')) + s = QString::number(rect.y()); + else if (c == QLatin1Char('w')) + s = QString::number(rect.width()); + else if (c == QLatin1Char('h')) + s = QString::number(rect.height()); + else if (c == QLatin1Char('W')) + s = QString::number(rect.width() / fm.width(QLatin1Char('x'))); + else if (c == QLatin1Char('H')) + s = QString::number(rect.height() / fm.lineSpacing()); + else if (c == QLatin1Char('%')) + s = c; + else { + s = QLatin1Char('%'); + cmd += c; + } + cmd += s; + continue; + + } + cmd += c; + } + + QProcess::startDetached(cmd); +} + +void EditorManager::setExternalEditor(const QString &editor) +{ + if (editor.isEmpty() || editor == defaultExternalEditor()) + m_d->m_externalEditor = defaultExternalEditor(); + else + m_d->m_externalEditor = editor; +} + +QString EditorManager::externalEditor() const +{ + if (m_d->m_externalEditor.isEmpty()) + return defaultExternalEditor(); + return m_d->m_externalEditor; +} + +void EditorManager::setReloadBehavior(IFile::ReloadBehavior behavior) +{ + m_d->m_reloadBehavior = behavior; +} + +IFile::ReloadBehavior EditorManager::reloadBehavior() const +{ + return m_d->m_reloadBehavior; +} + +Core::IEditor *EditorManager::duplicateEditor(Core::IEditor *editor) +{ + if (!editor->duplicateSupported()) + return 0; + + IEditor *duplicate = editor->duplicate(0); + duplicate->restoreState(editor->saveState()); + emit editorCreated(duplicate, duplicate->file()->fileName()); + addEditor(duplicate, true); + return duplicate; +} + +void EditorManager::split(Qt::Orientation orientation) +{ + SplitterOrView *view = m_d->m_currentView; + if (!view) + view = m_d->m_currentEditor ? m_d->m_splitter->findView(m_d->m_currentEditor) + : m_d->m_splitter->findFirstView(); + if (view && !view->splitter()) { + view->split(orientation); + } + updateActions(); +} + +void EditorManager::split() +{ + split(Qt::Vertical); +} + +void EditorManager::splitSideBySide() +{ + split(Qt::Horizontal); +} + +void EditorManager::removeCurrentSplit() +{ + SplitterOrView *viewToClose = m_d->m_currentView; + if (!viewToClose && m_d->m_currentEditor) + viewToClose = m_d->m_splitter->findView(m_d->m_currentEditor); + + if (!viewToClose || viewToClose->isSplitter() || viewToClose == m_d->m_splitter) + return; + + closeView(viewToClose->view()); + updateActions(); +} + +void EditorManager::removeAllSplits() +{ + if (!m_d->m_splitter->isSplitter()) + return; + IEditor *editor = m_d->m_currentEditor; + m_d->m_currentEditor = 0; // trigger update below + if (editor && m_d->m_editorModel->isDuplicate(editor)) + editor = m_d->m_editorModel->originalForDuplicate(editor); + m_d->m_splitter->unsplitAll(); + if (!editor) + editor = pickUnusedEditor(); + activateEditor(editor); +} + +void EditorManager::gotoOtherSplit() +{ + if (m_d->m_splitter->isSplitter()) { + SplitterOrView *currentView = m_d->m_currentView; + if (!currentView && m_d->m_currentEditor) + currentView = m_d->m_splitter->findView(m_d->m_currentEditor); + if (!currentView) + currentView = m_d->m_splitter->findFirstView(); + SplitterOrView *view = m_d->m_splitter->findNextView(currentView); + if (!view) + view = m_d->m_splitter->findFirstView(); + if (view) { + if (IEditor *editor = view->editor()) { + setCurrentEditor(editor, true); + editor->widget()->setFocus(); + } else { + setCurrentView(view); + } + } + } +} +//===================EditorClosingCoreListener====================== + +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); +} diff --git a/ground/src/plugins/coreplugin/images/openpilot_logo_256.png b/ground/src/plugins/coreplugin/images/openpilot_logo_256.png new file mode 100644 index 0000000000000000000000000000000000000000..9875d19940db7fede2a4067442204b143fd76282 GIT binary patch literal 15596 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 b3!nf-H58H`HTH7>@TDZLDpxII9Pobtq=BLQ literal 0 HcmV?d00001 diff --git a/ground/src/plugins/coreplugin/images/openpilot_logo_64.png b/ground/src/plugins/coreplugin/images/openpilot_logo_64.png new file mode 100644 index 0000000000000000000000000000000000000000..3db27973d40479cc641311cb4b0af8b2bb5fe23c GIT binary patch literal 3523 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 literal 0 HcmV?d00001 diff --git a/ground/src/plugins/coreplugin/mainwindow.cpp b/ground/src/plugins/coreplugin/mainwindow.cpp index 028fd513b..95e4c541e 100644 --- a/ground/src/plugins/coreplugin/mainwindow.cpp +++ b/ground/src/plugins/coreplugin/mainwindow.cpp @@ -156,7 +156,7 @@ MainWindow::MainWindow() : setWindowTitle(tr("OpenPilot GCS")); #ifndef Q_WS_MAC - qApp->setWindowIcon(QIcon(":/core/images/qtcreator_logo_128.png")); + qApp->setWindowIcon(QIcon(":/core/images/openpilot_logo_128.png")); #endif QCoreApplication::setApplicationName(QLatin1String("OpenPilotGCS")); QCoreApplication::setApplicationVersion(QLatin1String(Core::Constants::GCS_VERSION_LONG)); @@ -733,9 +733,9 @@ void MainWindow::registerDefaultActions() // About IDE Action #ifdef Q_WS_MAC - tmpaction = new QAction(tr("About &Qt Creator"), this); // it's convention not to add dots to the about menu + tmpaction = new QAction(tr("About &OpenPilot GCS"), this); // it's convention not to add dots to the about menu #else - tmpaction = new QAction(tr("About &Qt Creator..."), this); + tmpaction = new QAction(tr("About &OpenPilot GCS..."), this); #endif cmd = am->registerAction(tmpaction, Constants::ABOUT_QTCREATOR, m_globalContext); mhelp->addAction(cmd, Constants::G_HELP_ABOUT); diff --git a/ground/src/plugins/coreplugin/versiondialog.cpp b/ground/src/plugins/coreplugin/versiondialog.cpp index cb483a4fa..1d8292c0f 100644 --- a/ground/src/plugins/coreplugin/versiondialog.cpp +++ b/ground/src/plugins/coreplugin/versiondialog.cpp @@ -98,7 +98,7 @@ VersionDialog::VersionDialog(QWidget *parent) connect(buttonBox , SIGNAL(rejected()), this, SLOT(reject())); QLabel *logoLabel = new QLabel; - logoLabel->setPixmap(QPixmap(QLatin1String(":/core/images/qtcreator_logo_128.png"))); + logoLabel->setPixmap(QPixmap(QLatin1String(":/core/images/openpilot_logo_128.png"))); layout->addWidget(logoLabel , 0, 0, 1, 1); layout->addWidget(copyRightLabel, 0, 1, 4, 4); layout->addWidget(buttonBox, 4, 0, 1, 5);