OSDN Git Service

change createEditor() error handling
[qt-creator-jp/qt-creator-jp.git] / src / plugins / coreplugin / editormanager / editormanager.cpp
index a2ae0e3..0650599 100644 (file)
@@ -4,30 +4,29 @@
 **
 ** Copyright (c) 2011 Nokia Corporation and/or its subsidiary(-ies).
 **
-** Contact: Nokia Corporation (qt-info@nokia.com)
+** Contact: Nokia Corporation (info@qt.nokia.com)
 **
-** No Commercial Usage
-**
-** This file contains pre-release code and may not be distributed.
-** You may use this file in accordance with the terms and conditions
-** contained in the Technology Preview License Agreement accompanying
-** this package.
 **
 ** 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.
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this file.
+** Please review the following information to ensure the GNU Lesser General
+** Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
 **
 ** In addition, as a special exception, Nokia gives you certain additional
-** rights.  These rights are described in the Nokia Qt LGPL Exception
+** rights. These rights are described in the Nokia Qt LGPL Exception
 ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
 **
+** Other Usage
+**
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
 ** If you have questions regarding the use of this file, please contact
-** Nokia at qt-info@nokia.com.
+** Nokia at info@qt.nokia.com.
 **
 **************************************************************************/
 
 
 enum { debugEditorManager=0 };
 
+static const char kCurrentDocumentFilePath[] = "CurrentDocument:FilePath";
+static const char kCurrentDocumentPath[] = "CurrentDocument:Path";
+static const char kCurrentDocumentXPos[] = "CurrentDocument:XPos";
+static const char kCurrentDocumentYPos[] = "CurrentDocument:YPos";
+
 static inline ExtensionSystem::PluginManager *pluginManager()
 {
     return ExtensionSystem::PluginManager::instance();
@@ -200,7 +204,6 @@ struct EditorManagerPrivate {
     QAction *m_gotoPreviousDocHistoryAction;
     QAction *m_goBackAction;
     QAction *m_goForwardAction;
-    QAction *m_openInExternalEditorAction;
     QAction *m_splitAction;
     QAction *m_splitSideBySideAction;
     QAction *m_removeCurrentSplitAction;
@@ -214,10 +217,8 @@ struct EditorManagerPrivate {
     Internal::OpenEditorsViewFactory *m_openEditorsFactory;
 
     OpenEditorsModel *m_editorModel;
-    QString m_externalEditor;
 
     IFile::ReloadSetting m_reloadSetting;
-    IFile::Utf8BomSetting m_utf8BomSetting;
 
     QString m_titleAddition;
 };
@@ -237,11 +238,9 @@ EditorManagerPrivate::EditorManagerPrivate(ICore *core, QWidget *parent) :
     m_gotoPreviousDocHistoryAction(new QAction(EditorManager::tr("Previous Open Document in History"), parent)),
     m_goBackAction(new QAction(QIcon(QLatin1String(Constants::ICON_PREV)), EditorManager::tr("Go Back"), parent)),
     m_goForwardAction(new QAction(QIcon(QLatin1String(Constants::ICON_NEXT)), EditorManager::tr("Go Forward"), parent)),
-    m_openInExternalEditorAction(new QAction(EditorManager::tr("Open in External Editor"), parent)),
     m_windowPopup(0),
     m_coreListener(0),
-    m_reloadSetting(IFile::AlwaysAsk),
-    m_utf8BomSetting(IFile::OnlyKeep)
+    m_reloadSetting(IFile::AlwaysAsk)
 {
     m_editorModel = new OpenEditorsModel(parent);
 }
@@ -418,7 +417,7 @@ EditorManager::EditorManager(ICore *core, QWidget *parent) :
     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->menu()->setTitle(tr("Ad&vanced"));
     advancedMenu->appendGroup(Constants::G_EDIT_FORMAT);
     advancedMenu->appendGroup(Constants::G_EDIT_COLLAPSING);
     advancedMenu->appendGroup(Constants::G_EDIT_BLOCKS);
@@ -435,13 +434,6 @@ EditorManager::EditorManager(ICore *core, QWidget *parent) :
     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::initEditorManagerConnections();
     // other setup
     m_d->m_splitter = new SplitterOrView(m_d->m_editorModel);
     m_d->m_view = m_d->m_splitter->view();
@@ -479,6 +471,18 @@ void EditorManager::init()
 
     m_d->m_openEditorsFactory = new OpenEditorsViewFactory();
     pluginManager()->addObject(m_d->m_openEditorsFactory);
+
+    VariableManager *vm = VariableManager::instance();
+    vm->registerVariable(QLatin1String(kCurrentDocumentFilePath),
+        tr("Full path of the current document including file name."));
+    vm->registerVariable(QLatin1String(kCurrentDocumentPath),
+        tr("Full path of the current document excluding file name."));
+    vm->registerVariable(QLatin1String(kCurrentDocumentXPos),
+        tr("X-coordinate of the current editor's upper left corner, relative to screen."));
+    vm->registerVariable(QLatin1String(kCurrentDocumentYPos),
+        tr("Y-coordinate of the current editor's upper left corner, relative to screen."));
+    connect(vm, SIGNAL(variableUpdateRequested(QString)),
+            this, SLOT(updateVariable(QString)));
 }
 
 
@@ -487,19 +491,6 @@ EditorToolBar *EditorManager::createToolBar(QWidget *parent)
     return new EditorToolBar(parent);
 }
 
