OSDN Git Service

Application Output: Fix linkification of files in shadow builds / deployment folders
authorKai Koehne <kai.koehne@nokia.com>
Fri, 5 Nov 2010 14:00:34 +0000 (15:00 +0100)
committerKai Koehne <kai.koehne@nokia.com>
Mon, 8 Nov 2010 14:32:08 +0000 (15:32 +0100)
Try to map absolute paths pointing to files in shadow build directory
/ on the device to the respective files in the project directory.

Task-number: QTCREATORBUG-2371
Reviewed-by: dt
src/plugins/qt4projectmanager/qtoutputformatter.cpp
src/plugins/qt4projectmanager/qtoutputformatter.h

index 017adc4..0878d6a 100644 (file)
@@ -31,6 +31,7 @@
 
 #include <texteditor/basetexteditor.h>
 #include <qt4projectmanager/qt4project.h>
+#include <utils/qtcassert.h>
 
 #include <QtCore/QFileInfo>
 #include <QtCore/QUrl>
@@ -172,6 +173,48 @@ void QtOutputFormatter::appendLine(QTextCursor &cursor, LinkResult lr, const QSt
     cursor.insertText(line.mid(lr.end), normalFormat);
 }
 
+// Map absolute path in shadow build / in the deployment folder to the path in the project directory
+//
+// Input is e.g.
+//      C:/app-build-desktop/qml/app/main.qml (shadow build directory)
+//      C:/Private/e3026d63/qml/app/main.qml  (Application data folder on Symbian device)
+//      /Users/x/app-build-desktop/App.app/Contents/Resources/qml/App/main.qml (folder on Mac OS X)
+// which should be mapped to
+//      $PROJECTDIR/qml/app/main.qml
+QString QtOutputFormatter::pathInSourceDirectory(const QString &originalFilePath)
+{
+    QTC_ASSERT(QFileInfo(originalFilePath).isAbsolute(), return originalFilePath);
+
+    if (!m_project)
+        return originalFilePath;
+
+    const QString projectDirectory = m_project.data()->projectDirectory();
+
+    QTC_ASSERT(!projectDirectory.isEmpty(), return originalFilePath);
+    QTC_ASSERT(!projectDirectory.endsWith(QLatin1Char('/')), return originalFilePath);
+
+    const QChar separator = QLatin1Char('/');
+
+    if (originalFilePath.startsWith(projectDirectory + separator)) {
+        return originalFilePath;
+    }
+
+    // Strip directories one by one from the beginning of the path,
+    // and see if the new relative path exists in the build directory.
+    if (originalFilePath.contains(separator)) {
+        for (int pos = originalFilePath.indexOf(separator); pos != -1; pos = originalFilePath.indexOf(separator, pos + 1)) {
+            QString candidate = originalFilePath;
+            candidate.remove(0, pos);
+            candidate.prepend(projectDirectory);
+            QFileInfo candidateInfo(candidate);
+            if (candidateInfo.exists() && candidateInfo.isFile())
+                return candidate;
+        }
+    }
+
+    return originalFilePath;
+}
+
 void QtOutputFormatter::handleLink(const QString &href)
 {
     if (!href.isEmpty()) {
@@ -181,7 +224,7 @@ void QtOutputFormatter::handleLink(const QString &href)
             const QString fileName = QUrl(qmlErrorLink.cap(1)).toLocalFile();
             const int line = qmlErrorLink.cap(2).toInt();
             const int column = qmlErrorLink.cap(3).toInt();
-            TextEditor::BaseTextEditor::openEditorAt(fileName, line, column - 1);
+            TextEditor::BaseTextEditor::openEditorAt(pathInSourceDirectory(fileName), line, column - 1);
             return;
         }
 
@@ -221,6 +264,9 @@ void QtOutputFormatter::handleLink(const QString &href)
                         }
                     }
                 }
+            } else if (!fi.exists()) {
+                // map possible on-device path to source path
+                fileName = pathInSourceDirectory(fileName);
             }
             TextEditor::BaseTextEditor::openEditorAt(fileName, line, 0);
             return;
index a62b1c1..f1ba774 100644 (file)
@@ -63,6 +63,7 @@ public:
 private:
     LinkResult matchLine(const QString &line) const;
     void appendLine(QTextCursor & cursor, LinkResult lr, const QString &line, bool onStdError);
+    QString pathInSourceDirectory(const QString &originalFilePath);
 
     QRegExp m_qmlError;
     QRegExp m_qtError;