diff --git a/src/libs/utils/basetreeview.cpp b/src/libs/utils/basetreeview.cpp index 29c531e1cc5..98b997c5c84 100644 --- a/src/libs/utils/basetreeview.cpp +++ b/src/libs/utils/basetreeview.cpp @@ -51,7 +51,11 @@ class BaseTreeViewPrivate : public QObject public: explicit BaseTreeViewPrivate(BaseTreeView *parent) : q(parent), m_settings(0), m_expectUserChanges(false), m_progressIndicator(0) - {} + { + m_settingsTimer.setSingleShot(true); + connect(&m_settingsTimer, &QTimer::timeout, + this, &BaseTreeViewPrivate::doSaveState); + } bool eventFilter(QObject *, QEvent *event) { @@ -102,6 +106,12 @@ public: void saveState() { + m_settingsTimer.start(2000); // Once per 2 secs should be enough. + } + + void doSaveState() + { + m_settingsTimer.stop(); if (m_settings && !m_settingsKey.isEmpty()) { m_settings->beginGroup(m_settingsKey); QVariantList l; @@ -210,6 +220,7 @@ public: BaseTreeView *q; QMap m_userHandled; // column -> width, "not present" means "automatic" QSettings *m_settings; + QTimer m_settingsTimer; QString m_settingsKey; bool m_expectUserChanges; ProgressIndicator *m_progressIndicator; diff --git a/src/plugins/diffeditor/diffeditorplugin.cpp b/src/plugins/diffeditor/diffeditorplugin.cpp index f906fdb0277..6004f935156 100644 --- a/src/plugins/diffeditor/diffeditorplugin.cpp +++ b/src/plugins/diffeditor/diffeditorplugin.cpp @@ -1347,6 +1347,22 @@ void DiffEditor::Internal::DiffEditorPlugin::testReadPatch_data() QTest::newRow("Binary files") << patch << fileDataList8; + ////////////// + patch = _("diff --git a/script.sh b/script.sh\n" + "old mode 100644\n" + "new mode 100755\n" + ); + + fileData1 = FileData(); + fileData1.leftFileInfo = DiffFileInfo("script.sh"); + fileData1.rightFileInfo = DiffFileInfo("script.sh"); + fileData1.fileOperation = FileData::ChangeMode; + + QList fileDataList9; + fileDataList9 << fileData1; + + QTest::newRow("Mode change") << patch << fileDataList9; + ////////////// // Subversion New @@ -1362,10 +1378,10 @@ void DiffEditor::Internal::DiffEditorPlugin::testReadPatch_data() chunkData1.leftStartingLineNumber = -1; chunkData1.rightStartingLineNumber = 124; fileData1.chunks << chunkData1; - QList fileDataList9; - fileDataList9 << fileData1; + QList fileDataList21; + fileDataList21 << fileData1; QTest::newRow("Subversion New") << patch - << fileDataList9; + << fileDataList21; ////////////// @@ -1382,10 +1398,10 @@ void DiffEditor::Internal::DiffEditorPlugin::testReadPatch_data() chunkData1.leftStartingLineNumber = 0; chunkData1.rightStartingLineNumber = -1; fileData1.chunks << chunkData1; - QList fileDataList10; - fileDataList10 << fileData1; + QList fileDataList22; + fileDataList22 << fileData1; QTest::newRow("Subversion Deleted") << patch - << fileDataList10; + << fileDataList22; ////////////// @@ -1402,10 +1418,10 @@ void DiffEditor::Internal::DiffEditorPlugin::testReadPatch_data() chunkData1.leftStartingLineNumber = 119; chunkData1.rightStartingLineNumber = 119; fileData1.chunks << chunkData1; - QList fileDataList11; - fileDataList11 << fileData1; + QList fileDataList23; + fileDataList23 << fileData1; QTest::newRow("Subversion Normal") << patch - << fileDataList11; + << fileDataList23; } void DiffEditor::Internal::DiffEditorPlugin::testReadPatch() diff --git a/src/plugins/diffeditor/diffutils.cpp b/src/plugins/diffeditor/diffutils.cpp index a9d9b11ae24..69ddbb9ba96 100644 --- a/src/plugins/diffeditor/diffutils.cpp +++ b/src/plugins/diffeditor/diffutils.cpp @@ -1025,10 +1025,16 @@ static bool detectIndexAndBinary(QStringRef patch, bool hasNewLine; *remainingPatch = patch; - if (remainingPatch->isEmpty() && (fileData->fileOperation == FileData::CopyFile - || fileData->fileOperation == FileData::RenameFile)) { - // in case of 100% similarity we don't have more lines in the patch - return true; + if (remainingPatch->isEmpty()) { + switch (fileData->fileOperation) { + case FileData::CopyFile: + case FileData::RenameFile: + case FileData::ChangeMode: + // in case of 100% similarity we don't have more lines in the patch + return true; + default: + break; + } } QStringRef afterNextLine; @@ -1151,8 +1157,6 @@ static bool detectFileData(QStringRef patch, QStringRef afterSecondLine; const QStringRef secondLine = readLine(afterDiffGit, &afterSecondLine, &hasNewLine); - if (!hasNewLine) - return false; // we need to have at least one more line if (secondLine.startsWith(QStringLiteral("new file mode "))) { fileData->fileOperation = FileData::NewFile; @@ -1165,7 +1169,7 @@ static bool detectFileData(QStringRef patch, // new mode readLine(afterSecondLine, &afterThirdLine, &hasNewLine); if (!hasNewLine) - return false; // we need to have at least one more line + fileData->fileOperation = FileData::ChangeMode; // TODO: validate new mode line *remainingPatch = afterThirdLine; diff --git a/src/plugins/diffeditor/diffutils.h b/src/plugins/diffeditor/diffutils.h index 46a8bb40b0f..ed0130bfbdf 100644 --- a/src/plugins/diffeditor/diffutils.h +++ b/src/plugins/diffeditor/diffutils.h @@ -104,6 +104,7 @@ class DIFFEDITOR_EXPORT FileData { public: enum FileOperation { ChangeFile, + ChangeMode, NewFile, DeleteFile, CopyFile, diff --git a/src/plugins/qmakeprojectmanager/qmakeparsernodes.cpp b/src/plugins/qmakeprojectmanager/qmakeparsernodes.cpp index 7bb64a521c9..4c47e34d2f2 100644 --- a/src/plugins/qmakeprojectmanager/qmakeparsernodes.cpp +++ b/src/plugins/qmakeprojectmanager/qmakeparsernodes.cpp @@ -1089,9 +1089,12 @@ QmakeProFile::QmakeProFile(QmakeProject *project, const FileName &filePath) : QmakeProFile::~QmakeProFile() { qDeleteAll(m_extraCompilers); + m_parseFutureWatcher.cancel(); m_parseFutureWatcher.waitForFinished(); if (m_readerExact) applyAsyncEvaluate(); + + cleanupProFileReaders(); } bool QmakeProFile::isParent(QmakeProFile *node) @@ -1491,7 +1494,8 @@ void QmakeProFile::asyncEvaluate(QFutureInterface &fi, QmakeE void QmakeProFile::applyAsyncEvaluate() { - applyEvaluate(m_parseFutureWatcher.result()); + if (m_parseFutureWatcher.isFinished()) + applyEvaluate(m_parseFutureWatcher.result()); m_project->decrementPendingEvaluateFutures(); } @@ -1627,8 +1631,10 @@ void QmakeProFile::applyEvaluate(QmakeEvalResult *evalResult) void QmakeProFile::cleanupProFileReaders() { - m_project->destroyProFileReader(m_readerExact); - m_project->destroyProFileReader(m_readerCumulative); + if (m_readerExact) + m_project->destroyProFileReader(m_readerExact); + if (m_readerCumulative) + m_project->destroyProFileReader(m_readerCumulative); m_readerExact = nullptr; m_readerCumulative = nullptr; diff --git a/src/plugins/qmakeprojectmanager/qmakeproject.cpp b/src/plugins/qmakeprojectmanager/qmakeproject.cpp index bf0c16cba51..a1218a017ef 100644 --- a/src/plugins/qmakeprojectmanager/qmakeproject.cpp +++ b/src/plugins/qmakeprojectmanager/qmakeproject.cpp @@ -202,6 +202,12 @@ QmakeProject::~QmakeProject() m_cancelEvaluate = true; Q_ASSERT(m_qmakeGlobalsRefCnt == 0); delete m_qmakeVfs; + + if (m_asyncUpdateFutureInterface) { + m_asyncUpdateFutureInterface->reportCanceled(); + m_asyncUpdateFutureInterface->reportFinished(); + delete m_asyncUpdateFutureInterface; + } } QmakeProFile *QmakeProject::rootProFile() const @@ -508,6 +514,9 @@ void QmakeProject::decrementPendingEvaluateFutures() { --m_pendingEvaluateFuturesCount; + if (!rootProFile()) + return; // We are closing the project! + m_asyncUpdateFutureInterface->setProgressValue(m_asyncUpdateFutureInterface->progressValue() + 1); if (m_pendingEvaluateFuturesCount == 0) { // We are done! @@ -640,7 +649,7 @@ void QmakeProject::proFileParseError(const QString &errorMessage) QtSupport::ProFileReader *QmakeProject::createProFileReader(const QmakeProFile *qmakeProFile) { if (!m_qmakeGlobals) { - m_qmakeGlobals = new QMakeGlobals; + m_qmakeGlobals = std::make_unique(); m_qmakeGlobalsRefCnt = 0; Kit *k = KitManager::defaultKit(); @@ -664,7 +673,7 @@ QtSupport::ProFileReader *QmakeProject::createProFileReader(const QmakeProFile * if (qtVersion && qtVersion->isValid()) { m_qmakeGlobals->qmake_abslocation = QDir::cleanPath(qtVersion->qmakeCommand().toString()); - qtVersion->applyProperties(m_qmakeGlobals); + qtVersion->applyProperties(m_qmakeGlobals.get()); } m_qmakeGlobals->setDirectories(rootProFile()->sourceDir().toString(), rootProFile()->buildDir().toString()); @@ -693,7 +702,7 @@ QtSupport::ProFileReader *QmakeProject::createProFileReader(const QmakeProFile * } ++m_qmakeGlobalsRefCnt; - auto reader = new QtSupport::ProFileReader(m_qmakeGlobals, m_qmakeVfs); + auto reader = new QtSupport::ProFileReader(m_qmakeGlobals.get(), m_qmakeVfs); reader->setOutputDir(qmakeProFile->buildDir().toString()); @@ -702,7 +711,7 @@ QtSupport::ProFileReader *QmakeProject::createProFileReader(const QmakeProFile * QMakeGlobals *QmakeProject::qmakeGlobals() { - return m_qmakeGlobals; + return m_qmakeGlobals.get(); } QMakeVfs *QmakeProject::qmakeVfs() @@ -725,8 +734,7 @@ void QmakeProject::destroyProFileReader(QtSupport::ProFileReader *reader) QtSupport::ProFileCacheManager::instance()->discardFiles(dir); QtSupport::ProFileCacheManager::instance()->decRefCount(); - delete m_qmakeGlobals; - m_qmakeGlobals = nullptr; + m_qmakeGlobals.reset(); } } diff --git a/src/plugins/qmakeprojectmanager/qmakeproject.h b/src/plugins/qmakeprojectmanager/qmakeproject.h index 8fa4ab5c97d..3ead4c6b85c 100644 --- a/src/plugins/qmakeprojectmanager/qmakeproject.h +++ b/src/plugins/qmakeprojectmanager/qmakeproject.h @@ -179,7 +179,7 @@ private: QMakeVfs *m_qmakeVfs = nullptr; // cached data during project rescan - QMakeGlobals *m_qmakeGlobals = nullptr; + std::unique_ptr m_qmakeGlobals; int m_qmakeGlobalsRefCnt = 0; QString m_qmakeSysroot; diff --git a/src/shared/qbs b/src/shared/qbs index acf142851ae..08ce978733b 160000 --- a/src/shared/qbs +++ b/src/shared/qbs @@ -1 +1 @@ -Subproject commit acf142851aeec850083811afb012a3fbcba793c6 +Subproject commit 08ce978733b33c1b1a64e5e1e62dea22cde6148c