From 770fc594f0fb8d473b769ec98de34345cf40ec27 Mon Sep 17 00:00:00 2001
From: con <qtc-committer@nokia.com>
Date: Mon, 13 Dec 2010 17:35:40 +0100
Subject: [PATCH] Don't ask for reload if external tool claims to change
 current document

Take it as an expected file change.
---
 src/plugins/coreplugin/externaltool.cpp | 32 +++++++++++++++++--------
 src/plugins/coreplugin/externaltool.h   |  3 ++-
 src/plugins/coreplugin/filemanager.cpp  | 23 +++++++++++++++---
 3 files changed, 44 insertions(+), 14 deletions(-)

diff --git a/src/plugins/coreplugin/externaltool.cpp b/src/plugins/coreplugin/externaltool.cpp
index 23c563c1eeb..a5638788c10 100644
--- a/src/plugins/coreplugin/externaltool.cpp
+++ b/src/plugins/coreplugin/externaltool.cpp
@@ -36,6 +36,9 @@
 
 #include <coreplugin/icore.h>
 #include <coreplugin/messagemanager.h>
+#include <coreplugin/filemanager.h>
+#include <coreplugin/editormanager/editormanager.h>
+#include <coreplugin/editormanager/ieditor.h>
 #include <utils/qtcassert.h>
 #include <utils/stringutils.h>
 #include <utils/environment.h>
@@ -334,12 +337,16 @@ void ExternalToolRunner::run()
     }
     if (m_tool->outputHandling() == ExternalTool::ReloadDocument
                || m_tool->errorHandling() == ExternalTool::ReloadDocument) {
-        // TODO ask modified file to save, block modification notifications
+        // TODO ask modified file to save
+        if (IEditor *editor = EditorManager::instance()->currentEditor()) {
+            m_expectedFileName = editor->file()->fileName();
+            FileManager::instance()->expectFileChange(m_expectedFileName);
+        }
     }
     m_process = new QProcess;
     // TODO error handling, finish reporting, reading output, etc
     connect(m_process, SIGNAL(started()), this, SLOT(started()));
-    connect(m_process, SIGNAL(finished(int)), this, SLOT(finished()));
+    connect(m_process, SIGNAL(finished(int,QProcess::ExitStatus)), this, SLOT(finished(int,QProcess::ExitStatus)));
     connect(m_process, SIGNAL(error(QProcess::ProcessError)), this, SLOT(error(QProcess::ProcessError)));
     connect(m_process, SIGNAL(readyReadStandardOutput()), this, SLOT(readStandardOutput()));
     connect(m_process, SIGNAL(readyReadStandardError()), this, SLOT(readStandardError()));
@@ -358,24 +365,29 @@ void ExternalToolRunner::started()
     m_process->closeWriteChannel();
 }
 
-void ExternalToolRunner::finished()
+void ExternalToolRunner::finished(int exitCode, QProcess::ExitStatus status)
 {
-    if (m_tool->outputHandling() == ExternalTool::ReplaceSelection
-            || m_tool->errorHandling() == ExternalTool::ReplaceSelection) {
-        emit ExternalToolManager::instance()->replaceSelectionRequested(m_processOutput);
-    } else if (m_tool->outputHandling() == ExternalTool::ReloadDocument
-               || m_tool->errorHandling() == ExternalTool::ReloadDocument) {
-        // TODO reload document without popup
+    if (status == QProcess::NormalExit && exitCode == 0) {
+        if (m_tool->outputHandling() == ExternalTool::ReplaceSelection
+                || m_tool->errorHandling() == ExternalTool::ReplaceSelection) {
+            emit ExternalToolManager::instance()->replaceSelectionRequested(m_processOutput);
+        } else if (m_tool->outputHandling() == ExternalTool::ReloadDocument
+                || m_tool->errorHandling() == ExternalTool::ReloadDocument) {
+            FileManager::instance()->unexpectFileChange(m_expectedFileName);
+        }
     }
     ICore::instance()->messageManager()->printToOutputPane(
                 tr("'%1' finished").arg(m_resolvedExecutable), false);
-    // TODO handle the ReplaceSelection and ReloadDocument flags
     m_process->deleteLater();
     deleteLater();
 }
 
 void ExternalToolRunner::error(QProcess::ProcessError error)
 {
+    if (m_tool->outputHandling() == ExternalTool::ReloadDocument
+            || m_tool->errorHandling() == ExternalTool::ReloadDocument) {
+        FileManager::instance()->unexpectFileChange(m_expectedFileName);
+    }
     // TODO inform about errors
     m_process->deleteLater();
     deleteLater();
diff --git a/src/plugins/coreplugin/externaltool.h b/src/plugins/coreplugin/externaltool.h
index e710b365aee..75fe48c663f 100644
--- a/src/plugins/coreplugin/externaltool.h
+++ b/src/plugins/coreplugin/externaltool.h
@@ -94,7 +94,7 @@ public:
 
 private slots:
     void started();
-    void finished();
+    void finished(int exitCode, QProcess::ExitStatus status);
     void error(QProcess::ProcessError error);
     void readStandardOutput();
     void readStandardError();
@@ -113,6 +113,7 @@ private:
     QTextCodec::ConverterState m_outputCodecState;
     QTextCodec::ConverterState m_errorCodecState;
     QString m_processOutput;
+    QString m_expectedFileName;
 };
 
 } // Internal
