diff options
Diffstat (limited to 'src')
22 files changed, 243 insertions, 116 deletions
diff --git a/src/app/main.cpp b/src/app/main.cpp index 08cd1374d8..286f9074d9 100644 --- a/src/app/main.cpp +++ b/src/app/main.cpp @@ -203,31 +203,6 @@ static inline int askMsgSendFailed() QMessageBox::Retry); } -// taken from utils/fileutils.cpp. We cannot use utils here since that depends app_version.h. -static bool copyRecursively(const QString &srcFilePath, const QString &tgtFilePath) -{ - QFileInfo srcFileInfo(srcFilePath); - if (srcFileInfo.isDir()) { - QDir targetDir(tgtFilePath); - targetDir.cdUp(); - if (!targetDir.mkdir(Utils::FilePath::fromString(tgtFilePath).fileName())) - return false; - QDir sourceDir(srcFilePath); - const QStringList fileNames = sourceDir.entryList - (QDir::Files | QDir::Dirs | QDir::NoDotAndDotDot | QDir::Hidden | QDir::System); - for (const QString &fileName : fileNames) { - const QString newSrcFilePath = srcFilePath + '/' + fileName; - const QString newTgtFilePath = tgtFilePath + '/' + fileName; - if (!copyRecursively(newSrcFilePath, newTgtFilePath)) - return false; - } - } else { - if (!QFile::copy(srcFilePath, tgtFilePath)) - return false; - } - return true; -} - static inline QStringList getPluginPaths() { QStringList rc(QDir::cleanPath(QApplication::applicationDirPath() diff --git a/src/libs/utils/qtcprocess.cpp b/src/libs/utils/qtcprocess.cpp index 824c3eff0b..46b4eb5f70 100644 --- a/src/libs/utils/qtcprocess.cpp +++ b/src/libs/utils/qtcprocess.cpp @@ -774,15 +774,15 @@ bool QtcProcess::readDataFromProcess(int timeoutS, finished = waitForFinished(timeoutS > 0 ? timeoutS * 1000 : -1) || state() == QProcess::NotRunning; // First check 'stdout' - if (d->m_process->bytesAvailable()) { // applies to readChannel() only + const QByteArray newStdOut = readAllStandardOutput(); + if (!newStdOut.isEmpty()) { hasData = true; - const QByteArray newStdOut = d->m_process->readAllStandardOutput(); if (stdOut) stdOut->append(newStdOut); } // Check 'stderr' separately. This is a special handling // for 'git pull' and the like which prints its progress on stderr. - const QByteArray newStdErr = d->m_process->readAllStandardError(); + const QByteArray newStdErr = readAllStandardError(); if (!newStdErr.isEmpty()) { hasData = true; if (stdErr) diff --git a/src/plugins/clangcodemodel/clangdclient.cpp b/src/plugins/clangcodemodel/clangdclient.cpp index b4a0fe0568..07dd727041 100644 --- a/src/plugins/clangcodemodel/clangdclient.cpp +++ b/src/plugins/clangcodemodel/clangdclient.cpp @@ -682,6 +682,8 @@ public: Private(ClangdClient *q, Project *project) : q(q), settings(CppTools::ClangdProjectSettings(project).settings()) {} + void findUsages(TextEditor::TextDocument *document, const QTextCursor &cursor, + const QString &searchTerm, const Utils::optional<QString> &replacement); void handleFindUsagesResult(quint64 key, const QList<Location> &locations); static void handleRenameRequest(const SearchResult *search, const ReplacementData &replacementData, @@ -868,13 +870,77 @@ void ClangdClient::closeExtraFile(const Utils::FilePath &filePath) void ClangdClient::findUsages(TextEditor::TextDocument *document, const QTextCursor &cursor, const Utils::optional<QString> &replacement) { - // TODO: This will be wrong for e.g. operators. Use a Symbol info request to get the real symbol string. - const QString searchTerm = d->searchTermFromCursor(cursor); - if (searchTerm.isEmpty()) + // Quick check: Are we even on anything searchable? + if (d->searchTermFromCursor(cursor).isEmpty()) return; + // Get the proper spelling of the search term from clang, so we can put it into the + // search widget. + const TextDocumentIdentifier docId(DocumentUri::fromFilePath(document->filePath())); + const TextDocumentPositionParams params(docId, Range(cursor).start()); + SymbolInfoRequest symReq(params); + symReq.setResponseCallback([this, doc = QPointer(document), cursor, replacement] + (const SymbolInfoRequest::Response &response) { + if (!doc) + return; + const auto result = response.result(); + if (!result) + return; + const auto list = Utils::get_if<QList<SymbolDetails>>(&result.value()); + if (!list || list->isEmpty()) + return; + const SymbolDetails &sd = list->first(); + if (sd.name().isEmpty()) + return; + d->findUsages(doc.data(), cursor, sd.name(), replacement); + }); + sendContent(symReq); +} + +void ClangdClient::enableTesting() { d->isTesting = true; } + +void ClangdClient::handleDiagnostics(const PublishDiagnosticsParams ¶ms) +{ + const DocumentUri &uri = params.uri(); + Client::handleDiagnostics(params); + for (const Diagnostic &diagnostic : params.diagnostics()) { + const ClangdDiagnostic clangdDiagnostic(diagnostic); + for (const CodeAction &action : clangdDiagnostic.codeActions().value_or(QList<CodeAction>{})) + LanguageClient::updateCodeActionRefactoringMarker(this, action, uri); + } +} + +void ClangdClient::handleDocumentClosed(TextEditor::TextDocument *doc) +{ + d->highlighters.erase(doc); +} + +QVersionNumber ClangdClient::versionNumber() const +{ + if (d->versionNumber) + return d->versionNumber.value(); + + const QRegularExpression versionPattern("^clangd version (\\d+)\\.(\\d+)\\.(\\d+).*$"); + QTC_CHECK(versionPattern.isValid()); + const QRegularExpressionMatch match = versionPattern.match(serverVersion()); + if (match.isValid()) { + d->versionNumber.emplace({match.captured(1).toInt(), match.captured(2).toInt(), + match.captured(3).toInt()}); + } else { + qCWarning(clangdLog) << "Failed to parse clangd server string" << serverVersion(); + d->versionNumber.emplace({0}); + } + return d->versionNumber.value(); +} + +CppTools::ClangdSettings::Data ClangdClient::settingsData() const { return d->settings; } + +void ClangdClient::Private::findUsages(TextEditor::TextDocument *document, + const QTextCursor &cursor, const QString &searchTerm, + const Utils::optional<QString> &replacement) +{ ReferencesData refData; - refData.key = d->nextJobId++; + refData.key = nextJobId++; if (replacement) { ReplacementData replacementData; replacementData.oldSymbolName = searchTerm; @@ -883,6 +949,7 @@ void ClangdClient::findUsages(TextEditor::TextDocument *document, const QTextCur replacementData.newSymbolName = replacementData.oldSymbolName; refData.replacementData = replacementData; } + refData.search = SearchResultWindow::instance()->startNewSearch( tr("C++ Usages:"), {}, @@ -911,66 +978,28 @@ void ClangdClient::findUsages(TextEditor::TextDocument *document, const QTextCur Core::EditorManager::openEditorAtSearchResult(item); }); SearchResultWindow::instance()->popup(IOutputPane::ModeSwitch | IOutputPane::WithFocus); - d->runningFindUsages.insert(refData.key, refData); + runningFindUsages.insert(refData.key, refData); - const Utils::optional<MessageId> requestId = symbolSupport().findUsages( + const Utils::optional<MessageId> requestId = q->symbolSupport().findUsages( document, cursor, [this, key = refData.key](const QList<Location> &locations) { - d->handleFindUsagesResult(key, locations); + handleFindUsagesResult(key, locations); }); if (!requestId) { - d->finishSearch(refData, false); + finishSearch(refData, false); return; } - connect(refData.search, &SearchResult::cancelled, this, [this, requestId, key = refData.key] { - const auto refData = d->runningFindUsages.find(key); - if (refData == d->runningFindUsages.end()) + QObject::connect(refData.search, &SearchResult::cancelled, q, [this, requestId, key = refData.key] { + const auto refData = runningFindUsages.find(key); + if (refData == runningFindUsages.end()) return; - cancelRequest(*requestId); + q->cancelRequest(*requestId); refData->canceled = true; - refData->search->disconnect(this); - d->finishSearch(*refData, true); + refData->search->disconnect(q); + finishSearch(*refData, true); }); } -void ClangdClient::enableTesting() { d->isTesting = true; } - -void ClangdClient::handleDiagnostics(const PublishDiagnosticsParams ¶ms) -{ - const DocumentUri &uri = params.uri(); - Client::handleDiagnostics(params); - for (const Diagnostic &diagnostic : params.diagnostics()) { - const ClangdDiagnostic clangdDiagnostic(diagnostic); - for (const CodeAction &action : clangdDiagnostic.codeActions().value_or(QList<CodeAction>{})) - LanguageClient::updateCodeActionRefactoringMarker(this, action, uri); - } -} - -void ClangdClient::handleDocumentClosed(TextEditor::TextDocument *doc) -{ - d->highlighters.erase(doc); -} - -QVersionNumber ClangdClient::versionNumber() const -{ - if (d->versionNumber) - return d->versionNumber.value(); - - const QRegularExpression versionPattern("^clangd version (\\d+)\\.(\\d+)\\.(\\d+).*$"); - QTC_CHECK(versionPattern.isValid()); - const QRegularExpressionMatch match = versionPattern.match(serverVersion()); - if (match.isValid()) { - d->versionNumber.emplace({match.captured(1).toInt(), match.captured(2).toInt(), - match.captured(3).toInt()}); - } else { - qCWarning(clangdLog) << "Failed to parse clangd server string" << serverVersion(); - d->versionNumber.emplace({0}); - } - return d->versionNumber.value(); -} - -CppTools::ClangdSettings::Data ClangdClient::settingsData() const { return d->settings; } - void ClangdClient::Private::handleFindUsagesResult(quint64 key, const QList<Location> &locations) { const auto refData = runningFindUsages.find(key); @@ -2217,7 +2246,7 @@ static void cleanupDisabledCode(TextEditor::HighlightingResults &results, QTextD continue; } - if (wasInDisabled && (it == results.end() + if (wasInDisabled && (it + 1 == results.end() || (it + 1)->textStyles.mainStyle != TextEditor::C_DISABLED_CODE)) { // The #else or #endif that ends disabled code should not be disabled. it = results.erase(it); diff --git a/src/plugins/clangcodemodel/clangtextmark.cpp b/src/plugins/clangcodemodel/clangtextmark.cpp index 77ed1f2fa3..52b0d32f95 100644 --- a/src/plugins/clangcodemodel/clangtextmark.cpp +++ b/src/plugins/clangcodemodel/clangtextmark.cpp @@ -358,9 +358,12 @@ ClangdTextMark::ClangdTextMark(const FilePath &filePath, setPriority(isError ? TextEditor::TextMark::HighPriority : TextEditor::TextMark::NormalPriority); setIcon(isError ? Icons::CODEMODEL_ERROR.icon() : Icons::CODEMODEL_WARNING.icon()); - setLineAnnotation(diagnostic.message()); - setColor(isError ? Theme::CodeModel_Error_TextMarkColor - : Theme::CodeModel_Warning_TextMarkColor); + if (client->project()) { + setLineAnnotation(diagnostic.message()); + setColor(isError ? Theme::CodeModel_Error_TextMarkColor + : Theme::CodeModel_Warning_TextMarkColor); + ClangDiagnosticManager::addTask(m_diagnostic); + } // Copy to clipboard action QVector<QAction *> actions; @@ -387,8 +390,6 @@ ClangdTextMark::ClangdTextMark(const FilePath &filePath, } setActions(actions); - - ClangDiagnosticManager::addTask(m_diagnostic); } bool ClangdTextMark::addToolTipContent(QLayout *target) const diff --git a/src/plugins/cmakeprojectmanager/cmakebuildconfiguration.cpp b/src/plugins/cmakeprojectmanager/cmakebuildconfiguration.cpp index 2a1a27683b..8e064aaf98 100644 --- a/src/plugins/cmakeprojectmanager/cmakebuildconfiguration.cpp +++ b/src/plugins/cmakeprojectmanager/cmakebuildconfiguration.cpp @@ -947,7 +947,7 @@ CMakeBuildConfiguration::CMakeBuildConfiguration(Target *target, Id id) QtSupport::BaseQtVersion *qt = QtSupport::QtKitAspect::qtVersion(k); auto sdkLocation = bs->data(Android::Constants::SdkLocation).value<FilePath>(); - if (qt->qtVersion() >= QtSupport::QtVersionNumber{6, 0, 0}) { + if (qt && qt->qtVersion() >= QtSupport::QtVersionNumber{6, 0, 0}) { initialArgs.append("-DQT_HOST_PATH:PATH=%{Qt:QT_HOST_PREFIX}"); initialArgs.append("-DANDROID_SDK_ROOT:PATH=" + sdkLocation.path()); } else { @@ -956,7 +956,7 @@ CMakeBuildConfiguration::CMakeBuildConfiguration(Target *target, Id id) } const IDevice::ConstPtr device = DeviceKitAspect::device(k); - if (device->osType() == Utils::OsTypeMac) { + if (device && device->osType() == Utils::OsTypeMac) { if (isIos(k)) { QtSupport::BaseQtVersion *qt = QtSupport::QtKitAspect::qtVersion(k); if (qt && qt->qtVersion().majorVersion >= 6) { diff --git a/src/plugins/coreplugin/locator/executefilter.cpp b/src/plugins/coreplugin/locator/executefilter.cpp index 1a9c8cc4dc..54f7c29cfa 100644 --- a/src/plugins/coreplugin/locator/executefilter.cpp +++ b/src/plugins/coreplugin/locator/executefilter.cpp @@ -110,7 +110,8 @@ void ExecuteFilter::accept(LocatorFilterEntry selection, d.executable = value; } else { d.executable = value.left(pos); - d.arguments = value.right(value.length() - pos - 1); + d.arguments = Utils::globalMacroExpander()->expand( + value.right(value.length() - pos - 1)); } if (m_process->state() != QProcess::NotRunning) { diff --git a/src/plugins/cppeditor/cppquickfix_test.cpp b/src/plugins/cppeditor/cppquickfix_test.cpp index ab0bdf4d34..da0c8a944e 100644 --- a/src/plugins/cppeditor/cppquickfix_test.cpp +++ b/src/plugins/cppeditor/cppquickfix_test.cpp @@ -253,6 +253,8 @@ QuickFixOperationTest::QuickFixOperationTest(const QList<QuickFixTestDocument::P // Check QString result = testDocument->m_editorWidget->document()->toPlainText(); removeTrailingWhitespace(result); + QEXPECT_FAIL("escape string literal: raw string literal", "FIXME", Continue); + QEXPECT_FAIL("escape string literal: unescape adjacent literals", "FIXME", Continue); if (!expectedFailMessage.isEmpty()) QEXPECT_FAIL("", expectedFailMessage.data(), Continue); else if (result != testDocument->m_expectedSource) { @@ -1750,6 +1752,26 @@ void CppEditorPlugin::test_quickfix_data() << CppQuickFixFactoryPtr(new ConvertToCamelCase(true)) << _("void @WhAt_TODO_hErE();\n") << _("void WhAtTODOHErE();\n"); + QTest::newRow("escape string literal: simple case") + << CppQuickFixFactoryPtr(new EscapeStringLiteral) + << _(R"(const char *str = @"àxyz";)") + << _(R"(const char *str = "\xc3\xa0xyz";)"); + QTest::newRow("escape string literal: simple case reverse") + << CppQuickFixFactoryPtr(new EscapeStringLiteral) + << _(R"(const char *str = @"\xc3\xa0xyz";)") + << _(R"(const char *str = "àxyz";)"); + QTest::newRow("escape string literal: raw string literal") + << CppQuickFixFactoryPtr(new EscapeStringLiteral) + << _(R"x(const char *str = @R"(àxyz)";)x") + << _(R"x(const char *str = R"(\xc3\xa0xyz)";)x"); + QTest::newRow("escape string literal: splitting required") + << CppQuickFixFactoryPtr(new EscapeStringLiteral) + << _(R"(const char *str = @"àf23бgб1";)") + << _(R"(const char *str = "\xc3\xa0""f23\xd0\xb1g\xd0\xb1""1";)"); + QTest::newRow("escape string literal: unescape adjacent literals") + << CppQuickFixFactoryPtr(new EscapeStringLiteral) + << _(R"(const char *str = @"\xc3\xa0""f23\xd0\xb1g\xd0\xb1""1";)") + << _(R"(const char *str = "àf23бgб1";)"); } void CppEditorPlugin::test_quickfix() diff --git a/src/plugins/cppeditor/cppquickfixes.cpp b/src/plugins/cppeditor/cppquickfixes.cpp index 928a26f853..60d18cb65c 100644 --- a/src/plugins/cppeditor/cppquickfixes.cpp +++ b/src/plugins/cppeditor/cppquickfixes.cpp @@ -7079,17 +7079,25 @@ private: return false; } - static QByteArray escapeString(const QByteArray &contents) + static QByteArrayList escapeString(const QByteArray &contents) { - QByteArray newContents; + QByteArrayList newContents; + QByteArray chunk; + bool wasEscaped = false; for (const quint8 c : contents) { - if (isascii(c) && isprint(c)) { - newContents += c; - } else { - newContents += QByteArray("\\x") + - QByteArray::number(c, 16).rightJustified(2, '0'); + const bool needsEscape = !isascii(c) || !isprint(c); + if (!needsEscape && wasEscaped && std::isxdigit(c) && !chunk.isEmpty()) { + newContents << chunk; + chunk.clear(); } + if (needsEscape) + chunk += QByteArray("\\x") + QByteArray::number(c, 16).rightJustified(2, '0'); + else + chunk += c; + wasEscaped = needsEscape; } + if (!chunk.isEmpty()) + newContents << chunk; return newContents; } @@ -7154,25 +7162,35 @@ public: QTC_ASSERT(stringLiteral, return); const QByteArray oldContents(currentFile->tokenAt(stringLiteral->literal_token). identifier->chars()); - QByteArray newContents; + QByteArrayList newContents; if (m_escape) newContents = escapeString(oldContents); else - newContents = unescapeString(oldContents); + newContents = {unescapeString(oldContents)}; + + if (newContents.isEmpty() + || (newContents.size() == 1 && newContents.first() == oldContents)) { + return; + } + + QTextCodec *utf8codec = QTextCodec::codecForName("UTF-8"); + QScopedPointer<QTextDecoder> decoder(utf8codec->makeDecoder()); + ChangeSet changes; - if (oldContents != newContents) { - // Check UTF-8 byte array is correct or not. - QTextCodec *utf8codec = QTextCodec::codecForName("UTF-8"); - QScopedPointer<QTextDecoder> decoder(utf8codec->makeDecoder()); - const QString str = decoder->toUnicode(newContents); + bool replace = true; + for (const QByteArray &chunk : qAsConst(newContents)) { + const QString str = decoder->toUnicode(chunk); const QByteArray utf8buf = str.toUtf8(); - if (utf8codec->canEncode(str) && newContents == utf8buf) { - ChangeSet changes; + if (!utf8codec->canEncode(str) || chunk != utf8buf) + return; + if (replace) changes.replace(startPos + 1, endPos - 1, str); - currentFile->setChangeSet(changes); - currentFile->apply(); - } + else + changes.insert(endPos, "\"" + str + "\""); + replace = false; } + currentFile->setChangeSet(changes); + currentFile->apply(); } private: diff --git a/src/plugins/cpptools/semantichighlighter.cpp b/src/plugins/cpptools/semantichighlighter.cpp index 67ce04e042..d30f4d97c5 100644 --- a/src/plugins/cpptools/semantichighlighter.cpp +++ b/src/plugins/cpptools/semantichighlighter.cpp @@ -210,7 +210,13 @@ void SemanticHighlighter::onHighlighterResultAvailable(int from, int to) } QTC_ASSERT(paren.pos != -1, continue); paren.source = parenSource(); - parentheses.second << paren; + + static const auto posCmp = [](const Parenthesis &p1, const Parenthesis &p2) { + return p1.pos < p2.pos; + }; + const auto it = std::lower_bound(parentheses.second.begin(), parentheses.second.end(), + paren, posCmp); + parentheses.second.insert(it, paren); } if (parentheses.first.isValid()) TextDocumentLayout::setParentheses(parentheses.first, parentheses.second); diff --git a/src/plugins/debugger/commonoptionspage.cpp b/src/plugins/debugger/commonoptionspage.cpp index 2f0bc5c758..d4a3ecd2d6 100644 --- a/src/plugins/debugger/commonoptionspage.cpp +++ b/src/plugins/debugger/commonoptionspage.cpp @@ -84,13 +84,26 @@ public: }.attachTo(this); } - void apply() final { m_group.apply(); m_group.writeSettings(ICore::settings()); } + void apply() final; void finish() final { m_group.finish(); } private: AspectContainer &m_group = debuggerSettings()->page1; }; +void CommonOptionsPageWidget::apply() +{ + const DebuggerSettings *s = debuggerSettings(); + const bool originalPostMortem = s->registerForPostMortem->value(); + const bool currentPostMortem = s->registerForPostMortem->volatileValue().toBool(); + // explicitly trigger setValue() to override the setValueSilently() and trigger the registration + if (originalPostMortem != currentPostMortem) + s->registerForPostMortem->setValue(currentPostMortem); + + m_group.apply(); + m_group.writeSettings(ICore::settings()); +} + CommonOptionsPage::CommonOptionsPage() { setId(DEBUGGER_COMMON_SETTINGS_ID); diff --git a/src/plugins/projectexplorer/devicesupport/localprocesslist.cpp b/src/plugins/projectexplorer/devicesupport/localprocesslist.cpp index bab7615f7f..33796e3b12 100644 --- a/src/plugins/projectexplorer/devicesupport/localprocesslist.cpp +++ b/src/plugins/projectexplorer/devicesupport/localprocesslist.cpp @@ -161,7 +161,7 @@ static QMap<qint64, QString> getLocalProcessDataUsingPs(const QString &column) psProcess.start(); if (psProcess.waitForStarted()) { QByteArray output; - if (psProcess.readDataFromProcess(30000, &output, nullptr, false)) { + if (psProcess.readDataFromProcess(30, &output, nullptr, false)) { // Split "457 /Users/foo.app arg1 arg2" const QStringList lines = QString::fromLocal8Bit(output).split(QLatin1Char('\n')); const int lineCount = lines.size(); diff --git a/src/plugins/projectexplorer/sessiondialog.ui b/src/plugins/projectexplorer/sessiondialog.ui index 01720014dc..62e6c2f13a 100644 --- a/src/plugins/projectexplorer/sessiondialog.ui +++ b/src/plugins/projectexplorer/sessiondialog.ui @@ -6,8 +6,8 @@ <rect> <x>0</x> <y>0</y> - <width>373</width> - <height>282</height> + <width>550</width> + <height>400</height> </rect> </property> <property name="windowTitle"> diff --git a/src/plugins/qmldesigner/components/componentcore/theme.h b/src/plugins/qmldesigner/components/componentcore/theme.h index 9f21d8476d..4351f02c82 100644 --- a/src/plugins/qmldesigner/components/componentcore/theme.h +++ b/src/plugins/qmldesigner/components/componentcore/theme.h @@ -134,6 +134,7 @@ public: play, plus, promote, + readOnly, redo, rotationFill, rotationOutline, @@ -145,6 +146,7 @@ public: testIcon, textAlignBottom, textAlignCenter, + textAlignJustified, textAlignLeft, textAlignMiddle, textAlignRight, diff --git a/src/plugins/qmldesigner/components/itemlibrary/itemlibraryassetsmodel.cpp b/src/plugins/qmldesigner/components/itemlibrary/itemlibraryassetsmodel.cpp index 5429264733..1e4fef44d2 100644 --- a/src/plugins/qmldesigner/components/itemlibrary/itemlibraryassetsmodel.cpp +++ b/src/plugins/qmldesigner/components/itemlibrary/itemlibraryassetsmodel.cpp @@ -30,6 +30,9 @@ #include <synchronousimagecache.h> #include <theme.h> #include <hdrimage.h> +#include <designersettings.h> + +#include <coreplugin/icore.h> #include <QDebug> #include <QDir> @@ -39,6 +42,8 @@ #include <QMetaProperty> #include <QPainter> #include <QRawFont> +#include <QMessageBox> +#include <QCheckBox> #include <utils/stylehelper.h> #include <utils/filesystemwatcher.h> @@ -94,6 +99,41 @@ void ItemLibraryAssetsModel::toggleExpandAll(bool expand) endResetModel(); } +void ItemLibraryAssetsModel::removeFile(const QString &filePath) +{ + bool askBeforeDelete = DesignerSettings::getValue( + DesignerSettingsKey::ASK_BEFORE_DELETING_ASSET).toBool(); + bool assetDelete = true; + + if (askBeforeDelete) { + QMessageBox msg(QMessageBox::Question, tr("Confirm Delete File"), + tr("\"%1\" might be in use. Delete anyway?").arg(filePath), + QMessageBox::No | QMessageBox::Yes); + QCheckBox cb; + cb.setText(tr("Do not ask this again")); + msg.setCheckBox(&cb); + int ret = msg.exec(); + + if (ret == QMessageBox::No) + assetDelete = false; + + if (cb.isChecked()) + DesignerSettings::setValue(DesignerSettingsKey::ASK_BEFORE_DELETING_ASSET, false); + } + + if (assetDelete) { + if (!QFile::exists(filePath)) { + QMessageBox::warning(Core::ICore::dialogParent(), + tr("Failed to Locate File"), + tr("Could not find \"%1\".").arg(filePath)); + } else if (!QFile::remove(filePath)) { + QMessageBox::warning(Core::ICore::dialogParent(), + tr("Failed to Delete File"), + tr("Could not delete \"%1\".").arg(filePath)); + } + } +} + const QStringList &ItemLibraryAssetsModel::supportedImageSuffixes() { static QStringList retList; diff --git a/src/plugins/qmldesigner/components/itemlibrary/itemlibraryassetsmodel.h b/src/plugins/qmldesigner/components/itemlibrary/itemlibraryassetsmodel.h index 75c7132df4..641f987fc0 100644 --- a/src/plugins/qmldesigner/components/itemlibrary/itemlibraryassetsmodel.h +++ b/src/plugins/qmldesigner/components/itemlibrary/itemlibraryassetsmodel.h @@ -81,6 +81,7 @@ public: Q_INVOKABLE void toggleExpandAll(bool expand); Q_INVOKABLE DirExpandState getAllExpandedState() const; + Q_INVOKABLE void removeFile(const QString &filePath); private: SynchronousImageCache &m_fontImageCache; diff --git a/src/plugins/qmldesigner/designersettings.cpp b/src/plugins/qmldesigner/designersettings.cpp index 28d25afb6b..f771980766 100644 --- a/src/plugins/qmldesigner/designersettings.cpp +++ b/src/plugins/qmldesigner/designersettings.cpp @@ -81,6 +81,7 @@ void DesignerSettings::fromSettings(QSettings *settings) restoreValue(settings, DesignerSettingsKey::COLOR_PALETTE_FAVORITE, QStringList()); restoreValue(settings, DesignerSettingsKey::ALWAYS_DESIGN_MODE, true); restoreValue(settings, DesignerSettingsKey::DISABLE_ITEM_LIBRARY_UPDATE_TIMER, true); + restoreValue(settings, DesignerSettingsKey::ASK_BEFORE_DELETING_ASSET, true); settings->endGroup(); settings->endGroup(); diff --git a/src/plugins/qmldesigner/designersettings.h b/src/plugins/qmldesigner/designersettings.h index 5fc30ef2a9..9808c878a5 100644 --- a/src/plugins/qmldesigner/designersettings.h +++ b/src/plugins/qmldesigner/designersettings.h @@ -71,6 +71,7 @@ const char COLOR_PALETTE_RECENT[] = "ColorPaletteRecent"; const char COLOR_PALETTE_FAVORITE[] = "ColorPaletteFavorite"; const char ALWAYS_DESIGN_MODE[] = "AlwaysDesignMode"; const char DISABLE_ITEM_LIBRARY_UPDATE_TIMER[] = "DisableItemLibraryUpdateTimer"; +const char ASK_BEFORE_DELETING_ASSET[] = "AskBeforeDeletingAsset"; } class QMLDESIGNERCORE_EXPORT DesignerSettings : public QHash<QByteArray, QVariant> diff --git a/src/plugins/qmldesigner/settingspage.cpp b/src/plugins/qmldesigner/settingspage.cpp index 93a6fd566b..0f9d834472 100644 --- a/src/plugins/qmldesigner/settingspage.cpp +++ b/src/plugins/qmldesigner/settingspage.cpp @@ -178,6 +178,8 @@ DesignerSettings SettingsPageWidget::settings() const m_ui.featureTimelineEditorCheckBox->isChecked()); settings.insert(DesignerSettingsKey::ALWAYS_DESIGN_MODE, m_ui.designerAlwaysDesignModeCheckBox->isChecked()); + settings.insert(DesignerSettingsKey::ASK_BEFORE_DELETING_ASSET, + m_ui.askBeforeDeletingAssetCheckBox->isChecked()); return settings; } @@ -247,6 +249,8 @@ void SettingsPageWidget::setSettings(const DesignerSettings &settings) DesignerSettingsKey::ALWAYS_DESIGN_MODE).toBool()); m_ui.featureTimelineEditorCheckBox->setChecked(settings.value( DesignerSettingsKey::ENABLE_TIMELINEVIEW).toBool()); + m_ui.askBeforeDeletingAssetCheckBox->setChecked(settings.value( + DesignerSettingsKey::ASK_BEFORE_DELETING_ASSET).toBool()); if (settings.value(DesignerSettingsKey::STANDALONE_MODE).toBool()) { m_ui.debugGroupBox->hide(); diff --git a/src/plugins/qmldesigner/settingspage.ui b/src/plugins/qmldesigner/settingspage.ui index b6e5ff2497..eace952540 100644 --- a/src/plugins/qmldesigner/settingspage.ui +++ b/src/plugins/qmldesigner/settingspage.ui @@ -416,6 +416,13 @@ <string>Features</string> </property> <layout class="QGridLayout" name="gridLayout_6"> + <item row="0" column="1"> + <widget class="QCheckBox" name="featureTimelineEditorCheckBox"> + <property name="text"> + <string>Enable Timeline editor</string> + </property> + </widget> + </item> <item row="0" column="0"> <widget class="QCheckBox" name="designerAlwaysDesignModeCheckBox"> <property name="text"> @@ -423,10 +430,10 @@ </property> </widget> </item> - <item row="0" column="1"> - <widget class="QCheckBox" name="featureTimelineEditorCheckBox"> + <item row="1" column="0"> + <widget class="QCheckBox" name="askBeforeDeletingAssetCheckBox"> <property name="text"> - <string>Enable Timeline editor</string> + <string>Ask for confirmation before deleting asset</string> </property> </widget> </item> diff --git a/src/plugins/studiowelcome/examplecheckout.cpp b/src/plugins/studiowelcome/examplecheckout.cpp index 17cc306b36..42344d3527 100644 --- a/src/plugins/studiowelcome/examplecheckout.cpp +++ b/src/plugins/studiowelcome/examplecheckout.cpp @@ -157,6 +157,7 @@ void FileDownloader::start() m_url = reply->url(); start(); } else { + qDebug() << Q_FUNC_INFO << m_url << reply->errorString(); emit downloadFailed(); } } else { diff --git a/src/share/3rdparty/package-manager/auto-setup.cmake b/src/share/3rdparty/package-manager/auto-setup.cmake index e342c32e5f..4320b57d7f 100644 --- a/src/share/3rdparty/package-manager/auto-setup.cmake +++ b/src/share/3rdparty/package-manager/auto-setup.cmake @@ -1,3 +1,8 @@ +# +# Internal Qt Creator variable reference +# +set(__just_reference_QT_QMAKE_EXECUTABLE ${QT_QMAKE_EXECUTABLE}) + if (EXISTS "${CMAKE_SOURCE_DIR}/QtCreatorPackageManager.cmake") include("${CMAKE_SOURCE_DIR}/QtCreatorPackageManager.cmake") endif() diff --git a/src/shared/qbs b/src/shared/qbs -Subproject ea0e25b4ca6adeebe33187e5c12dd254aaa55fe +Subproject 80952f4f23eabcaada0a51e8c9bbf13b72aeb5d |