diff options
Diffstat (limited to 'src/libs/installer/packagemanagergui.cpp')
-rw-r--r-- | src/libs/installer/packagemanagergui.cpp | 227 |
1 files changed, 113 insertions, 114 deletions
diff --git a/src/libs/installer/packagemanagergui.cpp b/src/libs/installer/packagemanagergui.cpp index b91526663..1f0462eea 100644 --- a/src/libs/installer/packagemanagergui.cpp +++ b/src/libs/installer/packagemanagergui.cpp @@ -1,6 +1,6 @@ /************************************************************************** ** -** Copyright (C) 2023 The Qt Company Ltd. +** Copyright (C) 2024 The Qt Company Ltd. ** Contact: https://www.qt.io/licensing/ ** ** This file is part of the Qt Installer Framework. @@ -212,8 +212,9 @@ Q_DECLARE_METATYPE(DynamicInstallerPage*) class PackageManagerGui::Private { public: - Private() - : m_currentId(-1) + Private(PackageManagerGui *qq) + : q(qq) + , m_currentId(-1) , m_modified(false) , m_autoSwitchPage(true) , m_showSettingsButton(false) @@ -237,6 +238,20 @@ public: QLatin1String("unknown button")); } + void showSettingsButton(bool show) + { + if (m_showSettingsButton == show) + return; + q->setOption(QWizard::HaveCustomButton1, show); + q->setButtonText(QWizard::CustomButton1, tr("&Settings")); + q->button(QWizard::CustomButton1)->setToolTip( + PackageManagerGui::tr("Specify proxy settings and configure repositories for add-on components.")); + + q->updateButtonLayout(); + m_showSettingsButton = show; + } + + PackageManagerGui *q; int m_currentId; bool m_modified; bool m_autoSwitchPage; @@ -301,7 +316,7 @@ public: */ PackageManagerGui::PackageManagerGui(PackageManagerCore *core, QWidget *parent) : QWizard(parent) - , d(new Private) + , d(new Private(this)) , m_core(core) { if (m_core->isInstaller()) @@ -397,10 +412,13 @@ PackageManagerGui::PackageManagerGui(PackageManagerCore *core, QWidget *parent) connect(this, &QDialog::rejected, m_core, &PackageManagerCore::setCanceled); connect(this, &PackageManagerGui::interrupted, m_core, &PackageManagerCore::interrupt); - // both queued to show the finished page once everything is done + // all queued to show the finished page once everything is done connect(m_core, &PackageManagerCore::installationFinished, this, &PackageManagerGui::showFinishedPage, Qt::QueuedConnection); + connect(m_core, &PackageManagerCore::offlineGenerationFinished, + this, &PackageManagerGui::showFinishedPage, + Qt::QueuedConnection); connect(m_core, &PackageManagerCore::uninstallationFinished, this, &PackageManagerGui::showFinishedPage, Qt::QueuedConnection); @@ -505,7 +523,7 @@ void PackageManagerGui::updatePageListWidget() item->setFont(currentItemFont); // Current item should be always visible on the list m_pageListWidget->scrollToItem(item); - } else if (id > d->m_currentId) { + } else { item->setFlags(item->flags() & ~Qt::ItemIsEnabled); } } @@ -674,6 +692,22 @@ bool PackageManagerGui::isButtonEnabled(int wb) } /*! + Sets \a buttonText for button specified by \a buttonId to a installer page \a pageId. + + \note In some pages, installer will change the button text when entering + the page. In that case, you need to connect to \c entered() -signal of the + page to change the \a buttonText. + + \sa {gui::setWizardPageButtonText}{gui.setWizardPageButtonText} +*/ +void PackageManagerGui::setWizardPageButtonText(int pageId, int buttonId, const QString &buttonText) +{ + PackageManagerPage *const p = qobject_cast<PackageManagerPage*> (page(pageId)); + if (p) + p->setButtonText(static_cast<QWizard::WizardButton>(buttonId), buttonText); +} + +/*! Sets a validator for the custom page specified by \a name and \a callbackName requested by \a component. */ @@ -1036,16 +1070,18 @@ void PackageManagerGui::showFinishedPage() */ void PackageManagerGui::showSettingsButton(bool show) { - if (d->m_showSettingsButton == show) - return; - - d->m_showSettingsButton = show; - setOption(QWizard::HaveCustomButton1, show); - setButtonText(QWizard::CustomButton1, tr("&Settings")); - button(QWizard::CustomButton1)->setToolTip( - PackageManagerGui::tr("Specify proxy settings and configure repositories for add-on components.")); + m_core->setValue(QLatin1String("ShowSettingsButton"), QString::number(show)); + d->showSettingsButton(show); +} - updateButtonLayout(); +/*! + Shows the \uicontrol Settings button if \a request is \c true. If script has + set the settings button visibility, this function has no effect. +*/ +void PackageManagerGui::requestSettingsButtonByInstaller(bool request) +{ + if (m_core->value(QLatin1String("ShowSettingsButton")).isEmpty()) + d->showSettingsButton(request); } /*! @@ -1228,10 +1264,10 @@ void PackageManagerGui::currentPageChanged(int newId) PackageManagerPage::PackageManagerPage(PackageManagerCore *core) : m_complete(true) , m_titleColor(QString()) + , m_showOnPageList(true) , m_needsSettingsButton(false) , m_core(core) , validatorComponent(nullptr) - , m_showOnPageList(true) { if (!m_core->settings().titleColor().isEmpty()) m_titleColor = m_core->settings().titleColor(); @@ -1295,7 +1331,7 @@ QString PackageManagerPage::productName() const */ void PackageManagerPage::setColoredTitle(const QString &title) { - setTitle(QString::fromLatin1("<font color=\"%1\">%2</font>").arg(m_titleColor, title)); + setTitle(QString::fromLatin1("<center><font color=\"%1\">%2</font></center>").arg(m_titleColor, title)); } /*! @@ -1303,7 +1339,7 @@ void PackageManagerPage::setColoredTitle(const QString &title) */ void PackageManagerPage::setColoredSubTitle(const QString &subTitle) { - setSubTitle(QString::fromLatin1("<font color=\"%1\">%2</font>").arg(m_titleColor, subTitle)); + setSubTitle(QString::fromLatin1("<center><font color=\"%1\">%2</font></center>").arg(m_titleColor, subTitle)); } /*! @@ -1435,19 +1471,12 @@ int PackageManagerPage::nextId() const if (next == PackageManagerCore::LicenseCheck) { // calculate the page after the license page const int nextNextId = gui()->pageIds().value(gui()->pageIds().indexOf(next) + 1, -1); - const PackageManagerCore *const core = packageManagerCore(); + PackageManagerCore *const core = packageManagerCore(); if (core->isUninstaller()) return nextNextId; // forcibly hide the license page if we run as uninstaller - - foreach (Component* component, core->orderedComponentsToInstall()) { - if (core->isMaintainer() && component->isInstalled()) - continue; // package manager or updater, hide as long as the component is installed - - // The component is about to be installed and provides a license, so the page needs to - // be shown. - if (!component->licenses().isEmpty()) - return next; - } + core->recalculateAllComponents(); + if (core->hasLicenses()) + return next; return nextNextId; // no component with a license or all components with license installed } return next; // default, show the next page @@ -1486,7 +1515,7 @@ IntroductionPage::IntroductionPage(PackageManagerCore *core) , m_removeAllComponents(nullptr) { setObjectName(QLatin1String("IntroductionPage")); - setColoredTitle(tr("Setup - %1").arg(productName())); + setColoredTitle(tr("Welcome")); QVBoxLayout *layout = new QVBoxLayout(this); setLayout(layout); @@ -1534,6 +1563,8 @@ IntroductionPage::IntroductionPage(PackageManagerCore *core) m_errorLabel = new QLabel(this); m_errorLabel->setWordWrap(true); + m_errorLabel->setTextFormat(Qt::RichText); + m_errorLabel->setTextInteractionFlags(Qt::TextBrowserInteraction); boxLayout->addWidget(m_errorLabel); m_errorLabel->setObjectName(QLatin1String("ErrorLabel")); @@ -1590,7 +1621,7 @@ bool IntroductionPage::validatePage() bool isOfflineOnlyInstaller = core->isInstaller() && core->isOfflineOnly(); // If not offline only installer, at least one valid repository needs to be available - if (!isOfflineOnlyInstaller && !validRepositoriesAvailable()) { + if (!isOfflineOnlyInstaller && !core->validRepositoriesAvailable()) { setErrorMessage(QLatin1String("<font color=\"red\">") + tr("At least one valid and enabled " "repository required for this action to succeed.") + QLatin1String("</font>")); return isComplete(); @@ -1637,21 +1668,12 @@ bool IntroductionPage::validatePage() // fetch common packages if (core->isInstaller() || core->isPackageManager()) { - bool localPackagesTreeFetched = false; if (!m_allPackagesFetched) { // first try to fetch the server side packages tree m_allPackagesFetched = core->fetchRemotePackagesTree(); if (!m_allPackagesFetched) { QString error = core->error(); - if (core->isPackageManager() && core->status() != PackageManagerCore::ForceUpdate) { - // if that fails and we're in maintenance mode, try to fetch local installed tree - localPackagesTreeFetched = core->fetchLocalPackagesTree(); - if (localPackagesTreeFetched) { - // if that succeeded, adjust error message - error = QLatin1String("<font color=\"red\">") + error + tr(" Only local package " - "management available.") + QLatin1String("</font>"); - } - } else if (core->status() == PackageManagerCore::ForceUpdate) { + if (core->status() == PackageManagerCore::ForceUpdate) { // replaces the error string from packagemanagercore error = tr("There is an important update available. Please select '%1' first") .arg(m_updateComponents->text().remove(QLatin1Char('&'))); @@ -1669,7 +1691,7 @@ bool IntroductionPage::validatePage() } } - if (m_allPackagesFetched || localPackagesTreeFetched) + if (m_allPackagesFetched) setComplete(true); } @@ -1816,22 +1838,6 @@ void IntroductionPage::setErrorMessage(const QString &error) #endif } -/*! - Returns \c true if at least one valid and enabled repository is available. -*/ -bool IntroductionPage::validRepositoriesAvailable() const -{ - const PackageManagerCore *const core = packageManagerCore(); - bool valid = false; - - foreach (const Repository &repo, core->settings().repositories()) { - if (repo.isEnabled() && repo.isValid()) { - valid = true; - break; - } - } - return valid; -} // -- private slots @@ -1839,7 +1845,7 @@ void IntroductionPage::setUpdater(bool value) { if (value) { entering(); - gui()->showSettingsButton(true); + gui()->requestSettingsButtonByInstaller(true); packageManagerCore()->setUpdater(); emit packageManagerCoreTypeChanged(); @@ -1851,7 +1857,7 @@ void IntroductionPage::setUninstaller(bool value) { if (value) { entering(); - gui()->showSettingsButton(true); + gui()->requestSettingsButtonByInstaller(true); packageManagerCore()->setUninstaller(); emit packageManagerCoreTypeChanged(); @@ -1863,7 +1869,7 @@ void IntroductionPage::setPackageManager(bool value) { if (value) { entering(); - gui()->showSettingsButton(true); + gui()->requestSettingsButtonByInstaller(true); packageManagerCore()->setPackageManager(); emit packageManagerCoreTypeChanged(); @@ -1875,9 +1881,9 @@ void IntroductionPage::setPackageManager(bool value) */ void IntroductionPage::initializePage() { - const bool repositoriesAvailable = validRepositoriesAvailable(); - PackageManagerCore *core = packageManagerCore(); + const bool repositoriesAvailable = core->validRepositoriesAvailable(); + if (core->isPackageManager()) { m_packageManager->setChecked(true); } else if (core->isUpdater()) { @@ -1910,7 +1916,7 @@ void IntroductionPage::onCoreNetworkSettingsChanged() PackageManagerCore *core = packageManagerCore(); if (core->isUninstaller() || core->isMaintainer()) { - m_offlineMaintenanceTool = !validRepositoriesAvailable(); + m_offlineMaintenanceTool = !core->validRepositoriesAvailable(); setMaintainerToolsEnabled(!m_offlineMaintenanceTool); m_removeAllComponents->setChecked(m_offlineMaintenanceTool); @@ -2100,7 +2106,7 @@ void LicenseAgreementPage::entering() */ bool LicenseAgreementPage::isComplete() const { - return m_acceptCheckBox->isChecked(); + return m_acceptCheckBox->isChecked() && ProductKeyCheck::instance()->hasAcceptedAllLicenses(); } void LicenseAgreementPage::openLicenseUrl(const QUrl &url) @@ -2193,7 +2199,7 @@ void ComponentSelectionPage::entering() QT_TR_NOOP("Please select the components you want to update."), QT_TR_NOOP("Please select the components you want to install."), QT_TR_NOOP("Please select the components you want to uninstall."), - QT_TR_NOOP("Select the components to install. Deselect installed components to uninstall them. Any components already installed will not be updated."), + QT_TR_NOOP("Select the components to install. Deselect installed components to uninstall them.<br>Any components already installed will not be updated."), QT_TR_NOOP("Mandatory components need to be updated first before you can select other components to update.") }; @@ -2211,14 +2217,13 @@ void ComponentSelectionPage::entering() d->onModelStateChanged(d->m_currentModel->checkedState()); setModified(isComplete()); - if (core->settings().repositoryCategories().count() > 0 && !core->isOfflineOnly() - && !core->isUpdater()) { - d->showCategoryLayout(true); - core->settings().setAllowUnstableComponents(true); - } else { - d->showCategoryLayout(false); - } + d->showCategoryLayout(core->showRepositoryCategories()); d->showCompressedRepositoryButton(); + d->showCreateOfflineInstallerButton(true); + + // Reset to default supplement state. The page may set it to OfflineGenerator + // which needs to be reset after navigating back to the page. + core->resetBinaryMarkerSupplement(); } /*! @@ -2228,6 +2233,7 @@ void ComponentSelectionPage::entering() void ComponentSelectionPage::leaving() { d->hideCompressedRepositoryButton(); + d->showCreateOfflineInstallerButton(false); } /*! @@ -2311,16 +2317,6 @@ void ComponentSelectionPage::deselectComponent(const QString &id) } /*! - Adds the possibility to install a compressed repository on component selection - page. A new button which opens a file browser is added for compressed - repository selection. -*/ -void ComponentSelectionPage::allowCompressedRepositoryInstall() -{ - d->allowCompressedRepositoryInstall(); -} - -/*! Adds an additional virtual component with the \a name to be installed. Returns \c true if the virtual component is found and not installed. @@ -2340,6 +2336,11 @@ bool ComponentSelectionPage::addVirtualComponentToUninstall(const QString &name) return false; } +void ComponentSelectionPage::setAllowCreateOfflineInstaller(bool allow) +{ + d->setAllowCreateOfflineInstaller(allow); +} + void ComponentSelectionPage::setModified(bool modified) { setComplete(modified); @@ -2353,18 +2354,7 @@ bool ComponentSelectionPage::isComplete() const if (!d->componentsResolved()) return false; - if (packageManagerCore()->isInstaller() || packageManagerCore()->isUpdater()) - return d->m_currentModel->checked().count(); - - if (d->m_currentModel->checkedState().testFlag(ComponentModel::DefaultChecked) == false) - return true; - - const QSet<Component *> uncheckable = d->m_currentModel->uncheckable(); - for (auto &component : uncheckable) { - if (component->forcedInstallation() && !component->isInstalled()) - return true; // allow installation for new forced components - } - return false; + return d->m_currentModel->componentsSelected(); } @@ -2702,6 +2692,10 @@ void ReadyForInstallationPage::entering() setButtonText(QWizard::CommitButton, tr("U&pdate")); setColoredTitle(tr("Ready to Update Packages")); m_msgLabel->setText(tr("All required information is now available to begin updating your installation.")); + } else if (packageManagerCore()->isOfflineGenerator()) { + setButtonText(QWizard::CommitButton, tr("Create Offline Installer")); + setColoredTitle(tr("Ready to Create Offline Installer")); + m_msgLabel->setText(tr("All required information is now available to create an offline installer for selected components.")); } else { Q_ASSERT(packageManagerCore()->isInstaller()); setButtonText(QWizard::CommitButton, tr("&Install")); @@ -2718,11 +2712,10 @@ void ReadyForInstallationPage::entering() m_taskDetailsBrowser->setVisible(!componentsOk || LoggingHandler::instance().isVerbose()); setComplete(componentsOk); - QString spaceInfo; - if (packageManagerCore()->checkAvailableSpace(spaceInfo)) { - m_msgLabel->setText(QString::fromLatin1("%1 %2").arg(m_msgLabel->text(), spaceInfo)); + if (packageManagerCore()->checkAvailableSpace()) { + m_msgLabel->setText(QString::fromLatin1("%1 %2").arg(m_msgLabel->text(), packageManagerCore()->availableSpaceMessage())); } else { - m_msgLabel->setText(spaceInfo); + m_msgLabel->setText(packageManagerCore()->availableSpaceMessage()); setComplete(false); } } @@ -2742,7 +2735,9 @@ void ReadyForInstallationPage::leaving() void ReadyForInstallationPage::updatePageListTitle() { PackageManagerCore *core = packageManagerCore(); - if (core->isInstaller()) + if (core->isOfflineGenerator()) + setPageListTitle(tr("Ready to Create Offline Installer")); + else if (core->isInstaller()) setPageListTitle(tr("Ready to Install")); else if (core->isMaintainer()) setPageListTitle(tr("Ready to Update")); @@ -2800,6 +2795,11 @@ PerformInstallationPage::PerformInstallationPage(PackageManagerCore *core) connect(core, &PackageManagerCore::installationFinished, this, &PerformInstallationPage::installationFinished); + connect(core, &PackageManagerCore::offlineGenerationStarted, + this, &PerformInstallationPage::installationStarted); + connect(core, &PackageManagerCore::offlineGenerationFinished, + this, &PerformInstallationPage::installationFinished); + connect(core, &PackageManagerCore::uninstallationStarted, this, &PerformInstallationPage::uninstallationStarted); connect(core, &PackageManagerCore::uninstallationFinished, @@ -2869,6 +2869,11 @@ void PerformInstallationPage::entering() setColoredTitle(tr("Updating components of %1").arg(productName())); QTimer::singleShot(30, packageManagerCore(), SLOT(runPackageUpdater())); + } else if (packageManagerCore()->isOfflineGenerator()) { + setButtonText(QWizard::CommitButton, tr("&Create Offline Installer")); + setColoredTitle(tr("Creating Offline Installer for %1").arg(productName())); + + QTimer::singleShot(30, packageManagerCore(), SLOT(runOfflineGenerator())); } else { setButtonText(QWizard::CommitButton, tr("&Install")); setColoredTitle(tr("Installing %1").arg(productName())); @@ -2893,7 +2898,9 @@ void PerformInstallationPage::leaving() void PerformInstallationPage::updatePageListTitle() { PackageManagerCore *core = packageManagerCore(); - if (core->isInstaller()) + if (core->isOfflineGenerator()) + setPageListTitle(tr("Creating Offline Installer")); + else if (core->isInstaller()) setPageListTitle(tr("Installing")); else if (core->isMaintainer()) setPageListTitle(tr("Updating")); @@ -2997,7 +3004,7 @@ FinishedPage::FinishedPage(PackageManagerCore *core) , m_commitButton(nullptr) { setObjectName(QLatin1String("FinishedPage")); - setColoredTitle(tr("Completing the %1 Setup").arg(productName())); + setColoredTitle(tr("Finished the %1 Setup").arg(productName())); setPageListTitle(tr("Finished")); m_msgLabel = new QLabel(this); @@ -3022,7 +3029,7 @@ FinishedPage::FinishedPage(PackageManagerCore *core) */ void FinishedPage::entering() { - m_msgLabel->setText(tr("Click %1 to exit the %2 Wizard.") + m_msgLabel->setText(tr("Click %1 to exit the %2 Setup.") .arg(gui()->defaultButtonText(QWizard::FinishButton).remove(QLatin1Char('&'))) .arg(productName())); @@ -3115,16 +3122,8 @@ void FinishedPage::leaving() */ void FinishedPage::handleFinishClicked() { - const QString program = - packageManagerCore()->replaceVariables(packageManagerCore()->value(scRunProgram)); - - const QStringList args = packageManagerCore()->replaceVariables(packageManagerCore() - ->values(scRunProgramArguments)); - if (!m_runItCheckBox->isChecked() || program.isEmpty()) - return; - - qCDebug(QInstaller::lcInstallerInstallLog) << "starting" << program << args; - QProcess::startDetached(program, args); + if (m_runItCheckBox->isChecked()) + packageManagerCore()->runProgram(); } /*! @@ -3169,7 +3168,7 @@ RestartPage::RestartPage(PackageManagerCore *core) : PackageManagerPage(core) { setObjectName(QLatin1String("RestartPage")); - setColoredTitle(tr("Completing the %1 Setup").arg(productName())); + setColoredTitle(tr("Finished the %1 Setup").arg(productName())); // Never show this page on the page list setShowOnPageList(false); |