diff --git a/src/plugins/coreplugin/filemanager.cpp b/src/plugins/coreplugin/filemanager.cpp
index 2d9e308e5c6..6c770ff812a 100644
--- a/src/plugins/coreplugin/filemanager.cpp
+++ b/src/plugins/coreplugin/filemanager.cpp
@@ -120,6 +120,7 @@ struct FileManagerPrivate {
     QStringList m_changedFiles;
     QList<IFile *> m_filesWithoutWatch;
     QMap<IFile *, QStringList> m_filesWithWatch;
+    QSet<QString> m_expectedFileNames;
 
     QList<FileManager::RecentFile> m_recentFiles;
     static const int m_maxRecentFiles = 7;
@@ -514,8 +515,9 @@ void FileManager::unblockFileChange(IFile *file)
 */
 void FileManager::expectFileChange(const QString &fileName)
 {
-    // Nothing to do
-    Q_UNUSED(fileName);
+    if (fileName.isEmpty())
+        return;
+    d->m_expectedFileNames.insert(fileName);
 }
 
 /*!
@@ -534,6 +536,7 @@ void FileManager::unexpectFileChange(const QString &fileName)
 
     if (fileName.isEmpty())
         return;
+    d->m_expectedFileNames.remove(fileName);
     const QString fixedName = fixFileName(fileName, KeepLinks);
     updateExpectedState(fixedName);
     const QString fixedResolvedName = fixFileName(fileName, ResolveLinks);
@@ -864,6 +867,19 @@ void FileManager::checkForReload()
             changedIFiles.insert(file);
     }
 
+    // collect information about "expected" file names
+    // we can't do the "resolving" already in expectFileChange, because
+    // if the resolved names are different when unexpectFileChange is called
+    // we would end up with never-unexpected file names
+    QSet<QString> expectedFileNames;
+    foreach (const QString &fileName, d->m_expectedFileNames) {
+        const QString fixedName = fixFileName(fileName, KeepLinks);
+        expectedFileNames.insert(fixedName);
+        const QString fixedResolvedName = fixFileName(fileName, ResolveLinks);
+        if (fixedName != fixedResolvedName)
+            expectedFileNames.insert(fixedResolvedName);
+    }
+
     // handle the IFiles
     foreach (IFile *file, changedIFiles) {
         IFile::ChangeTrigger behavior = IFile::TriggerInternal;
@@ -890,7 +906,8 @@ void FileManager::checkForReload()
                 continue;
 
             // was the change unexpected?
-            if (currentState.modified != expectedState.modified || currentState.permissions != expectedState.permissions) {
+            if ((currentState.modified != expectedState.modified || currentState.permissions != expectedState.permissions)
+                    && !expectedFileNames.contains(fileName)) {
                 behavior = IFile::TriggerExternal;
             }
 
-- 
GitLab