// Copyright (C) 2016 The Qt Company Ltd. // SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0 #include "qtsupportplugin.h" #include "codegenerator.h" #include "codegensettingspage.h" #include "externaleditors.h" #include "gettingstartedwelcomepage.h" #include "profilereader.h" #include "qscxmlcgenerator.h" #include "qtkitinformation.h" #include "qtoptionspage.h" #include "qtoutputformatter.h" #include "qtsupporttr.h" #include "qtversionmanager.h" #include "qtversions.h" #include "translationwizardpage.h" #include "uicgenerator.h" #include #include #include #include #include #include #include #include #include #include #include #include #include using namespace Core; using namespace Utils; using namespace ProjectExplorer; namespace QtSupport { namespace Internal { class QtSupportPluginPrivate { public: QtVersionManager qtVersionManager; DesktopQtVersionFactory desktopQtVersionFactory; EmbeddedLinuxQtVersionFactory embeddedLinuxQtVersionFactory; CodeGenSettingsPage codeGenSettingsPage; QtOptionsPage qtOptionsPage; ExamplesWelcomePage examplesPage{true}; ExamplesWelcomePage tutorialPage{false}; QtKitAspect qtKiAspect; QtOutputFormatterFactory qtOutputFormatterFactory; UicGeneratorFactory uicGeneratorFactory; QScxmlcGeneratorFactory qscxmlcGeneratorFactory; DesignerExternalEditor designerEditor; LinguistEditor linguistEditor; }; QtSupportPlugin::~QtSupportPlugin() { delete d; } static void processRunnerCallback(ProcessData *data) { FilePath rootPath = FilePath::fromString(data->deviceRoot); Process proc; proc.setProcessChannelMode(data->processChannelMode); proc.setCommand({rootPath.withNewPath("/bin/sh"), {QString("-c"), data->command}}); proc.setWorkingDirectory(FilePath::fromString(data->workingDirectory)); proc.setEnvironment(Environment(data->environment.toStringList(), OsTypeLinux)); proc.runBlocking(); data->exitCode = proc.exitCode(); data->exitStatus = proc.exitStatus(); data->stdErr = proc.readAllRawStandardError(); data->stdOut = proc.readAllRawStandardOutput(); } void QtSupportPlugin::initialize() { theProcessRunner() = processRunnerCallback; QMakeParser::initialize(); ProFileEvaluator::initialize(); new ProFileCacheManager(this); JsExpander::registerGlobalObject("QtSupport"); ProjectExplorer::JsonWizardFactory::registerPageFactory(new TranslationWizardPageFactory); ProjectExplorerPlugin::showQtSettings(); d = new QtSupportPluginPrivate; QtVersionManager::initialized(); } const char kLinkWithQtInstallationSetting[] = "LinkWithQtInstallation"; static void askAboutQtInstallation() { // if the install settings exist, the Qt Creator installation is (probably) already linked to // a Qt installation, so don't ask if (!QtOptionsPage::canLinkWithQt() || QtOptionsPage::isLinkedWithQt() || !ICore::infoBar()->canInfoBeAdded(kLinkWithQtInstallationSetting)) return; Utils::InfoBarEntry info( kLinkWithQtInstallationSetting, Tr::tr( "Link with a Qt installation to automatically register Qt versions and kits? To do " "this later, select Edit > Preferences > Kits > Qt Versions > Link with Qt."), Utils::InfoBarEntry::GlobalSuppression::Enabled); info.addCustomButton(Tr::tr("Link with Qt"), [] { ICore::infoBar()->removeInfo(kLinkWithQtInstallationSetting); QTimer::singleShot(0, ICore::dialogParent(), &QtOptionsPage::linkWithQt); }); ICore::infoBar()->addInfo(info); } void QtSupportPlugin::extensionsInitialized() { Utils::MacroExpander *expander = Utils::globalMacroExpander(); static const auto currentQtVersion = []() -> const QtVersion * { ProjectExplorer::Project *project = ProjectExplorer::ProjectTree::currentProject(); if (!project || !project->activeTarget()) return nullptr; return QtKitAspect::qtVersion(project->activeTarget()->kit()); }; static const char kCurrentHostBins[] = "CurrentDocument:Project:QT_HOST_BINS"; expander->registerVariable( kCurrentHostBins, Tr::tr("Full path to the host bin directory of the Qt version in the active kit " "of the project containing the current document."), []() { const QtVersion * const qt = currentQtVersion(); return qt ? qt->hostBinPath().toUserOutput() : QString(); }); expander->registerVariable( "CurrentDocument:Project:QT_INSTALL_BINS", Tr::tr("Full path to the target bin directory of the Qt version in the active kit " "of the project containing the current document.
You probably want %1 instead.") .arg(QString::fromLatin1(kCurrentHostBins)), []() { const QtVersion * const qt = currentQtVersion(); return qt ? qt->binPath().toUserOutput() : QString(); }); expander->registerVariable( "CurrentDocument:Project:QT_HOST_LIBEXECS", Tr::tr("Full path to the host libexec directory of the Qt version in the active kit " "of the project containing the current document."), []() { const QtVersion *const qt = currentQtVersion(); return qt ? qt->hostLibexecPath().toUserOutput() : QString(); }); static const auto activeQtVersion = []() -> const QtVersion * { ProjectExplorer::Project *project = ProjectManager::startupProject(); if (!project || !project->activeTarget()) return nullptr; return QtKitAspect::qtVersion(project->activeTarget()->kit()); }; static const char kActiveHostBins[] = "ActiveProject:QT_HOST_BINS"; expander->registerVariable( kActiveHostBins, Tr::tr("Full path to the host bin directory of the Qt version in the active kit " "of the active project."), []() { const QtVersion * const qt = activeQtVersion(); return qt ? qt->hostBinPath().toUserOutput() : QString(); }); expander->registerVariable( "ActiveProject:QT_INSTALL_BINS", Tr::tr("Full path to the target bin directory of the Qt version in the active kit " "of the active project.
You probably want %1 instead.") .arg(QString::fromLatin1(kActiveHostBins)), []() { const QtVersion * const qt = activeQtVersion(); return qt ? qt->binPath().toUserOutput() : QString(); }); expander->registerVariable( "ActiveProject::QT_HOST_LIBEXECS", Tr::tr("Full path to the libexec bin directory of the Qt version in the active kit " "of the active project."), []() { const QtVersion *const qt = activeQtVersion(); return qt ? qt->hostLibexecPath().toUserOutput() : QString(); }); HelpItem::setLinkNarrower([](const HelpItem &item, const HelpItem::Links &links) { const FilePath filePath = item.filePath(); if (filePath.isEmpty()) return links; const Project *project = ProjectManager::projectForFile(filePath); Target *target = project ? project->activeTarget() : nullptr; QtVersion *qt = target ? QtKitAspect::qtVersion(target->kit()) : nullptr; if (!qt) return links; // Find best-suited documentation version, so // sort into buckets of links with exact, same minor, and same major, and return the first // that has entries. const QVersionNumber qtVersion = qt->qtVersion(); HelpItem::Links exactVersion; HelpItem::Links sameMinor; HelpItem::Links sameMajor; bool hasExact = false; bool hasSameMinor = false; bool hasSameMajor = false; for (const HelpItem::Link &link : links) { const QUrl url = link.second; const QVersionNumber version = HelpItem::extractQtVersionNumber(url).second; // version.isNull() means it's not a Qt documentation URL, so include regardless if (version.isNull() || version.majorVersion() == qtVersion.majorVersion()) { sameMajor.push_back(link); hasSameMajor = true; if (version.isNull() || version.minorVersion() == qtVersion.minorVersion()) { sameMinor.push_back(link); hasSameMinor = true; if (version.isNull() || version.microVersion() == qtVersion.microVersion()) { exactVersion.push_back(link); hasExact = true; } } } } // HelpItem itself finds the highest version within sameMinor/Major/etc itself if (hasExact) return exactVersion; if (hasSameMinor) return sameMinor; if (hasSameMajor) return sameMajor; return links; }); askAboutQtInstallation(); } } // Internal } // QtSupport