diff options
author | A. Wilcox <AWilcox@Wilcox-Tech.com> | 2023-10-29 02:20:25 -0500 |
---|---|---|
committer | A. Wilcox <AWilcox@Wilcox-Tech.com> | 2023-10-29 02:20:25 -0500 |
commit | 52661635b4f04c356f0092e5b59f1261dd04b34f (patch) | |
tree | f48c3bd27050bfdbab909c86715860429f6f1f95 | |
parent | 10318dee4e944cbf7ac59d805c3397a7df456a29 (diff) | |
download | horizon-52661635b4f04c356f0092e5b59f1261dd04b34f.tar.gz horizon-52661635b4f04c356f0092e5b59f1261dd04b34f.tar.bz2 horizon-52661635b4f04c356f0092e5b59f1261dd04b34f.tar.xz horizon-52661635b4f04c356f0092e5b59f1261dd04b34f.zip |
Qt UI: Add Advanced Options screen
Allows the user to select arch, repository, signingkey, and version.
Closes: #337
-rw-r--r-- | devel/requirements/3_functional.xml | 39 | ||||
-rw-r--r-- | ui/qt5/CMakeLists.txt | 1 | ||||
-rw-r--r-- | ui/qt5/advoptsdialog.cc | 127 | ||||
-rw-r--r-- | ui/qt5/advoptsdialog.hh | 24 | ||||
-rw-r--r-- | ui/qt5/horizonwizard.cc | 8 | ||||
-rw-r--r-- | ui/qt5/horizonwizard.hh | 38 | ||||
-rw-r--r-- | ui/qt5/intropage.cc | 13 | ||||
-rw-r--r-- | ui/qt5/intropage.hh | 4 |
8 files changed, 242 insertions, 12 deletions
diff --git a/devel/requirements/3_functional.xml b/devel/requirements/3_functional.xml index 701b557..7b1ea6e 100644 --- a/devel/requirements/3_functional.xml +++ b/devel/requirements/3_functional.xml @@ -119,11 +119,50 @@ <listitem id="UIT-1"><para>A terminal.</para></listitem> <listitem id="UIT-2"><para>An external partition editor.</para></listitem> <listitem id="UIT-3"><para>A lightweight Web browser.</para></listitem> + <listitem id="UIT-4"><para>A chooser for Advanced Options, as described in</para></listitem> </orderedlist> </para> </formalpara> </section> </section> + <section id="ui_advopts"> + <title>Advanced Options</title> + <section id="ui_advopts_meta"> + <title>Description / Priority</title> + <para>The system will allow the User to set certain advanced options, if desired. Priority: High.</para> + </section> + <section id="ui_advopts_req"> + <title>Functional Requirements</title> + <formalpara id="UI.AdvOpts.OnlyWhenRequested"> + <title>UI.AdvOpts.OnlyWhenRequested</title> + <para>The system shall only present the User with the Advanced Options screen if the user explicitly requests it to be shown.</para> + </formalpara> + <formalpara id="UI.AdvOpts.Repository"> + <title>UI.AdvOpts.Repository</title> + <para>The system shall allow the User to override the default repository information.</para> + </formalpara> + <formalpara id="UI.AdvOpts.SigningKeys"> + <title>UI.AdvOpts.SigningKeys</title> + <para>The system shall allow the User to override the default signing keys used to verify packages during installation.</para> + </formalpara> + <formalpara id="UI.AdvOpts.Arch"> + <title>UI.AdvOpts.Arch</title> + <para>The system shall allow the User to override the target system's CPU architecture.</para> + </formalpara> + <formalpara id="UI.AdvOpts.Version"> + <title>UI.AdvOpts.Version</title> + <para>The system shall allow the User to override the version of Adélie Linux being installed.</para> + </formalpara> + <formalpara id="UI.AdvOpts.Version.RepoAdmonish"> + <title>UI.AdvOpts.Version.RepoAdmonish</title> + <para>The system shall warn the User that the Version key has no effect when the repository information is overridden.</para> + </formalpara> + <formalpara id="UI.AdvOpts.ExtraLines"> + <title>UI.AdvOpts.ExtraLines</title> + <para>The system shall allow the User to enter additional lines to be appended to the end of the HorizonScript.</para> + </formalpara> + </section> + </section> <section id="ui_input"> <title>Input Device Configuration</title> <section id="ui_input_meta"> diff --git a/ui/qt5/CMakeLists.txt b/ui/qt5/CMakeLists.txt index 449e9bc..086abc7 100644 --- a/ui/qt5/CMakeLists.txt +++ b/ui/qt5/CMakeLists.txt @@ -16,6 +16,7 @@ set(UI_SOURCES crypt_sha512.c intropage.cc + advoptsdialog.cc inputpage.cc partitiondiskpage.cc partitionchoicepage.cc diff --git a/ui/qt5/advoptsdialog.cc b/ui/qt5/advoptsdialog.cc new file mode 100644 index 0000000..598f093 --- /dev/null +++ b/ui/qt5/advoptsdialog.cc @@ -0,0 +1,127 @@ +/* + * advoptsdialog.cc - Implementation of the UI.AdvOpts page + * horizon-qt5, the Qt 5 user interface for + * Project Horizon + * + * Copyright (c) 2023 Adélie Linux and contributors. All rights reserved. + * This code is licensed under the AGPL 3.0 license, as noted in the + * LICENSE-code file in the root directory of this repository. + * + * SPDX-License-Identifier: AGPL-3.0-only + */ + +#include <QVBoxLayout> +#include <QHBoxLayout> +#include <QComboBox> +#include <QLabel> +#include <QLineEdit> +#include <QTextEdit> +#include <QPushButton> + +#include "advoptsdialog.hh" + +void updateSubarchBox(QComboBox *subarchBox, HorizonWizard::Arch arch, HorizonWizard *wizard) { + subarchBox->clear(); + auto current = wizard->subarch; + for(const auto &subarch : wizard->subarchesForArch(arch)) { + const auto text = QString::fromStdString(subarch.first); + subarchBox->addItem(text, QVariant::fromValue<int>(subarch.second)); + if(current == subarch.second) { + subarchBox->setCurrentText(text); + } + } +} + +inline void configTextEdit(QTextEdit *edit) { + edit->setAcceptRichText(false); + edit->setFixedHeight(70); + edit->setHorizontalScrollBarPolicy(Qt::ScrollBarAsNeeded); + edit->setVerticalScrollBarPolicy(Qt::ScrollBarAsNeeded); +} + +AdvOptsDialog::AdvOptsDialog(HorizonWizard *wizard, QWidget *parent) : QDialog(parent) { + setWindowTitle(tr("System Installation Advanced Options")); + + auto warnLabel = new QLabel(tr("<b>WARNING</b>: Modifying <u>any</u> of the settings on this page may cause installation to fail.")); + warnLabel->setTextFormat(Qt::RichText); + + auto version = new QLabel(tr("&Version to install:")); + auto versionEdit = new QLineEdit(this); + versionEdit->setText(QString::fromStdString(wizard->version)); + version->setBuddy(versionEdit); + + auto repos = new QLabel(tr("URLs for package &repositories:")); + auto repoEdit = new QTextEdit(this); + configTextEdit(repoEdit); + repoEdit->setPlainText(wizard->repositories.join("\n")); + repos->setBuddy(repoEdit); + + auto keys = new QLabel(tr("URLs for package &signing keys: (<i>must begin with https:</i>)")); + keys->setTextFormat(Qt::RichText); + auto keyEdit = new QTextEdit(this); + configTextEdit(keyEdit); + keyEdit->setPlainText(wizard->signing_keys.join("\n")); + keys->setBuddy(keyEdit); + + auto arch = new QLabel(tr("Target CPU &architecture:")); + auto archBox = new QComboBox(this); + archBox->setEditable(false); + for(const auto &arches : wizard->arches) { + const auto text = QString::fromStdString(arches.first); + archBox->addItem(text, QVariant::fromValue<int>(arches.second)); + if(wizard->arch == arches.second) { + archBox->setCurrentText(text); + } + } + arch->setBuddy(archBox); + + auto subarch = new QLabel(tr("Sub-architecture (if applicable):")); + auto subarchBox = new QComboBox(this); + subarchBox->setEditable(false); + updateSubarchBox(subarchBox, wizard->arch, wizard); + subarch->setBuddy(subarchBox); + + connect(archBox, QOverload<int>::of(&QComboBox::currentIndexChanged), [=](int index) { + updateSubarchBox(subarchBox, static_cast<HorizonWizard::Arch>(archBox->itemData(index).toInt()), wizard); + }); + + auto saveButton = new QPushButton(tr("&Save")); + connect(saveButton, &QPushButton::clicked, + [this, wizard, archBox, subarchBox, versionEdit, repoEdit, keyEdit](bool) { + wizard->arch = static_cast<HorizonWizard::Arch>(archBox->currentData().toInt()); + wizard->subarch = static_cast<HorizonWizard::Subarch>(subarchBox->currentData().toInt()); + wizard->version = versionEdit->text().toStdString(); + wizard->repositories = repoEdit->toPlainText().split('\n'); + wizard->signing_keys = keyEdit->toPlainText().split('\n'); + this->accept(); + }); + auto cancelButton = new QPushButton(tr("&Cancel")); + connect(cancelButton, &QPushButton::clicked, [this](bool) { + this->reject(); + }); + + auto buttonLayout = new QHBoxLayout; + buttonLayout->addWidget(cancelButton); + buttonLayout->addStretch(); + buttonLayout->addWidget(saveButton); + + auto layout = new QVBoxLayout; + layout->addWidget(warnLabel); + layout->addSpacing(25); + layout->addWidget(arch); + layout->addWidget(archBox); + layout->addWidget(subarch); + layout->addWidget(subarchBox); + layout->addSpacing(25); + layout->addWidget(version); + layout->addWidget(versionEdit); + layout->addSpacing(25); + layout->addWidget(repos); + layout->addWidget(repoEdit); + layout->addSpacing(25); + layout->addWidget(keys); + layout->addWidget(keyEdit); + layout->addSpacing(25); + layout->addLayout(buttonLayout); + this->setLayout(layout); +}
\ No newline at end of file diff --git a/ui/qt5/advoptsdialog.hh b/ui/qt5/advoptsdialog.hh new file mode 100644 index 0000000..fee511c --- /dev/null +++ b/ui/qt5/advoptsdialog.hh @@ -0,0 +1,24 @@ +/* + * advoptsdialog.hh - Definition of the UI.AdvOpts page + * horizon-qt5, the Qt 5 user interface for + * Project Horizon + * + * Copyright (c) 2019 Adélie Linux and contributors. All rights reserved. + * This code is licensed under the AGPL 3.0 license, as noted in the + * LICENSE-code file in the root directory of this repository. + * + * SPDX-License-Identifier: AGPL-3.0-only + */ + +#ifndef ADVOPTSDIALOG_HH +#define ADVOPTSDIALOG_HH + +#include "horizonwizard.hh" +#include <QDialog> + +class AdvOptsDialog : public QDialog { +public: + AdvOptsDialog(HorizonWizard *wizard, QWidget *parent = nullptr); +}; + +#endif /* !ADVOPTSDIALOG_HH */ diff --git a/ui/qt5/horizonwizard.cc b/ui/qt5/horizonwizard.cc index e78d991..97b2939 100644 --- a/ui/qt5/horizonwizard.cc +++ b/ui/qt5/horizonwizard.cc @@ -583,8 +583,14 @@ QString HorizonWizard::toHScript() { break; } + if(!repositories.empty()) { + for(const auto &repo : repositories) { + lines << QString{"repository %1"}.arg(repo); + } + } + if(!signing_keys.empty()) { - for(const auto &key : signing_keys) { + for(const auto &key: signing_keys) { lines << QString{"signingkey %1"}.arg(key); } } diff --git a/ui/qt5/horizonwizard.hh b/ui/qt5/horizonwizard.hh index d4a5dfd..cd0552b 100644 --- a/ui/qt5/horizonwizard.hh +++ b/ui/qt5/horizonwizard.hh @@ -97,10 +97,10 @@ public: enum Arch { aarch64, armv7, - mips, - mips64, - mipsel, - mips64el, + mips, + mips64, + mipsel, + mips64el, pmmx, ppc, ppc64, @@ -115,6 +115,32 @@ public: ppc64_PowerNV }; + /*! Valid architectures, used by AdvOpts */ + const std::vector< std::pair<std::string, HorizonWizard::Arch> > arches = { + {"64-bit x86 (x86_64)", x86_64}, + {"32-bit x86, with MMX (pmmx)", pmmx}, + {"64-bit PowerPC, big-endian (ppc64)", ppc64}, + {"32-bit PowerPC, big-endian (ppc)", ppc}, + {"64-bit ARM, little-endian (aarch64)", aarch64}, + {"32-bit ARMv7, little-endian (armv7)", armv7}, + {"64-bit MIPS, big-endian (mips64)", mips64}, + {"32-bit MIPS, big-endian (mips)", mips}, + {"64-bit MIPS, little-endian (mips64el)", mips64el}, + {"32-bit MIPS, little-endian (mipsel)", mipsel}, + {"Native / Default (UnknownCPU)", UnknownCPU} + }; + + /*! Returns valid subarchitectures for a given architecture. */ + static std::vector< std::pair<std::string, HorizonWizard::Subarch> > subarchesForArch(HorizonWizard::Arch the_arch) { + if(the_arch == HorizonWizard::ppc64) { + return {std::make_pair("PowerMac", HorizonWizard::ppc64_PowerMac), + std::make_pair("PowerNV", HorizonWizard::ppc64_PowerNV), + std::make_pair("pSeries", HorizonWizard::ppc64_pSeries)}; + } + + return {std::make_pair("None", HorizonWizard::NoSubarch)}; + } + enum PackageType { Standard, Mobile, @@ -151,8 +177,10 @@ public: * @example distfiles.adelielinux.org */ std::string mirror_domain; - /*! The version of Adélie to install. Typically "1.0". */ + /*! The version of Adélie to install. Typically "stable". */ std::string version; + /*! The repositories to use. If empty, use defaults. */ + QStringList repositories; /*! The signing keys to use. If empty, use defaults. */ QStringList signing_keys; /*! The architecture being installed. */ diff --git a/ui/qt5/intropage.cc b/ui/qt5/intropage.cc index ab21657..94e222d 100644 --- a/ui/qt5/intropage.cc +++ b/ui/qt5/intropage.cc @@ -11,6 +11,7 @@ */ #include "intropage.hh" +#include "advoptsdialog.hh" #include <QLabel> #ifdef HAS_INSTALL_ENV @@ -36,6 +37,12 @@ IntroPage::IntroPage(QWidget *parent) : HorizonWizardPage(parent) { "<p>For more information about the installfile format and syntax, see the <a href=\"https://help.adelielinux.org/html/install/\">Adélie Linux Installation Handbook</a>.</p>")); descLabel->setOpenExternalLinks(true); descLabel->setTextFormat(Qt::RichText); + + toolButton = new QPushButton(tr("&Advanced Options..."), this); + connect(toolButton, &QPushButton::clicked, [this](bool) { + AdvOptsDialog dialog(horizonWizard(), this); + dialog.exec(); + }); #else /* HAS_INSTALL_ENV */ QMenu *toolMenu; toolButton = new QPushButton(tr("Launch &Tool..."), this); @@ -56,6 +63,10 @@ IntroPage::IntroPage(QWidget *parent) : HorizonWizardPage(parent) { p->start("netsurf-gtk3", QStringList()); horizonWizard()->tools.push_back(p); }); + connect(toolMenu->addAction("&Advanced Options"), &QAction::triggered, [this](void) { + AdvOptsDialog dialog(horizonWizard(), this); + dialog.exec(); + }); toolButton->setMenu(toolMenu); descLabel = new QLabel( @@ -75,9 +86,7 @@ IntroPage::IntroPage(QWidget *parent) : HorizonWizardPage(parent) { layout = new QVBoxLayout; layout->addWidget(descLabel); -#ifdef HAS_INSTALL_ENV layout->addStretch(); layout->addWidget(toolButton, 0, Qt::AlignCenter); -#endif /* HAS_INSTALL_ENV */ setLayout(layout); } diff --git a/ui/qt5/intropage.hh b/ui/qt5/intropage.hh index 5733985..aedb106 100644 --- a/ui/qt5/intropage.hh +++ b/ui/qt5/intropage.hh @@ -13,9 +13,7 @@ #ifndef INTROPAGE_HH #define INTROPAGE_HH -#ifdef HAS_INSTALL_ENV #include <QPushButton> -#endif /* HAS_INSTALL_ENV */ #include "horizonwizardpage.hh" @@ -23,10 +21,8 @@ class IntroPage : public HorizonWizardPage { public: IntroPage(QWidget *parent = nullptr); -#ifdef HAS_INSTALL_ENV private: QPushButton *toolButton; -#endif /* HAS_INSTALL_ENV */ }; #endif /* !INTROPAGE_HH */ |