-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);
@@ -1220,17 +1211,20 @@ IEditor *EditorManager::openEditor(Core::Internal::EditorView *view, const QStri
         return activateEditor(view, editor, flags);
     }
 
-    QApplication::setOverrideCursor(QCursor(Qt::WaitCursor));
     IEditor *editor = createEditor(editorId, fn);
     // If we could not open the file in the requested editor, fall
     // back to the default editor:
     if (!editor)
         editor = createEditor(QString(), fn);
-    if (!editor || !editor->open(fn)) {
+    if (!editor) // Internal error
+        return 0;
+
+    QApplication::setOverrideCursor(QCursor(Qt::WaitCursor));
+    QString errorString;
+    if (!editor->open(&errorString, fn)) {
         QApplication::restoreOverrideCursor();
-        QMessageBox::critical(m_d->m_core->mainWindow(), tr("Opening File"), tr("Cannot open file %1!").arg(QDir::toNativeSeparators(fn)));
+        QMessageBox::critical(m_d->m_core->mainWindow(), tr("File Error"), errorString);
         delete editor;
-        editor = 0;
         return 0;
     }
     addEditor(editor);
@@ -1382,13 +1376,12 @@ bool EditorManager::saveFile(IFile *fileParam)
         return saveFileAs(file);
 
     bool success = false;
+    bool isReadOnly;
 
     // 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);
+    success = m_d->m_core->fileManager()->saveFile(file, QString(), &isReadOnly);
 
-    if (!success) {
+    if (!success && isReadOnly) {
         MakeWritableResult answer =
                 makeFileWritable(file);
         if (answer == Failed)
@@ -1398,9 +1391,7 @@ bool EditorManager::saveFile(IFile *fileParam)
 
         file->checkPermissions();
 
-        m_d->m_core->fileManager()->blockFileChange(file);
-        success = file->save(fileName);
-        m_d->m_core->fileManager()->unblockFileChange(file);
+        success = m_d->m_core->fileManager()->saveFile(file);
     }
 
     if (success) {
@@ -1469,9 +1460,7 @@ bool EditorManager::saveFileAs(IFile *fileParam)
         }
     }
 
-    m_d->m_core->fileManager()->blockFileChange(file);
-    const bool success = file->save(absoluteFilePath);
-    m_d->m_core->fileManager()->unblockFileChange(file);
+    const bool success = m_d->m_core->fileManager()->saveFile(file, absoluteFilePath);
     file->checkPermissions();
 
     // @todo: There is an issue to be treated here. The new file might be of a different mime
@@ -1627,8 +1616,6 @@ void EditorManager::updateActions()
     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);
 }
 
 bool EditorManager::hasSplitter() const
@@ -1764,17 +1751,9 @@ bool EditorManager::restoreState(const QByteArray &state)
     if (version != "EditorManagerV4")
         return false;
 
-    QMap<QString, QVariant> editorstates;
-
     QApplication::setOverrideCursor(Qt::WaitCursor);
 
-    stream >> editorstates;
-
-    QMapIterator<QString, QVariant> i(editorstates);
-    while (i.hasNext()) {
-        i.next();
-        m_d->m_editorStates.insert(i.key(), i.value());
-    }
+    stream >> m_d->m_editorStates;
 
     int editorCount = 0;
     stream >> editorCount;
@@ -1809,18 +1788,14 @@ bool EditorManager::restoreState(const QByteArray &state)
     return true;
 }
 
-static const char * const documentStatesKey = "EditorManager/DocumentStates";
-static const char * const externalEditorKey = "EditorManager/ExternalEditorCommand";
-static const char * const reloadBehaviorKey = "EditorManager/ReloadBehavior";
-static const char * const utf8BomBehaviorKey = "EditorManager/Utf8BomBehavior";
+static const char documentStatesKey[] = "EditorManager/DocumentStates";
+static const char 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_reloadSetting);
-    settings->setValue(QLatin1String(utf8BomBehaviorKey), m_d->m_utf8BomSetting);
 }
 
 void EditorManager::readSettings()
@@ -1832,23 +1807,14 @@ void EditorManager::readSettings()
             .value<QMap<QString, QVariant> >();
         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<QMap<QString, QVariant> >();
