Merge remote-tracking branch 'origin/2.8' into HEAD

Conflicts:
	qtcreator.pri
	qtcreator.qbs

Change-Id: I5d2018d3437b99bcdffa92bf1a212f42923c4fad
This commit is contained in:
Eike Ziller
2013-07-03 16:55:27 +02:00
61 changed files with 1036 additions and 363 deletions

View File

@@ -19,7 +19,6 @@ Product {
}
return name;
}
moduleSearchPaths: "../../../qbs" // TODO: Should get inherited from project, but doesn't.
Depends { name: "ExtensionSystem" }
Depends { name: "pluginspec" }

View File

@@ -690,9 +690,9 @@ bool AndroidPackageCreationStep::createPackage()
buildProc->setProcessEnvironment(m_environment.toProcessEnvironment());
connect(buildProc, SIGNAL(readyReadStandardOutput()), this,
SLOT(handleBuildStdOutOutput()));
SLOT(handleBuildStdOutOutput()), Qt::DirectConnection);
connect(buildProc, SIGNAL(readyReadStandardError()), this,
SLOT(handleBuildStdErrOutput()));
SLOT(handleBuildStdErrOutput()), Qt::DirectConnection);
buildProc->setWorkingDirectory(m_androidDir.toString());

View File

@@ -144,6 +144,7 @@ void OutputPanePlaceHolder::ensureSizeHintAsMinimum()
if (idx < 0)
return;
d->m_splitter->refresh();
QList<int> sizes = d->m_splitter->sizes();
Internal::OutputPaneManager *om = Internal::OutputPaneManager::instance();
int minimum = (d->m_splitter->orientation() == Qt::Vertical

View File

@@ -556,23 +556,31 @@ void CppModelManager::updateProjectInfo(const ProjectInfo &pinfo)
return;
ProjectExplorer::Project *project = pinfo.project().data();
m_projects.insert(project, pinfo);
m_dirty = true;
m_srcToProjectPart.clear();
foreach (const ProjectInfo &projectInfo, m_projects) {
foreach (const ProjectPart::Ptr &projectPart, projectInfo.projectParts()) {
ProjectInfo oldProjectInfo = m_projects.value(project);
if (oldProjectInfo.isValid()) {
foreach (const ProjectPart::Ptr &projectPart, oldProjectInfo.projectParts()) {
foreach (const ProjectFile &cxxFile, projectPart->files) {
m_srcToProjectPart[cxxFile.path].append(projectPart);
foreach (const QString &fileName, m_snapshot.allIncludesForDocument(cxxFile.path))
foreach (const QString &fileName,
m_snapshot.allIncludesForDocument(cxxFile.path)) {
m_snapshot.remove(fileName);
}
m_snapshot.remove(cxxFile.path);
}
}
}
m_snapshot.remove(configurationFileName());
m_projects.insert(project, pinfo);
m_dirty = true;
m_srcToProjectPart.clear();
foreach (const ProjectInfo &projectInfo, m_projects) {
foreach (const ProjectPart::Ptr &projectPart, projectInfo.projectParts()) {
foreach (const ProjectFile &cxxFile, projectPart->files) {
m_srcToProjectPart[cxxFile.path].append(projectPart);
}
}
}
}
if (!qgetenv("QTCREATOR_DUMP_PROJECT_INFO").isEmpty())
@@ -607,9 +615,14 @@ void CppModelManager::deleteEditorSupport(TextEditor::BaseTextEditor *textEditor
if (!isCppEditor(textEditor))
return;
QMutexLocker locker(&m_editorSupportMutex);
CppEditorSupport *editorSupport = m_editorSupport.value(textEditor, 0);
m_editorSupport.remove(textEditor);
CppEditorSupport *editorSupport;
{ // only lock the operations on m_editorSupport
QMutexLocker locker(&m_editorSupportMutex);
editorSupport = m_editorSupport.value(textEditor, 0);
m_editorSupport.remove(textEditor);
}
delete editorSupport;
}

View File

@@ -32,6 +32,9 @@
#include "cpppreprocessor.h"
#include "modelmanagertesthelper.h"
#include <projectexplorer/projectexplorer.h>
#include <projectexplorer/session.h>
#include <QDebug>
#include <QFileInfo>
#include <QtTest>
@@ -96,6 +99,42 @@ private:
const QString m_testDataDirectory;
};
// TODO: When possible, use this helper class in all tests
class ProjectCreator
{
public:
ProjectCreator(ModelManagerTestHelper *modelManagerTestHelper)
: modelManagerTestHelper(modelManagerTestHelper)
{}
/// 'files' is expected to be a list of file names that reside in 'dir'.
void create(const QString &name, const QString &dir, const QStringList files)
{
const TestDataDirectory projectDir(dir);
foreach (const QString &file, files)
projectFiles << projectDir.file(file);
Project *project = modelManagerTestHelper->createProject(name);
projectInfo = CppModelManager::instance()->projectInfo(project);
QCOMPARE(projectInfo.project().data(), project);
ProjectPart::Ptr part(new ProjectPart);
projectInfo.appendProjectPart(part);
part->cxxVersion = ProjectPart::CXX98;
part->qtVersion = ProjectPart::Qt5;
foreach (const QString &file, projectFiles) {
ProjectFile projectFile(file, ProjectFile::classify(file));
part->files.append(projectFile);
}
}
ModelManagerTestHelper *modelManagerTestHelper;
ProjectInfo projectInfo;
QStringList projectFiles;
};
} // anonymous namespace
void CppToolsPlugin::test_modelmanager_paths()
@@ -278,3 +317,99 @@ void CppToolsPlugin::test_modelmanager_refresh_2()
QVERIFY(document->diagnosticMessages().isEmpty());
}
}
void CppToolsPlugin::test_modelmanager_snapshot_after_two_projects()
{
QStringList refreshedFiles;
ModelManagerTestHelper helper;
ProjectCreator project1(&helper);
ProjectCreator project2(&helper);
CppModelManager *mm = CppModelManager::instance();
// Project 1
project1.create(QLatin1String("snapshot_after_two_projects.1"),
QLatin1String("testdata_project1"),
QStringList() << QLatin1String("foo.h")
<< QLatin1String("foo.cpp")
<< QLatin1String("main.cpp"));
mm->updateProjectInfo(project1.projectInfo);
mm->updateSourceFiles(project1.projectFiles);
refreshedFiles = helper.waitForRefreshedSourceFiles();
QCOMPARE(refreshedFiles.toSet(), project1.projectFiles.toSet());
const int snapshotSizeAfterProject1 = mm->snapshot().size();
foreach (const QString &file, project1.projectFiles)
QVERIFY(mm->snapshot().contains(file));
// Project 2
project2.create(QLatin1String("snapshot_after_two_projects.2"),
QLatin1String("testdata_project2"),
QStringList() << QLatin1String("bar.h")
<< QLatin1String("bar.cpp")
<< QLatin1String("main.cpp"));
mm->updateProjectInfo(project2.projectInfo);
mm->updateSourceFiles(project2.projectFiles);
refreshedFiles = helper.waitForRefreshedSourceFiles();
QCOMPARE(refreshedFiles.toSet(), project2.projectFiles.toSet());
const int snapshotSizeAfterProject2 = mm->snapshot().size();
QVERIFY(snapshotSizeAfterProject2 > snapshotSizeAfterProject1);
QVERIFY(snapshotSizeAfterProject2 >= snapshotSizeAfterProject1 + project2.projectFiles.size());
foreach (const QString &file, project1.projectFiles)
QVERIFY(mm->snapshot().contains(file));
foreach (const QString &file, project2.projectFiles)
QVERIFY(mm->snapshot().contains(file));
}
void CppToolsPlugin::test_modelmanager_extraeditorsupport_uiFiles()
{
TestDataDirectory testDataDirectory(QLatin1String("testdata_guiproject1"));
const QString projectFile = testDataDirectory.file(QLatin1String("testdata_guiproject1.pro"));
// Open project with *.ui file
ProjectExplorer::ProjectExplorerPlugin *pe = ProjectExplorer::ProjectExplorerPlugin::instance();
QString errorOpeningProject;
Project *project = pe->openProject(projectFile, &errorOpeningProject);
QVERIFY(errorOpeningProject.isEmpty());
project->configureAsExampleProject(QStringList());
// Check working copy.
// An AbstractEditorSupport object should have been added for the ui_* file.
CppModelManagerInterface *mm = CppModelManagerInterface::instance();
CppModelManagerInterface::WorkingCopy workingCopy = mm->workingCopy();
QCOMPARE(workingCopy.size(), 2); // mm->configurationFileName() and "ui_*.h"
QStringList fileNamesInWorkinCopy;
QHashIterator<QString, QPair<QString, unsigned> > it = workingCopy.iterator();
while (it.hasNext()) {
it.next();
fileNamesInWorkinCopy << QFileInfo(it.key()).fileName();
}
fileNamesInWorkinCopy.sort();
const QString expectedUiHeaderFileName = QLatin1String("ui_mainwindow.h");
QCOMPARE(fileNamesInWorkinCopy.at(0), mm->configurationFileName());
QCOMPARE(fileNamesInWorkinCopy.at(1), expectedUiHeaderFileName);
// Check CppPreprocessor / includes.
// The CppPreprocessor is expected to find the ui_* file in the working copy.
const QString fileIncludingTheUiFile = testDataDirectory.file(QLatin1String("mainwindow.cpp"));
while (!mm->snapshot().document(fileIncludingTheUiFile))
QCoreApplication::processEvents();
const CPlusPlus::Snapshot snapshot = mm->snapshot();
const Document::Ptr document = snapshot.document(fileIncludingTheUiFile);
QVERIFY(document);
const QStringList includedFiles = document->includedFiles();
QCOMPARE(includedFiles.size(), 2);
QCOMPARE(QFileInfo(includedFiles.at(0)).fileName(), QLatin1String("mainwindow.h"));
QCOMPARE(QFileInfo(includedFiles.at(1)).fileName(), QLatin1String("ui_mainwindow.h"));
// Close Project
ProjectExplorer::SessionManager *sm = pe->session();
sm->removeProject(project);
ModelManagerTestHelper::verifyClean();
}

