--- /dev/null
+/**************************************************************************
+**
+** This file is part of Qt Creator
+**
+** Copyright (c) 2010 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 "fileinprojectfinder.h"
+#include <utils/qtcassert.h>
+
+#include <QFileInfo>
+
+namespace Utils {
+
+/**
+ \class FileInProjectFinder
+
+ Helper class to find the 'original' file in the project directory for a given file path.
+
+ Often files are copied in the build + deploy process. findFile() searches for an existing file
+ in the project directory for a given file path:
+
+ E.g. following file paths:
+ 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)
+ should all be mapped to
+ $PROJECTDIR/qml/app/main.qml
+ */
+FileInProjectFinder::FileInProjectFinder()
+{
+}
+
+void FileInProjectFinder::setProjectDirectory(const QString &absoluteProjectPath)
+{
+ QTC_ASSERT(QFileInfo(absoluteProjectPath).exists()
+ && QFileInfo(absoluteProjectPath).isAbsolute(), return);
+
+ if (absoluteProjectPath == m_projectDir)
+ return;
+
+ m_projectDir = absoluteProjectPath;
+ while (m_projectDir.endsWith(QLatin1Char('/')))
+ m_projectDir.remove(m_projectDir.length() - 1, 1);
+
+ m_cache.clear();
+}
+
+QString FileInProjectFinder::projectDirectory() const
+{
+ return m_projectDir;
+}
+
+/**
+ Returns the best match for the given originalPath in the project directory.
+
+ The method first checks whether the originalPath inside the project directory exists.
+ If not, the leading directory in the path is stripped, and the - now shorter - path is
+ checked for existence. This continues until either the file is found, or the relative path
+ does not contain any directories any more: In this case the originalPath is returned.
+ */
+QString FileInProjectFinder::findFile(const QString &originalPath, bool *success) const
+{
+ if (m_projectDir.isEmpty())
+ return originalPath;
+
+ const QChar separator = QLatin1Char('/');
+ if (originalPath.startsWith(m_projectDir + separator)) {
+ return originalPath;
+ }
+
+ if (m_cache.contains(originalPath))
+ return m_cache.value(originalPath);
+
+ // Strip directories one by one from the beginning of the path,
+ // and see if the new relative path exists in the build directory.
+ if (originalPath.contains(separator)) {
+ for (int pos = originalPath.indexOf(separator); pos != -1;
+ pos = originalPath.indexOf(separator, pos + 1)) {
+ QString candidate = originalPath;
+ candidate.remove(0, pos);
+ candidate.prepend(m_projectDir);
+ QFileInfo candidateInfo(candidate);
+ if (candidateInfo.exists() && candidateInfo.isFile()) {
+ if (success)
+ *success = true;
+
+ m_cache.insert(originalPath, candidate);
+ return candidate;
+ }
+ }
+ }
+
+ if (success)
+ *success = false;
+
+ return originalPath;
+}
+
+} // namespace Utils
--- /dev/null
+/**************************************************************************
+**
+** This file is part of Qt Creator
+**
+** Copyright (c) 2010 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.
+**
+**************************************************************************/
+
+#ifndef FILEINPROJECTFINDER_H
+#define FILEINPROJECTFINDER_H
+
+#include <utils/utils_global.h>
+
+#include <QtCore/QHash>
+#include <QtCore/QString>
+
+namespace Utils {
+
+class QTCREATOR_UTILS_EXPORT FileInProjectFinder
+{
+public:
+ FileInProjectFinder();
+
+ void setProjectDirectory(const QString &absoluteProjectPath);
+ QString projectDirectory() const;
+
+ QString findFile(const QString &originalPath, bool *success = 0) const;
+
+private:
+ QString m_projectDir;
+ QHash<QString,QString> m_cache;
+};
+
+} // namespace Utils
+
+#endif // FILEINPROJECTFINDER_H
$$PWD/debuggerlanguagechooser.cpp \
$$PWD/historycompleter.cpp \
$$PWD/buildablehelperlibrary.cpp \
- $$PWD/annotateditemdelegate.cpp
+ $$PWD/annotateditemdelegate.cpp \
+ $$PWD/fileinprojectfinder.cpp
win32 {
SOURCES += $$PWD/abstractprocess_win.cpp \
$$PWD/debuggerlanguagechooser.h \
$$PWD/historycompleter.h \
$$PWD/buildablehelperlibrary.h \
- $$PWD/annotateditemdelegate.h
+ $$PWD/annotateditemdelegate.h \
+ $$PWD/fileinprojectfinder.h
FORMS += $$PWD/filewizardpage.ui \
$$PWD/projectintropage.ui \
}
connect(m_debugProject, SIGNAL(destroyed()), SLOT(currentDebugProjectRemoved()));
+ m_projectFinder.setProjectDirectory(m_debugProject->projectDirectory());
setupToolbar(true);
resetViews();
if (source.lineNumber() < 0 || !QFile::exists(fileName))
return;
-
- // do some extra checking for filenames with shadow builds - we don't want to
- // open the shadow build file, but the real one by default.
- if (isShadowBuildProject()) {
- fileName = filenameForShadowBuildFile(fileName);
- }
+ fileName = m_projectFinder.findFile(fileName);
Core::EditorManager *editorManager = Core::EditorManager::instance();
Core::IEditor *editor = editorManager->openEditor(fileName);
}
}
-QString InspectorUi::filenameForShadowBuildFile(const QString &filename) const
-{
- if (!debugProject() || !isShadowBuildProject())
- return filename;
-
- QDir projectDir(debugProject()->projectDirectory());
- QDir buildDir(debugProjectBuildDirectory());
- QFileInfo fileInfo(filename);
-
- if (projectDir.exists() && buildDir.exists() && fileInfo.exists()) {
- if (fileInfo.absoluteFilePath().startsWith(buildDir.canonicalPath())) {
- QString fileRelativePath
- = fileInfo.canonicalFilePath().mid(debugProjectBuildDirectory().length());
-
-#ifdef Q_OS_MACX
- // Qt Quick Applications by default copy the qml directory to
- // buildDir()/X.app/Contents/Resources
- static QRegExp resourceBundlePattern(QLatin1String("^.*\\.app/Contents/Resources/"));
- fileRelativePath.remove(resourceBundlePattern);
-#endif
-
- QFileInfo projectFile(projectDir.canonicalPath() + QLatin1Char('/') + fileRelativePath);
-
- if (projectFile.exists())
- return projectFile.canonicalFilePath();
- }
-
- }
- return filename;
-}
-
bool InspectorUi::addQuotesForData(const QVariant &value) const
{
switch (value.type()) {
#include <coreplugin/basemode.h>
#include <debugger/debuggerconstants.h>
#include <qmlprojectmanager/qmlprojectrunconfiguration.h>
+#include <utils/fileinprojectfinder.h>
#include <qmljs/qmljsdocument.h>
#include <qmljs/parser/qmljsastfwd_p.h>
QString m_debugProjectBuildDir;
QStringList m_pendingPreviewDocumentNames;
+ Utils::FileInProjectFinder m_projectFinder;
static InspectorUi *m_instance;
};
, m_qtTestFail(QLatin1String("^ Loc: \\[(.*)\\]$"))
, m_project(project)
{
+ if(project)
+ m_projectFinder.setProjectDirectory(project->projectDirectory());
}
LinkResult QtOutputFormatter::matchLine(const QString &line) const
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()) {
const QString fileName = QUrl(qmlLineColumnLink.cap(1)).toLocalFile();
const int line = qmlLineColumnLink.cap(2).toInt();
const int column = qmlLineColumnLink.cap(3).toInt();
- TextEditor::BaseTextEditor::openEditorAt(pathInSourceDirectory(fileName), line, column - 1);
+ TextEditor::BaseTextEditor::openEditorAt(m_projectFinder.findFile(fileName), line, column - 1);
return;
}
if (qmlLineLink.indexIn(href) != -1) {
const QString fileName = QUrl(qmlLineLink.cap(1)).toLocalFile();
const int line = qmlLineLink.cap(2).toInt();
- TextEditor::BaseTextEditor::openEditorAt(pathInSourceDirectory(fileName), line);
+ TextEditor::BaseTextEditor::openEditorAt(m_projectFinder.findFile(fileName), line);
return;
}
}
} else if (!fi.exists()) {
// map possible on-device path to source path
- fileName = pathInSourceDirectory(fileName);
+ fileName = m_projectFinder.findFile(fileName);
}
TextEditor::BaseTextEditor::openEditorAt(fileName, line, 0);
return;
#include "qt4projectmanager_global.h"
#include <projectexplorer/outputformatter.h>
+#include <utils/fileinprojectfinder.h>
#include <QtCore/QRegExp>
#include <QtCore/QWeakPointer>
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;
QWeakPointer<ProjectExplorer::Project> m_project;
QString m_lastLine;
QString m_deferedText;
+ Utils::FileInProjectFinder m_projectFinder;
};