-    if (settings->contains(QLatin1String(externalEditorKey)))
-        m_d->m_externalEditor = settings->value(QLatin1String(externalEditorKey)).toString();
 
     if (settings->contains(QLatin1String(reloadBehaviorKey)))
         m_d->m_reloadSetting = (IFile::ReloadSetting)settings->value(QLatin1String(reloadBehaviorKey)).toInt();
-
-    if (settings->contains(QLatin1String(utf8BomBehaviorKey)))
-        m_d->m_utf8BomSetting = (IFile::Utf8BomSetting)settings->value(QLatin1String(utf8BomBehaviorKey)).toInt();
 }
 
 
@@ -1872,7 +1838,9 @@ void EditorManager::revertToSaved()
             return;
 
     }
-    currEditor->file()->reload(IFile::FlagReload, IFile::TypeContents);
+    QString errorString;
+    if (!currEditor->file()->reload(&errorString, IFile::FlagReload, IFile::TypeContents))
+        QMessageBox::critical(m_d->m_core->mainWindow(), tr("File Error"), errorString);
 }
 
 void EditorManager::showEditorInfoBar(const QString &id,
@@ -1906,106 +1874,6 @@ void EditorManager::hideEditorStatusBar(const QString &id)
     currentEditorView()->hideEditorStatusBar(id);
 }
 
-QString EditorManager::externalEditorHelpText() const
-{
-    QString help = tr(
-            "<table border=1 cellspacing=0 cellpadding=3>"
-            "<tr><th>Variable</th><th>Expands to</th></tr>"
-            "<tr><td>%f</td><td>file name</td></tr>"
-            "<tr><td>%l</td><td>current line number</td></tr>"
-            "<tr><td>%c</td><td>current column number</td></tr>"
-            "<tr><td>%x</td><td>editor's x position on screen</td></tr>"
-            "<tr><td>%y</td><td>editor's y position on screen</td></tr>"
-            "<tr><td>%w</td><td>editor's width in pixels</td></tr>"
-            "<tr><td>%h</td><td>editor's height in pixels</td></tr>"
-            "<tr><td>%W</td><td>editor's width in characters</td></tr>"
-            "<tr><td>%H</td><td>editor's height in characters</td></tr>"
-            "<tr><td>%%</td><td>%</td></tr>"
-            "</table>");
-    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<IFile*> list = m_d->m_core->fileManager()->
-                             saveModifiedFiles(QList<IFile*>() << 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('%');
-                s += 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::setReloadSetting(IFile::ReloadSetting behavior)
 {
     m_d->m_reloadSetting = behavior;
@@ -2016,17 +1884,7 @@ IFile::ReloadSetting EditorManager::reloadSetting() const
     return m_d->m_reloadSetting;
 }
 
-void EditorManager::setUtf8BomSetting(IFile::Utf8BomSetting behavior)
-{
-    m_d->m_utf8BomSetting = behavior;
-}
-
-IFile::Utf8BomSetting EditorManager::utf8BomSetting() const
-{
-    return m_d->m_utf8BomSetting;
-}
-
-QTextCodec *EditorManager::defaultTextEncoding() const
+QTextCodec *EditorManager::defaultTextCodec() const
 {
     QSettings *settings = Core::ICore::instance()->settings();
     if (QTextCodec *candidate = QTextCodec::codecForName(
@@ -2136,3 +1994,35 @@ QString EditorManager::windowTitleAddition() const
     return m_d->m_titleAddition;
 }
 
+void EditorManager::updateVariable(const QString &variable)
+{
+    if (variable == QLatin1String(kCurrentDocumentFilePath)
+            || variable == QLatin1String(kCurrentDocumentPath)) {
+        QString value;
+        IEditor *curEditor = currentEditor();
+        if (curEditor) {
+            QString fileName = curEditor->file()->fileName();
+            if (!fileName.isEmpty()) {
+                if (variable == QLatin1String(kCurrentDocumentFilePath))
+                    value = QFileInfo(fileName).filePath();
+                else if (variable == QLatin1String(kCurrentDocumentPath))
+                    value = QFileInfo(fileName).path();
+            }
+        }
+        VariableManager::instance()->insert(variable, value);
+    } else if (variable == QLatin1String(kCurrentDocumentXPos)) {
+        QString value;
+        IEditor *curEditor = currentEditor();
+        if (curEditor) {
+            value = QString::number(curEditor->widget()->mapToGlobal(QPoint(0,0)).x());
+        }
+        VariableManager::instance()->insert(variable, value);
+    } else if (variable == QLatin1String(kCurrentDocumentYPos)) {
+        QString value;
+        IEditor *curEditor = currentEditor();
+        if (curEditor) {
+            value = QString::number(curEditor->widget()->mapToGlobal(QPoint(0,0)).y());
+        }
+        VariableManager::instance()->insert(variable, value);
+    }
+}