diff --git a/src/plugins/qt4projectmanager/qtoutputformatter.cpp b/src/plugins/qt4projectmanager/qtoutputformatter.cpp index 017adc442e68fc162344964f810762ecc417eb1c..0878d6aa0bbd31a809c95c604688c24b235e0763 100644 --- a/src/plugins/qt4projectmanager/qtoutputformatter.cpp +++ b/src/plugins/qt4projectmanager/qtoutputformatter.cpp @@ -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; diff --git a/src/plugins/qt4projectmanager/qtoutputformatter.h b/src/plugins/qt4projectmanager/qtoutputformatter.h index a62b1c1d7a032bbc569eac2313275d407fa8efe3..f1ba774d6f9bf018371bfde841e75d7090a2afed 100644 --- a/src/plugins/qt4projectmanager/qtoutputformatter.h +++ b/src/plugins/qt4projectmanager/qtoutputformatter.h @@ -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;