forked from qt-creator/qt-creator
Merge remote-tracking branch 'origin/2.8' into HEAD
Conflicts: qtcreator.pri qtcreator.qbs Change-Id: I5d2018d3437b99bcdffa92bf1a212f42923c4fad
This commit is contained in:
@@ -19,7 +19,6 @@ Product {
|
||||
}
|
||||
return name;
|
||||
}
|
||||
moduleSearchPaths: "../../../qbs" // TODO: Should get inherited from project, but doesn't.
|
||||
|
||||
Depends { name: "ExtensionSystem" }
|
||||
Depends { name: "pluginspec" }
|
||||
|
||||
@@ -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());
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
@@ -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();
|
||||
|
||||
@@ -79,7 +79,7 @@ public:
|
||||
~ModelManagerTestHelper();
|
||||
|
||||
void cleanup();
|
||||
void verifyClean();
|
||||
static void verifyClean();
|
||||
|
||||
Project *createProject(const QString &name);
|
||||
|
||||
|
||||
@@ -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 {
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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());
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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 {
|
||||
|
||||
@@ -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))
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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";
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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()));
|
||||
|
||||
Reference in New Issue
Block a user