From c9f942ad673712fbdcab39622cd30579798f207a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ga=C3=ABl=20PORTAY?= Date: Sun, 21 Jun 2020 18:41:21 -0400 Subject: [PATCH 01/20] [libcalamares] Add default value to variant helpers - Some variant helpers take a default parameter if the map does not contains the given key or if the type mismatches. Make all helpers behave the same. --- src/libcalamares/utils/Variant.cpp | 41 ++++++++++++------------------ src/libcalamares/utils/Variant.h | 31 +++++++++++----------- 2 files changed, 31 insertions(+), 41 deletions(-) diff --git a/src/libcalamares/utils/Variant.cpp b/src/libcalamares/utils/Variant.cpp index c02efa9d9..18d7475f1 100644 --- a/src/libcalamares/utils/Variant.cpp +++ b/src/libcalamares/utils/Variant.cpp @@ -38,21 +38,19 @@ namespace CalamaresUtils bool getBool( const QVariantMap& map, const QString& key, bool d ) { - bool result = d; if ( map.contains( key ) ) { auto v = map.value( key ); if ( v.type() == QVariant::Bool ) { - result = v.toBool(); + return v.toBool(); } } - - return result; + return d; } QString -getString( const QVariantMap& map, const QString& key ) +getString( const QVariantMap& map, const QString& key, const QString& d ) { if ( map.contains( key ) ) { @@ -62,11 +60,11 @@ getString( const QVariantMap& map, const QString& key ) return v.toString(); } } - return QString(); + return d; } QStringList -getStringList( const QVariantMap& map, const QString& key ) +getStringList( const QVariantMap& map, const QString& key, const QStringList& d ) { if ( map.contains( key ) ) { @@ -76,60 +74,53 @@ getStringList( const QVariantMap& map, const QString& key ) return v.toStringList(); } } - return QStringList(); + return d; } qint64 getInteger( const QVariantMap& map, const QString& key, qint64 d ) { - qint64 result = d; if ( map.contains( key ) ) { auto v = map.value( key ); - result = v.toString().toLongLong(nullptr, 0); + return v.toString().toLongLong(nullptr, 0); } - - return result; + return d; } quint64 -getUnsignedInteger( const QVariantMap& map, const QString& key, quint64 u ) +getUnsignedInteger( const QVariantMap& map, const QString& key, quint64 d ) { - quint64 result = u; if ( map.contains( key ) ) { auto v = map.value( key ); - result = v.toString().toULongLong(nullptr, 0); + return v.toString().toULongLong(nullptr, 0); } - - return result; + return d; } double getDouble( const QVariantMap& map, const QString& key, double d ) { - double result = d; if ( map.contains( key ) ) { auto v = map.value( key ); if ( v.type() == QVariant::Int ) { - result = v.toInt(); + return v.toInt(); } else if ( v.type() == QVariant::Double ) { - result = v.toDouble(); + return v.toDouble(); } } - - return result; + return d; } QVariantMap -getSubMap( const QVariantMap& map, const QString& key, bool& success ) +getSubMap( const QVariantMap& map, const QString& key, bool& success, const QVariantMap& d ) { success = false; - if ( map.contains( key ) ) { auto v = map.value( key ); @@ -139,7 +130,7 @@ getSubMap( const QVariantMap& map, const QString& key, bool& success ) return v.toMap(); } } - return QVariantMap(); + return d; } } // namespace CalamaresUtils diff --git a/src/libcalamares/utils/Variant.h b/src/libcalamares/utils/Variant.h index b678a2c6e..fb9cdb205 100644 --- a/src/libcalamares/utils/Variant.h +++ b/src/libcalamares/utils/Variant.h @@ -33,45 +33,44 @@ namespace CalamaresUtils { /** - * Get a bool value from a mapping with a given key; returns the default - * if no value is stored in the map. + * Get a bool value from a mapping with a given key; returns @p d if no value. */ -DLLEXPORT bool getBool( const QVariantMap& map, const QString& key, bool d ); +DLLEXPORT bool getBool( const QVariantMap& map, const QString& key, bool d = false ); /** - * Get a string value from a mapping; returns empty QString if no value. + * Get a string value from a mapping with a given key; returns @p d if no value. */ -DLLEXPORT QString getString( const QVariantMap& map, const QString& key ); +DLLEXPORT QString getString( const QVariantMap& map, const QString& key, const QString& d = QString() ); /** - * Get a string list from a mapping; returns empty list if no value. + * Get a string list from a mapping with a given key; returns @p d if no value. */ -DLLEXPORT QStringList getStringList( const QVariantMap& map, const QString& key ); +DLLEXPORT QStringList getStringList( const QVariantMap& map, const QString& key, const QStringList& d = QStringList() ); /** - * Get an integer value from a mapping; returns @p d if no value. + * Get an integer value from a mapping with a given key; returns @p d if no value. */ -DLLEXPORT qint64 getInteger( const QVariantMap& map, const QString& key, qint64 d ); +DLLEXPORT qint64 getInteger( const QVariantMap& map, const QString& key, qint64 d = 0); /** - * Get an unsigned integer value from a mapping; returns @p u if no value. + * Get an unsigned integer value from a mapping with a given key; returns @p d if no value. */ -DLLEXPORT quint64 getUnsignedInteger( const QVariantMap& map, const QString& key, quint64 u ); +DLLEXPORT quint64 getUnsignedInteger( const QVariantMap& map, const QString& key, quint64 d = 0 ); /** - * Get a double value from a mapping (integers are converted); returns @p d if no value. + * Get a double value from a mapping with a given key (integers are converted); returns @p d if no value. */ -DLLEXPORT double getDouble( const QVariantMap& map, const QString& key, double d ); +DLLEXPORT double getDouble( const QVariantMap& map, const QString& key, double d = 0.0 ); /** - * Returns a sub-map (i.e. a nested map) from the given mapping with the + * Returns a sub-map (i.e. a nested map) from a given mapping with a * given key. @p success is set to true if the @p key exists * in @p map and converts to a map, false otherwise. * - * Returns an empty map if there is no such key or it is not a map-value. + * Returns @p d if there is no such key or it is not a map-value. * (e.g. if @p success is false). */ -DLLEXPORT QVariantMap getSubMap( const QVariantMap& map, const QString& key, bool& success ); +DLLEXPORT QVariantMap getSubMap( const QVariantMap& map, const QString& key, bool& success, const QVariantMap& d = QVariantMap() ); } // namespace CalamaresUtils #endif From 9392473fec2c56ee880a84c7215cbad6109fcdbd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ga=C3=ABl=20PORTAY?= Date: Tue, 16 Jun 2020 13:20:37 -0400 Subject: [PATCH 02/20] [partition] Add the GPT type and attributes to global storage --- src/modules/partition/jobs/FillGlobalStorageJob.cpp | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/modules/partition/jobs/FillGlobalStorageJob.cpp b/src/modules/partition/jobs/FillGlobalStorageJob.cpp index 1242b7804..d695a5f6a 100644 --- a/src/modules/partition/jobs/FillGlobalStorageJob.cpp +++ b/src/modules/partition/jobs/FillGlobalStorageJob.cpp @@ -93,6 +93,8 @@ mapForPartition( Partition* partition, const QString& uuid ) map[ "device" ] = partition->partitionPath(); map[ "partlabel" ] = partition->label(); map[ "partuuid" ] = partition->uuid(); + map[ "parttype" ] = partition->type(); + map[ "partattrs" ] = partition->attributes(); map[ "mountPoint" ] = PartitionInfo::mountPoint( partition ); map[ "fsName" ] = userVisibleFS( partition->fileSystem() ); map[ "fs" ] = untranslatedFS( partition->fileSystem() ); @@ -110,6 +112,7 @@ mapForPartition( Partition* partition, const QString& uuid ) using TR = Logger::DebugRow< const char* const, const QString& >; deb << Logger::SubEntry << "mapping for" << partition->partitionPath() << partition->deviceNode() << TR( "partlabel", map[ "partlabel" ].toString() ) << TR( "partuuid", map[ "partuuid" ].toString() ) + << TR( "parttype", map[ "partype" ].toString() ) << TR( "partattrs", map[ "partattrs" ].toString() ) << TR( "mountPoint:", PartitionInfo::mountPoint( partition ) ) << TR( "fs:", map[ "fs" ].toString() ) << TR( "fsName", map[ "fsName" ].toString() ) << TR( "uuid", uuid ) << TR( "claimed", map[ "claimed" ].toString() ); From 8a9e85db71cce9fade23fd17deaafe671cea8d2a Mon Sep 17 00:00:00 2001 From: Adriaan de Groot Date: Wed, 24 Jun 2020 04:53:22 -0400 Subject: [PATCH 03/20] Branding: shuffle around a bit, expand documentation --- src/branding/default/branding.desc | 63 ++++++++++++++++++++++-------- 1 file changed, 46 insertions(+), 17 deletions(-) diff --git a/src/branding/default/branding.desc b/src/branding/default/branding.desc index f8cc88295..fc0a16f7e 100644 --- a/src/branding/default/branding.desc +++ b/src/branding/default/branding.desc @@ -7,6 +7,12 @@ --- componentName: default + +### WELCOME / OVERALL WORDING +# +# These settings affect some overall phrasing and looks, +# which are most visible in the welcome page. + # This selects between different welcome texts. When false, uses # the traditional "Welcome to the %1 installer.", and when true, # uses "Welcome to the Calamares installer for %1." This allows @@ -20,6 +26,12 @@ welcomeStyleCalamares: false # may have surprising effects on HiDPI monitors). welcomeExpandingLogo: true +### WINDOW CONFIGURATION +# +# The settings here affect the placement of the Calamares +# window through hints to the window manager and initial +# sizing of the Calamares window. + # Size and expansion policy for Calamares. # - "normal" or unset, expand as needed, use *windowSize* # - "fullscreen", start as large as possible, ignore *windowSize* @@ -41,6 +53,14 @@ windowSize: 800px,520px # *windowExpanding* set to "fullscreen"). windowPlacement: center +### PANELS CONFIGURATION +# +# Calamares has a main content area, and two panels (navigation +# and progress / sidebar). The panels can be controlled individually, +# or switched off. If both panels are switched off, the layout of +# the main content area loses its margins, on the assumption that +# you're doing something special. + # Kind of sidebar (panel on the left, showing progress). # - "widget" or unset, use traditional sidebar (logo, items) # - "none", hide it entirely @@ -66,6 +86,12 @@ sidebar: widget # except the default is *bottom*. navigation: widget + +### STRINGS, IMAGES AND COLORS +# +# This section contains the "branding proper" of names +# and images, rather than global-look settings. + # These are strings shown to the user in the user interface. # There is no provision for translating them -- since they # are names, the string is included as-is. @@ -139,9 +165,28 @@ images: # productWallpaper: "wallpaper.png" productWelcome: "languages.png" +# Colors for text and background components. +# +# - sidebarBackground is the background of the sidebar +# - sidebarText is the (foreground) text color +# - sidebarTextHighlight sets the background of the selected (current) step. +# Optional, and defaults to the application palette. +# - sidebarSelect is the text color of the selected step. +# +# These colors can **also** be set through the stylesheet, if the +# branding component also ships a stylesheet.qss. Then they are +# the corresponding CSS attributes of #sidebarApp. +style: + sidebarBackground: "#292F34" + sidebarText: "#FFFFFF" + sidebarTextSelect: "#292F34" + sidebarTextHighlight: "#D35400" + +### SLIDESHOW +# # The slideshow is displayed during execution steps (e.g. when the # installer is actually writing to disk and doing other slow things). -# + # The slideshow can be a QML file (recommended) which can display # arbitrary things -- text, images, animations, or even play a game -- # during the execution step. The QML **is** abruptly stopped when the @@ -171,19 +216,3 @@ slideshow: "show.qml" slideshowAPI: 2 -# Colors for text and background components. -# -# - sidebarBackground is the background of the sidebar -# - sidebarText is the (foreground) text color -# - sidebarTextHighlight sets the background of the selected (current) step. -# Optional, and defaults to the application palette. -# - sidebarSelect is the text color of the selected step. -# -# These colors can **also** be set through the stylesheet, if the -# branding component also ships a stylesheet.qss. Then they are -# the corresponding CSS attributes of #sidebarApp. -style: - sidebarBackground: "#292F34" - sidebarText: "#FFFFFF" - sidebarTextSelect: "#292F34" - sidebarTextHighlight: "#D35400" From bfbb0f1c49ae6bd6f311fbf684aa7577517a9ee7 Mon Sep 17 00:00:00 2001 From: Adriaan de Groot Date: Wed, 24 Jun 2020 04:59:19 -0400 Subject: [PATCH 04/20] [libcalamaresui] Mark some TODO for 3.3, in passing --- src/libcalamaresui/utils/CalamaresUtilsGui.h | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/libcalamaresui/utils/CalamaresUtilsGui.h b/src/libcalamaresui/utils/CalamaresUtilsGui.h index 961ed5bc7..251741fad 100644 --- a/src/libcalamaresui/utils/CalamaresUtilsGui.h +++ b/src/libcalamaresui/utils/CalamaresUtilsGui.h @@ -87,6 +87,7 @@ UIDLLEXPORT QPixmap defaultPixmap( ImageType type, ImageMode mode = CalamaresUtils::Original, const QSize& size = QSize( 0, 0 ) ); +// TODO:3.3:This has only one consumer, move to ImageRegistry, make static /** * @brief createRoundedImage returns a rounded version of a pixmap. * @param avatar the input pixmap. @@ -103,6 +104,7 @@ UIDLLEXPORT QPixmap createRoundedImage( const QPixmap& avatar, const QSize& size */ UIDLLEXPORT void unmarginLayout( QLayout* layout ); +// TODO:3.3:This has only one consumer, move to LicensePage, make static /** * @brief clearLayout recursively walks the QLayout tree and deletes all the child * widgets and layouts. @@ -113,7 +115,7 @@ UIDLLEXPORT void clearLayout( QLayout* layout ); UIDLLEXPORT void setDefaultFontSize( int points ); UIDLLEXPORT int defaultFontSize(); // in points UIDLLEXPORT int defaultFontHeight(); // in pixels, DPI-specific -UIDLLEXPORT QFont defaultFont(); +UIDLLEXPORT QFont defaultFont(); // TODO:3.3:This has one consumer, move to BlankViewStep UIDLLEXPORT QFont largeFont(); UIDLLEXPORT QSize defaultIconSize(); From 4a6ee39f8bc8f64c740dbb4e92ea6ec58ade5df1 Mon Sep 17 00:00:00 2001 From: Adriaan de Groot Date: Wed, 24 Jun 2020 11:08:31 +0200 Subject: [PATCH 05/20] [libcalamaresui] Blanket unmargin the content area --- src/libcalamaresui/ViewManager.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/src/libcalamaresui/ViewManager.cpp b/src/libcalamaresui/ViewManager.cpp index c78680418..e72c434f8 100644 --- a/src/libcalamaresui/ViewManager.cpp +++ b/src/libcalamaresui/ViewManager.cpp @@ -71,6 +71,7 @@ ViewManager::ViewManager( QObject* parent ) Q_ASSERT( !s_instance ); QBoxLayout* mainLayout = new QVBoxLayout; + mainLayout->setContentsMargins( 0, 0, 0, 0 ); m_widget->setObjectName( "viewManager" ); m_widget->setLayout( mainLayout ); From 347a25d13d264efc71fc74059a5e4e607badf9f1 Mon Sep 17 00:00:00 2001 From: Adriaan de Groot Date: Wed, 24 Jun 2020 20:48:06 +0200 Subject: [PATCH 06/20] [libcalamaresui] Avoid nullptr deref - there's a check already there, and probably this means things are hopelessly broken anyway, but let's not crash here. --- src/libcalamaresui/ViewManager.cpp | 18 +++++++++++------- 1 file changed, 11 insertions(+), 7 deletions(-) diff --git a/src/libcalamaresui/ViewManager.cpp b/src/libcalamaresui/ViewManager.cpp index e72c434f8..40e621ae8 100644 --- a/src/libcalamaresui/ViewManager.cpp +++ b/src/libcalamaresui/ViewManager.cpp @@ -128,15 +128,19 @@ ViewManager::insertViewStep( int before, ViewStep* step ) { cError() << "ViewStep" << step->moduleInstanceKey() << "has no widget."; } - - QLayout* layout = step->widget()->layout(); - if ( layout ) + else { - layout->setContentsMargins( 0, 0, 0, 0 ); + // step->adjustMargins() "some magic" + QLayout* layout = step->widget()->layout(); + if ( layout ) + { + layout->setContentsMargins( 0, 0, 0, 0 ); + } + + m_stack->insertWidget( before, step->widget() ); + m_stack->setCurrentIndex( 0 ); + step->widget()->setFocus(); } - m_stack->insertWidget( before, step->widget() ); - m_stack->setCurrentIndex( 0 ); - step->widget()->setFocus(); emit endInsertRows(); } From 748d76df4f0f9c4b34f491f1d75234cbc1d8896f Mon Sep 17 00:00:00 2001 From: Adriaan de Groot Date: Wed, 24 Jun 2020 21:15:37 +0200 Subject: [PATCH 07/20] [libcalamaresui] Add support for steps with own margins --- src/libcalamaresui/viewpages/ViewStep.cpp | 13 ++++++++ src/libcalamaresui/viewpages/ViewStep.h | 40 +++++++++++++++++++++-- 2 files changed, 50 insertions(+), 3 deletions(-) diff --git a/src/libcalamaresui/viewpages/ViewStep.cpp b/src/libcalamaresui/viewpages/ViewStep.cpp index 82f8688dc..64979836f 100644 --- a/src/libcalamaresui/viewpages/ViewStep.cpp +++ b/src/libcalamaresui/viewpages/ViewStep.cpp @@ -19,6 +19,9 @@ #include "ViewStep.h" +#include +#include + namespace Calamares { @@ -85,4 +88,14 @@ ViewStep::checkRequirements() return RequirementsList(); } +QSize +ViewStep::widgetMargins( Qt::Orientations panelSides ) +{ + Q_UNUSED( panelSides ); + + // Application's default style + const auto* s = QApplication::style(); + return QSize( s->pixelMetric( QStyle::PM_LayoutLeftMargin ), s->pixelMetric( QStyle::PM_LayoutTopMargin ) ); +} + } // namespace Calamares diff --git a/src/libcalamaresui/viewpages/ViewStep.h b/src/libcalamaresui/viewpages/ViewStep.h index 707bc0b3b..59f307af2 100644 --- a/src/libcalamaresui/viewpages/ViewStep.h +++ b/src/libcalamaresui/viewpages/ViewStep.h @@ -52,27 +52,61 @@ public: explicit ViewStep( QObject* parent = nullptr ); virtual ~ViewStep() override; + /** @brief Human-readable name of the step + * + * This (translated) string is shown in the sidebar (progress) + * and during installation. There is no default. + */ virtual QString prettyName() const = 0; - /** + /** @brief Describe what this step will do during install + * * Optional. May return a non-empty string describing what this * step is going to do (should be translated). This is also used * in the summary page to describe what is going to be done. * Return an empty string to provide no description. + * + * The default implementation returns an empty string, so nothing + * will be displayed for this step when a summary is shown. */ virtual QString prettyStatus() const; - /** + /** @brief Return a long description what this step will do during install + * * Optional. May return a widget which will be inserted in the summary * page. The caller takes ownership of the widget. Return nullptr to * provide no widget. In general, this is only used for complicated * steps where prettyStatus() is not sufficient. + * + * The default implementation returns nullptr, so nothing + * will be displayed for this step when a summary is shown. */ virtual QWidget* createSummaryWidget() const; - //TODO: we might want to make this a QSharedPointer + /** @brief Get (or create) the widget for this view step + * + * While a view step **may** create the widget when it is loaded, + * it is recommended to wait with widget creation until the + * widget is actually asked for: a view step **may** be used + * without a UI. + */ virtual QWidget* widget() = 0; + /** @brief Get margins for this widget + * + * This is called by the layout manager to find the desired + * margins (width is used for left and right margin, height is + * used for top and bottom margins) for the widget. The + * @p panelSides indicates where there are panels in the overall + * layout: horizontally and / or vertically adjacent (or none!) + * to the view step's widget. + * + * Should return a size based also on QStyle metrics for layout. + * The default implementation just returns the default layout metrics + * (often 11 pixels on a side). + */ + virtual QSize widgetMargins( Qt::Orientations panelSides ); + /** * @brief Multi-page support, go next * From 1648f311fe18570ebafe89b25791b9c8655cf9f1 Mon Sep 17 00:00:00 2001 From: Adriaan de Groot Date: Wed, 24 Jun 2020 21:26:22 +0200 Subject: [PATCH 08/20] [libcalamaresui] apidox touch-up --- src/libcalamaresui/ViewManager.h | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/src/libcalamaresui/ViewManager.h b/src/libcalamaresui/ViewManager.h index cfff5abd9..73d1a0121 100644 --- a/src/libcalamaresui/ViewManager.h +++ b/src/libcalamaresui/ViewManager.h @@ -100,10 +100,11 @@ public: int currentStepIndex() const; /** - * @ brief Called when "Cancel" is clicked; asks for confirmation. + * @brief Called when "Cancel" is clicked; asks for confirmation. * Other means of closing Calamares also call this method, e.g. alt-F4. - * At the end of installation, no confirmation is asked. Returns true - * if the user confirms closing the window. + * At the end of installation, no confirmation is asked. + * + * @return @c true if the user confirms closing the window. */ bool confirmCancelInstallation(); From d7ed450dbfb334f24506915d5ee6a44de6965797 Mon Sep 17 00:00:00 2001 From: Adriaan de Groot Date: Wed, 24 Jun 2020 21:41:06 +0200 Subject: [PATCH 09/20] [libcalamaresui] Give ViewManager data about side-panels --- src/libcalamaresui/ViewManager.cpp | 1 + src/libcalamaresui/ViewManager.h | 5 +++++ 2 files changed, 6 insertions(+) diff --git a/src/libcalamaresui/ViewManager.cpp b/src/libcalamaresui/ViewManager.cpp index 40e621ae8..45baa2f59 100644 --- a/src/libcalamaresui/ViewManager.cpp +++ b/src/libcalamaresui/ViewManager.cpp @@ -67,6 +67,7 @@ ViewManager::ViewManager( QObject* parent ) : QAbstractListModel( parent ) , m_currentStep( -1 ) , m_widget( new QWidget() ) + , m_panelSides( Qt::Horizontal | Qt::Vertical ) { Q_ASSERT( !s_instance ); diff --git a/src/libcalamaresui/ViewManager.h b/src/libcalamaresui/ViewManager.h index 73d1a0121..0fb1cbb45 100644 --- a/src/libcalamaresui/ViewManager.h +++ b/src/libcalamaresui/ViewManager.h @@ -54,6 +54,9 @@ class UIDLLEXPORT ViewManager : public QAbstractListModel Q_PROPERTY( bool quitVisible READ quitVisible NOTIFY quitVisibleChanged FINAL ) + ///@brief Sides on which the ViewManager has side-panels + Q_PROPERTY( Qt::Orientations panelSides MEMBER m_panelSides ) + public: /** * @brief instance access to the ViewManager singleton. @@ -245,6 +248,8 @@ private: QString m_quitTooltip; bool m_quitVisible = true; + Qt::Orientations m_panelSides; + public: /** @section Model * From d952faf909bc423eb29df7e38e266460d1b9f0ff Mon Sep 17 00:00:00 2001 From: Adriaan de Groot Date: Wed, 24 Jun 2020 22:12:59 +0200 Subject: [PATCH 10/20] [libcalamaresui] Set margins based on viewstep suggestion --- src/libcalamaresui/ViewManager.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/libcalamaresui/ViewManager.cpp b/src/libcalamaresui/ViewManager.cpp index 45baa2f59..a39fc141f 100644 --- a/src/libcalamaresui/ViewManager.cpp +++ b/src/libcalamaresui/ViewManager.cpp @@ -131,11 +131,11 @@ ViewManager::insertViewStep( int before, ViewStep* step ) } else { - // step->adjustMargins() "some magic" QLayout* layout = step->widget()->layout(); if ( layout ) { - layout->setContentsMargins( 0, 0, 0, 0 ); + const auto margins = step->widgetMargins( m_panelSides ); + layout->setContentsMargins( margins.width(), margins.height(), margins.width(), margins.height() ); } m_stack->insertWidget( before, step->widget() ); From 68aecf6a26c3f2664e0974261c4dce714f184d4d Mon Sep 17 00:00:00 2001 From: Adriaan de Groot Date: Wed, 24 Jun 2020 23:41:20 +0200 Subject: [PATCH 11/20] [libcalamaresui] Special margins for QML view steps If there are no surrounding panels, drop the margin around the QML on the assumption it needs to be full screen under special circumstances. --- src/libcalamaresui/viewpages/QmlViewStep.cpp | 16 ++++++++++++++++ src/libcalamaresui/viewpages/QmlViewStep.h | 1 + 2 files changed, 17 insertions(+) diff --git a/src/libcalamaresui/viewpages/QmlViewStep.cpp b/src/libcalamaresui/viewpages/QmlViewStep.cpp index 2234c230a..6318e47d8 100644 --- a/src/libcalamaresui/viewpages/QmlViewStep.cpp +++ b/src/libcalamaresui/viewpages/QmlViewStep.cpp @@ -151,6 +151,22 @@ QmlViewStep::widget() return m_widget; } +QSize +QmlViewStep::widgetMargins( Qt::Orientations panelSides ) +{ + // If any panels around it, use the standard, but if all the + // panels are hidden, like on full-screen with subsumed navigation, + // then no margins. + if ( panelSides ) + { + return ViewStep::widgetMargins( panelSides ); + } + else + { + return QSize( 0, 0 ); + } +} + void QmlViewStep::loadComplete() { diff --git a/src/libcalamaresui/viewpages/QmlViewStep.h b/src/libcalamaresui/viewpages/QmlViewStep.h index cad6bb395..e1f4caf28 100644 --- a/src/libcalamaresui/viewpages/QmlViewStep.h +++ b/src/libcalamaresui/viewpages/QmlViewStep.h @@ -55,6 +55,7 @@ public: virtual QString prettyName() const override; virtual QWidget* widget() override; + virtual QSize widgetMargins( Qt::Orientations panelSides ) override; virtual bool isNextEnabled() const override; virtual bool isBackEnabled() const override; From 8ced67680d2632a24f52a375ded2f5cf95e49b82 Mon Sep 17 00:00:00 2001 From: Adriaan de Groot Date: Thu, 25 Jun 2020 00:00:13 +0200 Subject: [PATCH 12/20] [calamares] Allow get/set of panel-sides - Add access to the panel-sides membe of the view manager, and calculate which sides are populated by panels (if any). - Pass the calculated panel-sides to the view manager before it starts adding viewpages, so they get consistent margins. --- src/calamares/CalamaresWindow.cpp | 24 +++++++++++++++++------- src/libcalamaresui/ViewManager.h | 5 ++++- 2 files changed, 21 insertions(+), 8 deletions(-) diff --git a/src/calamares/CalamaresWindow.cpp b/src/calamares/CalamaresWindow.cpp index a3775c44e..28b9df626 100644 --- a/src/calamares/CalamaresWindow.cpp +++ b/src/calamares/CalamaresWindow.cpp @@ -111,12 +111,12 @@ CalamaresWindow::getWidgetSidebar( QWidget* parent, int desiredWidth ) sideLayout->addWidget( debugWindowBtn ); debugWindowBtn->setFlat( true ); debugWindowBtn->setCheckable( true ); - connect( debugWindowBtn, &QPushButton::clicked, this, [ = ]( bool checked ) { + connect( debugWindowBtn, &QPushButton::clicked, this, [=]( bool checked ) { if ( checked ) { m_debugWindow = new Calamares::DebugWindow(); m_debugWindow->show(); - connect( m_debugWindow.data(), &Calamares::DebugWindow::closed, this, [ = ]() { + connect( m_debugWindow.data(), &Calamares::DebugWindow::closed, this, [=]() { m_debugWindow->deleteLater(); debugWindowBtn->setChecked( false ); } ); @@ -167,7 +167,7 @@ CalamaresWindow::getWidgetNavigation( QWidget* parent ) connect( back, &QPushButton::clicked, m_viewManager, &Calamares::ViewManager::back ); connect( m_viewManager, &Calamares::ViewManager::backEnabledChanged, back, &QPushButton::setEnabled ); connect( m_viewManager, &Calamares::ViewManager::backLabelChanged, back, &QPushButton::setText ); - connect( m_viewManager, &Calamares::ViewManager::backIconChanged, this, [ = ]( QString n ) { + connect( m_viewManager, &Calamares::ViewManager::backIconChanged, this, [=]( QString n ) { setButtonIcon( back, n ); } ); bottomLayout->addWidget( back ); @@ -179,7 +179,7 @@ CalamaresWindow::getWidgetNavigation( QWidget* parent ) connect( next, &QPushButton::clicked, m_viewManager, &Calamares::ViewManager::next ); connect( m_viewManager, &Calamares::ViewManager::nextEnabledChanged, next, &QPushButton::setEnabled ); connect( m_viewManager, &Calamares::ViewManager::nextLabelChanged, next, &QPushButton::setText ); - connect( m_viewManager, &Calamares::ViewManager::nextIconChanged, this, [ = ]( QString n ) { + connect( m_viewManager, &Calamares::ViewManager::nextIconChanged, this, [=]( QString n ) { setButtonIcon( next, n ); } ); bottomLayout->addWidget( next ); @@ -191,7 +191,7 @@ CalamaresWindow::getWidgetNavigation( QWidget* parent ) connect( quit, &QPushButton::clicked, m_viewManager, &Calamares::ViewManager::quit ); connect( m_viewManager, &Calamares::ViewManager::quitEnabledChanged, quit, &QPushButton::setEnabled ); connect( m_viewManager, &Calamares::ViewManager::quitLabelChanged, quit, &QPushButton::setText ); - connect( m_viewManager, &Calamares::ViewManager::quitIconChanged, this, [ = ]( QString n ) { + connect( m_viewManager, &Calamares::ViewManager::quitIconChanged, this, [=]( QString n ) { setButtonIcon( quit, n ); } ); connect( m_viewManager, &Calamares::ViewManager::quitTooltipChanged, quit, &QPushButton::setToolTip ); @@ -237,11 +237,13 @@ CalamaresWindow::getQmlNavigation( QWidget* parent ) } #else // Bogus to keep the linker happy -QWidget * CalamaresWindow::getQmlSidebar(QWidget* , int ) +QWidget* +CalamaresWindow::getQmlSidebar( QWidget*, int ) { return nullptr; } -QWidget * CalamaresWindow::getQmlNavigation(QWidget* ) +QWidget* +CalamaresWindow::getQmlNavigation( QWidget* ) { return nullptr; } @@ -401,6 +403,14 @@ CalamaresWindow::CalamaresWindow( QWidget* parent ) insertIf( mainLayout, PanelSide::Right, navigation, branding->navigationSide() ); insertIf( mainLayout, PanelSide::Right, sideBox, branding->sidebarSide() ); + // layout->count() returns number of things in it; above we have put + // at **least** the central widget, which comes from the view manager, + // both vertically and horizontally -- so if there's a panel along + // either axis, the count in that axis will be > 1. + m_viewManager->setPanelSides( + ( contentsLayout->count() > 1 ? Qt::Orientations( Qt::Horizontal ) : Qt::Orientations() ) + | ( mainLayout->count() > 1 ? Qt::Orientations( Qt::Vertical ) : Qt::Orientations() ) ); + CalamaresUtils::unmarginLayout( mainLayout ); CalamaresUtils::unmarginLayout( contentsLayout ); baseWidget->setLayout( mainLayout ); diff --git a/src/libcalamaresui/ViewManager.h b/src/libcalamaresui/ViewManager.h index 0fb1cbb45..683b335d1 100644 --- a/src/libcalamaresui/ViewManager.h +++ b/src/libcalamaresui/ViewManager.h @@ -55,7 +55,7 @@ class UIDLLEXPORT ViewManager : public QAbstractListModel Q_PROPERTY( bool quitVisible READ quitVisible NOTIFY quitVisibleChanged FINAL ) ///@brief Sides on which the ViewManager has side-panels - Q_PROPERTY( Qt::Orientations panelSides MEMBER m_panelSides ) + Q_PROPERTY( Qt::Orientations panelSides READ panelSides WRITE setPanelSides MEMBER m_panelSides ) public: /** @@ -111,6 +111,9 @@ public: */ bool confirmCancelInstallation(); + Qt::Orientations panelSides() const { return m_panelSides; } + void setPanelSides( Qt::Orientations panelSides ) { m_panelSides = panelSides; } + public Q_SLOTS: /** * @brief next moves forward to the next page of the current ViewStep (if any), From fa2f91aa46c1c354bde59ac4b9c49ae296c60286 Mon Sep 17 00:00:00 2001 From: Adriaan de Groot Date: Thu, 25 Jun 2020 14:04:49 +0200 Subject: [PATCH 13/20] [libcalamaresui] Minor documentation improvements --- src/libcalamaresui/viewpages/QmlViewStep.h | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/src/libcalamaresui/viewpages/QmlViewStep.h b/src/libcalamaresui/viewpages/QmlViewStep.h index e1f4caf28..b15fbfa5c 100644 --- a/src/libcalamaresui/viewpages/QmlViewStep.h +++ b/src/libcalamaresui/viewpages/QmlViewStep.h @@ -35,6 +35,15 @@ namespace Calamares * This is generally a **base** class for other view steps, but * it can be used stand-alone for viewsteps that don't really have * any functionality. + * + * Most subclasses will override the following methods: + * - prettyName() to provide a meaningful human-readable name + * - jobs() if there is real work to be done during installation + * - getConfig() to return a meaningful configuration object + * + * For details on the interaction between the config object and + * the QML in the module, see the Calamares wiki: + * https://github.com/calamares/calamares/wiki/Develop-Design */ class QmlViewStep : public Calamares::ViewStep { From 6735ff1cd06d0c06e757cca62c1712336e6cf6eb Mon Sep 17 00:00:00 2001 From: Adriaan de Groot Date: Thu, 25 Jun 2020 14:38:09 +0200 Subject: [PATCH 14/20] Docs: give up on PythonQt modules --- src/modules/README.md | 41 ++++++++++++----------------------------- 1 file changed, 12 insertions(+), 29 deletions(-) diff --git a/src/modules/README.md b/src/modules/README.md index 2a9ef64c7..3e96d672d 100644 --- a/src/modules/README.md +++ b/src/modules/README.md @@ -9,20 +9,16 @@ Each Calamares module lives in its own directory. All modules are installed in `$DESTDIR/lib/calamares/modules`. There are two **types** of Calamares module: -* viewmodule, for user-visible modules. These may be in C++, or PythonQt. +* viewmodule, for user-visible modules. These use C++ and QWidgets or QML * jobmodule, for not-user-visible modules. These may be done in C++, Python, or as external processes. -A viewmodule exposes a UI to the user. The PythonQt-based modules -are considered experimental (and as of march 2019 may be on the -way out again as never-used-much and PythonQt is not packaged -on Debian anymore). +A viewmodule exposes a UI to the user. -There are three (four) **interfaces** for Calamares modules: +There are three **interfaces** for Calamares modules: * qtplugin (viewmodules, jobmodules), * python (jobmodules only), -* pythonqt (viewmodules, jobmodules, optional), -* process (jobmodules only). +* process (jobmodules only, not recommended). ## Module directory @@ -50,7 +46,7 @@ Module descriptors **must** have the following keys: - *interface* (see below for the different interfaces; generally we refer to the kinds of modules by their interface) -Module descriptors for Python and PythonQt modules **must** have the following key: +Module descriptors for Python modules **must** have the following key: - *script* (the name of the Python script to load, nearly always `main.py`) Module descriptors **may** have the following keys: @@ -139,9 +135,8 @@ nearly all cases can be described in CMake. Modules may use one of the python interfaces, which may be present in a Calamares installation (but also may not be). These modules must have -a `module.desc` file. The Python script must implement one or more of the -Python interfaces for Calamares -- either the python jobmodule interface, -or the experimental pythonqt job- and viewmodule interfaces. +a `module.desc` file. The Python script must implement the +Python jobmodule interface. To add a Python or process jobmodule, put it in a subdirectory and make sure it has a `module.desc`. It will be picked up automatically by our CMake magic. @@ -178,32 +173,20 @@ description if something went wrong. -## PythonQt modules +## PythonQt modules (deprecated) > Type: viewmodule, jobmodule > Interface: pythonqt -The PythonQt modules are considered experimental and may be removed again -due to low uptake. Their documentation is also almost completely lacking. - -### PythonQt Jobmodule - -A PythonQt jobmodule implements the experimental Job interface by defining -a subclass of something. - -### PythonQt Viewmodule - -A PythonQt viewmodule implements the experimental View interface by defining -a subclass of something. - -### Python API - -**TODO:** this needs documentation +The PythonQt modules are deprecated and will be removed in Calamares 3.3. +Their documentation is also almost completely lacking. ## Process jobmodules +Use of this kind of module is **not** recommended. + > Type: jobmodule > Interface: process From 31a1b710bcb92335a5d623cdd7adc33f83b89fe5 Mon Sep 17 00:00:00 2001 From: Adriaan de Groot Date: Thu, 25 Jun 2020 15:26:48 +0200 Subject: [PATCH 15/20] Docs: say something about QML modules --- src/libcalamaresui/viewpages/QmlViewStep.h | 4 +- src/modules/README.md | 55 +++++++++++++++++++++- 2 files changed, 56 insertions(+), 3 deletions(-) diff --git a/src/libcalamaresui/viewpages/QmlViewStep.h b/src/libcalamaresui/viewpages/QmlViewStep.h index b15fbfa5c..dc2af650d 100644 --- a/src/libcalamaresui/viewpages/QmlViewStep.h +++ b/src/libcalamaresui/viewpages/QmlViewStep.h @@ -42,8 +42,8 @@ namespace Calamares * - getConfig() to return a meaningful configuration object * * For details on the interaction between the config object and - * the QML in the module, see the Calamares wiki: - * https://github.com/calamares/calamares/wiki/Develop-Design + * the QML in the module, see the module documentation: + * src/modules/README.md */ class QmlViewStep : public Calamares::ViewStep { diff --git a/src/modules/README.md b/src/modules/README.md index 3e96d672d..ee6e378d2 100644 --- a/src/modules/README.md +++ b/src/modules/README.md @@ -129,6 +129,59 @@ a `CMakeLists.txt` with a `calamares_add_plugin` call. It will be picked up automatically by our CMake magic. The `module.desc` file is not recommended: nearly all cases can be described in CMake. +### C++ Jobmodule + +**TODO:** this needs documentation + +### C++ Widgets Viewmodule + +**TODO:** this needs documentation + +### C++ QML Viewmodule + +A QML Viewmodule (or view step) puts much of the UI work in one or more +QML files; the files may be loaded from the branding directory or compiled +into the module. Which QML is used depends on the deployment and the +configuration files for Calamares. + +#### Explicit properties + +The QML can access data from the C++ framework though properties +exposed to QML. There are two libraries that need to be imported +explicitly: + +``` +import io.calamares.core 1.0 +import io.calamares.ui 1.0 +``` + +The *ui* library contains the *Branding* object, which corresponds to +the branding information set through `branding.desc`. The Branding +class (in `src/libcalamaresui/Branding.h` offers a QObject-property +based API, where the most important functions are `string()` and the +convenience functions `versionedName()` and similar. + +The *core* library contains both *ViewManager*, which handles overall +progress through the application, and *Global*, which holds global +storage information. Both objects have an extensive API. The *ViewManager* +can behave as a model for list views and the like. + +These explicit properties from libraries are shared across all the +QML modules (for global storage that goes without saying: it is +the mechanism to share information with other modules). + +#### Implicit properties + +Each module also has an implicit context property available to it. +No import is needed. The context property *config* (note lower case) +holds the Config object for the module. + +The Config object is the bridge between C++ and QML. + +A Config object must inherit QObject and should expose, as `Q_PROPERTY`, +all of the relevant configuration information for the module instance. +The general description how to do that is available +in the [Qt documentation](https://doc.qt.io/qt-5/qtqml-cppintegration-topic.html). ## Python modules @@ -183,7 +236,7 @@ Their documentation is also almost completely lacking. -## Process jobmodules +## Process modules Use of this kind of module is **not** recommended. From 3b5c4839e3913f2cecf7ad211e4a82de2ec6f8ba Mon Sep 17 00:00:00 2001 From: Adriaan de Groot Date: Fri, 26 Jun 2020 20:34:33 +0200 Subject: [PATCH 16/20] [libcalamaresui] Warnings-- --- src/libcalamaresui/viewpages/ViewStep.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/libcalamaresui/viewpages/ViewStep.cpp b/src/libcalamaresui/viewpages/ViewStep.cpp index 64979836f..ad86d06a4 100644 --- a/src/libcalamaresui/viewpages/ViewStep.cpp +++ b/src/libcalamaresui/viewpages/ViewStep.cpp @@ -91,7 +91,7 @@ ViewStep::checkRequirements() QSize ViewStep::widgetMargins( Qt::Orientations panelSides ) { - Q_UNUSED( panelSides ); + Q_UNUSED( panelSides ) // Application's default style const auto* s = QApplication::style(); From 08aa362c5c308ad8b0345aa5f5bf4950c542b017 Mon Sep 17 00:00:00 2001 From: Adriaan de Groot Date: Sat, 27 Jun 2020 00:33:50 +0200 Subject: [PATCH 17/20] [license] Warnings-reduction - Don't do in code what is already done in the designer (.ui) file - setFrameStyle() is difficult because it mixes different enums into an int, which causes the warning from clang. --- src/modules/license/LicensePage.cpp | 4 ---- 1 file changed, 4 deletions(-) diff --git a/src/modules/license/LicensePage.cpp b/src/modules/license/LicensePage.cpp index 237e8d0dc..f2b1f4a50 100644 --- a/src/modules/license/LicensePage.cpp +++ b/src/modules/license/LicensePage.cpp @@ -107,10 +107,6 @@ LicensePage::LicensePage( QWidget* parent ) // ui->verticalLayout->insertSpacing( 1, CalamaresUtils::defaultFontHeight() ); CalamaresUtils::unmarginLayout( ui->verticalLayout ); - ui->mainText->setWordWrap( true ); - ui->mainText->setSizePolicy( QSizePolicy::Expanding, QSizePolicy::Minimum ); - - ui->acceptFrame->setFrameStyle( QFrame::NoFrame | QFrame::Plain ); ui->acceptFrame->setStyleSheet( mustAccept ); ui->acceptFrame->layout()->setMargin( CalamaresUtils::defaultFontHeight() / 2 ); From 8aa8ac2d2688d9723a6e04bdb3d53b7b09e8e9f8 Mon Sep 17 00:00:00 2001 From: Adriaan de Groot Date: Fri, 3 Jul 2020 21:51:39 +0200 Subject: [PATCH 18/20] [packages] Tidy up configuration - fix the schema so the schema is valid json-schema - the schema doesn't actually validate the *operations* yet - sort the named backends (needs a double-check that the list covers all the ones we currently support) SEE #1441 --- src/modules/packages/packages.conf | 16 ++++---- src/modules/packages/packages.schema.yaml | 50 +++++++++++------------ 2 files changed, 32 insertions(+), 34 deletions(-) diff --git a/src/modules/packages/packages.conf b/src/modules/packages/packages.conf index 032794177..bcf313972 100644 --- a/src/modules/packages/packages.conf +++ b/src/modules/packages/packages.conf @@ -1,16 +1,18 @@ --- # # Which package manager to use, options are: -# - packagekit - PackageKit CLI tool -# - zypp - Zypp RPM frontend -# - yum - Yum RPM frontend -# - dnf - DNF, the new RPM frontend -# - urpmi - Mandriva package manager +# - apk - Alpine Linux package manager # - apt - APT frontend for DEB and RPM +# - dnf - DNF, the new RPM frontend +# - entropy - Sabayon package manager +# - packagekit - PackageKit CLI tool # - pacman - Pacman # - portage - Gentoo package manager -# - entropy - Sabayon package manager -# - apk = Alpine Linux package manager +# - urpmi - Mandriva package manager +# - yum - Yum RPM frontend +# - zypp - Zypp RPM frontend +# +# Not actually a package manager, but suitable for testing: # - dummy - Dummy manager, only logs # backend: dummy diff --git a/src/modules/packages/packages.schema.yaml b/src/modules/packages/packages.schema.yaml index 8b8a9eb1d..24e1a271a 100644 --- a/src/modules/packages/packages.schema.yaml +++ b/src/modules/packages/packages.schema.yaml @@ -4,30 +4,26 @@ $id: https://calamares.io/schemas/packages additionalProperties: false type: object properties: - "backend": { type: string, required: true, enum: [packagekit, zypp, yum, dnf, urpmi, apt, pacman, portage, entropy] } - "update_db": { type: boolean, default: true } - "operations": - type: seq - sequence: - - type: map - mapping: - "install": - type: seq - sequence: - - { type: text } - "remove": - type: seq - sequence: - - { type: text } - "localInstall": - type: seq - sequence: - - { type: text } - "try_install": - type: seq - sequence: - - { type: text } - "try_remove": - type: seq - sequence: - - { type: text } + backend: + type: string + enum: + - apk + - apt + - dnf + - entropy + - packagekit + - pacman + - portage + - urpmi + - yum + - zypp + - dummy + + update_db: { type: boolean, default: true } + update_system: { type: boolean, default: false } + skip_if_no_internet: { type: boolean, default: false } + + operations: + type: array + +required: [ backend ] From d3f9415bc195e5b752f23a8c9de6ce63475ea4f7 Mon Sep 17 00:00:00 2001 From: Adriaan de Groot Date: Fri, 3 Jul 2020 22:06:57 +0200 Subject: [PATCH 19/20] [packages] Expand schema to cover the operations - Not complete, since the items in the operations aren't done --- src/modules/packages/packages.schema.yaml | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/src/modules/packages/packages.schema.yaml b/src/modules/packages/packages.schema.yaml index 24e1a271a..40f82bb35 100644 --- a/src/modules/packages/packages.schema.yaml +++ b/src/modules/packages/packages.schema.yaml @@ -25,5 +25,18 @@ properties: operations: type: array + items: + additionalProperties: false + type: object + properties: + # TODO: these are either-string-or-struct items, + # need their own little schema. + install: { type: array } + remove: { type: array } + try_install: { type: array } + try_remove: { type: array } + localInstall: { type: array } + source: { type: string } + required: [ backend ] From 46ad704ede0fa6aff65342814f46ec5e25619826 Mon Sep 17 00:00:00 2001 From: Adriaan de Groot Date: Fri, 3 Jul 2020 22:33:00 +0200 Subject: [PATCH 20/20] [partition] Fix build for old KPMCore SEE #1444 --- src/modules/partition/jobs/FillGlobalStorageJob.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/modules/partition/jobs/FillGlobalStorageJob.cpp b/src/modules/partition/jobs/FillGlobalStorageJob.cpp index d695a5f6a..e3f696bbc 100644 --- a/src/modules/partition/jobs/FillGlobalStorageJob.cpp +++ b/src/modules/partition/jobs/FillGlobalStorageJob.cpp @@ -93,8 +93,10 @@ mapForPartition( Partition* partition, const QString& uuid ) map[ "device" ] = partition->partitionPath(); map[ "partlabel" ] = partition->label(); map[ "partuuid" ] = partition->uuid(); +#ifdef WITH_KPMCORE42API map[ "parttype" ] = partition->type(); map[ "partattrs" ] = partition->attributes(); +#endif map[ "mountPoint" ] = PartitionInfo::mountPoint( partition ); map[ "fsName" ] = userVisibleFS( partition->fileSystem() ); map[ "fs" ] = untranslatedFS( partition->fileSystem() );