diff options
Diffstat (limited to 'src/plugins/qtsupport')
38 files changed, 954 insertions, 862 deletions
diff --git a/src/plugins/qtsupport/CMakeLists.txt b/src/plugins/qtsupport/CMakeLists.txt new file mode 100644 index 0000000000..125e949b35 --- /dev/null +++ b/src/plugins/qtsupport/CMakeLists.txt @@ -0,0 +1,35 @@ +add_qtc_plugin(QtSupport + DEPENDS Qt5::Xml + PUBLIC_DEPENDS ProParser + PLUGIN_DEPENDS Core CppTools ProjectExplorer ResourceEditor + SOURCES + baseqtversion.cpp baseqtversion.h + codegenerator.cpp codegenerator.h + codegensettings.cpp codegensettings.h + codegensettingspage.cpp codegensettingspage.h + codegensettingspagewidget.ui + desktopqtversion.cpp desktopqtversion.h + exampleslistmodel.cpp exampleslistmodel.h + gettingstartedwelcomepage.cpp gettingstartedwelcomepage.h + profilereader.cpp profilereader.h + qmldumptool.cpp qmldumptool.h + qscxmlcgenerator.cpp qscxmlcgenerator.h + qtconfigwidget.cpp qtconfigwidget.h + qtcppkitinfo.cpp qtcppkitinfo.h + qtkitinformation.cpp qtkitinformation.h + qtoptionspage.cpp qtoptionspage.h + qtoutputformatter.cpp qtoutputformatter.h + qtparser.cpp qtparser.h + qtprojectimporter.cpp qtprojectimporter.h + qtsupport.qrc + qtsupport_global.h + qtsupportconstants.h + qtsupportplugin.cpp qtsupportplugin.h + qttestparser.cpp qttestparser.h + qtversionfactory.cpp qtversionfactory.h + qtversioninfo.ui + qtversionmanager.cpp qtversionmanager.h qtversionmanager.ui + screenshotcropper.cpp screenshotcropper.h + showbuildlog.ui + uicgenerator.cpp uicgenerator.h +) diff --git a/src/plugins/qtsupport/baseqtversion.cpp b/src/plugins/qtsupport/baseqtversion.cpp index 4f58331d49..2dd4160a3b 100644 --- a/src/plugins/qtsupport/baseqtversion.cpp +++ b/src/plugins/qtsupport/baseqtversion.cpp @@ -28,8 +28,10 @@ #include "qmldumptool.h" #include "qtkitinformation.h" +#include "qtversionfactory.h" #include "qtversionmanager.h" #include "profilereader.h" + #include <coreplugin/icore.h> #include <coreplugin/progressmanager/progressmanager.h> #include <proparser/qmakevfs.h> @@ -193,18 +195,19 @@ bool QtVersionNumber::operator >=(const QtVersionNumber &b) const // BaseQtVersion /////////////// -BaseQtVersion::BaseQtVersion(const FileName &qmakeCommand, bool isAutodetected, const QString &autodetectionSource) - : m_id(QtVersionManager::getUniqueId()), - m_isAutodetected(isAutodetected), - m_autodetectionSource(autodetectionSource), - m_qmakeCommand(qmakeCommand) -{ } -BaseQtVersion::BaseQtVersion(const BaseQtVersion &other) = default; BaseQtVersion::BaseQtVersion() = default; BaseQtVersion::~BaseQtVersion() = default; -QString BaseQtVersion::defaultUnexpandedDisplayName(const FileName &qmakePath, bool fromPath) +void BaseQtVersion::setupQmakePathAndId(const FilePath &qmakeCommand) +{ + m_id = QtVersionManager::getUniqueId(); + QTC_CHECK(m_qmakeCommand.isEmpty()); // Should only be used once. + m_qmakeCommand = qmakeCommand; + setUnexpandedDisplayName(defaultUnexpandedDisplayName(m_qmakeCommand, false)); +} + +QString BaseQtVersion::defaultUnexpandedDisplayName(const FilePath &qmakePath, bool fromPath) { QString location; if (qmakePath.isEmpty()) { @@ -349,34 +352,34 @@ QSet<Id> BaseQtVersion::availableFeatures() const return features; } -QList<Task> BaseQtVersion::validateKit(const Kit *k) +Tasks BaseQtVersion::validateKit(const Kit *k) { - QList<Task> result; + Tasks result; - BaseQtVersion *version = QtKitInformation::qtVersion(k); + BaseQtVersion *version = QtKitAspect::qtVersion(k); Q_ASSERT(version == this); - const QList<Abi> qtAbis = version->qtAbis(); + const Abis qtAbis = version->qtAbis(); if (qtAbis.isEmpty()) // No need to test if Qt does not know anyway... return result; - const Id dt = DeviceTypeKitInformation::deviceTypeId(k); + const Id dt = DeviceTypeKitAspect::deviceTypeId(k); const QSet<Id> tdt = targetDeviceTypes(); if (!tdt.isEmpty() && !tdt.contains(dt)) { result << Task(Task::Warning, QCoreApplication::translate("BaseQtVersion", "Device type is not supported by Qt version."), - FileName(), -1, ProjectExplorer::Constants::TASK_CATEGORY_BUILDSYSTEM); + FilePath(), -1, ProjectExplorer::Constants::TASK_CATEGORY_BUILDSYSTEM); } - ToolChain *tc = ToolChainKitInformation::toolChain(k, ProjectExplorer::Constants::CXX_LANGUAGE_ID); + ToolChain *tc = ToolChainKitAspect::toolChain(k, ProjectExplorer::Constants::CXX_LANGUAGE_ID); if (tc) { Abi targetAbi = tc->targetAbi(); bool fuzzyMatch = false; bool fullMatch = false; QString qtAbiString; - foreach (const Abi &qtAbi, qtAbis) { + for (const Abi &qtAbi : qtAbis) { if (!qtAbiString.isEmpty()) qtAbiString.append(' '); qtAbiString.append(qtAbi.toString()); @@ -397,73 +400,76 @@ QList<Task> BaseQtVersion::validateKit(const Kit *k) "The compiler \"%1\" (%2) may not produce code compatible with the Qt version \"%3\" (%4)."); message = message.arg(tc->displayName(), targetAbi.toString(), version->displayName(), qtAbiString); - result << Task(fuzzyMatch ? Task::Warning : Task::Error, message, FileName(), -1, + result << Task(fuzzyMatch ? Task::Warning : Task::Error, message, FilePath(), -1, ProjectExplorer::Constants::TASK_CATEGORY_BUILDSYSTEM); } + } else if (ToolChainKitAspect::toolChain(k, ProjectExplorer::Constants::C_LANGUAGE_ID)) { + const QString message = QCoreApplication::translate("BaseQtVersion", + "The kit has a Qt version, but no C++ compiler."); + result << Task(Task::Warning, message, FilePath(), -1, + ProjectExplorer::Constants::TASK_CATEGORY_BUILDSYSTEM); } return result; } -FileName BaseQtVersion::headerPath() const +FilePath BaseQtVersion::headerPath() const { - return FileName::fromUserInput(qmakeProperty("QT_INSTALL_HEADERS")); + return FilePath::fromUserInput(qmakeProperty("QT_INSTALL_HEADERS")); } -FileName BaseQtVersion::docsPath() const +FilePath BaseQtVersion::docsPath() const { - return FileName::fromUserInput(qmakeProperty("QT_INSTALL_DOCS")); + return FilePath::fromUserInput(qmakeProperty("QT_INSTALL_DOCS")); } -FileName BaseQtVersion::libraryPath() const +FilePath BaseQtVersion::libraryPath() const { - return FileName::fromUserInput(qmakeProperty("QT_INSTALL_LIBS")); + return FilePath::fromUserInput(qmakeProperty("QT_INSTALL_LIBS")); } -FileName BaseQtVersion::pluginPath() const +FilePath BaseQtVersion::pluginPath() const { - return FileName::fromUserInput(qmakeProperty("QT_INSTALL_PLUGINS")); + return FilePath::fromUserInput(qmakeProperty("QT_INSTALL_PLUGINS")); } -FileName BaseQtVersion::qmlPath() const +FilePath BaseQtVersion::qmlPath() const { - return FileName::fromUserInput(qmakeProperty("QT_INSTALL_QML")); + return FilePath::fromUserInput(qmakeProperty("QT_INSTALL_QML")); } -FileName BaseQtVersion::binPath() const +FilePath BaseQtVersion::binPath() const { - return FileName::fromUserInput(qmakeProperty("QT_HOST_BINS")); + return FilePath::fromUserInput(qmakeProperty("QT_HOST_BINS")); } -FileName BaseQtVersion::mkspecsPath() const +FilePath BaseQtVersion::mkspecsPath() const { - FileName result = FileName::fromUserInput(qmakeProperty("QT_HOST_DATA")); + const FilePath result = FilePath::fromUserInput(qmakeProperty("QT_HOST_DATA")); if (result.isEmpty()) - result = FileName::fromUserInput(qmakeProperty("QMAKE_MKSPECS")); - else - result.appendPath("mkspecs"); - return result; + return FilePath::fromUserInput(qmakeProperty("QMAKE_MKSPECS")); + return result.pathAppended("mkspecs"); } -FileName BaseQtVersion::qmlBinPath() const +FilePath BaseQtVersion::qmlBinPath() const { - return FileName::fromUserInput(m_mkspecValues.value("QT.qml.bins")); + return FilePath::fromUserInput(m_mkspecValues.value("QT.qml.bins")); } -FileName BaseQtVersion::librarySearchPath() const +FilePath BaseQtVersion::librarySearchPath() const { return HostOsInfo::isWindowsHost() - ? FileName::fromUserInput(qmakeProperty("QT_INSTALL_BINS")) : libraryPath(); + ? FilePath::fromUserInput(qmakeProperty("QT_INSTALL_BINS")) : libraryPath(); } -FileNameList BaseQtVersion::directoriesToIgnoreInProjectTree() const +FilePathList BaseQtVersion::directoriesToIgnoreInProjectTree() const { - FileNameList result; - const FileName mkspecPathGet = mkspecsPath(); + FilePathList result; + const FilePath mkspecPathGet = mkspecsPath(); result.append(mkspecPathGet); - FileName mkspecPathSrc = FileName::fromUserInput(qmakeProperty("QT_HOST_DATA", PropertyVariantSrc)); + FilePath mkspecPathSrc = FilePath::fromUserInput(qmakeProperty("QT_HOST_DATA", PropertyVariantSrc)); if (!mkspecPathSrc.isEmpty()) { - mkspecPathSrc.appendPath("mkspecs"); + mkspecPathSrc = mkspecPathSrc.pathAppended("mkspecs"); if (mkspecPathSrc != mkspecPathGet) result.append(mkspecPathSrc); } @@ -504,6 +510,11 @@ void BaseQtVersion::setId(int id) m_id = id; } +void BaseQtVersion::setIsAutodetected(bool isAutodetected) +{ + m_isAutodetected = isAutodetected; +} + void BaseQtVersion::fromMap(const QVariantMap &map) { m_id = map.value(Constants::QTVERSIONID).toInt(); @@ -518,12 +529,12 @@ void BaseQtVersion::fromMap(const QVariantMap &map) if (string.startsWith('~')) string.remove(0, 1).prepend(QDir::homePath()); - m_qtSources = Utils::FileName::fromUserInput( + m_qtSources = Utils::FilePath::fromUserInput( map.value(QTVERSIONSOURCEPATH).toString()); // Handle ABIs provided by the SDKTool: // Note: Creator does not write these settings itself, so it has to come from the SDKTool! - m_qtAbis = Utils::transform(map.value(QTVERSION_ABIS, QStringList()).toStringList(), &Abi::fromString); + m_qtAbis = Utils::transform<Abis>(map.value(QTVERSION_ABIS).toStringList(), &Abi::fromString); m_qtAbis = Utils::filtered(m_qtAbis, &Abi::isValid); m_hasQtAbis = !m_qtAbis.isEmpty(); @@ -535,7 +546,7 @@ void BaseQtVersion::fromMap(const QVariantMap &map) string = BuildableHelperLibrary::qtChooserToQmakePath(fi.symLinkTarget()); } - m_qmakeCommand = Utils::FileName::fromString(string); + m_qmakeCommand = Utils::FilePath::fromString(string); } QVariantMap BaseQtVersion::toMap() const @@ -604,12 +615,12 @@ QStringList BaseQtVersion::warningReason() const return ret; } -FileName BaseQtVersion::qmakeCommand() const +FilePath BaseQtVersion::qmakeCommand() const { return m_qmakeCommand; } -QList<Abi> BaseQtVersion::qtAbis() const +Abis BaseQtVersion::qtAbis() const { if (!m_hasQtAbis) { m_qtAbis = detectQtAbis(); @@ -618,6 +629,11 @@ QList<Abi> BaseQtVersion::qtAbis() const return m_qtAbis; } +Abis BaseQtVersion::detectQtAbis() const +{ + return qtAbisFromLibrary(qtCorePaths()); +} + bool BaseQtVersion::equals(BaseQtVersion *other) { if (m_qmakeCommand != other->m_qmakeCommand) @@ -639,6 +655,12 @@ int BaseQtVersion::uniqueId() const return m_id; } +QString BaseQtVersion::type() const +{ + QTC_ASSERT(m_factory, return QString()); + return m_factory->supportedType(); +} + bool BaseQtVersion::isAutodetected() const { return m_isAutodetected; @@ -683,7 +705,7 @@ QString BaseQtVersion::toHtml(bool verbose) const } else { str << "<tr><td><b>" << QCoreApplication::translate("BaseQtVersion", "ABI:") << "</b></td>"; - const QList<Abi> abis = qtAbis(); + const Abis abis = qtAbis(); if (abis.isEmpty()) { str << "<td>" << Abi().toString() << "</td></tr>"; } else { @@ -696,7 +718,7 @@ QString BaseQtVersion::toHtml(bool verbose) const str << "<tr><td><b>" << QCoreApplication::translate("BaseQtVersion", "Source:") << "</b></td><td>" << sourcePath().toUserOutput() << "</td></tr>"; str << "<tr><td><b>" << QCoreApplication::translate("BaseQtVersion", "mkspec:") - << "</b></td><td>" << mkspec().toUserOutput() << "</td></tr>"; + << "</b></td><td>" << QDir::toNativeSeparators(mkspec()) << "</td></tr>"; str << "<tr><td><b>" << QCoreApplication::translate("BaseQtVersion", "qmake:") << "</b></td><td>" << m_qmakeCommand.toUserOutput() << "</td></tr>"; ensureMkSpecParsed(); @@ -750,21 +772,16 @@ QString BaseQtVersion::toHtml(bool verbose) const return rc; } -void BaseQtVersion::updateSourcePath() const +FilePath BaseQtVersion::sourcePath() const { - if (!m_sourcePath.isEmpty()) - return; - updateVersionInfo(); - m_sourcePath = sourcePath(m_versionInfo); -} - -FileName BaseQtVersion::sourcePath() const -{ - updateSourcePath(); + if (m_sourcePath.isEmpty()) { + updateVersionInfo(); + m_sourcePath = sourcePath(m_versionInfo); + } return m_sourcePath; } -FileName BaseQtVersion::qtPackageSourcePath() const +FilePath BaseQtVersion::qtPackageSourcePath() const { return m_qtSources; } @@ -881,13 +898,13 @@ void BaseQtVersion::updateMkspec() const if (m_mkspecFullPath.isEmpty()) return; - FileName baseMkspecDir = mkspecDirectoryFromVersionInfo(versionInfo()); + FilePath baseMkspecDir = mkspecDirectoryFromVersionInfo(versionInfo()); if (m_mkspec.isChildOf(baseMkspecDir)) { m_mkspec = m_mkspec.relativeChildPath(baseMkspecDir); // qDebug() << "Setting mkspec to"<<mkspec; } else { - FileName sourceMkSpecPath = sourcePath().appendPath("mkspecs"); + const FilePath sourceMkSpecPath = sourcePath().pathAppended("mkspecs"); if (m_mkspec.isChildOf(sourceMkSpecPath)) { m_mkspec = m_mkspec.relativeChildPath(sourceMkSpecPath); } else { @@ -948,22 +965,23 @@ void BaseQtVersion::parseMkSpec(ProFileEvaluator *evaluator) const m_mkspecValues.insert(ns, evaluator->value(ns)); } -FileName BaseQtVersion::mkspec() const +QString BaseQtVersion::mkspec() const { updateMkspec(); - return m_mkspec; + return m_mkspec.toString(); } -FileName BaseQtVersion::mkspecFor(ToolChain *tc) const +QString BaseQtVersion::mkspecFor(ToolChain *tc) const { - FileName versionSpec = mkspec(); + QString versionSpec = mkspec(); if (!tc) return versionSpec; - const FileNameList tcSpecList = tc->suggestedMkspecList(); + const QStringList tcSpecList = tc->suggestedMkspecList(); if (tcSpecList.contains(versionSpec)) return versionSpec; - foreach (const FileName &tcSpec, tcSpecList) { + + for (const QString &tcSpec : tcSpecList) { if (hasMkspec(tcSpec)) return tcSpec; } @@ -971,24 +989,24 @@ FileName BaseQtVersion::mkspecFor(ToolChain *tc) const return versionSpec; } -FileName BaseQtVersion::mkspecPath() const +FilePath BaseQtVersion::mkspecPath() const { updateMkspec(); return m_mkspecFullPath; } -bool BaseQtVersion::hasMkspec(const FileName &spec) const +bool BaseQtVersion::hasMkspec(const QString &spec) const { if (spec.isEmpty()) return true; // default spec of a Qt version QDir mkspecDir = QDir(QDir::fromNativeSeparators(qmakeProperty("QT_HOST_DATA")) + "/mkspecs/"); - const QString absSpec = mkspecDir.absoluteFilePath(spec.toString()); + const QString absSpec = mkspecDir.absoluteFilePath(spec); if (QFileInfo(absSpec).isDir() && QFileInfo(absSpec + "/qmake.conf").isFile()) return true; mkspecDir.setPath(sourcePath().toString() + "/mkspecs/"); - const QString absSrcSpec = mkspecDir.absoluteFilePath(spec.toString()); + const QString absSrcSpec = mkspecDir.absoluteFilePath(spec); return absSrcSpec != absSpec && QFileInfo(absSrcSpec).isDir() && QFileInfo(absSrcSpec + "/qmake.conf").isFile(); @@ -1181,151 +1199,151 @@ BaseQtVersion::createMacroExpander(const std::function<const BaseQtVersion *()> }; }; std::unique_ptr<Utils::MacroExpander> expander(new Utils::MacroExpander); - expander->setDisplayName(QtKitInformation::tr("Qt version")); + expander->setDisplayName(QtKitAspect::tr("Qt version")); expander->registerVariable( "Qt:Version", - QtKitInformation::tr("The version string of the current Qt version."), + QtKitAspect::tr("The version string of the current Qt version."), versionProperty([](const BaseQtVersion *version) { return version->qtVersionString(); })); expander->registerVariable( "Qt:Type", - QtKitInformation::tr("The type of the current Qt version."), + QtKitAspect::tr("The type of the current Qt version."), versionProperty([](const BaseQtVersion *version) { return version->type(); })); expander->registerVariable( "Qt:Mkspec", - QtKitInformation::tr("The mkspec of the current Qt version."), + QtKitAspect::tr("The mkspec of the current Qt version."), versionProperty([](const BaseQtVersion *version) { - return version->mkspec().toUserOutput(); + return QDir::toNativeSeparators(version->mkspec()); })); expander->registerVariable( "Qt:QT_INSTALL_PREFIX", - QtKitInformation::tr("The installation prefix of the current Qt version."), + QtKitAspect::tr("The installation prefix of the current Qt version."), versionProperty([](const BaseQtVersion *version) { return version->qmakeProperty(version->m_versionInfo, "QT_INSTALL_PREFIX"); })); expander->registerVariable( "Qt:QT_INSTALL_DATA", - QtKitInformation::tr("The installation location of the current Qt version's data."), + QtKitAspect::tr("The installation location of the current Qt version's data."), versionProperty([](const BaseQtVersion *version) { return version->qmakeProperty(version->m_versionInfo, "QT_INSTALL_DATA"); })); expander->registerVariable( "Qt:QT_INSTALL_HEADERS", - QtKitInformation::tr("The installation location of the current Qt version's header files."), + QtKitAspect::tr("The installation location of the current Qt version's header files."), versionProperty([](const BaseQtVersion *version) { return version->qmakeProperty(version->m_versionInfo, "QT_INSTALL_HEADERS"); })); expander->registerVariable( "Qt:QT_INSTALL_LIBS", - QtKitInformation::tr("The installation location of the current Qt version's library files."), + QtKitAspect::tr("The installation location of the current Qt version's library files."), versionProperty([](const BaseQtVersion *version) { return version->qmakeProperty(version->m_versionInfo, "QT_INSTALL_LIBS"); })); expander->registerVariable( "Qt:QT_INSTALL_DOCS", - QtKitInformation::tr("The installation location of the current Qt version's documentation files."), + QtKitAspect::tr("The installation location of the current Qt version's documentation files."), versionProperty([](const BaseQtVersion *version) { return version->qmakeProperty(version->m_versionInfo, "QT_INSTALL_DOCS"); })); expander->registerVariable( "Qt:QT_INSTALL_BINS", - QtKitInformation::tr("The installation location of the current Qt version's executable files."), + QtKitAspect::tr("The installation location of the current Qt version's executable files."), versionProperty([](const BaseQtVersion *version) { return version->qmakeProperty(version->m_versionInfo, "QT_INSTALL_BINS"); })); expander->registerVariable( "Qt:QT_INSTALL_PLUGINS", - QtKitInformation::tr("The installation location of the current Qt version's plugins."), + QtKitAspect::tr("The installation location of the current Qt version's plugins."), versionProperty([](const BaseQtVersion *version) { return version->qmakeProperty(version->m_versionInfo, "QT_INSTALL_PLUGINS"); })); expander->registerVariable( "Qt:QT_INSTALL_QML", - QtKitInformation::tr("The installation location of the current Qt version's QML files."), + QtKitAspect::tr("The installation location of the current Qt version's QML files."), versionProperty([](const BaseQtVersion *version) { return version->qmakeProperty(version->m_versionInfo, "QT_INSTALL_QML"); })); expander->registerVariable( "Qt:QT_INSTALL_IMPORTS", - QtKitInformation::tr("The installation location of the current Qt version's imports."), + QtKitAspect::tr("The installation location of the current Qt version's imports."), versionProperty([](const BaseQtVersion *version) { return version->qmakeProperty(version->m_versionInfo, "QT_INSTALL_IMPORTS"); })); expander->registerVariable( "Qt:QT_INSTALL_TRANSLATIONS", - QtKitInformation::tr("The installation location of the current Qt version's translation files."), + QtKitAspect::tr("The installation location of the current Qt version's translation files."), versionProperty([](const BaseQtVersion *version) { return version->qmakeProperty(version->m_versionInfo, "QT_INSTALL_TRANSLATIONS"); })); expander->registerVariable( "Qt:QT_INSTALL_CONFIGURATION", - QtKitInformation::tr("The installation location of the current Qt version's translation files."), + QtKitAspect::tr("The installation location of the current Qt version's translation files."), versionProperty([](const BaseQtVersion *version) { return version->qmakeProperty(version->m_versionInfo, "QT_INSTALL_CONFIGURATION"); })); expander->registerVariable( "Qt:QT_INSTALL_EXAMPLES", - QtKitInformation::tr("The installation location of the current Qt version's examples."), + QtKitAspect::tr("The installation location of the current Qt version's examples."), versionProperty([](const BaseQtVersion *version) { return version->qmakeProperty(version->m_versionInfo, "QT_INSTALL_EXAMPLES"); })); expander->registerVariable( "Qt:QT_INSTALL_DEMOS", - QtKitInformation::tr("The installation location of the current Qt version's demos."), + QtKitAspect::tr("The installation location of the current Qt version's demos."), versionProperty([](const BaseQtVersion *version) { return version->qmakeProperty(version->m_versionInfo, "QT_INSTALL_DEMOS"); })); expander->registerVariable( "Qt:QMAKE_MKSPECS", - QtKitInformation::tr("The current Qt version's default mkspecs (Qt 4)."), + QtKitAspect::tr("The current Qt version's default mkspecs (Qt 4)."), versionProperty([](const BaseQtVersion *version) { return version->qmakeProperty(version->m_versionInfo, "QMAKE_MKSPECS"); })); expander->registerVariable( "Qt:QMAKE_SPEC", - QtKitInformation::tr("The current Qt version's default mkspec (Qt 5; host system)."), + QtKitAspect::tr("The current Qt version's default mkspec (Qt 5; host system)."), versionProperty([](const BaseQtVersion *version) { return version->qmakeProperty(version->m_versionInfo, "QMAKE_SPEC"); })); expander->registerVariable( "Qt:QMAKE_XSPEC", - QtKitInformation::tr("The current Qt version's default mkspec (Qt 5; target system)."), + QtKitAspect::tr("The current Qt version's default mkspec (Qt 5; target system)."), versionProperty([](const BaseQtVersion *version) { return version->qmakeProperty(version->m_versionInfo, "QMAKE_XSPEC"); })); expander->registerVariable( "Qt:QMAKE_VERSION", - QtKitInformation::tr("The current Qt's qmake version."), + QtKitAspect::tr("The current Qt's qmake version."), versionProperty([](const BaseQtVersion *version) { return version->qmakeProperty(version->m_versionInfo, "QMAKE_VERSION"); })); // FIXME: Re-enable once we can detect expansion loops. // expander->registerVariable("Qt:Name", - // QtKitInformation::tr("The display name of the current Qt version."), + // QtKitAspect::tr("The display name of the current Qt version."), // versionProperty([](BaseQtVersion *version) { // return version->displayName(); // })); @@ -1346,8 +1364,8 @@ void BaseQtVersion::populateQmlFileFinder(FileInProjectFinder *finder, const Tar const QList<ProjectExplorer::Project *> projects = ProjectExplorer::SessionManager::projects(); QTC_CHECK(projects.isEmpty() || startupProject); - Utils::FileName projectDirectory; - Utils::FileNameList sourceFiles; + Utils::FilePath projectDirectory; + Utils::FilePathList sourceFiles; // Sort files from startupProject to the front of the list ... if (startupProject) { @@ -1368,11 +1386,11 @@ void BaseQtVersion::populateQmlFileFinder(FileInProjectFinder *finder, const Tar // ... and find the sysroot and qml directory if we have any target at all. const ProjectExplorer::Kit *kit = target ? target->kit() : nullptr; - const Utils::FileName activeSysroot = ProjectExplorer::SysRootKitInformation::sysRoot(kit); + const Utils::FilePath activeSysroot = ProjectExplorer::SysRootKitAspect::sysRoot(kit); const QtSupport::BaseQtVersion *qtVersion = QtVersionManager::isLoaded() - ? QtSupport::QtKitInformation::qtVersion(kit) : nullptr; - Utils::FileNameList additionalSearchDirectories = qtVersion - ? Utils::FileNameList({qtVersion->qmlPath()}) : Utils::FileNameList(); + ? QtSupport::QtKitAspect::qtVersion(kit) : nullptr; + Utils::FilePathList additionalSearchDirectories = qtVersion + ? Utils::FilePathList({qtVersion->qmlPath()}) : Utils::FilePathList(); if (target) { for (const ProjectExplorer::DeployableFile &file : target->deploymentData().allFiles()) @@ -1449,16 +1467,16 @@ void BaseQtVersion::recheckDumper() m_versionInfoUpToDate = false; } -QList<Task> BaseQtVersion::reportIssuesImpl(const QString &proFile, const QString &buildDir) const +Tasks BaseQtVersion::reportIssuesImpl(const QString &proFile, const QString &buildDir) const { Q_UNUSED(proFile); Q_UNUSED(buildDir); - QList<Task> results; + Tasks results; if (!isValid()) { //: %1: Reason for being invalid const QString msg = QCoreApplication::translate("QmakeProjectManager::QtVersion", "The Qt version is invalid: %1").arg(invalidReason()); - results.append(Task(Task::Error, msg, FileName(), -1, + results.append(Task(Task::Error, msg, FilePath(), -1, ProjectExplorer::Constants::TASK_CATEGORY_BUILDSYSTEM)); } @@ -1468,16 +1486,16 @@ QList<Task> BaseQtVersion::reportIssuesImpl(const QString &proFile, const QStrin //: %1: Path to qmake executable const QString msg = QCoreApplication::translate("QmakeProjectManager::QtVersion", "The qmake command \"%1\" was not found or is not executable.").arg(qmakeCommand().toUserOutput()); - results.append(Task(Task::Error, msg, FileName(), -1, + results.append(Task(Task::Error, msg, FilePath(), -1, ProjectExplorer::Constants::TASK_CATEGORY_BUILDSYSTEM)); } return results; } -QList<Task> BaseQtVersion::reportIssues(const QString &proFile, const QString &buildDir) const +Tasks BaseQtVersion::reportIssues(const QString &proFile, const QString &buildDir) const { - QList<Task> results = reportIssuesImpl(proFile, buildDir); + Tasks results = reportIssuesImpl(proFile, buildDir); Utils::sort(results); return results; } @@ -1487,7 +1505,7 @@ QtConfigWidget *BaseQtVersion::createConfigurationWidget() const return nullptr; } -static QByteArray runQmakeQuery(const FileName &binary, const Environment &env, +static QByteArray runQmakeQuery(const FilePath &binary, const Environment &env, QString *error) { QTC_ASSERT(error, return QByteArray()); @@ -1519,7 +1537,7 @@ static QByteArray runQmakeQuery(const FileName &binary, const Environment &env, return process.readAllStandardOutput(); } -bool BaseQtVersion::queryQMakeVariables(const FileName &binary, const Environment &env, +bool BaseQtVersion::queryQMakeVariables(const FilePath &binary, const Environment &env, QHash<ProKey, ProString> *versionInfo, QString *error) { QString tmp; @@ -1541,7 +1559,7 @@ bool BaseQtVersion::queryQMakeVariables(const FileName &binary, const Environmen // Try running qmake with all kinds of tool chains set up in the environment. // This is required to make non-static qmakes work on windows where every tool chain // tries to be incompatible with any other. - QList<Abi> abiList = Abi::abisOfBinary(binary); + Abis abiList = Abi::abisOfBinary(binary); const QList<ToolChain *> tcList = ToolChainManager::toolChains([&abiList](const ToolChain *t) { return abiList.contains(t->targetAbi()); }); for (ToolChain *tc : tcList) { @@ -1561,19 +1579,19 @@ bool BaseQtVersion::queryQMakeVariables(const FileName &binary, const Environmen return true; } -FileName BaseQtVersion::mkspecDirectoryFromVersionInfo(const QHash<ProKey, ProString> &versionInfo) +FilePath BaseQtVersion::mkspecDirectoryFromVersionInfo(const QHash<ProKey, ProString> &versionInfo) { QString dataDir = qmakeProperty(versionInfo, "QT_HOST_DATA", PropertyVariantSrc); if (dataDir.isEmpty()) - return FileName(); - return FileName::fromUserInput(dataDir + "/mkspecs"); + return FilePath(); + return FilePath::fromUserInput(dataDir + "/mkspecs"); } -FileName BaseQtVersion::mkspecFromVersionInfo(const QHash<ProKey, ProString> &versionInfo) +FilePath BaseQtVersion::mkspecFromVersionInfo(const QHash<ProKey, ProString> &versionInfo) { - FileName baseMkspecDir = mkspecDirectoryFromVersionInfo(versionInfo); + FilePath baseMkspecDir = mkspecDirectoryFromVersionInfo(versionInfo); if (baseMkspecDir.isEmpty()) - return FileName(); + return FilePath(); bool qt5 = false; QString theSpec = qmakeProperty(versionInfo, "QMAKE_XSPEC"); @@ -1582,8 +1600,7 @@ FileName BaseQtVersion::mkspecFromVersionInfo(const QHash<ProKey, ProString> &ve else qt5 = true; - FileName mkspecFullPath = baseMkspecDir; - mkspecFullPath.appendPath(theSpec); + FilePath mkspecFullPath = baseMkspecDir.pathAppended(theSpec); // qDebug() << "default mkspec is located at" << mkspecFullPath; @@ -1608,7 +1625,7 @@ FileName BaseQtVersion::mkspecFromVersionInfo(const QHash<ProKey, ProString> &ve // We sometimes get a mix of different slash styles here... possibleFullPath = possibleFullPath.replace('\\', '/'); if (QFileInfo::exists(possibleFullPath)) // Only if the path exists - mkspecFullPath = FileName::fromUserInput(possibleFullPath); + mkspecFullPath = FilePath::fromUserInput(possibleFullPath); } break; } @@ -1629,7 +1646,7 @@ FileName BaseQtVersion::mkspecFromVersionInfo(const QHash<ProKey, ProString> &ve if (value.contains("XCODE")) { // we don't want to generate xcode projects... // qDebug() << "default mkspec is xcode, falling back to g++"; - return baseMkspecDir.appendPath("macx-g++"); + return baseMkspecDir.pathAppended("macx-g++"); } } break; @@ -1642,18 +1659,18 @@ FileName BaseQtVersion::mkspecFromVersionInfo(const QHash<ProKey, ProString> &ve //resolve mkspec link QString rspec = mkspecFullPath.toFileInfo().symLinkTarget(); if (!rspec.isEmpty()) - mkspecFullPath = FileName::fromUserInput( + mkspecFullPath = FilePath::fromUserInput( QDir(baseMkspecDir.toString()).absoluteFilePath(rspec)); } } return mkspecFullPath; } -FileName BaseQtVersion::sourcePath(const QHash<ProKey, ProString> &versionInfo) +FilePath BaseQtVersion::sourcePath(const QHash<ProKey, ProString> &versionInfo) { const QString qt5Source = qmakeProperty(versionInfo, "QT_INSTALL_PREFIX/src"); if (!qt5Source.isEmpty()) - return Utils::FileName::fromString(QFileInfo(qt5Source).canonicalFilePath()); + return Utils::FilePath::fromString(QFileInfo(qt5Source).canonicalFilePath()); const QString installData = qmakeProperty(versionInfo, "QT_INSTALL_PREFIX"); QString sourcePath = installData; @@ -1672,12 +1689,12 @@ FileName BaseQtVersion::sourcePath(const QHash<ProKey, ProString> &versionInfo) } } } - return FileName::fromUserInput(QFileInfo(sourcePath).canonicalFilePath()); + return FilePath::fromUserInput(QFileInfo(sourcePath).canonicalFilePath()); } -bool BaseQtVersion::isInSourceDirectory(const Utils::FileName &filePath) +bool BaseQtVersion::isInSourceDirectory(const Utils::FilePath &filePath) { - const Utils::FileName &source = sourcePath(); + const Utils::FilePath &source = sourcePath(); if (source.isEmpty()) return false; QDir dir = QDir(source.toString()); @@ -1686,9 +1703,9 @@ bool BaseQtVersion::isInSourceDirectory(const Utils::FileName &filePath) return filePath.isChildOf(dir); } -bool BaseQtVersion::isSubProject(const Utils::FileName &filePath) const +bool BaseQtVersion::isSubProject(const Utils::FilePath &filePath) const { - const Utils::FileName &source = sourcePath(); + const Utils::FilePath &source = sourcePath(); if (!source.isEmpty()) { QDir dir = QDir(source.toString()); if (dir.dirName() == "qtbase") @@ -1712,7 +1729,7 @@ bool BaseQtVersion::isSubProject(const Utils::FileName &filePath) const bool BaseQtVersion::isQmlDebuggingSupported(Kit *k, QString *reason) { QTC_ASSERT(k, return false); - BaseQtVersion *version = QtKitInformation::qtVersion(k); + BaseQtVersion *version = QtKitAspect::qtVersion(k); if (!version) { if (reason) *reason = QCoreApplication::translate("BaseQtVersion", "No Qt version."); @@ -1741,7 +1758,7 @@ bool BaseQtVersion::isQmlDebuggingSupported(QString *reason) const bool BaseQtVersion::isQtQuickCompilerSupported(Kit *k, QString *reason) { QTC_ASSERT(k, return false); - BaseQtVersion *version = QtKitInformation::qtVersion(k); + BaseQtVersion *version = QtKitAspect::qtVersion(k); if (!version) { if (reason) *reason = QCoreApplication::translate("BaseQtVersion", "No Qt version."); @@ -1774,7 +1791,7 @@ bool BaseQtVersion::isQtQuickCompilerSupported(QString *reason) const return true; } -FileNameList BaseQtVersion::qtCorePaths() const +FilePathList BaseQtVersion::qtCorePaths() const { updateVersionInfo(); const QString &versionString = m_qtVersionString; @@ -1792,28 +1809,28 @@ FileNameList BaseQtVersion::qtCorePaths() const result += QDir(installBinDir).entryInfoList(filters); return result; }(); - FileNameList staticLibs; - FileNameList dynamicLibs; + FilePathList staticLibs; + FilePathList dynamicLibs; for (const QFileInfo &info : entryInfoList) { const QString file = info.fileName(); if (info.isDir() && file.startsWith("QtCore") && file.endsWith(".framework")) { // handle Framework - FileName lib(info); - dynamicLibs.append(lib.appendPath(file.left(file.lastIndexOf('.')))); + const FilePath lib = FilePath::fromFileInfo(info); + dynamicLibs.append(lib.pathAppended(file.left(file.lastIndexOf('.')))); } else if (info.isReadable()) { if (file.startsWith("libQtCore") || file.startsWith("libQt5Core") || file.startsWith("QtCore") || file.startsWith("Qt5Core")) { if (file.endsWith(".a") || file.endsWith(".lib")) - staticLibs.append(FileName(info)); + staticLibs.append(FilePath::fromFileInfo(info)); else if (file.endsWith(".dll") || file.endsWith(QString::fromLatin1(".so.") + versionString) || file.endsWith(".so") || file.endsWith(QLatin1Char('.') + versionString + ".dylib")) - dynamicLibs.append(FileName(info)); + dynamicLibs.append(FilePath::fromFileInfo(info)); } } } @@ -1823,7 +1840,7 @@ FileNameList BaseQtVersion::qtCorePaths() const return dynamicLibs; } -static QByteArray scanQtBinaryForBuildString(const FileName &library) +static QByteArray scanQtBinaryForBuildString(const FilePath &library) { QFile lib(library.toString()); QByteArray buildString; @@ -1976,10 +1993,10 @@ static Abi refineAbiFromBuildString(const QByteArray &buildString, const Abi &pr return Abi(arch, os, flavor, format, wordWidth); } -static Abi scanQtBinaryForBuildStringAndRefineAbi(const FileName &library, +static Abi scanQtBinaryForBuildStringAndRefineAbi(const FilePath &library, const Abi &probableAbi) { - static QHash<Utils::FileName, Abi> results; + static QHash<Utils::FilePath, Abi> results; if (!results.contains(library)) { const QByteArray buildString = scanQtBinaryForBuildString(library); @@ -1988,10 +2005,10 @@ static Abi scanQtBinaryForBuildStringAndRefineAbi(const FileName &library, return results.value(library); } -QList<Abi> BaseQtVersion::qtAbisFromLibrary(const FileNameList &coreLibraries) +Abis BaseQtVersion::qtAbisFromLibrary(const FilePathList &coreLibraries) { - QList<Abi> res; - foreach (const FileName &library, coreLibraries) { + Abis res; + for (const FilePath &library : coreLibraries) { for (Abi abi : Abi::abisOfBinary(library)) { Abi tmp = abi; if (abi.osFlavor() == Abi::UnknownFlavor) diff --git a/src/plugins/qtsupport/baseqtversion.h b/src/plugins/qtsupport/baseqtversion.h index 34627bfb62..34e33b1c20 100644 --- a/src/plugins/qtsupport/baseqtversion.h +++ b/src/plugins/qtsupport/baseqtversion.h @@ -31,6 +31,7 @@ #include <utils/macroexpander.h> #include <projectexplorer/abi.h> +#include <projectexplorer/task.h> #include <QSet> #include <QStringList> @@ -48,7 +49,6 @@ class Kit; class ToolChain; class HeaderPath; class Target; -class Task; } // namespace ProjectExplorer QT_BEGIN_NAMESPACE @@ -64,6 +64,7 @@ namespace QtSupport class QtConfigWidget; class BaseQtVersion; +class QtVersionFactory; // Wrapper to make the std::unique_ptr<Utils::MacroExpander> "copyable": class MacroExpanderWrapper @@ -113,7 +114,6 @@ public: virtual ~BaseQtVersion(); virtual void fromMap(const QVariantMap &map); - virtual BaseQtVersion *clone() const = 0; virtual bool equals(BaseQtVersion *other); bool isAutodetected() const; @@ -126,7 +126,7 @@ public: // All valid Ids are >= 0 int uniqueId() const; - virtual QString type() const = 0; + QString type() const; virtual QVariantMap toMap() const; virtual bool isValid() const; @@ -137,8 +137,8 @@ public: virtual QString description() const = 0; virtual QString toHtml(bool verbose) const; - QList<ProjectExplorer::Abi> qtAbis() const; - virtual QList<ProjectExplorer::Abi> detectQtAbis() const = 0; + ProjectExplorer::Abis qtAbis() const; + virtual ProjectExplorer::Abis detectQtAbis() const; enum PropertyVariant { PropertyVariantDev, PropertyVariantGet, PropertyVariantSrc }; QString qmakeProperty(const QByteArray &name, @@ -148,16 +148,16 @@ public: virtual Utils::Environment qmakeRunEnvironment() const; // source path defined by qmake property QT_INSTALL_PREFIX/src or by qmake.stash QT_SOURCE_TREE - virtual Utils::FileName sourcePath() const; + Utils::FilePath sourcePath() const; // returns source path for installed qt packages and empty string for self build qt - Utils::FileName qtPackageSourcePath() const; - bool isInSourceDirectory(const Utils::FileName &filePath); - bool isSubProject(const Utils::FileName &filePath) const; + Utils::FilePath qtPackageSourcePath() const; + bool isInSourceDirectory(const Utils::FilePath &filePath); + bool isSubProject(const Utils::FilePath &filePath) const; // used by UiCodeModelSupport - virtual QString uicCommand() const; - virtual QString designerCommand() const; - virtual QString linguistCommand() const; + QString uicCommand() const; + QString designerCommand() const; + QString linguistCommand() const; QString qscxmlcCommand() const; QString qtVersionString() const; @@ -172,19 +172,19 @@ public: bool hasDemos() const; QString demosPath() const; - virtual QString frameworkInstallPath() const; + QString frameworkInstallPath() const; // former local functions - Utils::FileName qmakeCommand() const; + Utils::FilePath qmakeCommand() const; /// @returns the name of the mkspec - Utils::FileName mkspec() const; - Utils::FileName mkspecFor(ProjectExplorer::ToolChain *tc) const; + QString mkspec() const; + QString mkspecFor(ProjectExplorer::ToolChain *tc) const; /// @returns the full path to the default directory /// specifally not the directory the symlink/ORIGINAL_QMAKESPEC points to - Utils::FileName mkspecPath() const; + Utils::FilePath mkspecPath() const; - bool hasMkspec(const Utils::FileName &spec) const; + bool hasMkspec(const QString &spec) const; enum QmakeBuildConfig { @@ -201,39 +201,39 @@ public: /// Check a .pro-file/Qt version combination on possible issues /// @return a list of tasks, ordered on severity (errors first, then /// warnings and finally info items. - QList<ProjectExplorer::Task> reportIssues(const QString &proFile, const QString &buildDir) const; + ProjectExplorer::Tasks reportIssues(const QString &proFile, const QString &buildDir) const; static bool isQmlDebuggingSupported(ProjectExplorer::Kit *k, QString *reason = nullptr); bool isQmlDebuggingSupported(QString *reason = nullptr) const; static bool isQtQuickCompilerSupported(ProjectExplorer::Kit *k, QString *reason = nullptr); bool isQtQuickCompilerSupported(QString *reason = nullptr) const; - virtual QString qmlDumpTool(bool debugVersion) const; + QString qmlDumpTool(bool debugVersion) const; - virtual bool hasQmlDump() const; - virtual bool hasQmlDumpWithRelocatableFlag() const; - virtual bool needsQmlDump() const; + bool hasQmlDump() const; + bool hasQmlDumpWithRelocatableFlag() const; + bool needsQmlDump() const; virtual QtConfigWidget *createConfigurationWidget() const; - static QString defaultUnexpandedDisplayName(const Utils::FileName &qmakePath, + static QString defaultUnexpandedDisplayName(const Utils::FilePath &qmakePath, bool fromPath = false); virtual QSet<Core::Id> targetDeviceTypes() const = 0; - virtual QList<ProjectExplorer::Task> validateKit(const ProjectExplorer::Kit *k); + virtual ProjectExplorer::Tasks validateKit(const ProjectExplorer::Kit *k); - Utils::FileName headerPath() const; - Utils::FileName docsPath() const; - Utils::FileName libraryPath() const; - Utils::FileName pluginPath() const; - Utils::FileName qmlPath() const; - Utils::FileName binPath() const; - Utils::FileName mkspecsPath() const; - Utils::FileName qmlBinPath() const; - Utils::FileName librarySearchPath() const; + Utils::FilePath headerPath() const; + Utils::FilePath docsPath() const; + Utils::FilePath libraryPath() const; + Utils::FilePath pluginPath() const; + Utils::FilePath qmlPath() const; + Utils::FilePath binPath() const; + Utils::FilePath mkspecsPath() const; + Utils::FilePath qmlBinPath() const; + Utils::FilePath librarySearchPath() const; - Utils::FileNameList directoriesToIgnoreInProjectTree() const; + Utils::FilePathList directoriesToIgnoreInProjectTree() const; QString qtNamespace() const; QString qtLibInfix() const; @@ -253,43 +253,46 @@ public: const ProjectExplorer::Target *target); QSet<Core::Id> features() const; + void setIsAutodetected(bool isAutodetected); + protected: virtual QSet<Core::Id> availableFeatures() const; + BaseQtVersion(); - BaseQtVersion(const Utils::FileName &path, bool isAutodetected = false, const QString &autodetectionSource = QString()); - BaseQtVersion(const BaseQtVersion &other); + BaseQtVersion(const BaseQtVersion &other) = delete; - virtual QList<ProjectExplorer::Task> reportIssuesImpl(const QString &proFile, const QString &buildDir) const; + virtual ProjectExplorer::Tasks reportIssuesImpl(const QString &proFile, const QString &buildDir) const; // helper function for desktop and simulator to figure out the supported abis based on the libraries - Utils::FileNameList qtCorePaths() const; - static QList<ProjectExplorer::Abi> qtAbisFromLibrary(const Utils::FileNameList &coreLibraries); + Utils::FilePathList qtCorePaths() const; + static ProjectExplorer::Abis qtAbisFromLibrary(const Utils::FilePathList &coreLibraries); void ensureMkSpecParsed() const; virtual void parseMkSpec(ProFileEvaluator *) const; private: + void setupQmakePathAndId(const Utils::FilePath &path); void setAutoDetectionSource(const QString &autodetectionSource); - void updateSourcePath() const; void updateVersionInfo() const; enum HostBinaries { Designer, Linguist, Uic, QScxmlc }; QString findHostBinary(HostBinaries binary) const; void updateMkspec() const; QHash<ProKey, ProString> versionInfo() const; - static bool queryQMakeVariables(const Utils::FileName &binary, + static bool queryQMakeVariables(const Utils::FilePath &binary, const Utils::Environment &env, QHash<ProKey, ProString> *versionInfo, QString *error = nullptr); static QString qmakeProperty(const QHash<ProKey, ProString> &versionInfo, const QByteArray &name, PropertyVariant variant = PropertyVariantGet); - static Utils::FileName mkspecDirectoryFromVersionInfo(const QHash<ProKey,ProString> &versionInfo); - static Utils::FileName mkspecFromVersionInfo(const QHash<ProKey,ProString> &versionInfo); - static Utils::FileName sourcePath(const QHash<ProKey,ProString> &versionInfo); + static Utils::FilePath mkspecDirectoryFromVersionInfo(const QHash<ProKey,ProString> &versionInfo); + static Utils::FilePath mkspecFromVersionInfo(const QHash<ProKey,ProString> &versionInfo); + static Utils::FilePath sourcePath(const QHash<ProKey,ProString> &versionInfo); void setId(int id); // used by the qtversionmanager for legacy restore // and by the qtoptionspage to replace Qt versions int m_id = -1; + const QtVersionFactory *m_factory = nullptr; // The factory that created us. bool m_isAutodetected = false; mutable bool m_hasQmlDump = false; // controlled by m_versionInfoUpToDate @@ -312,24 +315,24 @@ private: QString m_unexpandedDisplayName; QString m_autodetectionSource; QSet<Core::Id> m_overrideFeatures; - mutable Utils::FileName m_sourcePath; - mutable Utils::FileName m_qtSources; + mutable Utils::FilePath m_sourcePath; + mutable Utils::FilePath m_qtSources; - mutable Utils::FileName m_mkspec; - mutable Utils::FileName m_mkspecFullPath; + mutable Utils::FilePath m_mkspec; + mutable Utils::FilePath m_mkspecFullPath; mutable QHash<QString, QString> m_mkspecValues; mutable QHash<ProKey, ProString> m_versionInfo; - Utils::FileName m_qmakeCommand; + Utils::FilePath m_qmakeCommand; mutable QString m_qtVersionString; mutable QString m_uicCommand; mutable QString m_designerCommand; mutable QString m_linguistCommand; mutable QString m_qscxmlcCommand; - mutable QList<ProjectExplorer::Abi> m_qtAbis; + mutable ProjectExplorer::Abis m_qtAbis; MacroExpanderWrapper m_expander; }; diff --git a/src/plugins/qtsupport/codegensettingspage.cpp b/src/plugins/qtsupport/codegensettingspage.cpp index 39e64db8a2..8f45c02a14 100644 --- a/src/plugins/qtsupport/codegensettingspage.cpp +++ b/src/plugins/qtsupport/codegensettingspage.cpp @@ -94,7 +94,7 @@ CodeGenSettingsPage::CodeGenSettingsPage(QObject *parent) : { m_parameters.fromSettings(Core::ICore::settings()); setId(Constants::CODEGEN_SETTINGS_PAGE_ID); - setDisplayName(QCoreApplication::translate("QtSupport", Constants::CODEGEN_SETTINGS_PAGE_NAME)); + setDisplayName(QCoreApplication::translate("QtSupport", "Qt Class Generation")); setCategory(CppTools::Constants::CPP_SETTINGS_CATEGORY); } diff --git a/src/plugins/qtsupport/desktopqtversion.cpp b/src/plugins/qtsupport/desktopqtversion.cpp index fa7ae205bc..c3d23cb5bf 100644 --- a/src/plugins/qtsupport/desktopqtversion.cpp +++ b/src/plugins/qtsupport/desktopqtversion.cpp @@ -38,7 +38,7 @@ #include <QCoreApplication> #include <QFileInfo> -using namespace QtSupport; +namespace QtSupport { DesktopQtVersion::DesktopQtVersion() : BaseQtVersion() @@ -46,22 +46,6 @@ DesktopQtVersion::DesktopQtVersion() } -DesktopQtVersion::DesktopQtVersion(const Utils::FileName &path, bool isAutodetected, const QString &autodetectionSource) - : BaseQtVersion(path, isAutodetected, autodetectionSource) -{ - setUnexpandedDisplayName(defaultUnexpandedDisplayName(path, false)); -} - -DesktopQtVersion *DesktopQtVersion::clone() const -{ - return new DesktopQtVersion(*this); -} - -QString DesktopQtVersion::type() const -{ - return QLatin1String(Constants::DESKTOPQT); -} - QStringList DesktopQtVersion::warningReason() const { QStringList ret = BaseQtVersion::warningReason(); @@ -72,11 +56,6 @@ QStringList DesktopQtVersion::warningReason() const return ret; } -QList<ProjectExplorer::Abi> DesktopQtVersion::detectQtAbis() const -{ - return qtAbisFromLibrary(qtCorePaths()); -} - QString DesktopQtVersion::description() const { return QCoreApplication::translate("QtVersion", "Desktop", "Qt Version is meant for the desktop"); @@ -101,6 +80,7 @@ QSet<Core::Id> DesktopQtVersion::targetDeviceTypes() const void DesktopQtVersion::fromMap(const QVariantMap &map) { BaseQtVersion::fromMap(map); + // Clear the cached qmlscene command, it might not match the restored path anymore. m_qmlsceneCommand.clear(); } @@ -108,28 +88,31 @@ QString DesktopQtVersion::qmlsceneCommand() const { if (!isValid()) return QString(); + if (!m_qmlsceneCommand.isNull()) return m_qmlsceneCommand; - m_qmlsceneCommand = findTargetBinary(QmlScene); + + ensureMkSpecParsed(); + + const QString path = + qmlBinPath().pathAppended(Utils::HostOsInfo::withExecutableSuffix("qmlscene")).toString(); + + m_qmlsceneCommand = QFileInfo(path).isFile() ? path : QString(); + return m_qmlsceneCommand; } -DesktopQtVersion::DesktopQtVersion(const DesktopQtVersion &other) = default; +namespace Internal { -QString DesktopQtVersion::findTargetBinary(TargetBinaries binary) const -{ - QString path; - - ensureMkSpecParsed(); - switch (binary) { - case QmlScene: - path = qmlBinPath().appendPath( - Utils::HostOsInfo::withExecutableSuffix("qmlscene")).toString(); - break; - default: - // Can't happen - QTC_ASSERT(false, return QString()); - } +// Factory - return QFileInfo(path).isFile() ? path : QString(); +DesktopQtVersionFactory::DesktopQtVersionFactory() +{ + setQtVersionCreator([] { return new DesktopQtVersion; }); + setSupportedType(QtSupport::Constants::DESKTOPQT); + setPriority(0); // Lowest of all, we want to be the fallback + // No further restrictions. We are the fallback :) so we don't care what kind of qt it is. } + +} // Internal +} // QtSupport diff --git a/src/plugins/qtsupport/desktopqtversion.h b/src/plugins/qtsupport/desktopqtversion.h index 3ab82689ae..01e304e23e 100644 --- a/src/plugins/qtsupport/desktopqtversion.h +++ b/src/plugins/qtsupport/desktopqtversion.h @@ -25,6 +25,8 @@ #pragma once +#include <qtsupport/qtversionfactory.h> + #include "baseqtversion.h" namespace QtSupport { @@ -33,15 +35,9 @@ class QTSUPPORT_EXPORT DesktopQtVersion : public BaseQtVersion { public: DesktopQtVersion(); - DesktopQtVersion(const Utils::FileName &path, bool isAutodetected = false, const QString &autodetectionSource = QString()); - DesktopQtVersion *clone() const override; - - QString type() const override; QStringList warningReason() const override; - QList<ProjectExplorer::Abi> detectQtAbis() const override; - QString description() const override; QSet<Core::Id> availableFeatures() const override; @@ -51,15 +47,17 @@ public: QString qmlsceneCommand() const; -protected: - DesktopQtVersion(const DesktopQtVersion &other); - private: + mutable QString m_qmlsceneCommand; +}; - enum TargetBinaries { QmlScene }; - QString findTargetBinary(TargetBinaries binary) const; +namespace Internal { - mutable QString m_qmlsceneCommand; +class DesktopQtVersionFactory : public QtVersionFactory +{ +public: + DesktopQtVersionFactory(); }; +} // Internal } // QtSupport diff --git a/src/plugins/qtsupport/desktopqtversionfactory.cpp b/src/plugins/qtsupport/desktopqtversionfactory.cpp deleted file mode 100644 index ac633aa58c..0000000000 --- a/src/plugins/qtsupport/desktopqtversionfactory.cpp +++ /dev/null @@ -1,71 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of Qt Creator. -** -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 as published by the Free Software -** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-3.0.html. -** -****************************************************************************/ - -#include "desktopqtversionfactory.h" -#include "desktopqtversion.h" -#include <qtsupport/qtsupportconstants.h> - -#include <QFileInfo> - -using namespace QtSupport; -using namespace QtSupport::Internal; - -DesktopQtVersionFactory::DesktopQtVersionFactory(QObject *parent) - : QtVersionFactory(parent) -{ - -} - -DesktopQtVersionFactory::~DesktopQtVersionFactory() = default; - -bool DesktopQtVersionFactory::canRestore(const QString &type) -{ - return type == QLatin1String(Constants::DESKTOPQT); -} - -BaseQtVersion *DesktopQtVersionFactory::restore(const QString &type, const QVariantMap &data) -{ - if (!canRestore(type)) - return nullptr; - auto v = new DesktopQtVersion; - v->fromMap(data); - return v; -} - -int DesktopQtVersionFactory::priority() const -{ - // Lowest of all, we want to be the fallback - return 0; -} - -BaseQtVersion *DesktopQtVersionFactory::create(const Utils::FileName &qmakePath, ProFileEvaluator *evaluator, bool isAutoDetected, const QString &autoDetectionSource) -{ - Q_UNUSED(evaluator); - // we are the fallback :) so we don't care what kind of qt it is - QFileInfo fi = qmakePath.toFileInfo(); - if (fi.exists() && fi.isExecutable() && fi.isFile()) - return new DesktopQtVersion(qmakePath, isAutoDetected, autoDetectionSource); - return nullptr; -} diff --git a/src/plugins/qtsupport/exampleslistmodel.cpp b/src/plugins/qtsupport/exampleslistmodel.cpp index f83496ef54..ee0d88088a 100644 --- a/src/plugins/qtsupport/exampleslistmodel.cpp +++ b/src/plugins/qtsupport/exampleslistmodel.cpp @@ -504,7 +504,7 @@ void ExampleSetModel::updateQtVersionList() // prioritize default qt version ProjectExplorer::Kit *defaultKit = ProjectExplorer::KitManager::defaultKit(); - BaseQtVersion *defaultVersion = QtKitInformation::qtVersion(defaultKit); + BaseQtVersion *defaultVersion = QtKitAspect::qtVersion(defaultKit); if (defaultVersion && versions.contains(defaultVersion)) versions.move(versions.indexOf(defaultVersion), 0); diff --git a/src/plugins/qtsupport/gettingstartedwelcomepage.cpp b/src/plugins/qtsupport/gettingstartedwelcomepage.cpp index 943b9d08bd..fdc594866e 100644 --- a/src/plugins/qtsupport/gettingstartedwelcomepage.cpp +++ b/src/plugins/qtsupport/gettingstartedwelcomepage.cpp @@ -151,17 +151,17 @@ QString ExamplesWelcomePage::copyToAlternativeLocation(const QFileInfo& proFileI } else { QString error; QString targetDir = destBaseDir + QLatin1Char('/') + exampleDirName; - if (FileUtils::copyRecursively(FileName::fromString(projectDir), - FileName::fromString(targetDir), &error)) { + if (FileUtils::copyRecursively(FilePath::fromString(projectDir), + FilePath::fromString(targetDir), &error)) { // set vars to new location const QStringList::Iterator end = filesToOpen.end(); for (QStringList::Iterator it = filesToOpen.begin(); it != end; ++it) it->replace(projectDir, targetDir); foreach (const QString &dependency, dependencies) { - FileName targetFile = FileName::fromString(targetDir); - targetFile.appendPath(QDir(dependency).dirName()); - if (!FileUtils::copyRecursively(FileName::fromString(dependency), targetFile, + const FilePath targetFile = FilePath::fromString(targetDir) + .pathAppended(QDir(dependency).dirName()); + if (!FileUtils::copyRecursively(FilePath::fromString(dependency), targetFile, &error)) { QMessageBox::warning(ICore::mainWindow(), tr("Cannot Copy Project"), error); // do not fail, just warn; @@ -544,7 +544,7 @@ public: int xx = 0; int yy = y + tagsBase; for (const QString &tag : item.tags) { - const int ww = tagsFontMetrics.width(tag) + 5; + const int ww = tagsFontMetrics.horizontalAdvance(tag) + 5; if (xx + ww > w - 30) { yy += 15; xx = 0; @@ -644,7 +644,7 @@ public: ExampleSetModel *exampleSetModel = m_examplesModel->exampleSetModel(); exampleSetSelector->setModel(exampleSetModel); exampleSetSelector->setCurrentIndex(exampleSetModel->selectedExampleSet()); - connect(exampleSetSelector, static_cast<void(QComboBox::*)(int)>(&QComboBox::activated), + connect(exampleSetSelector, QOverload<int>::of(&QComboBox::activated), exampleSetModel, &ExampleSetModel::selectExampleSet); connect(exampleSetModel, &ExampleSetModel::selectedExampleSetChanged, exampleSetSelector, &QComboBox::setCurrentIndex); diff --git a/src/plugins/qtsupport/qmldumptool.cpp b/src/plugins/qtsupport/qmldumptool.cpp index 045353d004..dc9f766144 100644 --- a/src/plugins/qtsupport/qmldumptool.cpp +++ b/src/plugins/qtsupport/qmldumptool.cpp @@ -85,7 +85,7 @@ void QmlDumpTool::pathAndEnvironment(const ProjectExplorer::Kit *k, bool preferD if (!k) return; - const BaseQtVersion *version = QtSupport::QtKitInformation::qtVersion(k); + const BaseQtVersion *version = QtSupport::QtKitAspect::qtVersion(k); if (version && !version->hasQmlDump()) return; diff --git a/src/plugins/qtsupport/qscxmlcgenerator.cpp b/src/plugins/qtsupport/qscxmlcgenerator.cpp index 7874cde57d..415a6ea701 100644 --- a/src/plugins/qtsupport/qscxmlcgenerator.cpp +++ b/src/plugins/qtsupport/qscxmlcgenerator.cpp @@ -42,8 +42,8 @@ static QLoggingCategory log("qtc.qscxmlcgenerator", QtWarningMsg); static const char TaskCategory[] = "Task.Category.ExtraCompiler.QScxmlc"; QScxmlcGenerator::QScxmlcGenerator(const Project *project, - const Utils::FileName &source, - const Utils::FileNameList &targets, QObject *parent) : + const Utils::FilePath &source, + const Utils::FilePathList &targets, QObject *parent) : ProcessExtraCompiler(project, source, targets, parent), m_tmpdir("qscxmlgenerator") { @@ -52,14 +52,14 @@ QScxmlcGenerator::QScxmlcGenerator(const Project *project, m_impl = m_tmpdir.path() + QLatin1Char('/') + targets[1].fileName(); } -QList<Task> QScxmlcGenerator::parseIssues(const QByteArray &processStderr) +Tasks QScxmlcGenerator::parseIssues(const QByteArray &processStderr) { - QList<Task> issues; + Tasks issues; foreach (const QByteArray &line, processStderr.split('\n')) { QByteArrayList tokens = line.split(':'); if (tokens.length() > 4) { - Utils::FileName file = Utils::FileName::fromUtf8(tokens[0]); + Utils::FilePath file = Utils::FilePath::fromUtf8(tokens[0]); int line = tokens[1].toInt(); // int column = tokens[2].toInt(); <- nice, but not needed for now. Task::TaskType type = tokens[3].trimmed() == "error" ? @@ -72,19 +72,19 @@ QList<Task> QScxmlcGenerator::parseIssues(const QByteArray &processStderr) } -Utils::FileName QScxmlcGenerator::command() const +Utils::FilePath QScxmlcGenerator::command() const { QtSupport::BaseQtVersion *version = nullptr; Target *target; if ((target = project()->activeTarget())) - version = QtSupport::QtKitInformation::qtVersion(target->kit()); + version = QtSupport::QtKitAspect::qtVersion(target->kit()); else - version = QtSupport::QtKitInformation::qtVersion(KitManager::defaultKit()); + version = QtSupport::QtKitAspect::qtVersion(KitManager::defaultKit()); if (!version) - return Utils::FileName(); + return Utils::FilePath(); - return Utils::FileName::fromString(version->qscxmlcCommand()); + return Utils::FilePath::fromString(version->qscxmlcCommand()); } QStringList QScxmlcGenerator::arguments() const @@ -95,14 +95,14 @@ QStringList QScxmlcGenerator::arguments() const tmpFile().fileName()}); } -Utils::FileName QScxmlcGenerator::workingDirectory() const +Utils::FilePath QScxmlcGenerator::workingDirectory() const { - return Utils::FileName::fromString(m_tmpdir.path()); + return Utils::FilePath::fromString(m_tmpdir.path()); } bool QScxmlcGenerator::prepareToRun(const QByteArray &sourceContents) { - const Utils::FileName fn = tmpFile(); + const Utils::FilePath fn = tmpFile(); QFile input(fn.toString()); if (!input.open(QIODevice::WriteOnly)) return false; @@ -115,11 +115,10 @@ bool QScxmlcGenerator::prepareToRun(const QByteArray &sourceContents) FileNameToContentsHash QScxmlcGenerator::handleProcessFinished(QProcess *process) { Q_UNUSED(process); - const Utils::FileName wd = workingDirectory(); + const Utils::FilePath wd = workingDirectory(); FileNameToContentsHash result; - forEachTarget([&](const Utils::FileName &target) { - Utils::FileName file = wd; - file.appendPath(target.fileName()); + forEachTarget([&](const Utils::FilePath &target) { + const Utils::FilePath file = wd.pathAppended(target.fileName()); QFile generated(file.toString()); if (!generated.open(QIODevice::ReadOnly)) return; @@ -128,11 +127,9 @@ FileNameToContentsHash QScxmlcGenerator::handleProcessFinished(QProcess *process return result; } -Utils::FileName QScxmlcGenerator::tmpFile() const +Utils::FilePath QScxmlcGenerator::tmpFile() const { - Utils::FileName wd = workingDirectory(); - wd.appendPath(source().fileName()); - return wd; + return workingDirectory().pathAppended(source().fileName()); } FileType QScxmlcGeneratorFactory::sourceType() const @@ -146,8 +143,8 @@ QString QScxmlcGeneratorFactory::sourceTag() const } ExtraCompiler *QScxmlcGeneratorFactory::create( - const Project *project, const Utils::FileName &source, - const Utils::FileNameList &targets) + const Project *project, const Utils::FilePath &source, + const Utils::FilePathList &targets) { annouceCreation(project, source, targets); diff --git a/src/plugins/qtsupport/qscxmlcgenerator.h b/src/plugins/qtsupport/qscxmlcgenerator.h index 64a852c9e6..37c7617ed6 100644 --- a/src/plugins/qtsupport/qscxmlcgenerator.h +++ b/src/plugins/qtsupport/qscxmlcgenerator.h @@ -37,19 +37,19 @@ class QScxmlcGenerator : public ProjectExplorer::ProcessExtraCompiler { Q_OBJECT public: - QScxmlcGenerator(const ProjectExplorer::Project *project, const Utils::FileName &source, - const Utils::FileNameList &targets, QObject *parent = 0); + QScxmlcGenerator(const ProjectExplorer::Project *project, const Utils::FilePath &source, + const Utils::FilePathList &targets, QObject *parent = 0); protected: - Utils::FileName command() const override; + Utils::FilePath command() const override; QStringList arguments() const override; - Utils::FileName workingDirectory() const override; + Utils::FilePath workingDirectory() const override; private: - Utils::FileName tmpFile() const; + Utils::FilePath tmpFile() const; ProjectExplorer::FileNameToContentsHash handleProcessFinished(QProcess *process) override; bool prepareToRun(const QByteArray &sourceContents) override; - QList<ProjectExplorer::Task> parseIssues(const QByteArray &processStderr) override; + ProjectExplorer::Tasks parseIssues(const QByteArray &processStderr) override; Utils::TemporaryDirectory m_tmpdir; QString m_header; @@ -67,8 +67,8 @@ public: QString sourceTag() const override; ProjectExplorer::ExtraCompiler *create(const ProjectExplorer::Project *project, - const Utils::FileName &source, - const Utils::FileNameList &targets) override; + const Utils::FilePath &source, + const Utils::FilePathList &targets) override; }; } // QtSupport diff --git a/src/plugins/qtsupport/qtcppkitinfo.cpp b/src/plugins/qtsupport/qtcppkitinfo.cpp index 2028400ee4..07e404cce4 100644 --- a/src/plugins/qtsupport/qtcppkitinfo.cpp +++ b/src/plugins/qtsupport/qtcppkitinfo.cpp @@ -35,7 +35,7 @@ using namespace CppTools; CppKitInfo::CppKitInfo(ProjectExplorer::Project *project) : KitInfo(project) { - if (kit && (qtVersion = QtKitInformation::qtVersion(kit))) { + if (kit && (qtVersion = QtKitAspect::qtVersion(kit))) { if (qtVersion->qtVersion() < QtSupport::QtVersionNumber(5, 0, 0)) projectPartQtVersion = ProjectPart::Qt4; else diff --git a/src/plugins/qtsupport/qtkitconfigwidget.cpp b/src/plugins/qtsupport/qtkitconfigwidget.cpp deleted file mode 100644 index 8b32ba44de..0000000000 --- a/src/plugins/qtsupport/qtkitconfigwidget.cpp +++ /dev/null @@ -1,156 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of Qt Creator. -** -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 as published by the Free Software -** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-3.0.html. -** -****************************************************************************/ - -#include "qtkitconfigwidget.h" - -#include "qtsupportconstants.h" -#include "qtkitinformation.h" -#include "qtversionmanager.h" - -#include <coreplugin/icore.h> - -#include <utils/qtcassert.h> -#include <utils/algorithm.h> - -#include <QComboBox> -#include <QPushButton> - -namespace QtSupport { -namespace Internal { - -QtKitConfigWidget::QtKitConfigWidget(ProjectExplorer::Kit *k, const ProjectExplorer::KitInformation *ki) : - KitConfigWidget(k, ki) -{ - m_combo = new QComboBox; - m_combo->setSizePolicy(QSizePolicy::Ignored, m_combo->sizePolicy().verticalPolicy()); - m_combo->addItem(tr("None"), -1); - - QList<int> versionIds = Utils::transform(QtVersionManager::versions(), &BaseQtVersion::uniqueId); - versionsChanged(versionIds, QList<int>(), QList<int>()); - - m_manageButton = new QPushButton(KitConfigWidget::msgManage()); - - refresh(); - m_combo->setToolTip(toolTip()); - - connect(m_combo, static_cast<void (QComboBox::*)(int)>(&QComboBox::currentIndexChanged), - this, &QtKitConfigWidget::currentWasChanged); - - connect(QtVersionManager::instance(), &QtVersionManager::qtVersionsChanged, - this, &QtKitConfigWidget::versionsChanged); - - connect(m_manageButton, &QAbstractButton::clicked, this, &QtKitConfigWidget::manageQtVersions); -} - -QtKitConfigWidget::~QtKitConfigWidget() -{ - delete m_combo; - delete m_manageButton; -} - -QString QtKitConfigWidget::displayName() const -{ - return tr("Qt version"); -} - -QString QtKitConfigWidget::toolTip() const -{ - return tr("The Qt library to use for all projects using this kit.<br>" - "A Qt version is required for qmake-based projects " - "and optional when using other build systems."); -} - -void QtKitConfigWidget::makeReadOnly() -{ - m_combo->setEnabled(false); -} - -void QtKitConfigWidget::refresh() -{ - m_combo->setCurrentIndex(findQtVersion(QtKitInformation::qtVersionId(m_kit))); -} - -QWidget *QtKitConfigWidget::mainWidget() const -{ - return m_combo; -} - -QWidget *QtKitConfigWidget::buttonWidget() const -{ - return m_manageButton; -} - -static QString itemNameFor(const BaseQtVersion *v) -{ - QTC_ASSERT(v, return QString()); - QString name = v->displayName(); - if (!v->isValid()) - name = QCoreApplication::translate("QtSupport::Internal::QtKitConfigWidget", "%1 (invalid)").arg(v->displayName()); - return name; -} - -void QtKitConfigWidget::versionsChanged(const QList<int> &added, const QList<int> &removed, - const QList<int> &changed) -{ - foreach (const int id, added) { - BaseQtVersion *v = QtVersionManager::version(id); - QTC_CHECK(v); - QTC_CHECK(findQtVersion(id) < 0); - m_combo->addItem(itemNameFor(v), id); - } - foreach (const int id, removed) { - int pos = findQtVersion(id); - if (pos >= 0) // We do not include invalid Qt versions, so do not try to remove those. - m_combo->removeItem(pos); - } - foreach (const int id, changed) { - BaseQtVersion *v = QtVersionManager::version(id); - int pos = findQtVersion(id); - QTC_CHECK(pos >= 0); - m_combo->setItemText(pos, itemNameFor(v)); - } -} - -void QtKitConfigWidget::manageQtVersions() -{ - Core::ICore::showOptionsDialog(Constants::QTVERSION_SETTINGS_PAGE_ID, buttonWidget()); -} - -void QtKitConfigWidget::currentWasChanged(int idx) -{ - QtKitInformation::setQtVersionId(m_kit, m_combo->itemData(idx).toInt()); -} - -int QtKitConfigWidget::findQtVersion(const int id) const -{ - for (int i = 0; i < m_combo->count(); ++i) { - if (id == m_combo->itemData(i).toInt()) - return i; - } - return -1; -} - -} // namespace Internal -} // namespace QtSupport diff --git a/src/plugins/qtsupport/qtkitconfigwidget.h b/src/plugins/qtsupport/qtkitconfigwidget.h deleted file mode 100644 index 76cd30d5b5..0000000000 --- a/src/plugins/qtsupport/qtkitconfigwidget.h +++ /dev/null @@ -1,66 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of Qt Creator. -** -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 as published by the Free Software -** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-3.0.html. -** -****************************************************************************/ - -#pragma once - -#include <projectexplorer/kitconfigwidget.h> - -QT_BEGIN_NAMESPACE -class QComboBox; -class QPushButton; -QT_END_NAMESPACE - -namespace QtSupport { -namespace Internal { - -class QtKitConfigWidget : public ProjectExplorer::KitConfigWidget -{ - Q_OBJECT - -public: - QtKitConfigWidget(ProjectExplorer::Kit *k, const ProjectExplorer::KitInformation *ki); - ~QtKitConfigWidget() override; - - QString displayName() const override; - - void makeReadOnly() override; - - void refresh() override; - QWidget *mainWidget() const override; - QWidget *buttonWidget() const override; - QString toolTip() const override; - -private: - void versionsChanged(const QList<int> &added, const QList<int> &removed, const QList<int> &changed); - void manageQtVersions(); - void currentWasChanged(int idx); - int findQtVersion(const int id) const; - - QComboBox *m_combo; - QPushButton *m_manageButton; -}; - -} // namespace Internal -} // namespace Debugger diff --git a/src/plugins/qtsupport/qtkitinformation.cpp b/src/plugins/qtsupport/qtkitinformation.cpp index 3e55fb3fd0..3319aa732a 100644 --- a/src/plugins/qtsupport/qtkitinformation.cpp +++ b/src/plugins/qtsupport/qtkitinformation.cpp @@ -27,51 +27,173 @@ #include <QRegExp> -#include "qtkitconfigwidget.h" #include "qtsupportconstants.h" #include "qtversionmanager.h" #include "qtparser.h" +#include "qttestparser.h" +#include <coreplugin/icore.h> #include <projectexplorer/projectexplorerconstants.h> #include <projectexplorer/task.h> - #include <utils/algorithm.h> #include <utils/buildablehelperlibrary.h> #include <utils/macroexpander.h> #include <utils/qtcassert.h> +#include <QComboBox> +#include <QPushButton> + using namespace ProjectExplorer; using namespace Utils; namespace QtSupport { +namespace Internal { -QtKitInformation::QtKitInformation() +class QtKitAspectWidget : public KitAspectWidget { - setObjectName(QLatin1String("QtKitInformation")); - setId(QtKitInformation::id()); + Q_DECLARE_TR_FUNCTIONS(QtSupport::QtKitAspectWidget) +public: + QtKitAspectWidget(Kit *k, const KitAspect *ki) : KitAspectWidget(k, ki) + { + m_combo = new QComboBox; + m_combo->setSizePolicy(QSizePolicy::Ignored, m_combo->sizePolicy().verticalPolicy()); + m_combo->addItem(tr("None"), -1); + + QList<int> versionIds = Utils::transform(QtVersionManager::versions(), &BaseQtVersion::uniqueId); + versionsChanged(versionIds, QList<int>(), QList<int>()); + + m_manageButton = new QPushButton(KitAspectWidget::msgManage()); + + refresh(); + m_combo->setToolTip(ki->description()); + + connect(m_combo, QOverload<int>::of(&QComboBox::currentIndexChanged), + this, &QtKitAspectWidget::currentWasChanged); + + connect(QtVersionManager::instance(), &QtVersionManager::qtVersionsChanged, + this, &QtKitAspectWidget::versionsChanged); + + connect(m_manageButton, &QAbstractButton::clicked, this, &QtKitAspectWidget::manageQtVersions); + } + + ~QtKitAspectWidget() override + { + delete m_combo; + delete m_manageButton; + } + +private: + void makeReadOnly() override { m_combo->setEnabled(false); } + QWidget *mainWidget() const override { return m_combo; } + QWidget *buttonWidget() const override { return m_manageButton; } + + void refresh() override + { + m_combo->setCurrentIndex(findQtVersion(QtKitAspect::qtVersionId(m_kit))); + } + +private: + static QString itemNameFor(const BaseQtVersion *v) + { + QTC_ASSERT(v, return QString()); + QString name = v->displayName(); + if (!v->isValid()) + name = QCoreApplication::translate("QtSupport::Internal::QtKitConfigWidget", "%1 (invalid)").arg(v->displayName()); + return name; + } + + void versionsChanged(const QList<int> &added, const QList<int> &removed, const QList<int> &changed) + { + foreach (const int id, added) { + BaseQtVersion *v = QtVersionManager::version(id); + QTC_CHECK(v); + QTC_CHECK(findQtVersion(id) < 0); + m_combo->addItem(itemNameFor(v), id); + } + foreach (const int id, removed) { + int pos = findQtVersion(id); + if (pos >= 0) // We do not include invalid Qt versions, so do not try to remove those. + m_combo->removeItem(pos); + } + foreach (const int id, changed) { + BaseQtVersion *v = QtVersionManager::version(id); + int pos = findQtVersion(id); + QTC_CHECK(pos >= 0); + m_combo->setItemText(pos, itemNameFor(v)); + } + } + + void manageQtVersions() + { + Core::ICore::showOptionsDialog(Constants::QTVERSION_SETTINGS_PAGE_ID, buttonWidget()); + } + + void currentWasChanged(int idx) + { + QtKitAspect::setQtVersionId(m_kit, m_combo->itemData(idx).toInt()); + } + + int findQtVersion(const int id) const + { + for (int i = 0; i < m_combo->count(); ++i) { + if (id == m_combo->itemData(i).toInt()) + return i; + } + return -1; + } + + QComboBox *m_combo; + QPushButton *m_manageButton; +}; +} // namespace Internal + +QtKitAspect::QtKitAspect() +{ + setObjectName(QLatin1String("QtKitAspect")); + setId(QtKitAspect::id()); + setDisplayName(tr("Qt version")); + setDescription(tr("The Qt library to use for all projects using this kit.<br>" + "A Qt version is required for qmake-based projects " + "and optional when using other build systems.")); setPriority(26000); connect(KitManager::instance(), &KitManager::kitsLoaded, - this, &QtKitInformation::kitsWereLoaded); + this, &QtKitAspect::kitsWereLoaded); } -QVariant QtKitInformation::defaultValue(const Kit *k) const +void QtKitAspect::setup(ProjectExplorer::Kit *k) { - Q_UNUSED(k); - - // find "Qt in PATH": - BaseQtVersion *result = QtVersionManager::version(equal(&BaseQtVersion::autodetectionSource, - QString::fromLatin1("PATH"))); - if (result) - return result->uniqueId(); - - // Use *any* desktop Qt: - result = QtVersionManager::version(equal(&BaseQtVersion::type, - QString::fromLatin1(QtSupport::Constants::DESKTOPQT))); - return result ? result->uniqueId() : -1; + if (!k || k->hasValue(id())) + return; + const Abi tcAbi = ToolChainKitAspect::targetAbi(k); + const Core::Id deviceType = DeviceTypeKitAspect::deviceTypeId(k); + + const QList<BaseQtVersion *> matches + = QtVersionManager::versions([&tcAbi, &deviceType](const BaseQtVersion *qt) { + return qt->targetDeviceTypes().contains(deviceType) + && Utils::contains(qt->qtAbis(), [&tcAbi](const Abi &qtAbi) { + return qtAbi.isCompatibleWith(tcAbi); }); + }); + if (matches.empty()) + return; + + // An MSVC 2015 toolchain is compatible with an MSVC 2017 Qt, but we prefer an + // MSVC 2015 Qt if we find one. + const QList<BaseQtVersion *> exactMatches = Utils::filtered(matches, + [&tcAbi](const BaseQtVersion *qt) { + return qt->qtAbis().contains(tcAbi); + }); + const QList<BaseQtVersion *> &candidates = !exactMatches.empty() ? exactMatches : matches; + + BaseQtVersion * const qtFromPath = QtVersionManager::version( + equal(&BaseQtVersion::autodetectionSource, QString::fromLatin1("PATH"))); + if (qtFromPath && candidates.contains(qtFromPath)) + k->setValue(id(), qtFromPath->uniqueId()); + else + k->setValue(id(), candidates.first()->uniqueId()); } -QList<ProjectExplorer::Task> QtKitInformation::validate(const ProjectExplorer::Kit *k) const +Tasks QtKitAspect::validate(const ProjectExplorer::Kit *k) const { QTC_ASSERT(QtVersionManager::isLoaded(), return { }); BaseQtVersion *version = qtVersion(k); @@ -81,7 +203,7 @@ QList<ProjectExplorer::Task> QtKitInformation::validate(const ProjectExplorer::K return version->validateKit(k); } -void QtKitInformation::fix(ProjectExplorer::Kit *k) +void QtKitAspect::fix(ProjectExplorer::Kit *k) { QTC_ASSERT(QtVersionManager::isLoaded(), return); BaseQtVersion *version = qtVersion(k); @@ -91,36 +213,39 @@ void QtKitInformation::fix(ProjectExplorer::Kit *k) } } -ProjectExplorer::KitConfigWidget *QtKitInformation::createConfigWidget(ProjectExplorer::Kit *k) const +ProjectExplorer::KitAspectWidget *QtKitAspect::createConfigWidget(ProjectExplorer::Kit *k) const { QTC_ASSERT(k, return nullptr); - return new Internal::QtKitConfigWidget(k, this); + return new Internal::QtKitAspectWidget(k, this); } -QString QtKitInformation::displayNamePostfix(const ProjectExplorer::Kit *k) const +QString QtKitAspect::displayNamePostfix(const ProjectExplorer::Kit *k) const { BaseQtVersion *version = qtVersion(k); return version ? version->displayName() : QString(); } -ProjectExplorer::KitInformation::ItemList -QtKitInformation::toUserOutput(const ProjectExplorer::Kit *k) const +ProjectExplorer::KitAspect::ItemList +QtKitAspect::toUserOutput(const ProjectExplorer::Kit *k) const { BaseQtVersion *version = qtVersion(k); - return ItemList() << qMakePair(tr("Qt version"), version ? version->displayName() : tr("None")); + return {{tr("Qt version"), version ? version->displayName() : tr("None")}}; } -void QtKitInformation::addToEnvironment(const ProjectExplorer::Kit *k, Utils::Environment &env) const +void QtKitAspect::addToEnvironment(const ProjectExplorer::Kit *k, Utils::Environment &env) const { BaseQtVersion *version = qtVersion(k); if (version) version->addToEnvironment(k, env); } -ProjectExplorer::IOutputParser *QtKitInformation::createOutputParser(const ProjectExplorer::Kit *k) const +ProjectExplorer::IOutputParser *QtKitAspect::createOutputParser(const ProjectExplorer::Kit *k) const { - if (qtVersion(k)) - return new QtParser; + if (qtVersion(k)) { + const auto parser = new Internal::QtTestParser; + parser->appendOutputParser(new QtParser); + return parser; + } return nullptr; } @@ -129,7 +254,7 @@ class QtMacroSubProvider public: QtMacroSubProvider(Kit *kit) : expander(BaseQtVersion::createMacroExpander( - [kit] { return QtKitInformation::qtVersion(kit); })) + [kit] { return QtKitAspect::qtVersion(kit); })) {} MacroExpander *operator()() const @@ -140,7 +265,7 @@ public: std::shared_ptr<MacroExpander> expander; }; -void QtKitInformation::addToMacroExpander(Kit *kit, MacroExpander *expander) const +void QtKitAspect::addToMacroExpander(Kit *kit, MacroExpander *expander) const { QTC_ASSERT(kit, return); expander->registerSubProvider(QtMacroSubProvider(kit)); @@ -157,18 +282,18 @@ void QtKitInformation::addToMacroExpander(Kit *kit, MacroExpander *expander) con }); } -Core::Id QtKitInformation::id() +Core::Id QtKitAspect::id() { return "QtSupport.QtInformation"; } -int QtKitInformation::qtVersionId(const ProjectExplorer::Kit *k) +int QtKitAspect::qtVersionId(const ProjectExplorer::Kit *k) { if (!k) return -1; int id = -1; - QVariant data = k->value(QtKitInformation::id(), -1); + QVariant data = k->value(QtKitAspect::id(), -1); if (data.type() == QVariant::Int) { bool ok; id = data.toInt(&ok); @@ -183,18 +308,18 @@ int QtKitInformation::qtVersionId(const ProjectExplorer::Kit *k) return id; } -void QtKitInformation::setQtVersionId(ProjectExplorer::Kit *k, const int id) +void QtKitAspect::setQtVersionId(ProjectExplorer::Kit *k, const int id) { QTC_ASSERT(k, return); - k->setValue(QtKitInformation::id(), id); + k->setValue(QtKitAspect::id(), id); } -BaseQtVersion *QtKitInformation::qtVersion(const ProjectExplorer::Kit *k) +BaseQtVersion *QtKitAspect::qtVersion(const ProjectExplorer::Kit *k) { return QtVersionManager::version(qtVersionId(k)); } -void QtKitInformation::setQtVersion(ProjectExplorer::Kit *k, const BaseQtVersion *v) +void QtKitAspect::setQtVersion(ProjectExplorer::Kit *k, const BaseQtVersion *v) { if (!v) setQtVersionId(k, -1); @@ -202,7 +327,7 @@ void QtKitInformation::setQtVersion(ProjectExplorer::Kit *k, const BaseQtVersion setQtVersionId(k, v->uniqueId()); } -void QtKitInformation::qtVersionsChanged(const QList<int> &addedIds, +void QtKitAspect::qtVersionsChanged(const QList<int> &addedIds, const QList<int> &removedIds, const QList<int> &changedIds) { @@ -216,29 +341,29 @@ void QtKitInformation::qtVersionsChanged(const QList<int> &addedIds, } } -void QtKitInformation::kitsWereLoaded() +void QtKitAspect::kitsWereLoaded() { foreach (ProjectExplorer::Kit *k, ProjectExplorer::KitManager::kits()) fix(k); connect(QtVersionManager::instance(), &QtVersionManager::qtVersionsChanged, - this, &QtKitInformation::qtVersionsChanged); + this, &QtKitAspect::qtVersionsChanged); } -Kit::Predicate QtKitInformation::platformPredicate(Core::Id platform) +Kit::Predicate QtKitAspect::platformPredicate(Core::Id platform) { return [platform](const Kit *kit) -> bool { - BaseQtVersion *version = QtKitInformation::qtVersion(kit); + BaseQtVersion *version = QtKitAspect::qtVersion(kit); return version && version->targetDeviceTypes().contains(platform); }; } -Kit::Predicate QtKitInformation::qtVersionPredicate(const QSet<Core::Id> &required, +Kit::Predicate QtKitAspect::qtVersionPredicate(const QSet<Core::Id> &required, const QtVersionNumber &min, const QtVersionNumber &max) { return [required, min, max](const Kit *kit) -> bool { - BaseQtVersion *version = QtKitInformation::qtVersion(kit); + BaseQtVersion *version = QtKitAspect::qtVersion(kit); if (!version) return false; QtVersionNumber current = version->qtVersion(); @@ -250,16 +375,30 @@ Kit::Predicate QtKitInformation::qtVersionPredicate(const QSet<Core::Id> &requir }; } -QSet<Core::Id> QtKitInformation::supportedPlatforms(const Kit *k) const +QSet<Core::Id> QtKitAspect::supportedPlatforms(const Kit *k) const { - BaseQtVersion *version = QtKitInformation::qtVersion(k); + BaseQtVersion *version = QtKitAspect::qtVersion(k); return version ? version->targetDeviceTypes() : QSet<Core::Id>(); } -QSet<Core::Id> QtKitInformation::availableFeatures(const Kit *k) const +QSet<Core::Id> QtKitAspect::availableFeatures(const Kit *k) const { - BaseQtVersion *version = QtKitInformation::qtVersion(k); + BaseQtVersion *version = QtKitAspect::qtVersion(k); return version ? version->features() : QSet<Core::Id>(); } +int QtKitAspect::weight(const Kit *k) const +{ + const BaseQtVersion * const qt = qtVersion(k); + if (!qt) + return 0; + if (!qt->targetDeviceTypes().contains(DeviceTypeKitAspect::deviceTypeId(k))) + return 0; + const Abi tcAbi = ToolChainKitAspect::targetAbi(k); + if (qt->qtAbis().contains(tcAbi)) + return 2; + return Utils::contains(qt->qtAbis(), [&tcAbi](const Abi &qtAbi) { + return qtAbi.isCompatibleWith(tcAbi); }) ? 1 : 0; +} + } // namespace QtSupport diff --git a/src/plugins/qtsupport/qtkitinformation.h b/src/plugins/qtsupport/qtkitinformation.h index 459b9b2440..d155b8ea5f 100644 --- a/src/plugins/qtsupport/qtkitinformation.h +++ b/src/plugins/qtsupport/qtkitinformation.h @@ -35,19 +35,19 @@ namespace Utils { class MacroExpander; } namespace QtSupport { -class QTSUPPORT_EXPORT QtKitInformation : public ProjectExplorer::KitInformation +class QTSUPPORT_EXPORT QtKitAspect : public ProjectExplorer::KitAspect { Q_OBJECT public: - QtKitInformation(); + QtKitAspect(); - QVariant defaultValue(const ProjectExplorer::Kit *k) const override; + void setup(ProjectExplorer::Kit *k) override; - QList<ProjectExplorer::Task> validate(const ProjectExplorer::Kit *k) const override; + ProjectExplorer::Tasks validate(const ProjectExplorer::Kit *k) const override; void fix(ProjectExplorer::Kit *) override; - ProjectExplorer::KitConfigWidget *createConfigWidget(ProjectExplorer::Kit *k) const override; + ProjectExplorer::KitAspectWidget *createConfigWidget(ProjectExplorer::Kit *k) const override; QString displayNamePostfix(const ProjectExplorer::Kit *k) const override; @@ -73,6 +73,8 @@ public: QSet<Core::Id> availableFeatures(const ProjectExplorer::Kit *k) const override; private: + int weight(const ProjectExplorer::Kit *k) const override; + void qtVersionsChanged(const QList<int> &addedIds, const QList<int> &removedIds, const QList<int> &changedIds); diff --git a/src/plugins/qtsupport/qtoptionspage.cpp b/src/plugins/qtsupport/qtoptionspage.cpp index f891f38184..c2269ebe07 100644 --- a/src/plugins/qtsupport/qtoptionspage.cpp +++ b/src/plugins/qtsupport/qtoptionspage.cpp @@ -156,7 +156,7 @@ QtOptionsPage::QtOptionsPage() : m_widget(0) { setId(Constants::QTVERSION_SETTINGS_PAGE_ID); - setDisplayName(QCoreApplication::translate("QtSupport", Constants::QTVERSION_SETTINGS_PAGE_NAME)); + setDisplayName(QCoreApplication::translate("QtSupport", "Qt Versions")); setCategory(ProjectExplorer::Constants::KITS_SETTINGS_CATEGORY); } @@ -258,9 +258,6 @@ QtOptionsPageWidget::QtOptionsPageWidget(QWidget *parent) userChangedCurrentVersion(); updateCleanUpButton(); - connect(QtVersionManager::instance(), &QtVersionManager::dumpUpdatedFor, - this, &QtOptionsPageWidget::qtVersionsDumpUpdated); - connect(QtVersionManager::instance(), &QtVersionManager::qtVersionsChanged, this, &QtOptionsPageWidget::updateQtVersions); @@ -333,19 +330,6 @@ void QtOptionsPageWidget::toolChainsUpdated() }); } -void QtOptionsPageWidget::qtVersionsDumpUpdated(const FileName &qmakeCommand) -{ - m_model->forItemsAtLevel<2>([qmakeCommand](QtVersionItem *item) { - if (item->version()->qmakeCommand() == qmakeCommand) - item->version()->recheckDumper(); - }); - - if (currentVersion() && currentVersion()->qmakeCommand() == qmakeCommand) { - updateWidgets(); - updateDescriptionLabel(); - } -} - void QtOptionsPageWidget::setInfoWidgetVisibility() { m_ui->versionInfoWidget->setVisible(m_ui->infoWidget->state() == DetailsWidget::Collapsed); @@ -357,7 +341,7 @@ void QtOptionsPageWidget::infoAnchorClicked(const QUrl &url) QDesktopServices::openUrl(url); } -static QString formatAbiHtmlList(const QList<Abi> &abis) +static QString formatAbiHtmlList(const Abis &abis) { QString result = QStringLiteral("<ul><li>"); for (int i = 0, count = abis.size(); i < count; ++i) { @@ -385,8 +369,8 @@ QtOptionsPageWidget::ValidityInfo QtOptionsPageWidget::validInformation(const Ba } // Do we have tool chain issues? - QList<Abi> missingToolChains; - const QList<Abi> qtAbis = version->qtAbis(); + Abis missingToolChains; + const Abis qtAbis = version->qtAbis(); for (const Abi &abi : qtAbis) { const auto abiCompatePred = [&abi] (const ToolChain *tc) @@ -538,7 +522,7 @@ void QtOptionsPageWidget::updateQtVersions(const QList<int> &additions, const QL // Add changed/added items: foreach (int a, toAdd) { - BaseQtVersion *version = QtVersionManager::version(a)->clone(); + BaseQtVersion *version = QtVersionFactory::cloneQtVersion(QtVersionManager::version(a)); auto *item = new QtVersionItem(version); // Insert in the right place: @@ -558,20 +542,20 @@ QtOptionsPageWidget::~QtOptionsPageWidget() void QtOptionsPageWidget::addQtDir() { - FileName qtVersion = FileName::fromString( + FilePath qtVersion = FilePath::fromString( QFileDialog::getOpenFileName(this, tr("Select a qmake Executable"), QString(), BuildableHelperLibrary::filterForQmakeFileDialog(), 0, QFileDialog::DontResolveSymlinks)); - if (qtVersion.isNull()) + if (qtVersion.isEmpty()) return; QFileInfo fi = qtVersion.toFileInfo(); // should add all qt versions here ? if (BuildableHelperLibrary::isQtChooser(fi)) - qtVersion = FileName::fromString(BuildableHelperLibrary::qtChooserToQmakePath(fi.symLinkTarget())); + qtVersion = FilePath::fromString(BuildableHelperLibrary::qtChooserToQmakePath(fi.symLinkTarget())); auto checkAlreadyExists = [qtVersion](Utils::TreeItem *parent) { for (int i = 0; i < parent->childCount(); ++i) { @@ -630,14 +614,14 @@ void QtOptionsPageWidget::editPath() { BaseQtVersion *current = currentVersion(); QString dir = currentVersion()->qmakeCommand().toFileInfo().absolutePath(); - FileName qtVersion = FileName::fromString( + FilePath qtVersion = FilePath::fromString( QFileDialog::getOpenFileName(this, tr("Select a qmake Executable"), dir, BuildableHelperLibrary::filterForQmakeFileDialog(), 0, QFileDialog::DontResolveSymlinks)); - if (qtVersion.isNull()) + if (qtVersion.isEmpty()) return; BaseQtVersion *version = QtVersionFactory::createQtVersionFromQMakePath(qtVersion); if (!version) @@ -769,7 +753,7 @@ void QtOptionsPageWidget::apply() m_model->forItemsAtLevel<2>([&versions](QtVersionItem *item) { item->setChanged(false); - versions.append(item->version()->clone()); + versions.append(QtVersionFactory::cloneQtVersion(item->version())); }); QtVersionManager::setNewQtVersions(versions); diff --git a/src/plugins/qtsupport/qtoptionspage.h b/src/plugins/qtsupport/qtoptionspage.h index fc7899c9e0..04af543355 100644 --- a/src/plugins/qtsupport/qtoptionspage.h +++ b/src/plugins/qtsupport/qtoptionspage.h @@ -95,7 +95,6 @@ private: void cleanUpQtVersions(); void toolChainsUpdated(); - void qtVersionsDumpUpdated(const Utils::FileName &qmakeCommand); void setInfoWidgetVisibility(); void infoAnchorClicked(const QUrl &); diff --git a/src/plugins/qtsupport/qtoutputformatter.cpp b/src/plugins/qtsupport/qtoutputformatter.cpp index 84f8e692a1..1bffe659cc 100644 --- a/src/plugins/qtsupport/qtoutputformatter.cpp +++ b/src/plugins/qtsupport/qtoutputformatter.cpp @@ -75,7 +75,7 @@ public: const QRegularExpression qtTestFailUnix; const QRegularExpression qtTestFailWin; QPointer<Project> project; - QString lastLine; + QList<FormattedText> lastLine; FileInProjectFinder projectFinder; QTextCursor cursor; }; @@ -135,36 +135,45 @@ void QtOutputFormatter::appendMessage(const QString &txt, OutputFormat format) appendMessage(txt, charFormat(format)); } -void QtOutputFormatter::appendMessagePart(const QString &txt, const QTextCharFormat &format) +void QtOutputFormatter::appendMessagePart(const QString &txt, const QTextCharFormat &fmt) { QString deferredText; const int length = txt.length(); for (int start = 0, pos = -1; start < length; start = pos + 1) { + bool linkHandled = false; pos = txt.indexOf('\n', start); const QString newPart = txt.mid(start, (pos == -1) ? -1 : pos - start + 1); - const QString line = d->lastLine + newPart; + QString line = newPart; + QTextCharFormat format = fmt; + if (!d->lastLine.isEmpty()) { + line = d->lastLine.last().text + newPart; + format = d->lastLine.last().format; + } LinkResult lr = matchLine(line); if (!lr.href.isEmpty()) { // Found something && line continuation - d->cursor.insertText(deferredText, format); + d->cursor.insertText(deferredText, fmt); deferredText.clear(); if (!d->lastLine.isEmpty()) clearLastLine(); appendLine(lr, line, format); + linkHandled = true; } else { // Found nothing, just emit the new part deferredText += newPart; } if (pos == -1) { - d->lastLine = line; + d->lastLine.clear(); + if (!linkHandled) + d->lastLine.append(FormattedText(line, format)); break; } d->lastLine.clear(); // Handled line continuation } - d->cursor.insertText(deferredText, format); + d->cursor.insertText(deferredText, fmt); } void QtOutputFormatter::appendMessage(const QString &txt, const QTextCharFormat &format) @@ -178,6 +187,8 @@ void QtOutputFormatter::appendMessage(const QString &txt, const QTextCharFormat appendMessagePart(output.text, output.format); d->cursor.endEditBlock(); + + emit contentChanged(); } void QtOutputFormatter::appendLine(const LinkResult &lr, const QString &line, OutputFormat format) @@ -212,13 +223,14 @@ void QtOutputFormatter::handleLink(const QString &href) ":(\\d+)$"); // column const QRegularExpressionMatch qmlLineColumnMatch = qmlLineColumnLink.match(href); + const auto getFileToOpen = [this](const QUrl &fileUrl) { + return chooseFileFromList(d->projectFinder.findFile(fileUrl)).toString(); + }; if (qmlLineColumnMatch.hasMatch()) { const QUrl fileUrl = QUrl(qmlLineColumnMatch.captured(1)); const int line = qmlLineColumnMatch.captured(2).toInt(); const int column = qmlLineColumnMatch.captured(3).toInt(); - - openEditor(d->projectFinder.findFile(fileUrl), line, column - 1); - + openEditor(getFileToOpen(fileUrl), line, column - 1); return; } @@ -229,7 +241,7 @@ void QtOutputFormatter::handleLink(const QString &href) if (qmlLineMatch.hasMatch()) { const QUrl fileUrl = QUrl(qmlLineMatch.captured(1)); const int line = qmlLineMatch.captured(2).toInt(); - openEditor(d->projectFinder.findFile(fileUrl), line); + openEditor(getFileToOpen(fileUrl), line); return; } @@ -258,7 +270,7 @@ void QtOutputFormatter::handleLink(const QString &href) } if (!fileName.isEmpty()) { - fileName = d->projectFinder.findFile(QUrl::fromLocalFile(fileName)); + fileName = getFileToOpen(QUrl::fromLocalFile(fileName)); openEditor(fileName, line); return; } @@ -274,7 +286,8 @@ void QtOutputFormatter::setPlainTextEdit(QPlainTextEdit *plainText) void QtOutputFormatter::clearLastLine() { OutputFormatter::clearLastLine(); - d->lastLine.clear(); + if (!d->lastLine.isEmpty()) + d->lastLine.removeLast(); } void QtOutputFormatter::openEditor(const QString &fileName, int line, int column) @@ -447,6 +460,13 @@ static QTextCharFormat blueFormat() return result; } +static QTextCharFormat greenFormat() +{ + QTextCharFormat result; + result.setForeground(QColor(0, 127, 0)); + return result; +} + void QtSupportPlugin::testQtOutputFormatter_appendMessage_data() { QTest::addColumn<QString>("inputText"); @@ -500,24 +520,24 @@ void QtSupportPlugin::testQtOutputFormatter_appendMixedAssertAndAnsi() formatter.setPlainTextEdit(&edit); const QString inputText = - "\x1b[38;2;0;0;127mHello\n" - "Object::Test in test.cpp:123\n" - "\x1b[38;2;0;0;127mHello\n"; + "\x1b[38;2;0;127;0mGreen " + "file://test.cpp:123 " + "\x1b[38;2;0;0;127mBlue\n"; const QString outputText = - "Hello\n" - "Object::Test in test.cpp:123\n" - "Hello\n"; + "Green " + "file://test.cpp:123 " + "Blue\n"; formatter.appendMessage(inputText, QTextCharFormat()); QCOMPARE(edit.toPlainText(), outputText); edit.moveCursor(QTextCursor::Start); - QCOMPARE(edit.currentCharFormat(), blueFormat()); + QCOMPARE(edit.currentCharFormat(), greenFormat()); - edit.moveCursor(QTextCursor::Down); - edit.moveCursor(QTextCursor::EndOfLine); - QCOMPARE(edit.currentCharFormat(), linkFormat(QTextCharFormat(), "test.cpp:123")); + edit.moveCursor(QTextCursor::WordRight); + edit.moveCursor(QTextCursor::Right); + QCOMPARE(edit.currentCharFormat(), linkFormat(QTextCharFormat(), "file://test.cpp:123")); edit.moveCursor(QTextCursor::End); QCOMPARE(edit.currentCharFormat(), blueFormat()); diff --git a/src/plugins/qtsupport/qtoutputformatter.h b/src/plugins/qtsupport/qtoutputformatter.h index c3eedc2475..45f1a1e396 100644 --- a/src/plugins/qtsupport/qtoutputformatter.h +++ b/src/plugins/qtsupport/qtoutputformatter.h @@ -33,8 +33,8 @@ #define QT_QML_URL_REGEXP "(?:file|qrc):(?://)?/.+?" #define QT_ASSERT_REGEXP "ASSERT: .* in file (.+, line \\d+)" #define QT_ASSERT_X_REGEXP "ASSERT failure in .*: \".*\", file (.+, line \\d+)" -#define QT_TEST_FAIL_UNIX_REGEXP "^ Loc: \\[(.*)\\]$" -#define QT_TEST_FAIL_WIN_REGEXP "^(.*\\(\\d+\\)) : failure location\\s*$" +#define QT_TEST_FAIL_UNIX_REGEXP "^ Loc: \\[((?<file>.+)\\((?<line>\\d+)\\))\\]$" +#define QT_TEST_FAIL_WIN_REGEXP "^((?<file>.+)\\((?<line>\\d+)\\)) : failure location\\s*$" namespace ProjectExplorer { class Project; } @@ -70,7 +70,7 @@ protected: private: void updateProjectFileList(); LinkResult matchLine(const QString &line) const; - void appendMessagePart(const QString &txt, const QTextCharFormat &format); + void appendMessagePart(const QString &txt, const QTextCharFormat &fmt); void appendLine(const LinkResult &lr, const QString &line, Utils::OutputFormat format); void appendLine(const LinkResult &lr, const QString &line, const QTextCharFormat &format); void appendMessage(const QString &text, const QTextCharFormat &format) override; diff --git a/src/plugins/qtsupport/qtparser.cpp b/src/plugins/qtsupport/qtparser.cpp index a1642222f1..6176e281c4 100644 --- a/src/plugins/qtsupport/qtparser.cpp +++ b/src/plugins/qtsupport/qtparser.cpp @@ -58,7 +58,7 @@ void QtParser::stdError(const QString &line) if (level.compare(QLatin1String("Note"), Qt::CaseInsensitive) == 0) type = Task::Unknown; Task task(type, m_mocRegExp.cap(5).trimmed() /* description */, - Utils::FileName::fromUserInput(m_mocRegExp.cap(1)) /* filename */, + Utils::FilePath::fromUserInput(m_mocRegExp.cap(1)) /* filename */, lineno, ProjectExplorer::Constants::TASK_CATEGORY_COMPILE); emit addTask(task, 1); @@ -69,7 +69,7 @@ void QtParser::stdError(const QString &line) if (m_translationRegExp.cap(1) == QLatin1String("Error")) type = Task::Error; Task task(type, m_translationRegExp.cap(2), - Utils::FileName::fromUserInput(m_translationRegExp.cap(3)) /* filename */, + Utils::FilePath::fromUserInput(m_translationRegExp.cap(3)) /* filename */, -1, ProjectExplorer::Constants::TASK_CATEGORY_COMPILE); emit addTask(task, 1); @@ -96,19 +96,19 @@ void QtSupportPlugin::testQtOutputParser_data() QTest::addColumn<OutputParserTester::Channel>("inputChannel"); QTest::addColumn<QString>("childStdOutLines"); QTest::addColumn<QString>("childStdErrLines"); - QTest::addColumn<QList<ProjectExplorer::Task> >("tasks"); + QTest::addColumn<Tasks >("tasks"); QTest::addColumn<QString>("outputLines"); QTest::newRow("pass-through stdout") << QString::fromLatin1("Sometext") << OutputParserTester::STDOUT << QString::fromLatin1("Sometext\n") << QString() - << QList<ProjectExplorer::Task>() + << Tasks() << QString(); QTest::newRow("pass-through stderr") << QString::fromLatin1("Sometext") << OutputParserTester::STDERR << QString() << QString::fromLatin1("Sometext\n") - << QList<ProjectExplorer::Task>() + << Tasks() << QString(); QTest::newRow("pass-through gcc infos") << QString::fromLatin1("/temp/test/untitled8/main.cpp: In function `int main(int, char**)':\n" @@ -123,60 +123,60 @@ void QtSupportPlugin::testQtOutputParser_data() "../../scriptbug/main.cpp: In instantiation of void bar(i) [with i = double]:\n" "../../scriptbug/main.cpp:8: instantiated from void foo(i) [with i = double]\n" "../../scriptbug/main.cpp:22: instantiated from here\n") - << QList<ProjectExplorer::Task>() + << Tasks() << QString(); QTest::newRow("qdoc warning") << QString::fromLatin1("/home/user/dev/qt5/qtscript/src/script/api/qscriptengine.cpp:295: warning: Can't create link to 'Object Trees & Ownership'") << OutputParserTester::STDERR << QString() << QString() - << (QList<ProjectExplorer::Task>() << Task(Task::Warning, + << (Tasks() << Task(Task::Warning, QLatin1String("Can't create link to 'Object Trees & Ownership'"), - Utils::FileName::fromUserInput(QLatin1String("/home/user/dev/qt5/qtscript/src/script/api/qscriptengine.cpp")), 295, + Utils::FilePath::fromUserInput(QLatin1String("/home/user/dev/qt5/qtscript/src/script/api/qscriptengine.cpp")), 295, ProjectExplorer::Constants::TASK_CATEGORY_COMPILE)) << QString(); QTest::newRow("moc warning") << QString::fromLatin1("..\\untitled\\errorfile.h:0: Warning: No relevant classes found. No output generated.") << OutputParserTester::STDERR << QString() << QString() - << (QList<ProjectExplorer::Task>() << Task(Task::Warning, + << (Tasks() << Task(Task::Warning, QLatin1String("No relevant classes found. No output generated."), - Utils::FileName::fromUserInput(QLatin1String("..\\untitled\\errorfile.h")), 0, + Utils::FilePath::fromUserInput(QLatin1String("..\\untitled\\errorfile.h")), 0, ProjectExplorer::Constants::TASK_CATEGORY_COMPILE)) << QString(); QTest::newRow("moc warning 2") << QString::fromLatin1("c:\\code\\test.h(96): Warning: Property declaration ) has no READ accessor function. The property will be invalid.") << OutputParserTester::STDERR << QString() << QString() - << (QList<ProjectExplorer::Task>() << Task(Task::Warning, + << (Tasks() << Task(Task::Warning, QLatin1String("Property declaration ) has no READ accessor function. The property will be invalid."), - Utils::FileName::fromUserInput(QLatin1String("c:\\code\\test.h")), 96, + Utils::FilePath::fromUserInput(QLatin1String("c:\\code\\test.h")), 96, ProjectExplorer::Constants::TASK_CATEGORY_COMPILE)) << QString(); QTest::newRow("moc note") << QString::fromLatin1("/home/qtwebkithelpviewer.h:0: Note: No relevant classes found. No output generated.") << OutputParserTester::STDERR << QString() << QString() - << (QList<ProjectExplorer::Task>() << Task(Task::Unknown, + << (Tasks() << Task(Task::Unknown, QLatin1String("No relevant classes found. No output generated."), - Utils::FileName::fromUserInput(QLatin1String("/home/qtwebkithelpviewer.h")), 0, + Utils::FilePath::fromUserInput(QLatin1String("/home/qtwebkithelpviewer.h")), 0, ProjectExplorer::Constants::TASK_CATEGORY_COMPILE)) << QString(); QTest::newRow("ninja with moc") << QString::fromLatin1("E:/sandbox/creator/loaden/src/libs/utils/iwelcomepage.h(54): Error: Undefined interface") << OutputParserTester::STDERR << QString() << QString() - << (QList<ProjectExplorer::Task>() << Task(Task::Error, + << (Tasks() << Task(Task::Error, QLatin1String("Undefined interface"), - Utils::FileName::fromUserInput(QLatin1String("E:/sandbox/creator/loaden/src/libs/utils/iwelcomepage.h")), 54, + Utils::FilePath::fromUserInput(QLatin1String("E:/sandbox/creator/loaden/src/libs/utils/iwelcomepage.h")), 54, ProjectExplorer::Constants::TASK_CATEGORY_COMPILE)) << QString(); QTest::newRow("translation") << QString::fromLatin1("Warning: dropping duplicate messages in '/some/place/qtcreator_fr.qm'") << OutputParserTester::STDERR << QString() << QString() - << (QList<ProjectExplorer::Task>() << Task(Task::Warning, + << (Tasks() << Task(Task::Warning, QLatin1String("dropping duplicate messages"), - Utils::FileName::fromUserInput(QLatin1String("/some/place/qtcreator_fr.qm")), -1, + Utils::FilePath::fromUserInput(QLatin1String("/some/place/qtcreator_fr.qm")), -1, ProjectExplorer::Constants::TASK_CATEGORY_COMPILE)) << QString(); } @@ -187,7 +187,7 @@ void QtSupportPlugin::testQtOutputParser() testbench.appendOutputParser(new QtParser); QFETCH(QString, input); QFETCH(OutputParserTester::Channel, inputChannel); - QFETCH(QList<Task>, tasks); + QFETCH(Tasks, tasks); QFETCH(QString, childStdOutLines); QFETCH(QString, childStdErrLines); QFETCH(QString, outputLines); diff --git a/src/plugins/qtsupport/qtprojectimporter.cpp b/src/plugins/qtsupport/qtprojectimporter.cpp index a218ee2b5e..0e4124f7d9 100644 --- a/src/plugins/qtsupport/qtprojectimporter.cpp +++ b/src/plugins/qtsupport/qtprojectimporter.cpp @@ -45,22 +45,22 @@ using namespace ProjectExplorer; namespace QtSupport { -QtProjectImporter::QtProjectImporter(const Utils::FileName &path) : ProjectImporter(path) +QtProjectImporter::QtProjectImporter(const Utils::FilePath &path) : ProjectImporter(path) { - useTemporaryKitInformation(QtKitInformation::id(), + useTemporaryKitAspect(QtKitAspect::id(), [this](Kit *k, const QVariantList &vl) {cleanupTemporaryQt(k, vl);}, [this](Kit *k, const QVariantList &vl) {persistTemporaryQt(k, vl);}); } QtProjectImporter::QtVersionData -QtProjectImporter::findOrCreateQtVersion(const Utils::FileName &qmakePath) const +QtProjectImporter::findOrCreateQtVersion(const Utils::FilePath &qmakePath) const { QtVersionData result; result.qt = QtVersionManager::version(Utils::equal(&BaseQtVersion::qmakeCommand, qmakePath)); if (result.qt) { // Check if version is a temporary qt const int qtId = result.qt->uniqueId(); - result.isTemporary = hasKitWithTemporaryData(QtKitInformation::id(), qtId); + result.isTemporary = hasKitWithTemporaryData(QtKitAspect::id(), qtId); return result; } @@ -80,10 +80,10 @@ Kit *QtProjectImporter::createTemporaryKit(const QtVersionData &versionData, const ProjectImporter::KitSetupFunction &additionalSetup) const { return ProjectImporter::createTemporaryKit([&additionalSetup, &versionData, this](Kit *k) -> void { - QtKitInformation::setQtVersion(k, versionData.qt); + QtKitAspect::setQtVersion(k, versionData.qt); if (versionData.qt) { if (versionData.isTemporary) - addTemporaryData(QtKitInformation::id(), versionData.qt->uniqueId(), k); + addTemporaryData(QtKitAspect::id(), versionData.qt->uniqueId(), k); k->setUnexpandedDisplayName(versionData.qt->displayName());; } @@ -108,7 +108,7 @@ void QtProjectImporter::cleanupTemporaryQt(Kit *k, const QVariantList &vl) BaseQtVersion *version = versionFromVariant(vl.at(0)); QTC_ASSERT(version, return); QtVersionManager::removeVersion(version); - QtKitInformation::setQtVersion(k, nullptr); // Always mark Kit as not using this Qt + QtKitAspect::setQtVersion(k, nullptr); // Always mark Kit as not using this Qt } void QtProjectImporter::persistTemporaryQt(Kit *k, const QVariantList &vl) @@ -118,7 +118,7 @@ void QtProjectImporter::persistTemporaryQt(Kit *k, const QVariantList &vl) QTC_ASSERT(vl.count() == 1, return); const QVariant data = vl.at(0); BaseQtVersion *tmpVersion = versionFromVariant(data); - BaseQtVersion *actualVersion = QtKitInformation::qtVersion(k); + BaseQtVersion *actualVersion = QtKitAspect::qtVersion(k); // User changed Kit away from temporary Qt that was set up: if (tmpVersion && actualVersion != tmpVersion) @@ -144,9 +144,9 @@ namespace Internal { struct DirectoryData { DirectoryData(const QString &ip, Kit *k = nullptr, bool ink = false, - const Utils::FileName &qp = Utils::FileName(), bool inq = false) : + const Utils::FilePath &qp = Utils::FilePath(), bool inq = false) : isNewKit(ink), isNewQt(inq), - importPath(Utils::FileName::fromString(ip)), + importPath(Utils::FilePath::fromString(ip)), kit(k), qmakePath(qp) { } @@ -160,15 +160,15 @@ struct DirectoryData { const bool isNewKit = false; const bool isNewQt = false; - const Utils::FileName importPath; + const Utils::FilePath importPath; Kit *const kit = nullptr; - const Utils::FileName qmakePath; + const Utils::FilePath qmakePath; }; class TestQtProjectImporter : public QtProjectImporter { public: - TestQtProjectImporter(const Utils::FileName &pp, const QList<void *> &testData) : + TestQtProjectImporter(const Utils::FilePath &pp, const QList<void *> &testData) : QtProjectImporter(pp), m_testData(testData) { } @@ -178,7 +178,7 @@ public: bool allDeleted() const { return m_deletedTestData.count() == m_testData.count();} protected: - QList<void *> examineDirectory(const Utils::FileName &importPath) const override; + QList<void *> examineDirectory(const Utils::FilePath &importPath) const override; bool matchKit(void *directoryData, const Kit *k) const override; Kit *createKit(void *directoryData) const override; const QList<BuildInfo> buildInfoListForKit(const Kit *k, void *directoryData) const override; @@ -186,7 +186,7 @@ protected: private: const QList<void *> m_testData; - mutable Utils::FileName m_path; + mutable Utils::FilePath m_path; mutable QVector<void*> m_deletedTestData; QList<Kit *> m_deletedKits; @@ -197,7 +197,7 @@ QStringList TestQtProjectImporter::importCandidates() return QStringList(); } -QList<void *> TestQtProjectImporter::examineDirectory(const Utils::FileName &importPath) const +QList<void *> TestQtProjectImporter::examineDirectory(const Utils::FilePath &importPath) const { m_path = importPath; @@ -228,7 +228,7 @@ Kit *TestQtProjectImporter::createKit(void *directoryData) const // New temporary kit: return createTemporaryKit(findOrCreateQtVersion(dd->qmakePath), [dd](Kit *k) { - BaseQtVersion *qt = QtKitInformation::qtVersion(k); + BaseQtVersion *qt = QtKitAspect::qtVersion(k); QMap<Core::Id, QVariant> toKeep; for (const Core::Id &key : k->allKeys()) { if (key.toString().startsWith("PE.tmp.")) @@ -237,7 +237,7 @@ Kit *TestQtProjectImporter::createKit(void *directoryData) const k->copyFrom(dd->kit); for (auto i = toKeep.constBegin(); i != toKeep.constEnd(); ++i) k->setValue(i.key(), i.value()); - QtKitInformation::setQtVersion(k, qt); + QtKitAspect::setQtVersion(k, qt); }); } @@ -268,14 +268,14 @@ void TestQtProjectImporter::deleteDirectoryData(void *directoryData) const delete static_cast<DirectoryData *>(directoryData); } -static Utils::FileName setupQmake(const BaseQtVersion *qt, const QString &path) +static Utils::FilePath setupQmake(const BaseQtVersion *qt, const QString &path) { const QFileInfo fi = QFileInfo(qt->qmakeCommand().toFileInfo().canonicalFilePath()); const QString qmakeFile = path + "/" + fi.fileName(); if (!QFile::copy(fi.absoluteFilePath(), qmakeFile)) - return Utils::FileName(); + return Utils::FilePath(); - return Utils::FileName::fromString(qmakeFile); + return Utils::FilePath::fromString(qmakeFile); } void QtSupportPlugin::testQtProjectImporter_oneProject_data() @@ -362,7 +362,7 @@ void QtSupportPlugin::testQtProjectImporter_oneProject() Kit *defaultKit = KitManager::defaultKit(); QVERIFY(defaultKit); - BaseQtVersion *defaultQt = QtKitInformation::qtVersion(defaultKit); + BaseQtVersion *defaultQt = QtKitAspect::qtVersion(defaultKit); QVERIFY(defaultQt); const Utils::TemporaryDirectory tempDir1("tmp1"); @@ -373,12 +373,12 @@ void QtSupportPlugin::testQtProjectImporter_oneProject() // Templates referrenced by test data: QVector<Kit *> kitTemplates = {defaultKit, defaultKit->clone(), defaultKit->clone()}; // Customize kit numbers 1 and 2: - QtKitInformation::setQtVersion(kitTemplates[1], nullptr); - QtKitInformation::setQtVersion(kitTemplates[2], nullptr); - SysRootKitInformation::setSysRoot(kitTemplates[1], Utils::FileName::fromString("/some/path")); - SysRootKitInformation::setSysRoot(kitTemplates[2], Utils::FileName::fromString("/some/other/path")); + QtKitAspect::setQtVersion(kitTemplates[1], nullptr); + QtKitAspect::setQtVersion(kitTemplates[2], nullptr); + SysRootKitAspect::setSysRoot(kitTemplates[1], Utils::FilePath::fromString("/some/path")); + SysRootKitAspect::setSysRoot(kitTemplates[2], Utils::FilePath::fromString("/some/other/path")); - QVector<Utils::FileName> qmakePaths = {defaultQt->qmakeCommand(), + QVector<Utils::FilePath> qmakePaths = {defaultQt->qmakeCommand(), setupQmake(defaultQt, tempDir1.path()), setupQmake(defaultQt, tempDir2.path())}; @@ -405,13 +405,13 @@ void QtSupportPlugin::testQtProjectImporter_oneProject() testData.append(new DirectoryData(appDir, (kitIndex < 0) ? nullptr : kitTemplates.at(kitIndex), (kitIndex > 0), /* new Kit */ - (qtIndex < 0) ? Utils::FileName() : qmakePaths.at(qtIndex), + (qtIndex < 0) ? Utils::FilePath() : qmakePaths.at(qtIndex), (qtIndex > 0) /* new Qt */)); } // Finally set up importer: // Copy the directoryData so that importer is free to delete it later. - TestQtProjectImporter importer(Utils::FileName::fromString(tempDir1.path()), + TestQtProjectImporter importer(Utils::FilePath::fromString(tempDir1.path()), Utils::transform(testData, [](DirectoryData *i) { return static_cast<void *>(new DirectoryData(*i)); })); @@ -421,7 +421,7 @@ void QtSupportPlugin::testQtProjectImporter_oneProject() // -------------------------------------------------------------------- // choose an existing directory to "import" - const QList<BuildInfo> buildInfo = importer.import(Utils::FileName::fromString(appDir), true); + const QList<BuildInfo> buildInfo = importer.import(Utils::FilePath::fromString(appDir), true); // VALIDATE: Basic TestImporter state: QCOMPARE(importer.projectFilePath().toString(), tempDir1.path()); @@ -445,7 +445,7 @@ void QtSupportPlugin::testQtProjectImporter_oneProject() Kit *newKit = KitManager::kit(bi.kitId); QVERIFY(newKit); - const int newQtId = QtKitInformation::qtVersionId(newKit); + const int newQtId = QtKitAspect::qtVersionId(newKit); // VALIDATE: Qt id is unchanged (unless it is a new Qt) if (!dd->isNewQt) @@ -468,7 +468,7 @@ void QtSupportPlugin::testQtProjectImporter_oneProject() QCOMPARE(templateKeys.count(), newKitKeys.count()); // existing kit needs to be unchanged! for (Core::Id id : templateKeys) { - if (id == QtKitInformation::id()) + if (id == QtKitAspect::id()) continue; // with the exception of the Qt one... QVERIFY(newKit->hasValue(id)); QVERIFY(dd->kit->value(id) == newKit->value(id)); @@ -497,7 +497,7 @@ void QtSupportPlugin::testQtProjectImporter_oneProject() templateKit = defaultKit; } else { templateKit = dd->kit->clone(true); - QtKitInformation::setQtVersionId(templateKit, QtKitInformation::qtVersionId(newKit)); + QtKitAspect::setQtVersionId(templateKit, QtKitAspect::qtVersionId(newKit)); } const QList<Core::Id> templateKitKeys = templateKit->allKeys(); @@ -522,7 +522,7 @@ void QtSupportPlugin::testQtProjectImporter_oneProject() const QList<Core::Id> newKitKeys = newKit->allKeys(); const Core::Id newKitId = newKit->id(); - const int qtId = QtKitInformation::qtVersionId(newKit); + const int qtId = QtKitAspect::qtVersionId(newKit); // VALIDATE: Kit Id has not changed QCOMPARE(newKitId, newKitIdAfterImport); @@ -539,7 +539,7 @@ void QtSupportPlugin::testQtProjectImporter_oneProject() // VALIDATE: All the kit values are as set up in the template before QCOMPARE(newKitKeys.count(), templateKitKeys.count()); for (Core::Id id : templateKitKeys) { - if (id == QtKitInformation::id()) + if (id == QtKitAspect::id()) continue; QVERIFY(newKit->hasValue(id)); QVERIFY(newKit->value(id) == templateKit->value(id)); @@ -553,7 +553,7 @@ void QtSupportPlugin::testQtProjectImporter_oneProject() // VALIDATE: All keys that got added during import are gone QCOMPARE(newKitKeys.count(), templateKitKeys.count()); for (Core::Id id : newKitKeys) { - if (id == QtKitInformation::id()) + if (id == QtKitAspect::id()) continue; // Will be checked by Qt version later QVERIFY(templateKit->hasValue(id)); QVERIFY(newKit->value(id) == templateKit->value(id)); @@ -562,7 +562,7 @@ void QtSupportPlugin::testQtProjectImporter_oneProject() if (qtIsPersistent) { // VALIDATE: Qt is used in the Kit: - QVERIFY(QtKitInformation::qtVersionId(newKit) == qtId); + QVERIFY(QtKitAspect::qtVersionId(newKit) == qtId); // VALIDATE: Qt is still in QtVersionManager QVERIFY(QtVersionManager::version(qtId)); @@ -571,10 +571,10 @@ void QtSupportPlugin::testQtProjectImporter_oneProject() QCOMPARE(QtVersionManager::version(qtId)->qmakeCommand(), dd->qmakePath); // VALIDATE: Kit uses the expected Qt - QCOMPARE(QtKitInformation::qtVersionId(newKit), qtId); + QCOMPARE(QtKitAspect::qtVersionId(newKit), qtId); } else { // VALIDATE: Qt was reset in the kit - QVERIFY(QtKitInformation::qtVersionId(newKit) == -1); + QVERIFY(QtKitAspect::qtVersionId(newKit) == -1); // VALIDATE: New kit is still visible in KitManager QVERIFY(KitManager::kit(newKitId)); // Cleanup Kit does not unregister Kits, so it does @@ -584,7 +584,7 @@ void QtSupportPlugin::testQtProjectImporter_oneProject() QVERIFY(!QtVersionManager::version(qtId)); // VALIDATE: Qt version was reset on the kit - QVERIFY(newKit->value(QtKitInformation::id()).toInt() == -1); // new Qt will be reset to invalid! + QVERIFY(newKit->value(QtKitAspect::id()).toInt() == -1); // new Qt will be reset to invalid! } if (templateKit != defaultKit) diff --git a/src/plugins/qtsupport/qtprojectimporter.h b/src/plugins/qtsupport/qtprojectimporter.h index 082a689bb8..2736787f32 100644 --- a/src/plugins/qtsupport/qtprojectimporter.h +++ b/src/plugins/qtsupport/qtprojectimporter.h @@ -37,7 +37,7 @@ class BaseQtVersion; class QTSUPPORT_EXPORT QtProjectImporter : public ProjectExplorer::ProjectImporter { public: - QtProjectImporter(const Utils::FileName &path); + QtProjectImporter(const Utils::FilePath &path); class QtVersionData { @@ -47,7 +47,7 @@ public: }; protected: - QtVersionData findOrCreateQtVersion(const Utils::FileName &qmakePath) const; + QtVersionData findOrCreateQtVersion(const Utils::FilePath &qmakePath) const; ProjectExplorer::Kit *createTemporaryKit(const QtVersionData &versionData, const KitSetupFunction &setup) const; diff --git a/src/plugins/qtsupport/qtsupport.pro b/src/plugins/qtsupport/qtsupport.pro index 17797f6294..4c5900027f 100644 --- a/src/plugins/qtsupport/qtsupport.pro +++ b/src/plugins/qtsupport/qtsupport.pro @@ -15,9 +15,9 @@ HEADERS += \ qtprojectimporter.h \ qtsupportplugin.h \ qtsupport_global.h \ - qtkitconfigwidget.h \ qtkitinformation.h \ qtoutputformatter.h \ + qttestparser.h \ qtversionmanager.h \ qtversionfactory.h \ baseqtversion.h \ @@ -29,7 +29,6 @@ HEADERS += \ exampleslistmodel.h \ screenshotcropper.h \ qtconfigwidget.h \ - desktopqtversionfactory.h \ desktopqtversion.h \ uicgenerator.h \ qscxmlcgenerator.h @@ -42,9 +41,9 @@ SOURCES += \ qtcppkitinfo.cpp \ qtprojectimporter.cpp \ qtsupportplugin.cpp \ - qtkitconfigwidget.cpp \ qtkitinformation.cpp \ qtoutputformatter.cpp \ + qttestparser.cpp \ qtversionmanager.cpp \ qtversionfactory.cpp \ baseqtversion.cpp \ @@ -55,7 +54,6 @@ SOURCES += \ exampleslistmodel.cpp \ screenshotcropper.cpp \ qtconfigwidget.cpp \ - desktopqtversionfactory.cpp \ desktopqtversion.cpp \ uicgenerator.cpp \ qscxmlcgenerator.cpp diff --git a/src/plugins/qtsupport/qtsupport.qbs b/src/plugins/qtsupport/qtsupport.qbs index 8be90315eb..7e2aa71e32 100644 --- a/src/plugins/qtsupport/qtsupport.qbs +++ b/src/plugins/qtsupport/qtsupport.qbs @@ -82,8 +82,6 @@ Project { "qmldumptool.h", "qscxmlcgenerator.cpp", "qscxmlcgenerator.h", - "qtkitconfigwidget.cpp", - "qtkitconfigwidget.h", "qtkitinformation.cpp", "qtkitinformation.h", "qtoptionspage.cpp", @@ -96,6 +94,8 @@ Project { "qtsupportconstants.h", "qtsupportplugin.cpp", "qtsupportplugin.h", + "qttestparser.cpp", + "qttestparser.h", "qtversionfactory.cpp", "qtversionfactory.h", "qtversioninfo.ui", @@ -112,8 +112,8 @@ Project { Group { name: "QtVersion" files: [ - "desktopqtversion.cpp", "desktopqtversion.h", - "desktopqtversionfactory.cpp", "desktopqtversionfactory.h", + "desktopqtversion.cpp", + "desktopqtversion.h", ] } diff --git a/src/plugins/qtsupport/qtsupportconstants.h b/src/plugins/qtsupport/qtsupportconstants.h index 202378ef2e..f8a453d13d 100644 --- a/src/plugins/qtsupport/qtsupportconstants.h +++ b/src/plugins/qtsupport/qtsupportconstants.h @@ -30,10 +30,7 @@ namespace Constants { // Qt settings pages const char QTVERSION_SETTINGS_PAGE_ID[] = "H.Qt Versions"; -const char QTVERSION_SETTINGS_PAGE_NAME[] = QT_TRANSLATE_NOOP("QtSupport", "Qt Versions"); - const char CODEGEN_SETTINGS_PAGE_ID[] = "Class Generation"; -const char CODEGEN_SETTINGS_PAGE_NAME[] = QT_TRANSLATE_NOOP("QtSupport", "Qt Class Generation"); // QtVersions const char DESKTOPQT[] = "Qt4ProjectManager.QtVersion.Desktop"; diff --git a/src/plugins/qtsupport/qtsupportplugin.cpp b/src/plugins/qtsupport/qtsupportplugin.cpp index 2d99d01e38..5faa9f7a1a 100644 --- a/src/plugins/qtsupport/qtsupportplugin.cpp +++ b/src/plugins/qtsupport/qtsupportplugin.cpp @@ -27,14 +27,17 @@ #include "codegenerator.h" #include "codegensettingspage.h" -#include "desktopqtversionfactory.h" +#include "desktopqtversion.h" #include "gettingstartedwelcomepage.h" #include "qtkitinformation.h" #include "qtoptionspage.h" +#include "qtsupportconstants.h" +#include "qtversionfactory.h" #include "qtversionmanager.h" #include "uicgenerator.h" #include "qscxmlcgenerator.h" +#include "desktopqtversion.h" #include "profilereader.h" #include <coreplugin/icore.h> @@ -65,6 +68,8 @@ public: ExamplesWelcomePage examplesPage{true}; ExamplesWelcomePage tutorialPage{false}; + + QtKitAspect qtKiAspect; }; QtSupportPlugin::~QtSupportPlugin() @@ -80,12 +85,10 @@ bool QtSupportPlugin::initialize(const QStringList &arguments, QString *errorMes ProFileEvaluator::initialize(); new ProFileCacheManager(this); - JsExpander::registerQObjectForJs(QLatin1String("QtSupport"), new CodeGenerator); + JsExpander::registerGlobalObject<CodeGenerator>("QtSupport"); d = new QtSupportPluginPrivate; - ProjectExplorer::KitManager::registerKitInformation<QtKitInformation>(); - (void) new UicGeneratorFactory(this); (void) new QScxmlcGeneratorFactory(this); @@ -100,7 +103,7 @@ static QString qmakeProperty(const char *propertyName) if (!project || !project->activeTarget()) return QString(); - const BaseQtVersion *qtVersion = QtKitInformation::qtVersion(project->activeTarget()->kit()); + const BaseQtVersion *qtVersion = QtKitAspect::qtVersion(project->activeTarget()->kit()); if (!qtVersion) return QString(); return qtVersion->qmakeProperty(propertyName); diff --git a/src/plugins/qtsupport/qtsupportplugin.h b/src/plugins/qtsupport/qtsupportplugin.h index b5e950733b..7899a1bab4 100644 --- a/src/plugins/qtsupport/qtsupportplugin.h +++ b/src/plugins/qtsupport/qtsupportplugin.h @@ -48,6 +48,7 @@ private: private slots: void testQtOutputParser_data(); void testQtOutputParser(); + void testQtTestOutputParser(); void testQtOutputFormatter_data(); void testQtOutputFormatter(); void testQtOutputFormatter_appendMessage_data(); diff --git a/src/plugins/qtsupport/qttestparser.cpp b/src/plugins/qtsupport/qttestparser.cpp new file mode 100644 index 0000000000..901613437e --- /dev/null +++ b/src/plugins/qtsupport/qttestparser.cpp @@ -0,0 +1,132 @@ +/**************************************************************************** +** +** Copyright (C) 2019 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of Qt Creator. +** +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 as published by the Free Software +** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +****************************************************************************/ + +#include "qttestparser.h" + +#include "qtoutputformatter.h" + +#include <projectexplorer/projectexplorerconstants.h> +#include <utils/hostosinfo.h> +#include <utils/qtcassert.h> + +#include <QDir> +#include <QRegularExpression> +#include <QRegularExpressionMatch> + +#ifdef WITH_TESTS +#include "qtsupportplugin.h" +#include <projectexplorer/outputparser_test.h> +#include <QTest> +#endif // WITH_TESTS + +using namespace ProjectExplorer; +using namespace Utils; + +namespace QtSupport { +namespace Internal { + +void QtTestParser::stdOutput(const QString &line) +{ + const QString theLine = rightTrimmed(line); + static const QRegularExpression triggerPattern("^(?:XPASS|FAIL!) : .+$"); + QTC_CHECK(triggerPattern.isValid()); + if (triggerPattern.match(theLine).hasMatch()) { + emitCurrentTask(); + m_currentTask = Task(Task::Error, theLine, FilePath(), -1, + Constants::TASK_CATEGORY_AUTOTEST); + return; + } + if (m_currentTask.isNull()) { + IOutputParser::stdOutput(line); + return; + } + static const QRegularExpression locationPattern(HostOsInfo::isWindowsHost() + ? QString(QT_TEST_FAIL_WIN_REGEXP) + : QString(QT_TEST_FAIL_UNIX_REGEXP)); + QTC_CHECK(locationPattern.isValid()); + const QRegularExpressionMatch match = locationPattern.match(theLine); + if (match.hasMatch()) { + m_currentTask.file = FilePath::fromString( + QDir::fromNativeSeparators(match.captured("file"))); + m_currentTask.line = match.captured("line").toInt(); + emitCurrentTask(); + return; + } + m_currentTask.description.append('\n').append(theLine); +} + +void QtTestParser::emitCurrentTask() +{ + if (!m_currentTask.isNull()) { + emit taskAdded(m_currentTask); + m_currentTask.clear(); + } +} + +#ifdef WITH_TESTS +void QtSupportPlugin::testQtTestOutputParser() +{ + OutputParserTester testbench; + testbench.appendOutputParser(new QtTestParser); + const QString input = "random output\n" + "PASS : MyTest::someTest()\n" + "XPASS : MyTest::someTest()\n" +#ifdef Q_OS_WIN + "C:\\dev\\tests\\tst_mytest.cpp(154) : failure location\n" +#else + " Loc: [/home/me/tests/tst_mytest.cpp(154)]\n" +#endif + "FAIL! : MyTest::someOtherTest(init) Compared values are not the same\n" + " Actual (exceptionCaught): 0\n" + " Expected (true) : 1\n" +#ifdef Q_OS_WIN + "C:\\dev\\tests\\tst_mytest.cpp(220) : failure location\n" +#else + " Loc: [/home/me/tests/tst_mytest.cpp(220)]\n" +#endif + "XPASS: irrelevant\n" + "PASS : MyTest::anotherTest()"; + const QString expectedChildOutput = + "random output\n" + "PASS : MyTest::someTest()\n" + "XPASS: irrelevant\n" + "PASS : MyTest::anotherTest()\n"; + const FilePath theFile = FilePath::fromString(HostOsInfo::isWindowsHost() + ? QString("C:/dev/tests/tst_mytest.cpp") : QString("/home/me/tests/tst_mytest.cpp")); + const Tasks expectedTasks{ + Task(Task::Error, "XPASS : MyTest::someTest()", theFile, 154, + Constants::TASK_CATEGORY_AUTOTEST), + Task(Task::Error, "FAIL! : MyTest::someOtherTest(init) " + "Compared values are not the same\n" + " Actual (exceptionCaught): 0\n" + " Expected (true) : 1", + theFile, 220, Constants::TASK_CATEGORY_AUTOTEST)}; + testbench.testParsing(input, OutputParserTester::STDOUT, expectedTasks, expectedChildOutput, + QString(), QString()); +} +#endif // WITH_TESTS + +} // namespace Internal +} // namespace QtSupport diff --git a/src/plugins/qtsupport/desktopqtversionfactory.h b/src/plugins/qtsupport/qttestparser.h index 7f5f476d45..28ca1f3b04 100644 --- a/src/plugins/qtsupport/desktopqtversionfactory.h +++ b/src/plugins/qtsupport/qttestparser.h @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2016 The Qt Company Ltd. +** Copyright (C) 2019 The Qt Company Ltd. ** Contact: https://www.qt.io/licensing/ ** ** This file is part of Qt Creator. @@ -25,24 +25,23 @@ #pragma once -#include "qtversionfactory.h" +#include <projectexplorer/ioutputparser.h> +#include <projectexplorer/task.h> namespace QtSupport { namespace Internal { -class DesktopQtVersionFactory : public QtVersionFactory +class QtTestParser : public ProjectExplorer::IOutputParser { -public: - explicit DesktopQtVersionFactory(QObject *parent = nullptr); - ~DesktopQtVersionFactory() override; + Q_OBJECT +private: + void stdOutput(const QString &line) override; + void doFlush() override { emitCurrentTask(); } - bool canRestore(const QString &type) override; - BaseQtVersion *restore(const QString &type, const QVariantMap &data) override; + void emitCurrentTask(); - int priority() const override; - BaseQtVersion *create(const Utils::FileName &qmakePath, ProFileEvaluator *evaluator, - bool isAutoDetected = false, const QString &autoDetectionSource = QString()) override; + ProjectExplorer::Task m_currentTask; }; -} // Internal -} // QtSupport +} // namespace Internal +} // namespace QtSupport diff --git a/src/plugins/qtsupport/qtversionfactory.cpp b/src/plugins/qtsupport/qtversionfactory.cpp index ebc8ae36ee..4560667d8f 100644 --- a/src/plugins/qtsupport/qtversionfactory.cpp +++ b/src/plugins/qtsupport/qtversionfactory.cpp @@ -30,16 +30,19 @@ #include <proparser/qmakevfs.h> #include <extensionsystem/pluginmanager.h> + #include <utils/algorithm.h> #include <utils/environment.h> +#include <utils/qtcassert.h> + +#include <QFileInfo> using namespace QtSupport; using namespace QtSupport::Internal; static QList<QtVersionFactory *> g_qtVersionFactories; -QtVersionFactory::QtVersionFactory(QObject *parent) : - QObject(parent) +QtVersionFactory::QtVersionFactory() { g_qtVersionFactories.append(this); } @@ -54,13 +57,27 @@ const QList<QtVersionFactory *> QtVersionFactory::allQtVersionFactories() return g_qtVersionFactories; } -BaseQtVersion *QtVersionFactory::createQtVersionFromQMakePath(const Utils::FileName &qmakePath, bool isAutoDetected, const QString &autoDetectionSource, QString *error) +bool QtVersionFactory::canRestore(const QString &type) +{ + return type == m_supportedType; +} + +BaseQtVersion *QtVersionFactory::restore(const QString &type, const QVariantMap &data) +{ + QTC_ASSERT(canRestore(type), return nullptr); + QTC_ASSERT(m_creator, return nullptr); + BaseQtVersion *version = create(); + version->fromMap(data); + return version; +} + +BaseQtVersion *QtVersionFactory::createQtVersionFromQMakePath(const Utils::FilePath &qmakePath, bool isAutoDetected, const QString &autoDetectionSource, QString *error) { QHash<ProKey, ProString> versionInfo; if (!BaseQtVersion::queryQMakeVariables(qmakePath, Utils::Environment::systemEnvironment(), &versionInfo, error)) return 0; - Utils::FileName mkspec = BaseQtVersion::mkspecFromVersionInfo(versionInfo); + Utils::FilePath mkspec = BaseQtVersion::mkspecFromVersionInfo(versionInfo); QMakeVfs vfs; QMakeGlobals globals; @@ -76,15 +93,79 @@ BaseQtVersion *QtVersionFactory::createQtVersionFromQMakePath(const Utils::FileN return l->priority() > r->priority(); }); + QFileInfo fi = qmakePath.toFileInfo(); + if (!fi.exists() || !fi.isExecutable() || !fi.isFile()) + return nullptr; + + SetupData setup; + setup.config = evaluator.values("CONFIG"); + setup.platforms = evaluator.values("QMAKE_PLATFORM"); // It's a list in general. + setup.isQnx = !evaluator.value("QNX_CPUDIR").isEmpty(); + foreach (QtVersionFactory *factory, factories) { - BaseQtVersion *ver = factory->create(qmakePath, &evaluator, isAutoDetected, autoDetectionSource); - if (ver) { + if (!factory->m_restrictionChecker || factory->m_restrictionChecker(setup)) { + BaseQtVersion *ver = factory->create(); + QTC_ASSERT(ver, continue); + ver->setupQmakePathAndId(qmakePath); + ver->setAutoDetectionSource(autoDetectionSource); + ver->setIsAutodetected(isAutoDetected); ProFileCacheManager::instance()->decRefCount(); return ver; } } ProFileCacheManager::instance()->decRefCount(); - if (error) - *error = tr("No factory found for qmake: \"%1\"").arg(qmakePath.toUserOutput()); + if (error) { + *error = QCoreApplication::translate("QtSupport::QtVersionFactory", + "No factory found for qmake: \"%1\"").arg(qmakePath.toUserOutput()); + } return 0; } + +BaseQtVersion *QtVersionFactory::create() const +{ + QTC_ASSERT(m_creator, return nullptr); + BaseQtVersion *version = m_creator(); + version->m_factory = this; + return version; +} + +QString QtVersionFactory::supportedType() const +{ + return m_supportedType; +} + +BaseQtVersion *QtVersionFactory::cloneQtVersion(const BaseQtVersion *source) +{ + QTC_ASSERT(source, return nullptr); + const QString sourceType = source->type(); + for (QtVersionFactory *factory : g_qtVersionFactories) { + if (factory->m_supportedType == sourceType) { + BaseQtVersion *version = factory->create(); + QTC_ASSERT(version, return nullptr); + version->fromMap(source->toMap()); + return version; + } + } + QTC_CHECK(false); + return nullptr; +} + +void QtVersionFactory::setQtVersionCreator(const std::function<BaseQtVersion *()> &creator) +{ + m_creator = creator; +} + +void QtVersionFactory::setRestrictionChecker(const std::function<bool(const SetupData &)> &checker) +{ + m_restrictionChecker = checker; +} + +void QtVersionFactory::setSupportedType(const QString &type) +{ + m_supportedType = type; +} + +void QtVersionFactory::setPriority(int priority) +{ + m_priority = priority; +} diff --git a/src/plugins/qtsupport/qtversionfactory.h b/src/plugins/qtsupport/qtversionfactory.h index fad90280cd..4bafe40c14 100644 --- a/src/plugins/qtsupport/qtversionfactory.h +++ b/src/plugins/qtsupport/qtversionfactory.h @@ -27,45 +27,58 @@ #include "qtsupport_global.h" -#include <QObject> #include <QVariantMap> -QT_BEGIN_NAMESPACE -class QSettings; -class ProFileEvaluator; -QT_END_NAMESPACE - -namespace Utils { class FileName; } +namespace Utils { class FilePath; } namespace QtSupport { class BaseQtVersion; -class QTSUPPORT_EXPORT QtVersionFactory : public QObject +class QTSUPPORT_EXPORT QtVersionFactory { - Q_OBJECT - public: - explicit QtVersionFactory(QObject *parent = nullptr); - ~QtVersionFactory() override; + QtVersionFactory(); + virtual ~QtVersionFactory(); static const QList<QtVersionFactory *> allQtVersionFactories(); - virtual bool canRestore(const QString &type) = 0; - virtual BaseQtVersion *restore(const QString &type, const QVariantMap &data) = 0; + bool canRestore(const QString &type); + BaseQtVersion *restore(const QString &type, const QVariantMap &data); /// factories with higher priority are asked first to identify /// a qtversion, the priority of the desktop factory is 0 and /// the desktop factory claims to handle all paths - virtual int priority() const = 0; - virtual BaseQtVersion *create(const Utils::FileName &qmakePath, - ProFileEvaluator *evaluator, - bool isAutoDetected = false, - const QString &autoDetectionSource = QString()) = 0; + int priority() const { return m_priority; } + + QString supportedType() const; static BaseQtVersion *createQtVersionFromQMakePath( - const Utils::FileName &qmakePath, bool isAutoDetected = false, + const Utils::FilePath &qmakePath, bool isAutoDetected = false, const QString &autoDetectionSource = QString(), QString *error = nullptr); + + static BaseQtVersion *cloneQtVersion(const BaseQtVersion *source); + +protected: + struct SetupData + { + QStringList platforms; + QStringList config; + bool isQnx = false; // eeks... + }; + + void setQtVersionCreator(const std::function<BaseQtVersion *()> &creator); + void setRestrictionChecker(const std::function<bool(const SetupData &)> &checker); + void setSupportedType(const QString &type); + void setPriority(int priority); + +private: + BaseQtVersion *create() const; + + std::function<BaseQtVersion *()> m_creator; + std::function<bool(const SetupData &)> m_restrictionChecker; + QString m_supportedType; + int m_priority = 0; }; } // namespace QtSupport diff --git a/src/plugins/qtsupport/qtversionmanager.cpp b/src/plugins/qtsupport/qtversionmanager.cpp index c67edb4a36..36e720a8f0 100644 --- a/src/plugins/qtsupport/qtversionmanager.cpp +++ b/src/plugins/qtsupport/qtversionmanager.cpp @@ -75,14 +75,14 @@ static PersistentSettingsWriter *m_writer = nullptr; enum { debug = 0 }; -static FileName globalSettingsFileName() +static FilePath globalSettingsFileName() { - return FileName::fromString(Core::ICore::installerResourcePath() + QTVERSION_FILENAME); + return FilePath::fromString(Core::ICore::installerResourcePath() + QTVERSION_FILENAME); } -static FileName settingsFileName(const QString &path) +static FilePath settingsFileName(const QString &path) { - return FileName::fromString(Core::ICore::userResourcePath() + path); + return FilePath::fromString(Core::ICore::userResourcePath() + path); } @@ -109,7 +109,7 @@ QtVersionManager::QtVersionManager() m_writer = nullptr; m_idcount = 1; - qRegisterMetaType<FileName>(); + qRegisterMetaType<FilePath>(); // Give the file a bit of time to settle before reading it... m_fileWatcherTimer->setInterval(2000); @@ -134,11 +134,11 @@ void QtVersionManager::triggerQtVersionRestore() emit m_instance->qtVersionsChanged(m_versions.keys(), QList<int>(), QList<int>()); saveQtVersions(); - const FileName configFileName = globalSettingsFileName(); + const FilePath configFileName = globalSettingsFileName(); if (configFileName.exists()) { m_configFileWatcher = new FileSystemWatcher(m_instance); connect(m_configFileWatcher, &FileSystemWatcher::fileChanged, - m_fileWatcherTimer, static_cast<void (QTimer::*)()>(&QTimer::start)); + m_fileWatcherTimer, QOverload<>::of(&QTimer::start)); m_configFileWatcher->addFile(configFileName.toString(), FileSystemWatcher::WatchModifiedDate); } // exists @@ -178,7 +178,7 @@ static bool restoreQtVersions() const QList<QtVersionFactory *> factories = QtVersionFactory::allQtVersionFactories(); PersistentSettingsReader reader; - FileName filename = settingsFileName(QLatin1String(QTVERSION_FILENAME)); + FilePath filename = settingsFileName(QLatin1String(QTVERSION_FILENAME)); if (!reader.load(filename)) return false; @@ -234,7 +234,7 @@ void QtVersionManager::updateFromInstaller(bool emitSignal) { m_fileWatcherTimer->stop(); - const FileName path = globalSettingsFileName(); + const FilePath path = globalSettingsFileName(); // Handle overwritting of data: if (m_configFileWatcher) { m_configFileWatcher->removeFile(path.toString()); @@ -408,16 +408,16 @@ static QString qmakePath(const QString &qtchooser, const QString &version) return QString(); } -static FileNameList gatherQmakePathsFromQtChooser() +static FilePathList gatherQmakePathsFromQtChooser() { const QString qtchooser = QStandardPaths::findExecutable(QStringLiteral("qtchooser")); if (qtchooser.isEmpty()) - return FileNameList(); + return FilePathList(); QList<QByteArray> versions = runQtChooser(qtchooser, QStringList("-l")); - QSet<FileName> foundQMakes; + QSet<FilePath> foundQMakes; foreach (const QByteArray &version, versions) { - FileName possibleQMake = FileName::fromString( + FilePath possibleQMake = FilePath::fromString( qmakePath(qtchooser, QString::fromLocal8Bit(version))); if (!possibleQMake.isEmpty()) foundQMakes << possibleQMake; @@ -427,14 +427,12 @@ static FileNameList gatherQmakePathsFromQtChooser() static void findSystemQt() { - FileNameList systemQMakes; - FileName systemQMakePath = BuildableHelperLibrary::findSystemQt(Environment::systemEnvironment()); - if (!systemQMakePath.isEmpty()) - systemQMakes << systemQMakePath; + FilePathList systemQMakes + = BuildableHelperLibrary::findQtsInEnvironment(Environment::systemEnvironment()); systemQMakes.append(gatherQmakePathsFromQtChooser()); - foreach (const FileName &qmakePath, Utils::filteredUnique(systemQMakes)) { + foreach (const FilePath &qmakePath, Utils::filteredUnique(systemQMakes)) { BaseQtVersion *version = QtVersionFactory::createQtVersionFromQMakePath(qmakePath, false, QLatin1String("PATH")); if (version) { @@ -483,15 +481,6 @@ static void updateDocumentation() Core::HelpManager::registerDocumentation(files); } -void QtVersionManager::updateDumpFor(const FileName &qmakeCommand) -{ - foreach (BaseQtVersion *v, versions()) { - if (v->qmakeCommand() == qmakeCommand) - v->recheckDumper(); - } - emit dumpUpdatedFor(qmakeCommand); -} - int QtVersionManager::getUniqueId() { return m_idcount++; @@ -602,7 +591,7 @@ void QtVersionManager::setNewQtVersions(QList<BaseQtVersion *> newVersions) emit m_instance->qtVersionsChanged(addedVersions, removedVersions, changedVersions); } -BaseQtVersion *QtVersionManager::qtVersionForQMakeBinary(const FileName &qmakePath) +BaseQtVersion *QtVersionManager::qtVersionForQMakeBinary(const FilePath &qmakePath) { return version(Utils::equal(&BaseQtVersion::qmakeCommand, qmakePath)); } diff --git a/src/plugins/qtsupport/qtversionmanager.h b/src/plugins/qtsupport/qtversionmanager.h index 790dc543ff..4a9d077752 100644 --- a/src/plugins/qtsupport/qtversionmanager.h +++ b/src/plugins/qtsupport/qtversionmanager.h @@ -58,7 +58,7 @@ public: // Sorting is potentially expensive since it might require qmake --query to run for each version! static QList<BaseQtVersion *> sortVersions(const QList<BaseQtVersion *> &input); - static BaseQtVersion *qtVersionForQMakeBinary(const Utils::FileName &qmakePath); + static BaseQtVersion *qtVersionForQMakeBinary(const Utils::FilePath &qmakePath); static void addVersion(BaseQtVersion *version); static void removeVersion(BaseQtVersion *version); @@ -67,13 +67,9 @@ public: signals: // content of BaseQtVersion objects with qmake path might have changed - void dumpUpdatedFor(const Utils::FileName &qmakeCommand); void qtVersionsChanged(const QList<int> &addedIds, const QList<int> &removedIds, const QList<int> &changedIds); void qtVersionsLoaded(); -public slots: - void updateDumpFor(const Utils::FileName &qmakeCommand); - private: void updateFromInstaller(bool emitSignal = true); void triggerQtVersionRestore(); diff --git a/src/plugins/qtsupport/screenshotcropper.cpp b/src/plugins/qtsupport/screenshotcropper.cpp index 1865826ebf..79e10a8b84 100644 --- a/src/plugins/qtsupport/screenshotcropper.cpp +++ b/src/plugins/qtsupport/screenshotcropper.cpp @@ -52,7 +52,7 @@ Q_GLOBAL_STATIC(AreasOfInterest, welcomeScreenAreas) static inline QString fileNameForPath(const QString &path) { - return Utils::FileName::fromString(path).fileName(); + return Utils::FilePath::fromString(path).fileName(); } static QRect cropRectForAreaOfInterest(const QSize &imageSize, const QSize &cropSize, const QRect &areaOfInterest) diff --git a/src/plugins/qtsupport/uicgenerator.cpp b/src/plugins/qtsupport/uicgenerator.cpp index 89e8713b22..9d86893278 100644 --- a/src/plugins/qtsupport/uicgenerator.cpp +++ b/src/plugins/qtsupport/uicgenerator.cpp @@ -43,32 +43,31 @@ using namespace ProjectExplorer; namespace QtSupport { -UicGenerator::UicGenerator(const Project *project, const Utils::FileName &source, - const Utils::FileNameList &targets, QObject *parent) : +UicGenerator::UicGenerator(const Project *project, const Utils::FilePath &source, + const Utils::FilePathList &targets, QObject *parent) : ProcessExtraCompiler(project, source, targets, parent) { QTC_ASSERT(targets.count() == 1, return); } -Utils::FileName UicGenerator::command() const +Utils::FilePath UicGenerator::command() const { QtSupport::BaseQtVersion *version = nullptr; Target *target; if ((target = project()->activeTarget())) - version = QtSupport::QtKitInformation::qtVersion(target->kit()); + version = QtSupport::QtKitAspect::qtVersion(target->kit()); else - version = QtSupport::QtKitInformation::qtVersion(KitManager::defaultKit()); + version = QtSupport::QtKitAspect::qtVersion(KitManager::defaultKit()); if (!version) - return Utils::FileName(); + return Utils::FilePath(); - return Utils::FileName::fromString(version->uicCommand()); + return Utils::FilePath::fromString(version->uicCommand()); } -void UicGenerator::handleProcessStarted(QProcess *process, const QByteArray &sourceContents) +QStringList UicGenerator::arguments() const { - process->write(sourceContents); - process->closeWriteChannel(); + return {source().toString()}; } FileNameToContentsHash UicGenerator::handleProcessFinished(QProcess *process) @@ -77,7 +76,7 @@ FileNameToContentsHash UicGenerator::handleProcessFinished(QProcess *process) if (process->exitStatus() != QProcess::NormalExit && process->exitCode() != 0) return result; - const Utils::FileNameList targetList = targets(); + const Utils::FilePathList targetList = targets(); if (targetList.size() != 1) return result; // As far as I can discover in the UIC sources, it writes out local 8-bit encoding. The @@ -97,8 +96,8 @@ QString UicGeneratorFactory::sourceTag() const } ExtraCompiler *UicGeneratorFactory::create(const Project *project, - const Utils::FileName &source, - const Utils::FileNameList &targets) + const Utils::FilePath &source, + const Utils::FilePathList &targets) { annouceCreation(project, source, targets); diff --git a/src/plugins/qtsupport/uicgenerator.h b/src/plugins/qtsupport/uicgenerator.h index b0253eb73c..1253e8f1ab 100644 --- a/src/plugins/qtsupport/uicgenerator.h +++ b/src/plugins/qtsupport/uicgenerator.h @@ -36,12 +36,12 @@ class UicGenerator : public ProjectExplorer::ProcessExtraCompiler { Q_OBJECT public: - UicGenerator(const ProjectExplorer::Project *project, const Utils::FileName &source, - const Utils::FileNameList &targets, QObject *parent = 0); + UicGenerator(const ProjectExplorer::Project *project, const Utils::FilePath &source, + const Utils::FilePathList &targets, QObject *parent = 0); protected: - Utils::FileName command() const override; - void handleProcessStarted(QProcess *process, const QByteArray &sourceContents) override; + Utils::FilePath command() const override; + QStringList arguments() const override; ProjectExplorer::FileNameToContentsHash handleProcessFinished(QProcess *process) override; }; @@ -56,8 +56,8 @@ public: QString sourceTag() const override; ProjectExplorer::ExtraCompiler *create(const ProjectExplorer::Project *project, - const Utils::FileName &source, - const Utils::FileNameList &targets) override; + const Utils::FilePath &source, + const Utils::FilePathList &targets) override; }; } // QtSupport |