diff --git a/doc/qtcreator/images/qtcreator-external-tools.png b/doc/qtcreator/images/qtcreator-external-tools.png index 8caa35a2371..31b325b1809 100644 Binary files a/doc/qtcreator/images/qtcreator-external-tools.png and b/doc/qtcreator/images/qtcreator-external-tools.png differ diff --git a/doc/qtcreator/images/qtquick-rtf-editor.png b/doc/qtcreator/images/qtquick-rtf-editor.png new file mode 100644 index 00000000000..07ebbe46ca1 Binary files /dev/null and b/doc/qtcreator/images/qtquick-rtf-editor.png differ diff --git a/doc/qtcreator/images/qtquick-text-rtf.gif b/doc/qtcreator/images/qtquick-text-rtf.gif new file mode 100644 index 00000000000..1748662e7f0 Binary files /dev/null and b/doc/qtcreator/images/qtquick-text-rtf.gif differ diff --git a/doc/qtcreator/src/howto/creator-external-tools.qdoc b/doc/qtcreator/src/howto/creator-external-tools.qdoc index 986f371005a..9032cf7df41 100644 --- a/doc/qtcreator/src/howto/creator-external-tools.qdoc +++ b/doc/qtcreator/src/howto/creator-external-tools.qdoc @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2019 The Qt Company Ltd. +** Copyright (C) 2021 The Qt Company Ltd. ** Contact: https://www.qt.io/licensing/ ** ** This file is part of the Qt Creator documentation. @@ -70,7 +70,7 @@ By default, the project .pro file is passed to the tools as an argument. To specify other command line arguments for the tools, select \uicontrol Tools > - \uicontrol External > \uicontrol Configure}. + \uicontrol External > \uicontrol Configure. To open TS files in Qt Linguist, right-click a TS file in the \uicontrol Projects or \uicontrol {File System} view and select @@ -106,6 +106,11 @@ \image qtcreator-external-tools.png + Select the \inlineimage replace.png + (\uicontrol {Variables}) button in a field to select from a list of + \l{Using Qt Creator Variables}{variables} that are available in a + particular context. + To configure external tools: \list 1 diff --git a/doc/qtcreator/src/qtquick/library/qtquick-text.qdoc b/doc/qtcreator/src/qtquick/library/qtquick-text.qdoc index 63b612ad300..a495375c1ab 100644 --- a/doc/qtcreator/src/qtquick/library/qtquick-text.qdoc +++ b/doc/qtcreator/src/qtquick/library/qtquick-text.qdoc @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2020 The Qt Company Ltd. +** Copyright (C) 2021 The Qt Company Ltd. ** Contact: https://www.qt.io/licensing/ ** ** This file is part of the Qt Creator documentation. @@ -47,6 +47,30 @@ To create a label with a background, use the \l Label type from the Qt Quick Controls module. + \section1 Using Rich Text + + You can use rich text in the \l Text and \l TextInput components. To + open the rich text editor, select the \inlineimage icons/edit.png + (\uicontrol Edit) button next to the \uicontrol Text field in + \uicontrol Properties. + + \image qtquick-text-rtf.gif "Editing text in the rich text editor" + + In the rich text editor, you can: + + \list + \li Emphasize text + \li Create hyperlinks + \li Align text + \li Create bulleted and numbered lists + \li Specify text color + \li Select text font + \li Set font size + \li Create tables + \endlist + + \image qtquick-rtf-editor.png "Text formatted as rich text in the editor" + \section1 Typography For each string that you enter in the \uicontrol Text field, you can diff --git a/share/qtcreator/debugger/stdtypes.py b/share/qtcreator/debugger/stdtypes.py index 41bdc4ec76f..3a8c443ac00 100644 --- a/share/qtcreator/debugger/stdtypes.py +++ b/share/qtcreator/debugger/stdtypes.py @@ -242,7 +242,11 @@ def qdump__std__list(d, value): def qdump__std__list__QNX(d, value): - (proxy, head, size) = value.split("ppp") + try: + _ = value["_Mypair"]["_Myval2"]["_Myproxy"] + (proxy, head, size) = value.split("ppp") + except Exception: + (head, size) = value.split("pp") d.putItemCount(size, 1000) if d.isExpanded(): @@ -330,7 +334,11 @@ def qdump__std__map(d, value): def qdump_std__map__helper(d, value): - (proxy, head, size) = value.split("ppp") + try: + _ = value["_Mypair"]["_Myval2"]["_Myval2"]["_Myproxy"] + (proxy, head, size) = value.split("ppp") + except Exception: + (head, size) = value.split("pp") d.check(0 <= size and size <= 100 * 1000 * 1000) d.putItemCount(size) if d.isExpanded(): @@ -505,7 +513,11 @@ def qdump__std__set(d, value): def qdump__std__set__QNX(d, value): - (proxy, head, size) = value.split("ppp") + try: + _ = value["_Mypair"]["_Myval2"]["_Myval2"]["_Myproxy"] + (proxy, head, size) = value.split("ppp") + except Exception: + (head, size) = value.split("pp") d.check(0 <= size and size <= 100 * 1000 * 1000) d.putItemCount(size) if d.isExpanded(): @@ -744,12 +756,12 @@ def qdumpHelper__std__string__QNX(d, value, charType, format): def qdumpHelper__std__string__MSVC(d, value, charType, format): try: + _ = value["_Mypair"]["_Myval2"]["_Myproxy"] (proxy, buffer, size, alloc) = value.split("p16spp") - d.check(0 <= size and size <= alloc and alloc <= 100 * 1000 * 1000) - except RuntimeError: + except Exception: proxy = None (buffer, size, alloc) = value.split("16spp") - d.check(0 <= size and size <= alloc and alloc <= 100 * 1000 * 1000) + d.check(0 <= size and size <= alloc and alloc <= 100 * 1000 * 1000) _BUF_SIZE = int(16 / charType.size()) if _BUF_SIZE <= alloc: if proxy is None: @@ -1128,21 +1140,21 @@ def qdumpHelper__std__vector__libcxx(d, value): def qdumpHelper__std__vector__msvc(d, value): inner_type = value.type[0] if inner_type.name == "bool": - proxy1, proxy2, start, finish, alloc, size = value.split("pppppi") try: - d.check(0 <= size and size <= 1000 * 1000 * 1000) - d.check(finish <= alloc) + _ = value["_Myproxy"] + proxy1, proxy2, start, finish, alloc, size = value.split("pppppi") except RuntimeError: start, finish, alloc, size = value.split("pppi") + d.check(0 <= size and size <= 1000 * 1000 * 1000) qdumpHelper__std__vector__bool(d, start, size, inner_type) else: - proxy, start, finish, alloc = value.split("pppp") - size = (finish - start) // inner_type.size() try: - d.check(0 <= size and size <= 1000 * 1000 * 1000) - d.check(finish <= alloc) + _ = value["_Mypair"]["_Myval2"]["_Myproxy"] + proxy, start, finish, alloc = value.split("pppp") except RuntimeError: start, finish, alloc = value.split("ppp") + size = (finish - start) // inner_type.size() + d.check(0 <= size and size <= 1000 * 1000 * 1000) qdumpHelper__std__vector__nonbool(d, start, finish, alloc, inner_type) diff --git a/src/libs/ssh/sftptransfer.cpp b/src/libs/ssh/sftptransfer.cpp index 02391943348..3f674ed2eb9 100644 --- a/src/libs/ssh/sftptransfer.cpp +++ b/src/libs/ssh/sftptransfer.cpp @@ -154,7 +154,7 @@ void SftpTransfer::doStart() batchFile.write("-mkdir " + QtcProcess::quoteArgUnix(dir).toLocal8Bit() + '\n'); break; case Internal::FileTransferType::Download: - if (!QDir::root().mkdir(dir)) { + if (!QDir::root().mkpath(dir)) { emitError(tr("Failed to create local directory \"%1\".") .arg(QDir::toNativeSeparators(dir))); return; @@ -163,7 +163,7 @@ void SftpTransfer::doStart() } } for (const FileToTransfer &f : d->files) { - QString sourceFileOrLinkTarget; + QString sourceFileOrLinkTarget = f.sourceFile; bool link = false; if (d->transferType == Internal::FileTransferType::Upload) { QFileInfo fi(f.sourceFile); @@ -172,8 +172,6 @@ void SftpTransfer::doStart() batchFile.write("-rm " + QtcProcess::quoteArgUnix(f.targetFile).toLocal8Bit() + '\n'); sourceFileOrLinkTarget = fi.dir().relativeFilePath(fi.symLinkTarget()); // see QTBUG-5817. - } else { - sourceFileOrLinkTarget = f.sourceFile; } } batchFile.write(d->transferCommand(link) + ' ' diff --git a/src/libs/utils/outputformatter.cpp b/src/libs/utils/outputformatter.cpp index c03cfd15b63..875ba0ebecf 100644 --- a/src/libs/utils/outputformatter.cpp +++ b/src/libs/utils/outputformatter.cpp @@ -329,7 +329,9 @@ OutputLineParser::Result OutputFormatter::handleMessage(const QString &text, Out QList &involvedParsers) { // We only invoke the line parsers for stdout and stderr - if (format != StdOutFormat && format != StdErrFormat) + // Bad: on Windows we may get stdout and stdErr only as DebugFormat as e.g. GUI applications + // print them Windows-internal and we retrieve this separately + if (format != StdOutFormat && format != StdErrFormat && format != DebugFormat) return OutputLineParser::Status::NotHandled; const OutputLineParser * const oldNextParser = d->nextParser; if (d->nextParser) { diff --git a/src/plugins/projectexplorer/projecttreewidget.cpp b/src/plugins/projectexplorer/projecttreewidget.cpp index 96ff5006ee2..2ee230f58d5 100644 --- a/src/plugins/projectexplorer/projecttreewidget.cpp +++ b/src/plugins/projectexplorer/projecttreewidget.cpp @@ -498,6 +498,7 @@ void ProjectTreeWidget::setCurrentItem(Node *node) } } else { m_view->clearSelection(); + m_view->setCurrentIndex({}); } } diff --git a/src/plugins/qmldesigner/components/debugview/debugview.cpp b/src/plugins/qmldesigner/components/debugview/debugview.cpp index 159bdfaebb2..a51283bb543 100644 --- a/src/plugins/qmldesigner/components/debugview/debugview.cpp +++ b/src/plugins/qmldesigner/components/debugview/debugview.cpp @@ -235,6 +235,11 @@ void DebugView::selectedNodesChanged(const QList &selectedNodes /*sel message << lineBreak; + for (const SignalHandlerProperty &property : selectedNode.signalProperties()) + message << property << lineBreak; + + message << lineBreak; + if (selectedNode.metaInfo().isValid()) { for (const NodeMetaInfo &metaInfo : selectedNode.metaInfo().classHierarchy()) message << metaInfo.typeName() << lineBreak; diff --git a/src/plugins/qtsupport/profilereader.cpp b/src/plugins/qtsupport/profilereader.cpp index b35ea5d5ce4..cdc77c2d9b8 100644 --- a/src/plugins/qtsupport/profilereader.cpp +++ b/src/plugins/qtsupport/profilereader.cpp @@ -34,6 +34,16 @@ using namespace ProjectExplorer; using namespace QtSupport; +static QString format(const QString &fileName, int lineNo, const QString &msg) +{ + if (lineNo > 0) + return QString::fromLatin1("%1(%2): %3").arg(fileName, QString::number(lineNo), msg); + else if (!fileName.isEmpty()) + return QString::fromLatin1("%1: %2").arg(fileName, msg); + else + return msg; +} + ProMessageHandler::ProMessageHandler(bool verbose, bool exact) : m_verbose(verbose) , m_exact(exact) @@ -54,8 +64,12 @@ void ProMessageHandler::message(int type, const QString &msg, const QString &fil { if ((type & CategoryMask) == ErrorMessage && ((type & SourceMask) == SourceParser || m_verbose)) { // parse error in qmake files - TaskHub::addTask( - BuildSystemTask(Task::Error, msg, Utils::FilePath::fromString(fileName), lineNo)); + if (m_exact) { + TaskHub::addTask( + BuildSystemTask(Task::Error, msg, Utils::FilePath::fromString(fileName), lineNo)); + } else { + appendMessage(format(fileName, lineNo, msg)); + } } } @@ -64,9 +78,9 @@ void ProMessageHandler::fileMessage(int type, const QString &msg) // message(), warning() or error() calls in qmake files if (!m_verbose) return; - if (type == QMakeHandler::ErrorMessage) + if (m_exact && type == QMakeHandler::ErrorMessage) TaskHub::addTask(BuildSystemTask(Task::Error, msg)); - else if (type == QMakeHandler::WarningMessage) + else if (m_exact && type == QMakeHandler::WarningMessage) TaskHub::addTask(BuildSystemTask(Task::Warning, msg)); else appendMessage(msg); diff --git a/src/plugins/qtsupport/qttestparser.cpp b/src/plugins/qtsupport/qttestparser.cpp index 827cdffa47f..e2bb435ad92 100644 --- a/src/plugins/qtsupport/qttestparser.cpp +++ b/src/plugins/qtsupport/qttestparser.cpp @@ -49,7 +49,7 @@ namespace Internal { OutputLineParser::Result QtTestParser::handleLine(const QString &line, OutputFormat type) { - if (type != StdOutFormat) + if (type != StdOutFormat && type != DebugFormat) return Status::NotHandled; const QString theLine = rightTrimmed(line); diff --git a/src/plugins/texteditor/texteditor.cpp b/src/plugins/texteditor/texteditor.cpp index 9e74d09eac3..b4149370211 100644 --- a/src/plugins/texteditor/texteditor.cpp +++ b/src/plugins/texteditor/texteditor.cpp @@ -3682,7 +3682,7 @@ void TextEditorWidgetPrivate::highlightSearchResults(const QTextBlock &block, co .toTextCharFormat(C_SEARCH_RESULT).background().color().darker(120); while (idx < text.length()) { - const QRegularExpressionMatch match = m_searchExpr.match(text, idx + 1); + const QRegularExpressionMatch match = m_searchExpr.match(text, idx + l + 1); if (!match.hasMatch()) break; idx = match.capturedStart(); diff --git a/src/shared/qbs b/src/shared/qbs index 8621465db2c..01a8b6e1198 160000 --- a/src/shared/qbs +++ b/src/shared/qbs @@ -1 +1 @@ -Subproject commit 8621465db2c7fa10eb014ef14d55ec7dd3e085a0 +Subproject commit 01a8b6e11986a3260e911e6a95a0d85d17467c49 diff --git a/src/tools/qml2puppet/CMakeLists.txt b/src/tools/qml2puppet/CMakeLists.txt index fde52312769..1f59c5322a0 100644 --- a/src/tools/qml2puppet/CMakeLists.txt +++ b/src/tools/qml2puppet/CMakeLists.txt @@ -197,3 +197,13 @@ extend_qtc_executable(qml2puppet designersupportdelegate.h qmlprivategate_56.cpp qmlprivategate.h ) + +if(DEFINED MULTILANGUAGE_SUPPORT_SUBDIRECTORY) + add_subdirectory(${MULTILANGUAGE_SUPPORT_SUBDIRECTORY} multilanguagesupport_static_build) +endif() + +extend_qtc_executable(qml2puppet + CONDITION TARGET QtCreator::multilanguage-support + DEPENDS QtCreator::multilanguage-support + FEATURE_INFO "multilanguage-support in qml2puppet" +) diff --git a/tests/auto/ssh/tst_ssh.cpp b/tests/auto/ssh/tst_ssh.cpp index 743b4280116..6552be12272 100644 --- a/tests/auto/ssh/tst_ssh.cpp +++ b/tests/auto/ssh/tst_ssh.cpp @@ -28,6 +28,7 @@ #include #include #include +#include #include #include @@ -371,12 +372,15 @@ void tst_Ssh::sftp() // Create and upload 1000 small files and one big file QTemporaryDir dirForFilesToUpload; QTemporaryDir dirForFilesToDownload; + QTemporaryDir dir2ForFilesToDownload; QVERIFY2(dirForFilesToUpload.isValid(), qPrintable(dirForFilesToUpload.errorString())); QVERIFY2(dirForFilesToDownload.isValid(), qPrintable(dirForFilesToDownload.errorString())); + QVERIFY2(dir2ForFilesToDownload.isValid(), qPrintable(dirForFilesToDownload.errorString())); static const auto getRemoteFilePath = [](const QString &localFileName) { return QString("/tmp/").append(localFileName).append(".upload"); }; - const auto getDownloadFilePath = [&dirForFilesToDownload](const QString &localFileName) { + const auto getDownloadFilePath = [](const QTemporaryDir &dirForFilesToDownload, + const QString &localFileName) { return QString(dirForFilesToDownload.path()).append('/').append(localFileName); }; FilesToTransfer filesToUpload; @@ -464,7 +468,7 @@ void tst_Ssh::sftp() for (const QString &fileName : allUploadedFileNames) { const QString localFilePath = dirForFilesToUpload.path() + '/' + fileName; const QString remoteFilePath = getRemoteFilePath(fileName); - const QString downloadFilePath = getDownloadFilePath(fileName); + const QString downloadFilePath = getDownloadFilePath(dirForFilesToDownload, fileName); const SftpJobId downloadJob = sftpChannel->downloadFile(remoteFilePath, downloadFilePath); QVERIFY(downloadJob != SftpInvalidJob); jobs << downloadJob; @@ -477,24 +481,55 @@ void tst_Ssh::sftp() QVERIFY(jobs.empty()); // Compare contents of uploaded and downloaded files - for (const QString &fileName : allUploadedFileNames) { - QFile originalFile(dirForFilesToUpload.path() + '/' + fileName); - QVERIFY2(originalFile.open(QIODevice::ReadOnly), qPrintable(originalFile.errorString())); - QFile downloadedFile(dirForFilesToDownload.path() + '/' + fileName); - QVERIFY2(downloadedFile.open(QIODevice::ReadOnly), - qPrintable(downloadedFile.errorString())); - QVERIFY(originalFile.fileName() != downloadedFile.fileName()); - QCOMPARE(originalFile.size(), downloadedFile.size()); - qint64 bytesLeft = originalFile.size(); - while (bytesLeft > 0) { - const qint64 bytesToRead = qMin(bytesLeft, Q_INT64_C(1024 * 1024)); - const QByteArray origBlock = originalFile.read(bytesToRead); - const QByteArray copyBlock = downloadedFile.read(bytesToRead); - QCOMPARE(origBlock.size(), bytesToRead); - QCOMPARE(origBlock, copyBlock); - bytesLeft -= bytesToRead; + bool success; + const auto compareFiles = [&](const QTemporaryDir &downloadDir) { + success = false; + for (const QString &fileName : allUploadedFileNames) { + QFile originalFile(dirForFilesToUpload.path() + '/' + fileName); + QVERIFY2(originalFile.open(QIODevice::ReadOnly), qPrintable(originalFile.errorString())); + QFile downloadedFile(getDownloadFilePath(downloadDir, fileName)); + QVERIFY2(downloadedFile.open(QIODevice::ReadOnly), + qPrintable(downloadedFile.errorString())); + QVERIFY(originalFile.fileName() != downloadedFile.fileName()); + QCOMPARE(originalFile.size(), downloadedFile.size()); + qint64 bytesLeft = originalFile.size(); + while (bytesLeft > 0) { + const qint64 bytesToRead = qMin(bytesLeft, Q_INT64_C(1024 * 1024)); + const QByteArray origBlock = originalFile.read(bytesToRead); + const QByteArray copyBlock = downloadedFile.read(bytesToRead); + QCOMPARE(origBlock.size(), bytesToRead); + QCOMPARE(origBlock, copyBlock); + bytesLeft -= bytesToRead; + } } - } + success = true; + }; + compareFiles(dirForFilesToDownload); + QVERIFY(success); + + // The same again, with a non-interactive download. + FilesToTransfer filesToDownload = Utils::transform(filesToUpload, [&](const FileToTransfer &fileToUpload) { + return FileToTransfer(fileToUpload.targetFile, + getDownloadFilePath(dir2ForFilesToDownload, + QFileInfo(fileToUpload.sourceFile).fileName())); + }); + const SftpTransferPtr download = connection.createDownload(filesToDownload, + FileTransferErrorHandling::Abort); + connect(download.get(), &SftpTransfer::done, [&jobError, &loop](const QString &error) { + jobError = error; + loop.quit(); + }); + QObject::connect(&timer, &QTimer::timeout, &loop, &QEventLoop::quit); + timer.setSingleShot(true); + timer.setInterval(30 * 1000); + timer.start(); + download->start(); + loop.exec(); + QVERIFY(timer.isActive()); + timer.stop(); + QVERIFY2(jobError.isEmpty(), qPrintable(jobError)); + compareFiles(dir2ForFilesToDownload); + QVERIFY(success); // Remove the uploaded files on the remote system timer.setInterval((params.timeout + 5) * 1000);