diff --git a/src/libcalamaresui/Branding.h b/src/libcalamaresui/Branding.h
index f1b26fbb5..3dfcd0586 100644
--- a/src/libcalamaresui/Branding.h
+++ b/src/libcalamaresui/Branding.h
@@ -146,9 +146,6 @@ public:
QString slideshowPath() const { return m_slideshowPath; }
int slideshowAPI() const { return m_slideshowAPI; }
- QString string( Branding::StringEntry stringEntry ) const;
- QString styleString( Branding::StyleEntry styleEntry ) const;
- QString imagePath( Branding::ImageEntry imageEntry ) const;
QPixmap image( Branding::ImageEntry imageEntry, const QSize& size ) const;
/** @brief Look up an image in the branding directory or as an icon
@@ -185,6 +182,11 @@ public:
*/
void setGlobals( GlobalStorage* globalStorage ) const;
+public slots:
+ QString string( StringEntry stringEntry ) const;
+ QString styleString( StyleEntry styleEntry ) const;
+ QString imagePath( ImageEntry imageEntry ) const;
+
private:
static Branding* s_instance;
diff --git a/src/libcalamaresui/viewpages/QmlViewStep.cpp b/src/libcalamaresui/viewpages/QmlViewStep.cpp
index 2bfc72757..e13e022d8 100644
--- a/src/libcalamaresui/viewpages/QmlViewStep.cpp
+++ b/src/libcalamaresui/viewpages/QmlViewStep.cpp
@@ -29,12 +29,14 @@
#include "widgets/WaitingWidget.h"
#include
+#include
#include
#include
#include
#include
#include
+
static const NamedEnumTable< Calamares::QmlViewStep::QmlSearch >&
searchNames()
{
@@ -82,6 +84,20 @@ changeQMLState( QMLAction action, QQuickItem* item )
}
}
+static void
+registerCalamaresModels()
+{
+ static bool done = false;
+ if ( !done )
+ {
+ done = true;
+ qmlRegisterSingletonType< Calamares::Branding >(
+ "calamares.ui", 1, 0, "Branding", []( QQmlEngine*, QJSEngine* ) -> QObject* {
+ return Calamares::Branding::instance();
+ } );
+ }
+}
+
namespace Calamares
{
@@ -92,6 +108,8 @@ QmlViewStep::QmlViewStep( const QString& name, QObject* parent )
, m_spinner( new WaitingWidget( tr( "Loading ..." ) ) )
, m_qmlWidget( new QQuickWidget )
{
+ registerCalamaresModels();
+
QVBoxLayout* layout = new QVBoxLayout( m_widget );
layout->addWidget( m_spinner );
@@ -297,6 +315,12 @@ QmlViewStep::setConfigurationMap( const QVariantMap& configurationMap )
{
m_qmlFileName = searchQmlFile( m_searchMethod, qmlFile, m_name );
+ QObject* config = this->getConfig();
+ if ( config )
+ {
+ m_qmlWidget->engine()->rootContext()->setContextProperty( "config", config );
+ }
+
cDebug() << "QmlViewStep" << moduleInstanceKey() << "loading" << m_qmlFileName;
m_qmlComponent = new QQmlComponent(
m_qmlWidget->engine(), QUrl( m_qmlFileName ), QQmlComponent::CompilationMode::Asynchronous );
@@ -316,7 +340,17 @@ void
QmlViewStep::showFailedQml()
{
cWarning() << "QmlViewStep" << moduleInstanceKey() << "loading failed.";
+ if ( m_qmlComponent )
+ {
+ cDebug() << Logger::SubEntry << "QML error:" << m_qmlComponent->errorString();
+ }
m_spinner->setText( prettyName() + ' ' + tr( "Loading failed." ) );
}
+QObject*
+QmlViewStep::getConfig()
+{
+ return nullptr;
+}
+
} // namespace Calamares
diff --git a/src/libcalamaresui/viewpages/QmlViewStep.h b/src/libcalamaresui/viewpages/QmlViewStep.h
index 46ba29a53..b54dc2fb7 100644
--- a/src/libcalamaresui/viewpages/QmlViewStep.h
+++ b/src/libcalamaresui/viewpages/QmlViewStep.h
@@ -73,9 +73,21 @@ public:
/// @brief QML widgets don't produce jobs by default
virtual JobList jobs() const override;
- /// @brief Configure search paths; subclasses should call this as well
+ /// @brief Configure search paths; subclasses should call this at the **end** of their own implementation
virtual void setConfigurationMap( const QVariantMap& configurationMap ) override;
+protected:
+ /** @brief Gets a pointer to the Config of this view step
+ *
+ * Parts of the configuration of the viewstep can be passed to QML
+ * by placing them in a QObject (as properties). The default
+ * implementation returns nullptr, for no-config.
+ *
+ * Ownership of the config object remains with the ViewStep; it is possible
+ * to return a pointer to a member variable.
+ */
+ virtual QObject* getConfig();
+
private Q_SLOTS:
void loadComplete();
diff --git a/src/modules/notesqml/NotesQmlViewStep.cpp b/src/modules/notesqml/NotesQmlViewStep.cpp
index e729c2df7..79c2e39f2 100644
--- a/src/modules/notesqml/NotesQmlViewStep.cpp
+++ b/src/modules/notesqml/NotesQmlViewStep.cpp
@@ -36,9 +36,7 @@ NotesQmlViewStep::prettyName() const
void
NotesQmlViewStep::setConfigurationMap( const QVariantMap& configurationMap )
-{
- Calamares::QmlViewStep::setConfigurationMap( configurationMap ); // call parent implementation
-
+{
bool qmlLabel_ok = false;
auto qmlLabel = CalamaresUtils::getSubMap( configurationMap, "qmlLabel", qmlLabel_ok );
@@ -46,7 +44,8 @@ NotesQmlViewStep::setConfigurationMap( const QVariantMap& configurationMap )
{
m_notesName = new CalamaresUtils::Locale::TranslatedString( qmlLabel, "notes" );
}
-
+
+ Calamares::QmlViewStep::setConfigurationMap( configurationMap ); // call parent implementation last
}
CALAMARES_PLUGIN_FACTORY_DEFINITION( NotesQmlViewStepFactory, registerPlugin< NotesQmlViewStep >(); )
diff --git a/src/modules/notesqml/notesqml.qml b/src/modules/notesqml/notesqml.qml
index d1ff4f1b5..a41fa98fd 100644
--- a/src/modules/notesqml/notesqml.qml
+++ b/src/modules/notesqml/notesqml.qml
@@ -1,6 +1,7 @@
/* === This file is part of Calamares - ===
*
* Copyright 2020, Anke Boersma
+ * Copyright 2020, Adriaan de Groot
*
* Calamares is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -16,6 +17,14 @@
* along with Calamares. If not, see .
*/
+/* Some Calamares internals are available to all QML modules.
+ * They live in the calamares.ui namespace (filled programmatically
+ * by Calamares). One of the internals that is exposed is the
+ * Branding object, which can be used to retrieve strings and paths
+ * and colors.
+ */
+import calamares.ui 1.0
+
import QtQuick 2.7
import QtQuick.Controls 2.2
import QtQuick.Window 2.2
@@ -30,9 +39,9 @@ Item {
id: flick
anchors.fill: parent
contentHeight: 800
-
+
ScrollBar.vertical: ScrollBar {
- id: fscrollbar
+ id: fscrollbar
width: 10
policy: ScrollBar.AlwaysOn
}
@@ -48,27 +57,27 @@ Item {
activeFocusOnPress: false
wrapMode: Text.WordWrap
- text: qsTr("Generic GNU/Linux 2020.2 LTS Turgid Tuba
+ text: qsTr("%1
This an example QML file, showing options in RichText with Flickable content.
-
+
QML with RichText can use HTML tags, Flickable content is useful for touchscreens.
-
+
This is bold text
This is italic text
This is underlined text
This text will be center-aligned.
This is strikethrough
-
+
Code example:
ls -l /home
-
+
Lists:
- Intel CPU systems
- AMD CPU systems
-
- The vertical scrollbar is adjustable, current width set to 10.
")
+
+ The vertical scrollbar is adjustable, current width set to 10.
").arg(Branding.string(Branding.VersionedName))
}
}
diff --git a/src/modules/welcomeq/Config.cpp b/src/modules/welcomeq/Config.cpp
index 6d085143c..cfa6336e2 100644
--- a/src/modules/welcomeq/Config.cpp
+++ b/src/modules/welcomeq/Config.cpp
@@ -18,11 +18,6 @@
#include "Config.h"
-Config::Config()
- : m_helpUrl( "https://www.kde.org/" )
-{
-}
+Config::Config() {}
-Config::~Config()
-{
-}
+Config::~Config() {}
diff --git a/src/modules/welcomeq/Config.h b/src/modules/welcomeq/Config.h
index 2295d4ee2..50c3e387b 100644
--- a/src/modules/welcomeq/Config.h
+++ b/src/modules/welcomeq/Config.h
@@ -16,8 +16,8 @@
* along with Calamares. If not, see .
*/
-#ifndef WELCOME_CONFIG_H
-#define WELCOME_CONFIG_H
+#ifndef WELCOMEQ_CONFIG_H
+#define WELCOMEQ_CONFIG_H
#include
#include
@@ -25,16 +25,27 @@
class Config : public QObject
{
Q_OBJECT
- Q_PROPERTY( QUrl helpUrl READ helpUrl WRITE setHelpUrl CONSTANT )
+ Q_PROPERTY( QUrl helpUrl READ helpUrl CONSTANT FINAL )
+ Q_PROPERTY( QUrl issuesUrl READ issuesUrl CONSTANT FINAL )
+ Q_PROPERTY( QUrl notesUrl READ notesUrl CONSTANT FINAL )
+ Q_PROPERTY( QUrl donateUrl READ donateUrl CONSTANT FINAL )
public:
Config();
virtual ~Config();
- QUrl helpUrl() const { return m_helpUrl; }
void setHelpUrl( const QUrl& url ) { m_helpUrl = url; }
+ void setIssuesUrl( const QUrl& url ) { m_issuesUrl = url; }
+ void setNotesUrl( const QUrl& url ) { m_notesUrl = url; }
+ void setDonateUrl( const QUrl& url ) { m_donateUrl = url; }
+
+public slots:
+ QUrl helpUrl() const { return m_helpUrl; }
+ QUrl issuesUrl() const { return m_issuesUrl; }
+ QUrl notesUrl() const { return m_notesUrl; }
+ QUrl donateUrl() const { return m_donateUrl; }
private:
- QUrl m_helpUrl;
+ QUrl m_helpUrl, m_issuesUrl, m_notesUrl, m_donateUrl;
};
#endif
diff --git a/src/modules/welcomeq/WelcomeQmlViewStep.cpp b/src/modules/welcomeq/WelcomeQmlViewStep.cpp
index 2a5b0f661..382e0b4d1 100644
--- a/src/modules/welcomeq/WelcomeQmlViewStep.cpp
+++ b/src/modules/welcomeq/WelcomeQmlViewStep.cpp
@@ -37,7 +37,7 @@
CALAMARES_PLUGIN_FACTORY_DEFINITION( WelcomeQmlViewStepFactory, registerPlugin< WelcomeQmlViewStep >(); )
WelcomeQmlViewStep::WelcomeQmlViewStep( QObject* parent )
- : Calamares::ViewStep( parent )
+ : Calamares::QmlViewStep( QStringLiteral( "welcomeq" ), parent )
, m_requirementsChecker( new GeneralRequirements( this ) )
{
connect( Calamares::ModuleManager::instance(),
@@ -47,10 +47,7 @@ WelcomeQmlViewStep::WelcomeQmlViewStep( QObject* parent )
}
-WelcomeQmlViewStep::~WelcomeQmlViewStep()
-{
-}
-
+WelcomeQmlViewStep::~WelcomeQmlViewStep() {}
QString
WelcomeQmlViewStep::prettyName() const
@@ -58,53 +55,6 @@ WelcomeQmlViewStep::prettyName() const
return tr( "Welcome" );
}
-
-QWidget*
-WelcomeQmlViewStep::widget()
-{
- return nullptr;
-}
-
-
-bool
-WelcomeQmlViewStep::isNextEnabled() const
-{
- // TODO: should return true
- return false;
-}
-
-
-bool
-WelcomeQmlViewStep::isBackEnabled() const
-{
- // TODO: should return true (it's weird that you are not allowed to have welcome *after* anything
- return false;
-}
-
-
-bool
-WelcomeQmlViewStep::isAtBeginning() const
-{
- // TODO: adjust to "pages" in the QML
- return true;
-}
-
-
-bool
-WelcomeQmlViewStep::isAtEnd() const
-{
- // TODO: adjust to "pages" in the QML
- return true;
-}
-
-
-Calamares::JobList
-WelcomeQmlViewStep::jobs() const
-{
- return Calamares::JobList();
-}
-
-
/** @brief Look up a URL for a button
*
* Looks up @p key in @p map; if it is a *boolean* value, then
@@ -143,7 +93,9 @@ WelcomeQmlViewStep::setConfigurationMap( const QVariantMap& configurationMap )
using Calamares::Branding;
m_config.setHelpUrl( jobOrBrandingSetting( Branding::SupportUrl, configurationMap, "showSupportUrl" ) );
- // TODO: expand Config class and set the remaining fields
+ m_config.setIssuesUrl( jobOrBrandingSetting( Branding::KnownIssuesUrl, configurationMap, "showKnownIssuesUrl" ) );
+ m_config.setNotesUrl( jobOrBrandingSetting( Branding::ReleaseNotesUrl, configurationMap, "showReleaseNotesUrl" ) );
+ m_config.setDonateUrl( CalamaresUtils::getString( configurationMap, "showDonateUrl" ) );
// TODO: figure out how the requirements (held by ModuleManager) should be accessible
// to QML as a odel.
@@ -193,6 +145,8 @@ WelcomeQmlViewStep::setConfigurationMap( const QVariantMap& configurationMap )
// TODO: figure out where to set this: Config?
}
}
+
+ QmlViewStep::setConfigurationMap( configurationMap ); // call parent implementation last
}
Calamares::RequirementsList
@@ -241,3 +195,9 @@ WelcomeQmlViewStep::setCountry( const QString& countryCode, CalamaresUtils::GeoI
}
}
}
+
+QObject*
+WelcomeQmlViewStep::getConfig()
+{
+ return &m_config;
+}
diff --git a/src/modules/welcomeq/WelcomeQmlViewStep.h b/src/modules/welcomeq/WelcomeQmlViewStep.h
index 468dd7621..064be0455 100644
--- a/src/modules/welcomeq/WelcomeQmlViewStep.h
+++ b/src/modules/welcomeq/WelcomeQmlViewStep.h
@@ -21,11 +21,10 @@
#include "Config.h"
+#include "DllMacro.h"
#include "modulesystem/Requirement.h"
#include "utils/PluginFactory.h"
-#include "viewpages/ViewStep.h"
-
-#include
+#include "viewpages/QmlViewStep.h"
#include
#include
@@ -40,13 +39,7 @@ class Handler;
class GeneralRequirements;
-class QQmlComponent;
-class QQuickItem;
-class QQuickWidget;
-
-// TODO: Needs a generic Calamares::QmlViewStep as base class
-// TODO: refactor and move what makes sense to base class
-class PLUGINDLLEXPORT WelcomeQmlViewStep : public Calamares::ViewStep
+class PLUGINDLLEXPORT WelcomeQmlViewStep : public Calamares::QmlViewStep
{
Q_OBJECT
@@ -56,16 +49,6 @@ public:
QString prettyName() const override;
- QWidget* widget() override;
-
- bool isNextEnabled() const override;
- bool isBackEnabled() const override;
-
- bool isAtBeginning() const override;
- bool isAtEnd() const override;
-
- Calamares::JobList jobs() const override;
-
void setConfigurationMap( const QVariantMap& configurationMap ) override;
/** @brief Sets the country that Calamares is running in.
@@ -78,16 +61,13 @@ public:
Calamares::RequirementsList checkRequirements() override;
+protected:
+ QObject* getConfig() override;
+
private:
// TODO: a generic QML viewstep should return a config object from a method
Config m_config;
GeneralRequirements* m_requirementsChecker;
-
- // TODO: these need to be in the base class (also a base class of ExecutionViewStep)
- QQuickWidget* m_qmlWidget;
- QQmlComponent* m_qmlComponent;
- QQuickItem* m_qmlItem;
-
};
CALAMARES_PLUGIN_FACTORY_DECLARATION( WelcomeQmlViewStepFactory )
diff --git a/src/modules/welcomeq/welcomeq.conf b/src/modules/welcomeq/welcomeq.conf
new file mode 100644
index 000000000..0068ebe5c
--- /dev/null
+++ b/src/modules/welcomeq/welcomeq.conf
@@ -0,0 +1,25 @@
+# Configuration for the welcome module. The welcome page
+# displays some information from the branding file.
+# Which parts it displays can be configured through
+# the show* variables.
+#
+# In addition to displaying the welcome page, this module
+# can check requirements for installation.
+---
+# Display settings for various buttons on the welcome page.
+# The URLs themselves come from branding.desc is the setting
+# here is "true". If the setting is false, the button is hidden.
+# The setting can also be a full URL which will then be used
+# instead of the one from the branding file, or empty or not-set
+# which will hide the button.
+showSupportUrl: true
+showKnownIssuesUrl: true
+showReleaseNotesUrl: true
+
+# If this Url is set to something non-empty, a "donate"
+# button is added to the welcome page alongside the
+# others (see settings, above). Clicking the button opens
+# the corresponding link. (This button has no corresponding
+# branding.desc string)
+#
+# showDonateUrl: https://kde.org/community/donations/
diff --git a/src/modules/welcomeq/welcomeq.qml b/src/modules/welcomeq/welcomeq.qml
new file mode 100644
index 000000000..b40ec4813
--- /dev/null
+++ b/src/modules/welcomeq/welcomeq.qml
@@ -0,0 +1,129 @@
+/* === This file is part of Calamares - ===
+ *
+ * Copyright 2020, Adriaan de Groot
+ *
+ * Calamares is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * Calamares is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with Calamares. If not, see .
+ */
+import calamares.ui 1.0
+
+import QtQuick 2.10
+import QtQuick.Controls 2.10
+import QtQuick.Layouts 1.3
+import org.kde.kirigami 2.7 as Kirigami
+import QtGraphicalEffects 1.0
+import QtQuick.Window 2.3
+
+Page
+{
+ id: welcome
+
+ header: Item
+ {
+ width: parent.width
+ height: 150
+
+ Text
+ {
+ id: welcomeTopText
+ anchors.horizontalCenter: parent.horizontalCenter
+ anchors.top: parent.top
+ // In QML, QString::arg() only takes one argument
+ text: qsTr("%1 %2
").arg(Branding.string(Branding.ProductName)).arg(Branding.string(Branding.Version))
+ }
+ Image
+ {
+ id: welcomeImage
+ anchors.centerIn: parent
+ // imagePath() returns a full pathname, so make it refer to the filesystem
+ // .. otherwise the path is interpreted relative to the "call site", which
+ // .. might be the QRC file.
+ source: "file:/" + Branding.imagePath(Branding.ProductWelcome)
+ height: Math.min(100, parent.height)
+ width: height
+ sourceSize.width: width
+ sourceSize.height: height
+ }
+
+ RowLayout
+ {
+ id: buttonBar
+ width: parent.width
+ height: 64
+
+ anchors.bottom: parent.bottom
+
+ spacing: Kirigami.Units.largeSpacing* 2
+
+/* Traditionally Calamares has had an "About" button that talks about
+ * Calamares itself, which just isn't a very useful thing in someone
+ * else's installation ISO.
+ */
+ Button
+ {
+ Layout.fillWidth: true
+ text: qsTr("About")
+ icon.name: "documentinfo"
+ Kirigami.Theme.backgroundColor: Qt.rgba(Kirigami.Theme.backgroundColor.r, Kirigami.Theme.backgroundColor.g, Kirigami.Theme.backgroundColor.b, 0.4)
+ Kirigami.Theme.textColor: "#fff"
+
+ visible: false
+ onClicked: { } // TODO: show an about-Calamares window
+ }
+ Button
+ {
+ Layout.fillWidth: true
+ text: qsTr("Support")
+ icon.name: "documentinfo"
+ Kirigami.Theme.backgroundColor: Qt.rgba(Kirigami.Theme.backgroundColor.r, Kirigami.Theme.backgroundColor.g, Kirigami.Theme.backgroundColor.b, 0.4)
+ Kirigami.Theme.textColor: "#fff"
+
+ visible: config.helpUrl.isValid
+ onClicked: Qt.openUrlExternally(config.helpUrl)
+ }
+ Button
+ {
+ Layout.fillWidth: true
+ text: qsTr("Known issues")
+ icon.name: "documentinfo"
+ Kirigami.Theme.backgroundColor: Qt.rgba(Kirigami.Theme.backgroundColor.r, Kirigami.Theme.backgroundColor.g, Kirigami.Theme.backgroundColor.b, 0.4)
+ Kirigami.Theme.textColor: "#fff"
+
+ visible: config.issuesUrl.isValid
+ onClicked: Qt.openUrlExternally(config.issuesUrl)
+ }
+ Button
+ {
+ Layout.fillWidth: true
+ text: qsTr("Release notes")
+ icon.name: "documentinfo"
+ Kirigami.Theme.backgroundColor: Qt.rgba(Kirigami.Theme.backgroundColor.r, Kirigami.Theme.backgroundColor.g, Kirigami.Theme.backgroundColor.b, 0.4)
+ Kirigami.Theme.textColor: "#fff"
+
+ visible: config.notesUrl.isValid
+ onClicked: Qt.openUrlExternally(config.notesUrl)
+ }
+ Button
+ {
+ Layout.fillWidth: true
+ text: qsTr("Donate")
+ icon.name: "documentinfo"
+ Kirigami.Theme.backgroundColor: Qt.rgba(Kirigami.Theme.backgroundColor.r, Kirigami.Theme.backgroundColor.g, Kirigami.Theme.backgroundColor.b, 0.4)
+ Kirigami.Theme.textColor: "#fff"
+
+ visible: config.donateUrl.isValid
+ onClicked: Qt.openUrlExternally(config.donateUrl)
+ }
+ }
+ }
+}
diff --git a/src/modules/welcomeq/welcomeq.qrc b/src/modules/welcomeq/welcomeq.qrc
new file mode 100644
index 000000000..772bf7e88
--- /dev/null
+++ b/src/modules/welcomeq/welcomeq.qrc
@@ -0,0 +1,5 @@
+
+
+ welcomeq.qml
+
+