View File

@@ -233,7 +233,7 @@ QString CppPreprocessor::resolveFile_helper(const QString &fileName, IncludeType
foreach (const QString &includePath, m_includePaths) {
QString path = includePath + fileName;
if (checkFile(path))
if (m_workingCopy.contains(path) || checkFile(path))
return path;
}

View File

@@ -171,6 +171,8 @@ private slots:
void test_modelmanager_framework_headers();
void test_modelmanager_refresh_1();
void test_modelmanager_refresh_2();
void test_modelmanager_snapshot_after_two_projects();
void test_modelmanager_extraeditorsupport_uiFiles();
private:
void test_completion();

View File

@@ -79,7 +79,7 @@ public:
~ModelManagerTestHelper();
void cleanup();
void verifyClean();
static void verifyClean();
Project *createProject(const QString &name);

View File

@@ -156,7 +156,7 @@ equals(TEST, 1):!isEmpty(copydata) {
else: OUTPUT_DIR = $$IDE_BUILD_TREE/$$TEST_DIR
testfile.target = $$OUTPUT_DIR/$$basename(INPUT_FILE)
testfile.depends = $$INPUT_FILE
win32 {
win32:isEmpty(QMAKE_SH) {
INPUT_FILE ~= s,/,\\\\,g
OUTPUT_DIR ~= s,/,\\\\,g
} else {

View File

@@ -1678,7 +1678,7 @@ void DebuggerPluginPrivate::attachToProcess(bool startServerOnly)
DebuggerKitChooser::RemoteDebugging : DebuggerKitChooser::LocalDebugging;
DebuggerKitChooser *kitChooser = new DebuggerKitChooser(mode);
DeviceProcessesDialog *dlg = new DeviceProcessesDialog(kitChooser, mainWindow());
dlg->addAcceptButton(DeviceProcessesDialog::tr("&Attach to Process"));
dlg->addAcceptButton(ProjectExplorer::DeviceProcessesDialog::tr("&Attach to Process"));
dlg->showAllDevices();
if (dlg->exec() == QDialog::Rejected) {
delete dlg;

View File

@@ -69,6 +69,7 @@ void ImageWidget::setImage(const QImage &image)
{
setFixedSize(image.size() + QSize(2, 2));
m_image = image;
update();
}
void ImageWidget::mousePressEvent(QMouseEvent *ev)

View File

@@ -1679,28 +1679,37 @@ void WatchHandler::showEditValue(const WatchData &data)
showSeparateWidget(l);
m_model->m_editHandlers[key] = l;
}
int width = 0, height = 0, format = 0;
int width = 0, height = 0, nbytes = 0, format = 0;
QByteArray ba;
uchar *bits = 0;
if (data.editformat == DisplayImageData) {
ba = QByteArray::fromHex(data.editvalue);
QTC_ASSERT(ba.size() > 16, return);
const int *header = (int *)(ba.data());
if (!ba.at(0) && !ba.at(1)) // Check on 'width' for Python dumpers returning 4-byte swapped-data.
swapEndian(ba.data(), ba.size());
bits = 12 + (uchar *)(ba.data());
swapEndian(ba.data(), 16);
bits = 16 + (uchar *)(ba.data());
width = header[0];
height = header[1];
format = header[2];
nbytes = header[2];
format = header[3];
} else if (data.editformat == DisplayImageFile) {
QTextStream ts(data.editvalue);
QString fileName;
ts >> width >> height >> format >> fileName;
ts >> width >> height >> nbytes >> format >> fileName;
QFile f(fileName);
f.open(QIODevice::ReadOnly);
ba = f.readAll();
bits = (uchar*)ba.data();
nbytes = width * height;
}
l->setImage(QImage(bits, width, height, QImage::Format(format)));
QTC_ASSERT(0 < width && width < 10000, return);
QTC_ASSERT(0 < height && height < 10000, return);
QTC_ASSERT(0 < nbytes && nbytes < 10000 * 10000, return);
QTC_ASSERT(0 < format && format < 32, return);
QImage im(width, height, QImage::Format(format));
qMemCopy(im.bits(), bits, nbytes);
l->setImage(im);
showSeparateWidget(l);
}
break;

View File

@@ -418,6 +418,8 @@ void DiffViewEditorWidget::mouseDoubleClickEvent(QMouseEvent *e)
if (e->button() == Qt::LeftButton && !(e->modifiers() & Qt::ShiftModifier)) {
QTextCursor cursor = cursorForPosition(e->pos());
jumpToOriginalFile(cursor);
e->accept();
return;
}
SnippetEditorWidget::mouseDoubleClickEvent(e);
}

View File

@@ -76,7 +76,8 @@
static const char GIT_DIRECTORY[] = ".git";
static const char graphLogFormatC[] = "%h %d %an %s %ci";
static const char HEAD[] = "HEAD";
static const char noColorOption[] = "--no-color";
static const char decorateOption[] = "--decorate";
namespace Git {
namespace Internal {
@@ -118,8 +119,8 @@ public:
// index -> working tree
void diffFile(const QString &fileName);
// stagedFileNames - files in index, diff will compare the state in HEAD to the one in the index
// unstagedFileNames - diff will compare the state in the index to the one in the working tree
// stagedFileNames: HEAD -> index
// unstagedFileNames: index -> working tree
void diffFiles(const QStringList &stagedFileNames, const QStringList &unstagedFileNames);
// index -> working tree
void diffProjects(const QStringList &projectPaths);
@@ -191,7 +192,7 @@ GitDiffHandler::GitDiffHandler(DiffEditor::DiffEditor *editor,
void GitDiffHandler::diffFile(const QString &fileName)
{
m_requestedRevisionRange = RevisionRange(
Revision(Other, QLatin1String(HEAD)),
Revision(Index),
Revision(WorkingTree));
collectFilesList(QStringList() << QLatin1String("--") << fileName);
@@ -201,7 +202,7 @@ void GitDiffHandler::diffFiles(const QStringList &stagedFileNames, const QString
{
RevisionRange stagedRange = RevisionRange(
Revision(Other, QLatin1String(HEAD)),
Revision(WorkingTree));
Revision(Index));
RevisionRange unstagedRange = RevisionRange(
Revision(Index),
Revision(WorkingTree));
@@ -219,7 +220,7 @@ void GitDiffHandler::diffFiles(const QStringList &stagedFileNames, const QString
void GitDiffHandler::diffProjects(const QStringList &projectPaths)
{
m_requestedRevisionRange = RevisionRange(
Revision(Other, QLatin1String(HEAD)),
Revision(Index),
Revision(WorkingTree));
collectFilesList(QStringList() << QLatin1String("--") << projectPaths);
@@ -228,7 +229,7 @@ void GitDiffHandler::diffProjects(const QStringList &projectPaths)
void GitDiffHandler::diffRepository()
{
m_requestedRevisionRange = RevisionRange(
Revision(Other, QLatin1String(HEAD)),
Revision(Index),
Revision(WorkingTree));
collectFilesList(QStringList());
@@ -254,23 +255,27 @@ void GitDiffHandler::show(const QString &id)
void GitDiffHandler::collectShowDescription(const QString &id)
{
if (m_editor.isNull())
return;
m_editor->clear(m_waitMessage);
VcsBase::Command *command = new VcsBase::Command(m_gitPath, m_workingDirectory, m_processEnvironment);
connect(command, SIGNAL(outputData(QByteArray)), this, SLOT(slotShowDescriptionReceived(QByteArray)));
QStringList arguments;
arguments << QLatin1String("show") << QLatin1String("-s") << QLatin1String("--format=fuller") << id;
arguments << QLatin1String("show") << QLatin1String("-s") << QLatin1String("--format=fuller")
<< QLatin1String(noColorOption) << QLatin1String(decorateOption) << id;
command->addJob(arguments, m_timeout);
command->execute();
}
void GitDiffHandler::slotShowDescriptionReceived(const QByteArray &data)
{
if (m_editor.isNull())
return;
const QString description = m_editor->editorWidget()->codec()->toUnicode(data).remove(QLatin1Char('\r'));
DiffEditor::DiffShowEditor *editor = qobject_cast<DiffEditor::DiffShowEditor *>(m_editor);
if (editor) {
if (editor)
editor->setDescription(description);
}
collectFilesList(QStringList()
<< m_requestedRevisionRange.begin.id
@@ -279,6 +284,8 @@ void GitDiffHandler::slotShowDescriptionReceived(const QByteArray &data)
void GitDiffHandler::collectFilesList(const QStringList &additionalArguments)
{
if (m_editor.isNull())
return;
m_editor->clear(m_waitMessage);
VcsBase::Command *command = new VcsBase::Command(m_gitPath, m_workingDirectory, m_processEnvironment);
connect(command, SIGNAL(outputData(QByteArray)), this, SLOT(slotFileListReceived(QByteArray)));
@@ -632,6 +639,7 @@ public:
m_enableAnnotationContextMenu(enableAnnotationContextMenu),
m_fileNames(fileNames)
{
QTC_ASSERT(!directory.isEmpty(), return);
QToolButton *diffButton = addToggleButton(QLatin1String("--patch"), tr("Show Diff"),
tr("Show difference."));
mapSetting(diffButton, m_client->settings()->boolPointer(GitSettings::logDiffKey));
@@ -790,9 +798,6 @@ GitClient::~GitClient()
{
}
const char *GitClient::noColorOption = "--no-color";
const char *GitClient::decorateOption = "--decorate";
QString GitClient::findRepositoryForDirectory(const QString &dir)
{
if (dir.isEmpty() || dir.endsWith(QLatin1String("/.git"))
@@ -1307,7 +1312,7 @@ bool GitClient::synchronousLog(const QString &workingDirectory, const QStringLis
QByteArray outputText;
QByteArray errorText;
QStringList allArguments;
allArguments << QLatin1String("log") << QLatin1String(GitClient::noColorOption);
allArguments << QLatin1String("log") << QLatin1String(noColorOption);
allArguments.append(arguments);
const bool rc = fullySynchronousGit(workingDirectory, allArguments, &outputText, &errorText);
if (rc) {
@@ -1785,7 +1790,7 @@ QString GitClient::synchronousShortDescription(const QString &workingDirectory,
QByteArray outputTextData;
QByteArray errorText;
QStringList arguments;
arguments << QLatin1String("log") << QLatin1String(GitClient::noColorOption)
arguments << QLatin1String("log") << QLatin1String(noColorOption)
<< (QLatin1String("--pretty=format:") + format)
<< QLatin1String("--max-count=1") << revision;
const bool rc = fullySynchronousGit(workingDirectory, arguments, &outputTextData, &errorText);
@@ -2685,8 +2690,11 @@ bool GitClient::getCommitData(const QString &workingDirectory,
QString templateFilename = gitDirectory.absoluteFilePath(QLatin1String("MERGE_MSG"));
if (!QFile::exists(templateFilename))
templateFilename = gitDirectory.absoluteFilePath(QLatin1String("SQUASH_MSG"));
if (!QFile::exists(templateFilename))
templateFilename = readConfigValue(workingDirectory, QLatin1String("commit.template"));
if (!QFile::exists(templateFilename)) {
Utils::FileName templateName = Utils::FileName::fromUserInput(
readConfigValue(workingDirectory, QLatin1String("commit.template")));
templateFilename = templateName.toString();
}
if (!templateFilename.isEmpty()) {
// Make relative to repository
const QFileInfo templateFileInfo(templateFilename);

View File

@@ -313,9 +313,6 @@ public:
static QString msgNoChangedFiles();
static QString msgNoCommits(bool includeRemote);
static const char *noColorOption;
static const char *decorateOption;
public slots:
void show(const QString &source, const QString &id,
const QStringList &args = QStringList(), const QString &name = QString());

View File

@@ -66,7 +66,9 @@ PerforceEditor::PerforceEditor(const VcsBase::VcsBaseEditorParameters *type,
// Diff format:
// 1) "==== //depot/.../mainwindow.cpp#2 - /depot/.../mainwindow.cpp ====" (created by p4 diff)
// 2) "==== //depot/.../mainwindow.cpp#15 (text) ====" (created by p4 describe)
setDiffFilePattern(QRegExp(QLatin1String("^==== (.+)#\\d")));
// 3) --- //depot/XXX/closingkit/trunk/source/cui/src/cui_core.cpp<tab>2012-02-08 13:54:01.000000000 0100
// +++ P:/XXX\closingkit\trunk\source\cui\src\cui_core.cpp<tab>2012-02-08 13:54:01.000000000 0100
setDiffFilePattern(QRegExp(QLatin1String("^(?:={4}|\\+{3}) (.+)(?:\\t|#\\d)")));
setLogEntryPattern(QRegExp(QLatin1String("^... #\\d change (\\d+) ")));
setAnnotateRevisionTextFormat(tr("Annotate change list \"%1\""));
if (Perforce::Constants::debug)

View File

@@ -734,7 +734,7 @@ void SettingsAccessor::backupUserFile() const
// Do we need to do a backup?
const QString origName = oldSettings.fileName().toString();
QString backupName = origName;
if (oldSettings.environmentId() != creatorId())
if (!oldSettings.environmentId().isEmpty() && oldSettings.environmentId() != creatorId())
backupName += QLatin1String(".") + QString::fromLatin1(oldSettings.environmentId()).mid(1, 7);
if (oldSettings.version() != currentVersion()) {
if (m_handlers.contains(oldSettings.version()))
@@ -774,7 +774,7 @@ SettingsAccessor::SettingsData SettingsAccessor::readUserSettings() const
"<p>All settings files were either too new or too "
"old to be read.</p>"),
QMessageBox::Ok);
} else if (result.environmentId() != creatorId()) {
} else if (!result.environmentId().isEmpty() && result.environmentId() != creatorId()) {
// Wrong environment!
QMessageBox msgBox(
QMessageBox::Question,
@@ -873,7 +873,7 @@ SettingsAccessor::SettingsData SettingsAccessor::findBestSettings(const QStringL
continue;
}
if (!tmp.environmentId().isEmpty() && tmp.environmentId() == creatorId()) {
if (tmp.environmentId().isEmpty() || tmp.environmentId() == creatorId()) {
if (tmp.version() > newestMatching.version())
newestMatching = tmp;
} else {

View File

@@ -1096,15 +1096,21 @@ QString PropertyEditor::locateQmlFile(const NodeMetaInfo &info, const QString &r
const QString relativePathWithVersion = relativePathWithoutEnding + versionString + QLatin1String(".qml");
//Check for qml files with versions first
const QString withoutDirWithVersion = relativePathWithVersion.split(QLatin1String("/")).last();
if (importDir.exists(relativePathWithVersion))
return importDir.absoluteFilePath(relativePathWithVersion);
if (importDir.exists(withoutDirWithVersion)) //Since we are in a subfolder of the import we do not require the directory
return importDir.absoluteFilePath(withoutDirWithVersion);
if (fileSystemDir.exists(relativePathWithVersion))
return fileSystemDir.absoluteFilePath(relativePathWithVersion);
if (resourcesDir.exists(relativePathWithVersion))
return resourcesDir.absoluteFilePath(relativePathWithVersion);
const QString withoutDir = relativePath.split(QLatin1String("/")).last();
if (importDir.exists(relativePath))
return importDir.absoluteFilePath(relativePath);
if (importDir.exists(withoutDir)) //Since we are in a subfolder of the import we do not require the directory
return importDir.absoluteFilePath(withoutDir);
if (fileSystemDir.exists(relativePath))
return fileSystemDir.absoluteFilePath(relativePath);
if (resourcesDir.exists(relativePath))

View File

@@ -39,7 +39,7 @@ namespace Internal {
typedef QSharedPointer<InternalNodeAbstractProperty> InternalNodeAbstractPropertyPointer;
}
class NodeAbstractProperty : public AbstractProperty
class QMLDESIGNERCORE_EXPORT NodeAbstractProperty : public AbstractProperty
{
friend class QmlDesigner::ModelNode;
friend class QmlDesigner::Internal::ModelPrivate;

View File

@@ -195,7 +195,7 @@ QmlJS::Document::Language QmlJSTools::languageOfFile(const QString &fileName)
Core::MimeType qbsSourceTy = db->findByType(QLatin1String(Constants::QBS_MIMETYPE));
mergeSuffixes(qbsSuffixes, qbsSourceTy.suffixes());
Core::MimeType qmlProjectSourceTy = db->findByType(QLatin1String(Constants::QMLPROJECT_MIMETYPE));
mergeSuffixes(qbsSuffixes, qmlProjectSourceTy.suffixes());
mergeSuffixes(qmlProjectSuffixes, qmlProjectSourceTy.suffixes());
Core::MimeType jsonSourceTy = db->findByType(QLatin1String(Constants::JSON_MIMETYPE));
mergeSuffixes(jsonSuffixes, jsonSourceTy.suffixes());
}
@@ -243,6 +243,11 @@ ModelManager::ModelManager(QObject *parent):
m_updateCppQmlTypesTimer->setSingleShot(true);
connect(m_updateCppQmlTypesTimer, SIGNAL(timeout()), SLOT(startCppQmlTypeUpdate()));
m_asyncResetTimer = new QTimer(this);
m_asyncResetTimer->setInterval(1000);
m_asyncResetTimer->setSingleShot(true);
connect(m_asyncResetTimer, SIGNAL(timeout()), SLOT(resetCodeModel()));
qRegisterMetaType<QmlJS::Document::Ptr>("QmlJS::Document::Ptr");
qRegisterMetaType<QmlJS::LibraryInfo>("QmlJS::LibraryInfo");
qRegisterMetaType<QmlJSTools::SemanticInfo>("QmlJSTools::SemanticInfo");
@@ -1056,6 +1061,11 @@ void ModelManager::startCppQmlTypeUpdate()
m_queuedCppDocuments.clear();
}
void ModelManager::asyncReset()
{
m_asyncResetTimer->start();
}
void ModelManager::updateCppQmlTypes(QFutureInterface<void> &interface,
ModelManager *qmlModelManager,
CPlusPlus::Snapshot snapshot,
@@ -1100,7 +1110,7 @@ void ModelManager::updateCppQmlTypes(QFutureInterface<void> &interface,
qmlModelManager->m_cppDataHash = newData;
if (hasNewInfo)
// one could get away with re-linking the cpp types...
QMetaObject::invokeMethod(qmlModelManager, "resetCodeModel");
QMetaObject::invokeMethod(qmlModelManager, "asyncReset");
}
ModelManager::CppDataHash ModelManager::cppData() const

View File

@@ -141,6 +141,7 @@ private slots:
void maybeQueueCppQmlTypeUpdate(const CPlusPlus::Document::Ptr &doc);
void queueCppQmlTypeUpdate(const CPlusPlus::Document::Ptr &doc, bool scan);
void startCppQmlTypeUpdate();
void asyncReset();
private:
static bool matchesMimeType(const Core::MimeType &fileMimeType, const Core::MimeType &knownMimeType);
@@ -160,6 +161,7 @@ private:
QFutureSynchronizer<void> m_synchronizer;
QTimer *m_updateCppQmlTypesTimer;
QTimer *m_asyncResetTimer;
QHash<QString, QPair<CPlusPlus::Document::Ptr, bool> > m_queuedCppDocuments;
QFuture<void> m_cppQmlTypesUpdater;
QmlJS::QrcCache m_qrcCache;

View File

@@ -557,7 +557,7 @@ QStringList Qt4PriFileNode::fullVPaths(const QStringList &baseVPaths, QtSupport:
return vPaths;
}
static QSet<Utils::FileName> recursiveEnumerate(const QString &folder)
QSet<Utils::FileName> Qt4PriFileNode::recursiveEnumerate(const QString &folder)
{
QSet<Utils::FileName> result;
QFileInfo fi(folder);
@@ -718,10 +718,66 @@ void Qt4PriFileNode::watchFolders(const QSet<QString> &folders)
m_watchedFolders = folders;
}
void Qt4PriFileNode::folderChanged(const QString &changedFolder)
bool Qt4PriFileNode::folderChanged(const QString &changedFolder, const QSet<Utils::FileName> &newFiles)
{
Q_UNUSED(changedFolder);
scheduleUpdate();
//qDebug()<<"########## Qt4PriFileNode::folderChanged";
// So, we need to figure out which files changed.
QSet<Utils::FileName> addedFiles = newFiles;
addedFiles.subtract(m_recursiveEnumerateFiles);
QSet<Utils::FileName> removedFiles = m_recursiveEnumerateFiles;
removedFiles.subtract(newFiles);
foreach (const Utils::FileName &file, removedFiles) {
if (!file.isChildOf(Utils::FileName::fromString(changedFolder)))
removedFiles.remove(file);
}
if (addedFiles.isEmpty() && removedFiles.isEmpty())
return false;
m_recursiveEnumerateFiles = newFiles;
// Apply the differences
// per file type
const QVector<Qt4NodeStaticData::FileTypeData> &fileTypes = qt4NodeStaticData()->fileTypeData;
for (int i = 0; i < fileTypes.size(); ++i) {
FileType type = fileTypes.at(i).type;
QSet<Utils::FileName> add = filterFilesRecursiveEnumerata(type, addedFiles);
QSet<Utils::FileName> remove = filterFilesRecursiveEnumerata(type, removedFiles);
if (!add.isEmpty() || !remove.isEmpty()) {
// Scream :)
// qDebug()<<"For type"<<fileTypes.at(i).typeName<<"\n"
// <<"added files"<<add<<"\n"
// <<"removed files"<<remove;
m_files[type].unite(add);
m_files[type].subtract(remove);
}
}
// Now apply stuff
InternalNode contents;
for (int i = 0; i < fileTypes.size(); ++i) {
FileType type = fileTypes.at(i).type;
if (!m_files[type].isEmpty()) {
InternalNode *subfolder = new InternalNode;
subfolder->type = type;
subfolder->icon = fileTypes.at(i).icon;
subfolder->fullPath = m_projectDir;
subfolder->typeName = fileTypes.at(i).typeName;
subfolder->priority = -i;
subfolder->displayName = fileTypes.at(i).typeName;
contents.virtualfolders.append(subfolder);
// create the hierarchy with subdirectories
subfolder->create(m_projectDir, m_files[type], type);
}
}
contents.updateSubFolders(this, this);
return true;
}
bool Qt4PriFileNode::deploysFolder(const QString &folder) const

View File

@@ -162,7 +162,7 @@ public:
bool renameFile(const FileType fileType,
const QString &filePath, const QString &newFilePath);
void folderChanged(const QString &changedFolder);
bool folderChanged(const QString &changedFolder, const QSet<Utils::FileName> &newFiles);
bool deploysFolder(const QString &folder) const;
QList<ProjectExplorer::RunConfiguration *> runConfigurationsFor(Node *node);
@@ -172,6 +172,7 @@ public:
// Set by parent
bool includedInExactParse() const;
static QSet<Utils::FileName> recursiveEnumerate(const QString &folder);
protected:
void setIncludedInExactParse(bool b);
static QStringList varNames(FileType type);

View File

@@ -146,7 +146,7 @@ class CentralizedFolderWatcher : public QObject
{
Q_OBJECT
public:
CentralizedFolderWatcher(QObject *parent);
CentralizedFolderWatcher(Qt4Project *parent);
~CentralizedFolderWatcher();
void watchFolders(const QList<QString> &folders, Qt4ProjectManager::Qt4PriFileNode *node);
void unwatchFolders(const QList<QString> &folders, Qt4ProjectManager::Qt4PriFileNode *node);
@@ -157,6 +157,7 @@ private slots:
void delayedFolderChanged(const QString &folder);
private:
Qt4Project *m_project;
QSet<QString> recursiveDirs(const QString &folder);
QFileSystemWatcher m_watcher;
QMultiMap<QString, Qt4ProjectManager::Qt4PriFileNode *> m_map;
@@ -1215,7 +1216,8 @@ namespace {
bool debugCFW = false;
}
CentralizedFolderWatcher::CentralizedFolderWatcher(QObject *parent) : QObject(parent)
CentralizedFolderWatcher::CentralizedFolderWatcher(Qt4Project *parent)
: QObject(parent), m_project(parent)
{
m_compressTimer.setSingleShot(true);
m_compressTimer.setInterval(200);
@@ -1337,12 +1339,19 @@ void CentralizedFolderWatcher::delayedFolderChanged(const QString &folder)
QString dir = folder;
const QChar slash = QLatin1Char('/');
bool newOrRemovedFiles = false;
while (true) {
if (!dir.endsWith(slash))
dir.append(slash);
QList<Qt4ProjectManager::Qt4PriFileNode *> nodes = m_map.values(dir);
foreach (Qt4ProjectManager::Qt4PriFileNode *node, nodes) {
node->folderChanged(folder);
if (!nodes.isEmpty()) {
// Collect all the files
QSet<Utils::FileName> newFiles;
newFiles += Qt4PriFileNode::recursiveEnumerate(folder);
foreach (Qt4ProjectManager::Qt4PriFileNode *node, nodes) {
newOrRemovedFiles = newOrRemovedFiles
|| node->folderChanged(folder, newFiles);
}
}
// Chop off last part, and break if there's nothing to chop off
@@ -1357,7 +1366,6 @@ void CentralizedFolderWatcher::delayedFolderChanged(const QString &folder)
dir.truncate(index + 1);
}
QString folderWithSlash = folder;
if (!folder.endsWith(slash))
folderWithSlash.append(slash);
@@ -1374,6 +1382,11 @@ void CentralizedFolderWatcher::delayedFolderChanged(const QString &folder)
m_watcher.addPaths(tmp.toList());
m_recursiveWatchedFolders += tmp;
}
if (newOrRemovedFiles) {
m_project->updateFileList();
m_project->updateCodeModels();
}
}
bool Qt4Project::needsConfiguration() const

View File

@@ -64,10 +64,13 @@ QList<FilterEntry> LineNumberFilter::matchesFor(QFutureInterface<Locator::Filter
int sectionCount = lineAndColumn.size();
int line = 0;
int column = 0;
bool ok;
if (sectionCount > 0)
line = lineAndColumn.at(0).toInt();
if (sectionCount > 1)
column = lineAndColumn.at(1).toInt();
line = lineAndColumn.at(0).toInt(&ok);
if (ok && sectionCount > 1)
column = lineAndColumn.at(1).toInt(&ok);
if (!ok)
return value;
if (currentTextEditor() && (line > 0 || column > 0)) {
LineColumn data;
data.first = line;

View File

@@ -87,7 +87,7 @@ const char *nameForStyle(TextStyle style)
case C_DIFF_FILE: return "DiffFile";
case C_DIFF_LOCATION: return "DiffLocation";
case C_DIFF_FILE_LINE: return "DillFileLine";
case C_DIFF_FILE_LINE: return "DiffFileLine";
case C_DIFF_CONTEXT_LINE: return "DiffContextLine";
case C_DIFF_SOURCE_LINE: return "DiffSourceLine";
case C_DIFF_SOURCE_CHAR: return "DiffSourceChar";

View File

@@ -98,9 +98,11 @@ bool DiffChunk::isValid() const
return !fileName.isEmpty() && !chunk.isEmpty();
}
QByteArray DiffChunk::asPatch() const
QByteArray DiffChunk::asPatch(const QString &workingDirectory) const
{
const QByteArray fileNameBA = QFile::encodeName(fileName);
QString relativeFile = workingDirectory.isEmpty() ?
fileName : QDir(workingDirectory).relativeFilePath(fileName);
const QByteArray fileNameBA = QFile::encodeName(relativeFile);
QByteArray rc = "--- ";
rc += fileNameBA;
rc += "\n+++ ";
@@ -1466,7 +1468,8 @@ bool VcsBaseEditorWidget::canApplyDiffChunk(const DiffChunk &dc) const
// (passing '-R' for revert), assuming we got absolute paths from the VCS plugins.
bool VcsBaseEditorWidget::applyDiffChunk(const DiffChunk &dc, bool revert) const
{
return VcsBasePlugin::runPatch(dc.asPatch(), QString(), 0, revert);
return VcsBasePlugin::runPatch(dc.asPatch(d->m_diffBaseDirectory),
d->m_diffBaseDirectory, 0, revert);
}
QString VcsBaseEditorWidget::fileNameFromDiffSpecification(const QTextBlock &inBlock) const

View File

@@ -78,7 +78,7 @@ class VCSBASE_EXPORT DiffChunk
{
public:
bool isValid() const;
QByteArray asPatch() const;
QByteArray asPatch(const QString &workingDirectory) const;
QString fileName;
QByteArray chunk;

View File

@@ -1056,7 +1056,7 @@ bool VcsBasePlugin::runPatch(const QByteArray &input, const QString &workingDire
QStringList args(QLatin1String("-p") + QString::number(strip));
if (reverse)
args << QLatin1String("-R");
ow->appendCommand(QString(), patch, args);
ow->appendCommand(workingDirectory, patch, args);
patchProcess.start(patch, args);
if (!patchProcess.waitForStarted()) {
ow->appendError(tr("Unable to launch '%1': %2").arg(patch, patchProcess.errorString()));