diff --git a/doc/images/qtcreator-ios-add-kit.png b/doc/images/qtcreator-ios-add-kit.png index fcde8b8c14e..fa3bee62b51 100644 Binary files a/doc/images/qtcreator-ios-add-kit.png and b/doc/images/qtcreator-ios-add-kit.png differ diff --git a/doc/images/qtcreator-project-kits.png b/doc/images/qtcreator-project-kits.png index d8f5a69c4eb..0a3eb9964bc 100644 Binary files a/doc/images/qtcreator-project-kits.png and b/doc/images/qtcreator-project-kits.png differ diff --git a/doc/images/qtcreator-valgrind-callgrind.png b/doc/images/qtcreator-valgrind-callgrind.png index 14781917831..34396a56633 100755 Binary files a/doc/images/qtcreator-valgrind-callgrind.png and b/doc/images/qtcreator-valgrind-callgrind.png differ diff --git a/doc/images/qtcreator-valgrind-memcheck.png b/doc/images/qtcreator-valgrind-memcheck.png index 3054d4ffbe6..8bcbcbc404b 100644 Binary files a/doc/images/qtcreator-valgrind-memcheck.png and b/doc/images/qtcreator-valgrind-memcheck.png differ diff --git a/doc/src/editors/creator-beautifier.qdoc b/doc/src/editors/creator-beautifier.qdoc index 1ac074ce246..308aaf40a80 100644 --- a/doc/src/editors/creator-beautifier.qdoc +++ b/doc/src/editors/creator-beautifier.qdoc @@ -106,24 +106,37 @@ \li In the \uicontrol Options group, select the configuration file that defines the style to use in the source files. If you select several - options, they are applied from top down. + options, they are applied from top down. The available options + depend on the tool. \list \li Select the \uicontrol {Use file defined in project files} option to use the configuration file defined in the qmake DISTFILES variable as the configuration file for the - selected tool. + selected tool. This option is available for Artistic Style + and Uncrustify. \li Select the \uicontrol {Use file in $HOME} option to use the specified file in the user's home directory as the - configuration file for the selected tool. + configuration file for the selected tool. This option is + available for Artistic Style and Uncrustify. + + \li For Clang Format, you can use a predefined style, by + selecting the \uicontrol {Use predefined style} radio + button, and then selecting the style to use from the list of + available styles. + + Select \uicontrol File to load the style configuration from + the \c .clang-format or \c _clang-format file located in the + same directory as the source file or in one of its parent + directories. \li Select the \uicontrol {Use customized style} option, and then \uicontrol Add to define your own style. Define code formatting in the - \uicontrol {Edit Configuration} dialog. It provides syntax + \uicontrol {Add Configuration} dialog. It provides syntax highlighting, auto-completion, and context-sensitive help. For these features, you must have the tool installed. @@ -143,8 +156,7 @@ In addition to the \uicontrol {Format Current File} command, ClangFormat and Uncrustify provide the \uicontrol {Format Selected Text} command. If you - select it when no text is selected, nothing happens. To format the entire - file in this case when using Clang, select the - \uicontrol {Format entire file if no text was selected} check box in the - \uicontrol {Clang Format} options. + select it when no text is selected, the whole file is formatted by default. + To disable this behavior, deselect the + \uicontrol {Format entire file if no text was selected} check box. */ diff --git a/doc/src/projects/creator-projects-settings-overview.qdoc b/doc/src/projects/creator-projects-settings-overview.qdoc index f8a0e38c4eb..bc62575c598 100644 --- a/doc/src/projects/creator-projects-settings-overview.qdoc +++ b/doc/src/projects/creator-projects-settings-overview.qdoc @@ -79,7 +79,7 @@ kit. To import an existing build for the project, select - \uicontrol {Import Existing Build} in the context menu. + \uicontrol {Import Existing Build}. \section1 Specifying Settings diff --git a/share/qtcreator/debugger/dumper.py b/share/qtcreator/debugger/dumper.py index cfeb8f652a8..390be8953df 100644 --- a/share/qtcreator/debugger/dumper.py +++ b/share/qtcreator/debugger/dumper.py @@ -3499,20 +3499,6 @@ class DumperBase: val.type = self.createReferenceType(targetType) return val - def createBitfieldValue(self, targetType, bitsize): - if not isinstance(targetType, self.Type): - error('Expected type in createBitfieldValue(), got %s' - % type(targetType)) - targetTypeId = targetType.typeId - typeId = '%s:%d' % (targetTypeId, bitsize) - tdata = self.TypeData(self) - tdata.name = '%s : %d' % (targetType.name, bitsize) - tdata.typeId = typeId - tdata.code = TypeCodeArray - tdata.ltarget = targetType - self.registerType(typeId, tdata) - return self.Type(self, typeId) - def createPointerType(self, targetType): if not isinstance(targetType, self.Type): error('Expected type in createPointerType(), got %s' diff --git a/share/qtcreator/debugger/lldbbridge.py b/share/qtcreator/debugger/lldbbridge.py index bf3dae2f2db..8bd31a2f68e 100644 --- a/share/qtcreator/debugger/lldbbridge.py +++ b/share/qtcreator/debugger/lldbbridge.py @@ -789,10 +789,9 @@ class Dumper(DumperBase): self.breakOnMain_ = args.get('breakonmain', 0) self.useTerminal_ = args.get('useterminal', 0) self.processArgs_ = args.get('processargs', []) - self.dyldImageSuffix = args.get('dyldimagesuffix', '') - self.dyldLibraryPath = args.get('dyldlibrarypath', '') - self.dyldFrameworkPath = args.get('dyldframeworkpath', '') self.processArgs_ = list(map(lambda x: self.hexdecode(x), self.processArgs_)) + self.environment_ = args.get('environment', []) + self.environment_ = list(map(lambda x: self.hexdecode(x), self.environment_)) self.attachPid_ = args.get('attachpid', 0) self.sysRoot_ = args.get('sysroot', '') self.remoteChannel_ = args.get('remotechannel', '') @@ -883,14 +882,7 @@ class Dumper(DumperBase): else: launchInfo = lldb.SBLaunchInfo(self.processArgs_) launchInfo.SetWorkingDirectory(self.workingDirectory_) - environmentList = [key + '=' + value for key,value in os.environ.items()] - if self.dyldImageSuffix: - environmentList.append('DYLD_IMAGE_SUFFIX=' + self.dyldImageSuffix) - if self.dyldLibraryPath: - environmentList.append('DYLD_LIBRARY_PATH=' + self.dyldLibraryPath) - if self.dyldFrameworkPath: - environmentList.append('DYLD_FRAMEWORK_PATH=' + self.dyldFrameworkPath) - launchInfo.SetEnvironmentEntries(environmentList, False) + launchInfo.SetEnvironmentEntries(self.environment_, False) if self.breakOnMain_: self.createBreakpointAtMain() self.process = self.target.Launch(launchInfo, error) diff --git a/src/plugins/android/androidmanager.cpp b/src/plugins/android/androidmanager.cpp index a137338cbcc..a91a7404aad 100644 --- a/src/plugins/android/androidmanager.cpp +++ b/src/plugins/android/androidmanager.cpp @@ -285,6 +285,8 @@ QString AndroidManager::androidNameForApiLevel(int x) return QLatin1String("Android 6.0"); case 24: return QLatin1String("Android 7.0"); + case 25: + return QLatin1String("Android 7.1"); default: return tr("Unknown Android version. API Level: %1").arg(QString::number(x)); } diff --git a/src/plugins/android/androidrunner.cpp b/src/plugins/android/androidrunner.cpp index f3110db2da6..81bea64acfd 100644 --- a/src/plugins/android/androidrunner.cpp +++ b/src/plugins/android/androidrunner.cpp @@ -668,8 +668,9 @@ void AndroidRunnerWorker::onProcessIdChanged(qint64 pid) logcatReadStandardOutput(); QTC_ASSERT(!m_psIsAlive, /**/); m_psIsAlive.reset(new QProcess); - connect(m_psIsAlive.get(), &QIODevice::readyRead, [this](){ - if (!m_psIsAlive->readAllStandardOutput().simplified().isEmpty()) + m_psIsAlive->setProcessChannelMode(QProcess::MergedChannels); + connect(m_psIsAlive.get(), &QProcess::readyRead, [this](){ + if (!m_psIsAlive->readAll().simplified().isEmpty()) onProcessIdChanged(-1); }); m_psIsAlive->start(m_adb, selector() << QStringLiteral("shell") diff --git a/src/plugins/autotest/qtest/qttesttreeitem.cpp b/src/plugins/autotest/qtest/qttesttreeitem.cpp index 95237cc1a0f..7f62bf60b03 100644 --- a/src/plugins/autotest/qtest/qttesttreeitem.cpp +++ b/src/plugins/autotest/qtest/qttesttreeitem.cpp @@ -268,7 +268,7 @@ bool QtTestTreeItem::modify(const TestParseResult *result) case TestSpecialFunction: return modifyTestFunctionContent(result); case TestDataTag: - return modifyDataTagContent(result->name, result->fileName, result->line, result->line); + return modifyDataTagContent(result->name, result->fileName, result->line, result->column); default: return false; } diff --git a/src/plugins/coreplugin/mainwindow.cpp b/src/plugins/coreplugin/mainwindow.cpp index 308a1ee5783..6d3c24df7b0 100644 --- a/src/plugins/coreplugin/mainwindow.cpp +++ b/src/plugins/coreplugin/mainwindow.cpp @@ -1155,7 +1155,7 @@ void MainWindow::restoreWindowState() QSettings *settings = PluginManager::settings(); settings->beginGroup(QLatin1String(settingsGroup)); if (!restoreGeometry(settings->value(QLatin1String(windowGeometryKey)).toByteArray())) - resize(1008, 700); // size without window decoration + resize(1260, 700); // size without window decoration restoreState(settings->value(QLatin1String(windowStateKey)).toByteArray()); settings->endGroup(); show(); diff --git a/src/plugins/debugger/lldb/lldbengine.cpp b/src/plugins/debugger/lldb/lldbengine.cpp index 00830be482c..1a8593686bd 100644 --- a/src/plugins/debugger/lldb/lldbengine.cpp +++ b/src/plugins/debugger/lldb/lldbengine.cpp @@ -61,6 +61,7 @@ #include #include #include +#include using namespace Core; using namespace Utils; @@ -125,7 +126,10 @@ void LldbEngine::runCommand(const DebuggerCommand &cmd) command.arg("token", tok); QString token = QString::number(tok); QString function = command.function + "(" + command.argsToPython() + ")"; - showMessage(token + function + '\n', LogInput); + QString msg = token + function + '\n'; + if (cmd.flags == LldbEngine::Silent) + msg.replace(QRegularExpression("\"environment\":.[^]]*."), ""); + showMessage(msg, LogInput); m_commandForToken[currentToken()] = command; m_lldbProc.write("script theDumper." + function.toUtf8() + "\n"); } @@ -301,17 +305,6 @@ void LldbEngine::startLldbStage2() void LldbEngine::setupInferior() { - Environment sysEnv = Environment::systemEnvironment(); - Environment runEnv = runParameters().inferior.environment; - foreach (const EnvironmentItem &item, sysEnv.diff(runEnv)) { - DebuggerCommand cmd("executeDebuggerCommand"); - if (item.unset) - cmd.arg("command", "settings remove target.env-vars " + item.name); - else - cmd.arg("command", "settings set target.env-vars '" + item.name + '=' + item.value + '\''); - runCommand(cmd); - } - const QString path = stringSetting(ExtraDumperFile); if (!path.isEmpty() && QFileInfo(path).isReadable()) { DebuggerCommand cmd("addDumperModule"); @@ -345,12 +338,13 @@ void LldbEngine::setupInferior() cmd2.arg("useterminal", rp.useTerminal); cmd2.arg("startmode", rp.startMode); cmd2.arg("nativemixed", isNativeMixedActive()); - - cmd2.arg("dyldimagesuffix", rp.inferior.environment.value("DYLD_IMAGE_SUFFIX")); - cmd2.arg("dyldframeworkpath", rp.inferior.environment.value("DYLD_LIBRARY_PATH")); - cmd2.arg("dyldlibrarypath", rp.inferior.environment.value("DYLD_FRAMEWORK_PATH")); cmd2.arg("workingdirectory", rp.inferior.workingDirectory); + QJsonArray env; + foreach (const QString &item, rp.inferior.environment.toStringList()) + env.append(toHex(item)); + cmd2.arg("environment", env); + QJsonArray processArgs; foreach (const QString &arg, args.toUnixArgs()) processArgs.append(QLatin1String(arg.toUtf8().toHex())); @@ -402,6 +396,8 @@ void LldbEngine::setupInferior() notifyInferiorSetupFailed(); } }; + + cmd2.flags = LldbEngine::Silent; runCommand(cmd2); } diff --git a/src/plugins/debugger/lldb/lldbengine.h b/src/plugins/debugger/lldb/lldbengine.h index c3aca9df412..3cc52f5ea34 100644 --- a/src/plugins/debugger/lldb/lldbengine.h +++ b/src/plugins/debugger/lldb/lldbengine.h @@ -61,6 +61,12 @@ public: explicit LldbEngine(const DebuggerRunParameters &runParameters); ~LldbEngine() override; + enum LldbCommandFlag { + NoFlags = 0, + // Do not echo to log. + Silent = 1 + }; + signals: void outputReady(const QString &data); diff --git a/src/plugins/debugger/watchhandler.cpp b/src/plugins/debugger/watchhandler.cpp index 33a8cc7d58c..b5652e17829 100644 --- a/src/plugins/debugger/watchhandler.cpp +++ b/src/plugins/debugger/watchhandler.cpp @@ -734,10 +734,8 @@ static QString formattedValue(const WatchItem *item) if (!isPointerType(item->type) && !item->isVTablePointer()) { bool ok = false; qulonglong integer = item->value.toULongLong(&ok, 0); - if (ok) { - const int format = itemFormat(item); + if (ok) return reformatInteger(integer, format, item->size, false); - } } if (item->elided) { diff --git a/src/plugins/ios/simulatorcontrol.cpp b/src/plugins/ios/simulatorcontrol.cpp index 4af05f00e3d..e3436d9fb01 100644 --- a/src/plugins/ios/simulatorcontrol.cpp +++ b/src/plugins/ios/simulatorcontrol.cpp @@ -362,6 +362,7 @@ void SimulatorControlPrivate::startSimulator(QFutureInterface #include #include +#include #include #include #include @@ -386,6 +387,17 @@ public: this, &SelectorModel::deregisterProject); connect(sessionManager, &SessionManager::startupProjectChanged, this, &SelectorModel::startupProjectChanged); + + m_importBuild = new QPushButton(ProjectWindow::tr("Import Existing Build...")); + connect(m_importBuild, &QPushButton::clicked, + this, &SelectorModel::handleImportBuild); + connect(sessionManager, &SessionManager::startupProjectChanged, this, [this](Project *project) { + m_importBuild->setEnabled(project && project->projectImporter()); + }); + + m_manageKits = new QPushButton(ProjectWindow::tr("Manage Kits...")); + connect(m_manageKits, &QPushButton::clicked, + this, &SelectorModel::handleManageKits); } void updatePanel() @@ -457,7 +469,6 @@ public: ProjectItem *projectItem = m_projectsModel.rootItem()->childAt(0); Project *project = projectItem ? projectItem->project() : nullptr; - ProjectImporter *projectImporter = project ? project->projectImporter() : nullptr; QModelIndex index = m_selectorTree->indexAt(pos); TreeItem *item = m_projectsModel.itemForIndex(index); @@ -468,49 +479,65 @@ public: menu.addSeparator(); QAction *importBuild = menu.addAction(ProjectWindow::tr("Import Existing Build...")); - importBuild->setEnabled(projectImporter); + importBuild->setEnabled(project && project->projectImporter()); QAction *manageKits = menu.addAction(ProjectWindow::tr("Manage Kits...")); QAction *act = menu.exec(m_selectorTree->mapToGlobal(pos)); - if (project && projectImporter && act == importBuild) { - QString dir = project->projectDirectory().toString(); - QString importDir = QFileDialog::getExistingDirectory(ICore::mainWindow(), - ProjectWindow::tr("Import directory"), - dir); - FileName path = FileName::fromString(importDir); - - const QList toImport = projectImporter->import(path, false); - for (BuildInfo *info : toImport) { - Target *target = project->target(info->kitId); - if (!target) { - target = project->createTarget(KitManager::find(info->kitId)); - if (target) - project->addTarget(target); - } - if (target) { - projectImporter->makePersistent(target->kit()); - BuildConfiguration *bc = info->factory()->create(target, info); - QTC_ASSERT(bc, continue); - target->addBuildConfiguration(bc); - } - } - qDeleteAll(toImport); - } else if (act == manageKits) { - if (KitOptionsPage *page = ExtensionSystem::PluginManager::getObject()) { - if (item) - page->showKit(KitManager::find(Id::fromSetting(item->data(0, KitIdRole)))); - } - ICore::showOptionsDialog(Constants::KITS_SETTINGS_PAGE_ID, ICore::mainWindow()); - }; + if (act == importBuild) + handleImportBuild(); + else if (act == manageKits) + handleManageKits(); } -public: + void handleManageKits() + { + if (ProjectItem *projectItem = m_projectsModel.rootItem()->childAt(0)) { + if (KitOptionsPage *page = ExtensionSystem::PluginManager::getObject()) + page->showKit(KitManager::find(Id::fromSetting(projectItem->data(0, KitIdRole)))); + } + ICore::showOptionsDialog(Constants::KITS_SETTINGS_PAGE_ID, ICore::mainWindow()); + } + + void handleImportBuild() + { + ProjectItem *projectItem = m_projectsModel.rootItem()->childAt(0); + Project *project = projectItem ? projectItem->project() : 0; + ProjectImporter *projectImporter = project ? project->projectImporter() : 0; + QTC_ASSERT(projectImporter, return); + + QString dir = project->projectDirectory().toString(); + QString importDir = QFileDialog::getExistingDirectory(ICore::mainWindow(), + ProjectWindow::tr("Import directory"), + dir); + FileName path = FileName::fromString(importDir); + + const QList toImport = projectImporter->import(path, false); + for (BuildInfo *info : toImport) { + Target *target = project->target(info->kitId); + if (!target) { + target = project->createTarget(KitManager::find(info->kitId)); + if (target) + project->addTarget(target); + } + if (target) { + projectImporter->makePersistent(target->kit()); + BuildConfiguration *bc = info->factory()->create(target, info); + QTC_ASSERT(bc, continue); + target->addBuildConfiguration(bc); + } + } + qDeleteAll(toImport); + } + + std::function m_changeListener; ProjectsModel m_projectsModel; ComboBoxModel m_comboBoxModel; QComboBox *m_projectSelection; SelectorTree *m_selectorTree; + QPushButton *m_importBuild; + QPushButton *m_manageKits; }; // @@ -547,6 +574,9 @@ ProjectWindow::ProjectWindow() auto innerLayout = new QVBoxLayout; innerLayout->setSpacing(10); innerLayout->setContentsMargins(14, innerLayout->spacing(), 14, 0); + innerLayout->addWidget(selectorModel->m_manageKits); + innerLayout->addWidget(selectorModel->m_importBuild); + innerLayout->addSpacerItem(new QSpacerItem(10, 30, QSizePolicy::Maximum, QSizePolicy::Maximum)); innerLayout->addWidget(activeLabel); innerLayout->addWidget(selectorModel->m_projectSelection); innerLayout->addWidget(selectorModel->m_selectorTree); diff --git a/src/plugins/projectexplorer/targetsettingspanel.cpp b/src/plugins/projectexplorer/targetsettingspanel.cpp index c62d9aa60f6..69cec0e85a8 100644 --- a/src/plugins/projectexplorer/targetsettingspanel.cpp +++ b/src/plugins/projectexplorer/targetsettingspanel.cpp @@ -701,7 +701,7 @@ TargetGroupItem::TargetGroupItem(const QString &displayName, Project *project) QObject::connect(project, &Project::removedTarget, d, &TargetGroupItemPrivate::handleTargetRemoved); QObject::connect(project, &Project::activeTargetChanged, - d, &TargetGroupItemPrivate::handleTargetChanged); + d, &TargetGroupItemPrivate::handleTargetChanged, Qt::QueuedConnection); } TargetGroupItem::~TargetGroupItem() diff --git a/src/plugins/qmakeprojectmanager/profilecompletionassist.cpp b/src/plugins/qmakeprojectmanager/profilecompletionassist.cpp index 8594f862801..dea84b50dc3 100644 --- a/src/plugins/qmakeprojectmanager/profilecompletionassist.cpp +++ b/src/plugins/qmakeprojectmanager/profilecompletionassist.cpp @@ -236,13 +236,13 @@ static const char *const variableKeywords[] = { }; static const char *const functionKeywords[] = { + "CONFIG", "absolute_path", "basename", "cache", "cat", "clean_path", "clear", - "CONFIG", "contains", "count", "debug", @@ -252,9 +252,9 @@ static const char *const functionKeywords[] = { "equals", "error", "escape_expand", + "eval", "exists", "export", - "eval", "files", "find", "first", @@ -269,9 +269,9 @@ static const char *const functionKeywords[] = { "isActiveConfig", "isEmpty", "isEqual", - "lessThan", "join", "last", + "lessThan", "list", "load", "log", @@ -283,20 +283,20 @@ static const char *const functionKeywords[] = { "parseJson", "prompt", "quote", + "re_escape", "relative_path", "replace", "requires", "resolve_depends", "reverse", - "re_escape", "section", "shadowed", "shell_path", "shell_quote", "size", + "sort_depends", "split", "sprintf", - "sort_depends", "system", "system_path", "system_quote", @@ -306,8 +306,8 @@ static const char *const functionKeywords[] = { "unset", "upper", "val_escape", - "write_file", "warning", + "write_file", 0 }; diff --git a/src/plugins/qmakeprojectmanager/qmakenodes.cpp b/src/plugins/qmakeprojectmanager/qmakenodes.cpp index cbe8a7445fa..d86f2a0b2bf 100644 --- a/src/plugins/qmakeprojectmanager/qmakenodes.cpp +++ b/src/plugins/qmakeprojectmanager/qmakenodes.cpp @@ -73,6 +73,7 @@ #include #include #include +#include #include #include @@ -1203,7 +1204,8 @@ QPair QmakePriFileNode::readProFile(const QString &file) QmakeProject::proFileParseError(reader.errorString()); return qMakePair(includeFile, lines); } - contents = QString::fromLocal8Bit(reader.data()); + const QTextCodec *codec = Core::EditorManager::defaultTextCodec(); + contents = codec->toUnicode(reader.data()); lines = contents.split(QLatin1Char('\n')); } @@ -1321,7 +1323,8 @@ void QmakePriFileNode::save(const QStringList &lines) { FileChangeBlocker changeGuard(m_projectFilePath.toString()); FileSaver saver(m_projectFilePath.toString(), QIODevice::Text); - saver.write(lines.join(QLatin1Char('\n')).toLocal8Bit()); + const QTextCodec *codec = Core::EditorManager::defaultTextCodec(); + saver.write(codec->fromUnicode(lines.join(QLatin1Char('\n')))); saver.finalize(Core::ICore::mainWindow()); } diff --git a/src/plugins/qmljseditor/qmljshoverhandler.cpp b/src/plugins/qmljseditor/qmljshoverhandler.cpp index c83caef54d7..a767d6713ba 100644 --- a/src/plugins/qmljseditor/qmljshoverhandler.cpp +++ b/src/plugins/qmljseditor/qmljshoverhandler.cpp @@ -29,6 +29,7 @@ #include "qmljseditordocument.h" #include "qmlexpressionundercursor.h" +#include #include #include #include @@ -49,6 +50,8 @@ #include #include #include +#include +#include using namespace Core; using namespace QmlJS; @@ -143,30 +146,57 @@ bool QmlJSHoverHandler::setQmlTypeHelp(const ScopeChain &scopeChain, const Docum const ObjectValue *value, const QStringList &qName) { QString moduleName = getModuleName(scopeChain, qmlDocument, value); + + QMap urlMap; + QString helpId; do { QStringList helpIdPieces(qName); helpIdPieces.prepend(moduleName); helpIdPieces.prepend(QLatin1String("QML")); helpId = helpIdPieces.join(QLatin1Char('.')); - if (!HelpManager::linksForIdentifier(helpId).isEmpty()) + urlMap = HelpManager::linksForIdentifier(helpId); + if (!urlMap.isEmpty()) break; if (helpIdPieces.size() > 3) { QString lm = helpIdPieces.value(2); helpIdPieces.removeAt(2); helpId = helpIdPieces.join(QLatin1Char('.')); - if (!HelpManager::linksForIdentifier(helpId).isEmpty()) + urlMap = HelpManager::linksForIdentifier(helpId); + if (!urlMap.isEmpty()) break; helpIdPieces.replace(1, lm); - if (!HelpManager::linksForIdentifier(helpId).isEmpty()) + urlMap = HelpManager::linksForIdentifier(helpId); + if (!urlMap.isEmpty()) break; } helpIdPieces.removeAt(1); helpId = helpIdPieces.join(QLatin1Char('.')); - if (!HelpManager::linksForIdentifier(helpId).isEmpty()) + urlMap = HelpManager::linksForIdentifier(helpId); + if (!urlMap.isEmpty()) break; return false; } while (0); + + // Check if the module name contains a major version. + QRegularExpression version("^([^\\d]*)(\\d+)\\.*\\d*$"); + QRegularExpressionMatch m = version.match(moduleName); + if (m.hasMatch()) { + QMap filteredUrlMap; + QStringRef maj = m.capturedRef(2); + for (auto x = urlMap.begin(); x != urlMap.end(); ++x) { + QString urlModuleName = x.value().path().split('/')[1]; + if (urlModuleName.contains(maj)) + filteredUrlMap.insert(x.key(), x.value()); + } + if (!filteredUrlMap.isEmpty()) { + // Use the url as helpId, to disambiguate different versions + helpId = filteredUrlMap.first().toString(); + const HelpItem helpItem(helpId, qName.join(QLatin1Char('.')), HelpItem::QmlComponent, filteredUrlMap); + setLastHelpItemIdentified(helpItem); + return true; + } + } setLastHelpItemIdentified(HelpItem(helpId, qName.join(QLatin1Char('.')), HelpItem::QmlComponent)); return true; } diff --git a/src/plugins/texteditor/fontsettings.cpp b/src/plugins/texteditor/fontsettings.cpp index e0017a4e896..c0abf4c24b3 100644 --- a/src/plugins/texteditor/fontsettings.cpp +++ b/src/plugins/texteditor/fontsettings.cpp @@ -233,10 +233,6 @@ void FontSettings::addMixinStyle(QTextCharFormat &textCharFormat, textCharFormat.setBackground(mixBrush(textCharFormat.background(), format.relativeBackgroundSaturation(), format.relativeBackgroundLightness())); - } else { - textCharFormat.setBackground(mixBrush(m_scheme.formatFor(C_TEXT).background(), - format.relativeBackgroundSaturation(), - format.relativeBackgroundLightness())); } if (!textCharFormat.fontItalic()) diff --git a/src/shared/qbs b/src/shared/qbs index 0971e0b7453..64e336b7af5 160000 --- a/src/shared/qbs +++ b/src/shared/qbs @@ -1 +1 @@ -Subproject commit 0971e0b7453439f01c72551870d8a2a140758593 +Subproject commit 64e336b7af5b863de7e8108448f9103706786714 diff --git a/src/tools/iostool/main.cpp b/src/tools/iostool/main.cpp index a02fb446e32..83bba027b3c 100644 --- a/src/tools/iostool/main.cpp +++ b/src/tools/iostool/main.cpp @@ -103,7 +103,7 @@ class RelayServer: public QObject public: RelayServer(IosTool *parent); ~RelayServer(); - bool startServer(int port); + bool startServer(); void stopServer(); quint16 serverPort(); IosTool *iosTool(); @@ -115,6 +115,7 @@ protected: QTcpServer m_ipv4Server; QTcpServer m_ipv6Server; + quint16 m_port = 0; QList m_connections; }; @@ -404,20 +405,23 @@ RelayServer::~RelayServer() stopServer(); } -bool RelayServer::startServer(int port) +bool RelayServer::startServer() { QTC_CHECK(!m_ipv4Server.isListening()); QTC_CHECK(!m_ipv6Server.isListening()); + connect(&m_ipv4Server, &QTcpServer::newConnection, this, &RelayServer::handleNewRelayConnection); connect(&m_ipv6Server, &QTcpServer::newConnection, this, &RelayServer::handleNewRelayConnection); - quint16 portValue = static_cast(port); - if (port < 0 || port > 0xFFFF) - return false; - m_ipv4Server.listen(QHostAddress(QHostAddress::LocalHostIPv6), portValue); - m_ipv6Server.listen(QHostAddress(QHostAddress::LocalHost), portValue); - return m_ipv4Server.isListening() || m_ipv6Server.isListening(); + + m_port = 0; + if (m_ipv4Server.listen(QHostAddress(QHostAddress::LocalHost), 0)) + m_port = m_ipv4Server.serverPort(); + if (m_ipv6Server.listen(QHostAddress(QHostAddress::LocalHostIPv6), m_port)) + m_port = m_ipv6Server.serverPort(); + + return m_port > 0; } void RelayServer::stopServer() @@ -432,11 +436,7 @@ void RelayServer::stopServer() quint16 RelayServer::serverPort() { - if (m_ipv4Server.isListening()) - return m_ipv4Server.serverPort(); - if (m_ipv6Server.isListening()) - return m_ipv6Server.serverPort(); - return 0; + return m_port; } IosTool *RelayServer::iosTool() @@ -728,12 +728,12 @@ void IosTool::didStartApp(const QString &bundlePath, const QString &deviceId, int qmlPort = deviceSession->qmljsDebugPort(); if (qmlPort) { qmlServer = new GenericRelayServer(this, qmlPort, deviceSession); - qmlServer->startServer(0); + qmlServer->startServer(); } } if (debug) { gdbServer = new SingleRelayServer(this, gdbFd); - if (!gdbServer->startServer(0)) { + if (!gdbServer->startServer()) { doExit(-4); return; } diff --git a/tests/auto/debugger/tst_dumpers.cpp b/tests/auto/debugger/tst_dumpers.cpp index 48e10ce52d6..2c8359ebc88 100644 --- a/tests/auto/debugger/tst_dumpers.cpp +++ b/tests/auto/debugger/tst_dumpers.cpp @@ -5278,6 +5278,20 @@ void tst_Dumpers::dumper_data() + Check("p.a", "0", "int") + Check("p.b", "2", "int"); + QTest::newRow("This") + << Data("struct Foo {\n" + " Foo() : x(143) {}\n" + " int foo() {\n" + " BREAK;\n" + " return x;\n" + " }\n\n" + " int x;\n" + "};\n", + "Foo f;\n" + "f.foo();\n") + + + Check("this", "", "Foo") + + Check("this.x", "143", "int"); QTest::newRow("Union") << Data("union U { int a; int b; };", "U u;\n" diff --git a/tests/unit/unittest/clangsupportivetranslationunitinitializertest.cpp b/tests/unit/unittest/clangsupportivetranslationunitinitializertest.cpp index dcb970e4100..3c75c20c6f6 100644 --- a/tests/unit/unittest/clangsupportivetranslationunitinitializertest.cpp +++ b/tests/unit/unittest/clangsupportivetranslationunitinitializertest.cpp @@ -122,14 +122,14 @@ protected: protected: Data d; - Utf8String &filePath{d.filePath}; - Utf8String &projectPartId{d.projectPartId}; + Utf8String &filePath = d.filePath; + Utf8String &projectPartId = d.projectPartId; - ProjectParts projects{d.projects}; - Document &document{d.document}; - Documents &documents{d.documents}; - Jobs &jobs{d.jobs}; - ClangBackEnd::SupportiveTranslationUnitInitializer &initializer{*d.initializer}; + ProjectParts projects = d.projects; + Document &document = d.document; + Documents &documents = d.documents; + Jobs &jobs = d.jobs; + ClangBackEnd::SupportiveTranslationUnitInitializer &initializer = *d.initializer; }; TEST_F(SupportiveTranslationUnitInitializer, HasInitiallyNotInitializedState)