diff --git a/src/modules/officechooser/CMakeLists.txt b/src/modules/officechooser/CMakeLists.txt index a632f6750..4a839aad8 100644 --- a/src/modules/officechooser/CMakeLists.txt +++ b/src/modules/officechooser/CMakeLists.txt @@ -1,4 +1,15 @@ find_package( Qt5 COMPONENTS Core Gui Widgets REQUIRED ) +set( _extra_libraries "" ) + +### OPTIONAL AppData XML support in PackageModel +# +# +find_package(Qt5 COMPONENTS Xml) +if ( Qt5Xml_FOUND ) + add_definitions( -DHAVE_XML ) + list( APPEND _extra_libraries Qt5::Xml ) +endif() + calamares_add_plugin( officechooser TYPE viewmodule @@ -13,6 +24,7 @@ calamares_add_plugin( officechooser page_package.ui LINK_PRIVATE_LIBRARIES calamaresui + ${_extra_libraries} SHARED_LIB ) @@ -20,11 +32,14 @@ if( ECM_FOUND AND BUILD_TESTING ) ecm_add_test( Tests.cpp TEST_NAME - packagechooosertest + packagechoosertest LINK_LIBRARIES ${CALAMARES_LIBRARIES} + calamares_viewmodule_packagechooser Qt5::Core Qt5::Test + Qt5::Gui + ${_extra_libraries} ) - calamares_automoc( packagechooosertest) + calamares_automoc( packagechoosertest) endif() diff --git a/src/modules/officechooser/PackageChooserPage.cpp b/src/modules/officechooser/PackageChooserPage.cpp index c3d1ba3d0..6f565c914 100644 --- a/src/modules/officechooser/PackageChooserPage.cpp +++ b/src/modules/officechooser/PackageChooserPage.cpp @@ -1,7 +1,6 @@ /* === This file is part of Calamares - === * * Copyright 2019, Adriaan de Groot - * Copyright 2019, Philip MÜller * * Calamares is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -31,10 +30,10 @@ PackageChooserPage::PackageChooserPage( PackageChooserMode mode, QWidget* parent , ui( new Ui::PackageChooserPage ) , m_introduction( QString(), QString(), - tr( "Office Suite" ), - tr( "Please pick an office suite from the list. The selected product will be installed." ) ) + tr( "Package Selection" ), + tr( "Please pick a product from the list. The selected product will be installed." ) ) { - m_introduction.screenshot = QPixmap( QStringLiteral( ":/images/choose-office.jpg" ) ); + m_introduction.screenshot = QPixmap( QStringLiteral( ":/images/no-selection.png" ) ); ui->setupUi( this ); CALAMARES_RETRANSLATE( updateLabels(); ) @@ -42,9 +41,12 @@ PackageChooserPage::PackageChooserPage( PackageChooserMode mode, QWidget* parent switch ( mode ) { case PackageChooserMode::Optional: + FALLTHRU; case PackageChooserMode::Required: ui->products->setSelectionMode( QAbstractItemView::SingleSelection ); + break; case PackageChooserMode::OptionalMultiple: + FALLTHRU; case PackageChooserMode::RequiredMultiple: ui->products->setSelectionMode( QAbstractItemView::ExtendedSelection ); } @@ -55,9 +57,9 @@ PackageChooserPage::currentChanged( const QModelIndex& index ) { if ( !index.isValid() || !ui->products->selectionModel()->hasSelection() ) { - ui->productName->setText( m_introduction.name ); + ui->productName->setText( m_introduction.name.get() ); ui->productScreenshot->setPixmap( m_introduction.screenshot ); - ui->productDescription->setText( m_introduction.description ); + ui->productDescription->setText( m_introduction.description.get() ); } else { diff --git a/src/modules/officechooser/PackageChooserViewStep.cpp b/src/modules/officechooser/PackageChooserViewStep.cpp index faafa9951..6df785a06 100644 --- a/src/modules/officechooser/PackageChooserViewStep.cpp +++ b/src/modules/officechooser/PackageChooserViewStep.cpp @@ -1,7 +1,6 @@ /* === This file is part of Calamares - === * * Copyright 2019, Adriaan de Groot - * Copyright 2019, Philip MÜller * * Calamares is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -57,7 +56,7 @@ PackageChooserViewStep::~PackageChooserViewStep() QString PackageChooserViewStep::prettyName() const { - return tr( "Office Suite" ); + return tr( "Packages" ); } @@ -77,7 +76,7 @@ PackageChooserViewStep::widget() } else { - cWarning() << "OfficeChooser Widget created before model."; + cWarning() << "PackageChooser Widget created before model."; } } return m_widget; @@ -146,7 +145,7 @@ PackageChooserViewStep::onLeave() } Calamares::JobQueue::instance()->globalStorage()->insert( key, value ); - cDebug() << "OfficeChooser" << key << "selected" << value; + cDebug() << "PackageChooser" << key << "selected" << value; } Calamares::JobList @@ -178,35 +177,68 @@ PackageChooserViewStep::setConfigurationMap( const QVariantMap& configurationMap m_id = moduleInstanceKey().split( '@' ).last(); } + bool first_time = !m_model; + if ( configurationMap.contains( "items" ) ) + { + fillModel( configurationMap.value( "items" ).toList() ); + } + // TODO: replace this hard-coded model if ( !m_model ) { m_model = new PackageListModel( nullptr ); m_model->addPackage( PackageItem { QString(), QString(), - "No Office Suite", - "Please pick an office suite from the list. " - "If you don't want to install an office suite, that's fine, " - "you can install one later as needed.", - ":/images/choose-office.jpg" } ); - m_model->addPackage( PackageItem { "libreoffice-still", - "libreoffice-still", - "LibreOffice", - "LibreOffice is a powerful and free office suite, used by millions of people around the world. " - "Its clean interface and feature-rich tools help you unleash your creativity and enhance your productivity.", - ":/images/LibreOffice.jpg" } ); + "No Desktop", + "Please pick a desktop environment from the list. " + "If you don't want to install a desktop, that's fine, " + "your system will start up in text-only mode and you can " + "install a desktop environment later.", + ":/images/no-selection.png" } ); + m_model->addPackage( PackageItem { "kde", "kde", "Plasma", "Plasma Desktop", ":/images/kde.png" } ); + m_model->addPackage( PackageItem { + "gnome", "gnome", "GNOME", "GNU Networked Object Modeling Environment Desktop", ":/images/gnome.png" } ); + } - m_model->addPackage( PackageItem { "freeoffice", - "freeoffice", - "FreeOffice", - "FreeOffice 2018 is a full-featured Office suite with word processing, " - "spreadsheet and presentation software. It is seamlessly compatible with Microsoft Office. " - "(Note: You need to register the product for free longterm usage)", - ":/images/FreeOffice.jpg" } ); + if ( first_time && m_widget && m_model ) + { + hookupModel(); + } +} - if ( m_widget ) +void +PackageChooserViewStep::fillModel( const QVariantList& items ) +{ + if ( !m_model ) + { + m_model = new PackageListModel( nullptr ); + } + + if ( items.isEmpty() ) + { + cWarning() << "No *items* for PackageChooser module."; + return; + } + + cDebug() << "Loading PackageChooser model items from config"; + int item_index = 0; + for ( const auto& item_it : items ) + { + ++item_index; + QVariantMap item_map = item_it.toMap(); + if ( item_map.isEmpty() ) { - hookupModel(); + cWarning() << "PackageChooser entry" << item_index << "is not valid."; + continue; + } + + if ( item_map.contains( "appdata" ) ) + { + m_model->addPackage( PackageItem::fromAppData( item_map ) ); + } + else + { + m_model->addPackage( PackageItem( item_map ) ); } } } diff --git a/src/modules/officechooser/PackageChooserViewStep.h b/src/modules/officechooser/PackageChooserViewStep.h index 55ed2d4d5..e3ffc1d5b 100644 --- a/src/modules/officechooser/PackageChooserViewStep.h +++ b/src/modules/officechooser/PackageChooserViewStep.h @@ -56,6 +56,7 @@ public: void setConfigurationMap( const QVariantMap& configurationMap ) override; private: + void fillModel( const QVariantList& items ); void hookupModel(); PackageChooserPage* m_widget; diff --git a/src/modules/officechooser/PackageModel.cpp b/src/modules/officechooser/PackageModel.cpp index aa8dd39fc..59c6973ba 100644 --- a/src/modules/officechooser/PackageModel.cpp +++ b/src/modules/officechooser/PackageModel.cpp @@ -19,6 +19,13 @@ #include "PackageModel.h" #include "utils/Logger.h" +#include "utils/Variant.h" + +#ifdef HAVE_XML +#include +#include +#include +#endif const NamedEnumTable< PackageChooserMode >& roleNames() @@ -40,13 +47,6 @@ roleNames() return names; } -PackageItem -PackageItem::fromAppStream( const QString& filename ) -{ - // TODO: implement this - return PackageItem {}; -} - PackageItem::PackageItem() {} PackageItem::PackageItem( const QString& a_id, @@ -73,6 +73,239 @@ PackageItem::PackageItem( const QString& a_id, { } +PackageItem::PackageItem::PackageItem( const QVariantMap& item_map ) + : id( CalamaresUtils::getString( item_map, "id" ) ) + , package( CalamaresUtils::getString( item_map, "package" ) ) + , name( CalamaresUtils::Locale::TranslatedString( item_map, "name" ) ) + , description( CalamaresUtils::Locale::TranslatedString( item_map, "description" ) ) + , screenshot( CalamaresUtils::getString( item_map, "screenshot" ) ) +{ + if ( name.isEmpty() && id.isEmpty() ) + { + name = QObject::tr( "No product" ); + } + else if ( name.isEmpty() ) + { + cWarning() << "PackageChooser item" << id << "has an empty name."; + } + if ( description.isEmpty() ) + { + description = QObject::tr( "No description provided." ); + } +} + +#ifdef HAVE_XML +/** @brief try to load the given @p fileName XML document + * + * Returns a QDomDocument, which will be valid iff the file can + * be read and contains valid XML data. + */ +static inline QDomDocument +loadAppData( const QString& fileName ) +{ + QFile file( fileName ); + if ( !file.open( QIODevice::ReadOnly ) ) + { + return QDomDocument(); + } + QDomDocument doc( "AppData" ); + if ( !doc.setContent( &file ) ) + { + file.close(); + return QDomDocument(); + } + file.close(); + return doc; +} + +/** @brief gets the text of child element @p tagName + */ +static inline QString +getChildText( const QDomNode& n, const QString& tagName ) +{ + QDomElement e = n.firstChildElement( tagName ); + return e.isNull() ? QString() : e.text(); +} + +/** @brief Gets a suitable screenshot path + * + * The element contains zero or more + * elements, which can have a *type* associated with them. + * Scan the screenshot elements, return the path + * for the one labeled with type=default or, if there is no + * default, the first element. + */ +static inline QString +getScreenshotPath( const QDomNode& n ) +{ + QDomElement shotsNode = n.firstChildElement( "screenshots" ); + if ( shotsNode.isNull() ) + { + return QString(); + } + + const QDomNodeList shotList = shotsNode.childNodes(); + int firstScreenshot = -1; // Use which screenshot node? + for ( int i = 0; i < shotList.count(); ++i ) + { + if ( !shotList.at( i ).isElement() ) + { + continue; + } + QDomElement e = shotList.at( i ).toElement(); + if ( e.tagName() != "screenshot" ) + { + continue; + } + // If none has the "type=default" attribute, use the first one + if ( firstScreenshot < 0 ) + { + firstScreenshot = i; + } + // But type=default takes precedence. + if ( e.hasAttribute( "type" ) && e.attribute( "type" ) == "default" ) + { + firstScreenshot = i; + break; + } + } + + if ( firstScreenshot >= 0 ) + { + return shotList.at( firstScreenshot ).firstChildElement( "image" ).text(); + } + + return QString(); +} + +/** @brief Returns language of the given element @p e + * + * Transforms the attribute value for xml:lang to something + * suitable for TranslatedString (e.g. [lang]). + */ +static inline QString +getLanguage( const QDomElement& e ) +{ + QString language = e.attribute( "xml:lang" ); + if ( !language.isEmpty() ) + { + language.replace( '-', '_' ); + language.prepend( '[' ); + language.append( ']' ); + } + return language; +} + +/** @brief Scan the list of @p children for @p tagname elements and add them to the map + * + * Uses @p mapname instead of @p tagname for the entries in map @p m + * to allow renaming from XML to map keys (in particular for + * TranslatedString). Also transforms xml:lang attributes to suitable + * key-decorations on @p mapname. + */ +static inline void +fillMap( QVariantMap& m, const QDomNodeList& children, const QString& tagname, const QString& mapname ) +{ + for ( int i = 0; i < children.count(); ++i ) + { + if ( !children.at( i ).isElement() ) + { + continue; + } + + QDomElement e = children.at( i ).toElement(); + if ( e.tagName() != tagname ) + { + continue; + } + + m[ mapname + getLanguage( e ) ] = e.text(); + } +} + +/** @brief gets the and elements +* +* Builds up a map of the elements (which may have a *lang* +* attribute to indicate translations and paragraphs of the +* element (also with lang). Uses the +* elements to supplement the description if no description +* is available for a given language. +* +* Returns a map with keys suitable for use by TranslatedString. +*/ +static inline QVariantMap +getNameAndSummary( const QDomNode& n ) +{ + QVariantMap m; + + const QDomNodeList children = n.childNodes(); + fillMap( m, children, "name", "name" ); + fillMap( m, children, "summary", "description" ); + + const QDomElement description = n.firstChildElement( "description" ); + if ( !description.isNull() ) + { + fillMap( m, description.childNodes(), "p", "description" ); + } + + return m; +} +#endif + +PackageItem +PackageItem::fromAppData( const QVariantMap& item_map ) +{ +#ifdef HAVE_XML + QString fileName = CalamaresUtils::getString( item_map, "appdata" ); + if ( fileName.isEmpty() ) + { + cWarning() << "Can't load AppData without a suitable key."; + return PackageItem(); + } + cDebug() << "Loading AppData XML from" << fileName; + + QDomDocument doc = loadAppData( fileName ); + if ( doc.isNull() ) + { + return PackageItem(); + } + + QDomElement componentNode = doc.documentElement(); + if ( !componentNode.isNull() && componentNode.tagName() == "component" ) + { + // An "id" entry in the Calamares config overrides ID in the AppData + QString id = CalamaresUtils::getString( item_map, "id" ); + if ( id.isEmpty() ) + { + id = getChildText( componentNode, "id" ); + } + if ( id.isEmpty() ) + { + return PackageItem(); + } + + // A "screenshot" entry in the Calamares config overrides AppData + QString screenshotPath = CalamaresUtils::getString( item_map, "screenshot" ); + if ( screenshotPath.isEmpty() ) + { + screenshotPath = getScreenshotPath( componentNode ); + } + + QVariantMap map = getNameAndSummary( componentNode ); + map.insert( "id", id ); + map.insert( "screenshot", screenshotPath ); + + return PackageItem( map ); + } + + return PackageItem(); +#else + cWarning() << "Loading AppData XML is not supported."; + + return PackageItem(); +#endif +} + PackageListModel::PackageListModel( QObject* parent ) : QAbstractListModel( parent ) @@ -90,10 +323,14 @@ PackageListModel::~PackageListModel() {} void PackageListModel::addPackage( PackageItem&& p ) { - int c = m_packages.count(); - beginInsertRows( QModelIndex(), c, c ); - m_packages.append( p ); - endInsertRows(); + // Only add valid packages + if ( p.isValid() ) + { + int c = m_packages.count(); + beginInsertRows( QModelIndex(), c, c ); + m_packages.append( p ); + endInsertRows(); + } } int @@ -118,11 +355,11 @@ PackageListModel::data( const QModelIndex& index, int role ) const if ( role == Qt::DisplayRole /* Also PackageNameRole */ ) { - return m_packages[ row ].name; + return m_packages[ row ].name.get(); } else if ( role == DescriptionRole ) { - return m_packages[ row ].description; + return m_packages[ row ].description.get(); } else if ( role == ScreenshotRole ) { diff --git a/src/modules/officechooser/PackageModel.h b/src/modules/officechooser/PackageModel.h index 7f8fff8ec..869e124f0 100644 --- a/src/modules/officechooser/PackageModel.h +++ b/src/modules/officechooser/PackageModel.h @@ -19,6 +19,7 @@ #ifndef PACKAGEMODEL_H #define PACKAGEMODEL_H +#include "locale/TranslatableConfiguration.h" #include "utils/NamedEnum.h" #include @@ -39,12 +40,10 @@ const NamedEnumTable< PackageChooserMode >& roleNames(); struct PackageItem { QString id; - // TODO: may need more than one + // FIXME: unused QString package; - // TODO: name and description are localized - QString name; - QString description; - // TODO: may be more than one + CalamaresUtils::Locale::TranslatedString name; + CalamaresUtils::Locale::TranslatedString description; QPixmap screenshot; /// @brief Create blank PackageItem @@ -56,14 +55,44 @@ struct PackageItem */ PackageItem( const QString& id, const QString& package, const QString& name, const QString& description ); + /** @brief Creates a PackageItem from given strings. + * + * Set all the text members and load the screenshot from the given + * @p screenshotPath, which may be a QRC path (:/path/in/qrc) or + * a filesystem path, whatever QPixmap understands. + */ PackageItem( const QString& id, const QString& package, const QString& name, const QString& description, const QString& screenshotPath ); - // TODO: implement this - PackageItem fromAppStream( const QString& filename ); + /** @brief Creates a PackageItem from a QVariantMap + * + * This is intended for use when loading PackageItems from a + * configuration map. It will look up the various keys in the map + * and handle translation strings as well. + */ + PackageItem( const QVariantMap& map ); + + /** @brief Is this item valid? + * + * A valid item has an untranslated name available. + */ + bool isValid() const { return !name.isEmpty(); } + + /** @brief Loads an AppData XML file and returns a PackageItem + * + * The @p map must have a key *appdata*. That is used as the + * primary source of information, but keys *id* and *screenshotPath* + * may be used to override parts of the AppData -- so that the + * ID is under the control of Calamares, and the screenshot can be + * forced to a local path available on the installation medium. + * + * Requires XML support in libcalamares, if not present will + * return invalid PackageItems. + */ + static PackageItem fromAppData( const QVariantMap& map ); }; using PackageList = QVector< PackageItem >; @@ -75,6 +104,10 @@ public: PackageListModel( QObject* parent ); virtual ~PackageListModel() override; + /** @brief Add a package @p to the model + * + * Only valid packages are added -- that is, they must have a name. + */ void addPackage( PackageItem&& p ); int rowCount( const QModelIndex& index ) const override; diff --git a/src/modules/officechooser/Tests.cpp b/src/modules/officechooser/Tests.cpp index c016f1808..3e7961b92 100644 --- a/src/modules/officechooser/Tests.cpp +++ b/src/modules/officechooser/Tests.cpp @@ -18,9 +18,13 @@ #include "Tests.h" +#include "PackageModel.h" + +#include "utils/Logger.h" + #include -QTEST_GUILESS_MAIN( PackageChooserTests ) +QTEST_MAIN( PackageChooserTests ) PackageChooserTests::PackageChooserTests() {} @@ -29,6 +33,7 @@ PackageChooserTests::~PackageChooserTests() {} void PackageChooserTests::initTestCase() { + Logger::setupLogLevel( Logger::LOGDEBUG ); } void @@ -36,3 +41,37 @@ PackageChooserTests::testBogus() { QVERIFY( true ); } + +void +PackageChooserTests::testAppData() +{ + // Path from the build-dir + QString appdataName( "../io.calamares.calamares.appdata.xml" ); + QVERIFY( QFile::exists( appdataName ) ); + + QVariantMap m; + m.insert( "appdata", appdataName ); + + PackageItem p1 = PackageItem::fromAppData( m ); +#ifdef HAVE_XML + QVERIFY( p1.isValid() ); + QCOMPARE( p1.id, "io.calamares.calamares.desktop" ); + QCOMPARE( p1.name.get(), "Calamares" ); + // The entry has precedence + QCOMPARE( p1.description.get(), "Calamares is an installer program for Linux distributions." ); + // .. but en_GB doesn't have an entry in description, so uses + QCOMPARE( p1.description.get( QLocale( "en_GB" ) ), "Calamares Linux Installer" ); + QCOMPARE( p1.description.get( QLocale( "nl" ) ), "Calamares is een installatieprogramma voor Linux distributies." ); + QVERIFY( p1.screenshot.isNull() ); + + m.insert( "id", "calamares" ); + m.insert( "screenshot", ":/images/calamares.png" ); + PackageItem p2= PackageItem::fromAppData( m ); + QVERIFY( p2.isValid() ); + QCOMPARE( p2.id, "calamares" ); + QCOMPARE( p2.description.get( QLocale( "nl" ) ), "Calamares is een installatieprogramma voor Linux distributies." ); + QVERIFY( !p2.screenshot.isNull() ); +#else + QVERIFY( !p1.isValid() ); +#endif +} diff --git a/src/modules/officechooser/Tests.h b/src/modules/officechooser/Tests.h index bc257f5a5..62efe92cc 100644 --- a/src/modules/officechooser/Tests.h +++ b/src/modules/officechooser/Tests.h @@ -31,6 +31,7 @@ public: private Q_SLOTS: void initTestCase(); void testBogus(); + void testAppData(); }; #endif diff --git a/src/modules/officechooser/officechooser.conf b/src/modules/officechooser/officechooser.conf index b4e48c995..b90571a85 100644 --- a/src/modules/officechooser/officechooser.conf +++ b/src/modules/officechooser/officechooser.conf @@ -19,3 +19,61 @@ # or "optionalmultiple", "requiredmultiple" (for zero-or-more # or one-or-more). mode: required + +# Items to display in the chooser. In general, this should be a +# pretty short list to avoid overwhelming the UI. This is a list +# of objects, and the items are displayed in list order. +# +# Either provide the data for an item in the list (using the keys +# below), or use existing AppData XML files as a source for the data. +# +# For data provided by the list: the item has an id, which is used in +# setting the value of *packagechooser_*). The following fields +# are mandatory: +# +# - *id* ID for the product. The ID "" is special, and is used for +# "no package selected". Only include this if the mode allows +# selecting none. +# - *package* Package name for the product. While mandatory, this is +# not actually used anywhere. +# - *name* Human-readable name of the product. To provide translations, +# add a *[lang]* decoration as part of the key name, e.g. `name[nl]` +# for Dutch. The list of usable languages can be found in +# `CMakeLists.txt` or as part of the debug output of Calamares. +# - *description* Human-readable description. These can be translated +# as well. +# - *screenshot* Path to a single screenshot of the product. May be +# a filesystem path or a QRC path (e.g. ":/images/no-selection.png"). +# +# Use the empty string "" as ID / key for the "no selection" item if +# you want to customize the display of that item as well. +# +# For data provided by AppData XML: the item has an *appdata* +# key which points to an AppData XML file in the local filesystem. +# This file is parsed to provide the id (from AppData id), name +# (from AppData name), description (from AppData description paragraphs +# or the summary entries), and a screenshot (the defautl screenshot +# from AppData). No package is set (but that is unused anyway). +# +# AppData may contain IDs that are not useful inside Calamares, +# and the screenshot URL may be remote -- a remote URL will not +# be loaded and the screenshot will be missing. An item with *appdata* +# **may** specify an ID or screenshot path, as above. This will override +# the settings from AppData. +items: + - id: "" + package: "" + name: "No Office Suite" + description: "Please pick an office suite from the list. If you don't want to install an office suite, that's fine, you can install one later as needed." + screenshot: ":/images/choose-office.jpg" + - id: libreoffice-still + package: libreoffice-still + name: LibreOffice + description: "LibreOffice is a powerful and free office suite, used by millions of people around the world. Its clean interface and feature-rich tools help you unleash your creativity and enhance your productivity." + screenshot: ":/images/LibreOffice.jpg" + - id: freeoffice + package: freeoffice + name: FreeOffice + description: "FreeOffice 2018 is a full-featured Office suite with word processing, spreadsheet and presentation software. It is seamlessly compatible with Microsoft Office. (Note: You need to register the product for free longterm usage) + screenshot: ":/images/FreeOffice.jpg" + diff --git a/src/modules/officechooser/packagechooser.qrc b/src/modules/officechooser/packagechooser.qrc index f0b5e03fb..8f211c1bb 100644 --- a/src/modules/officechooser/packagechooser.qrc +++ b/src/modules/officechooser/packagechooser.qrc @@ -1,7 +1,8 @@ - images/choose-office.jpg - images/LibreOffice.jpg - images/FreeOffice.jpg + images/no-selection.png + images/kde.png + images/gnome.png + images/calamares.png diff --git a/src/modules/officechooser/page_package.ui b/src/modules/officechooser/page_package.ui index ea85acff3..17a960549 100644 --- a/src/modules/officechooser/page_package.ui +++ b/src/modules/officechooser/page_package.ui @@ -39,9 +39,6 @@ TextLabel - - Qt::AlignCenter - @@ -49,9 +46,6 @@ TextLabel - - Qt::AlignCenter - @@ -59,9 +53,6 @@ TextLabel - - Qt::AlignCenter - true diff --git a/src/modules/packagechooser/PackageChooserPage.cpp b/src/modules/packagechooser/PackageChooserPage.cpp index 6f565c914..37c1a2156 100644 --- a/src/modules/packagechooser/PackageChooserPage.cpp +++ b/src/modules/packagechooser/PackageChooserPage.cpp @@ -1,6 +1,7 @@ /* === This file is part of Calamares - === * * Copyright 2019, Adriaan de Groot + * Copyright 2019, Philip MÜller * * Calamares is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -30,10 +31,10 @@ PackageChooserPage::PackageChooserPage( PackageChooserMode mode, QWidget* parent , ui( new Ui::PackageChooserPage ) , m_introduction( QString(), QString(), - tr( "Package Selection" ), - tr( "Please pick a product from the list. The selected product will be installed." ) ) + tr( "Office Suite" ), + tr( "Please pick an office suite from the list. The selected product will be installed." ) ) { - m_introduction.screenshot = QPixmap( QStringLiteral( ":/images/no-selection.png" ) ); + m_introduction.screenshot = QPixmap( QStringLiteral( ":/images/choose-office.jpg" ) ); ui->setupUi( this ); CALAMARES_RETRANSLATE( updateLabels(); ) diff --git a/src/modules/packagechooser/PackageChooserViewStep.cpp b/src/modules/packagechooser/PackageChooserViewStep.cpp index 6df785a06..74b0c5693 100644 --- a/src/modules/packagechooser/PackageChooserViewStep.cpp +++ b/src/modules/packagechooser/PackageChooserViewStep.cpp @@ -1,6 +1,7 @@ /* === This file is part of Calamares - === * * Copyright 2019, Adriaan de Groot + * Copyright 2019, Philip MÜller * * Calamares is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -76,7 +77,7 @@ PackageChooserViewStep::widget() } else { - cWarning() << "PackageChooser Widget created before model."; + cWarning() << "OfficeChooser Widget created before model."; } } return m_widget; @@ -189,16 +190,24 @@ PackageChooserViewStep::setConfigurationMap( const QVariantMap& configurationMap m_model = new PackageListModel( nullptr ); m_model->addPackage( PackageItem { QString(), QString(), - "No Desktop", - "Please pick a desktop environment from the list. " - "If you don't want to install a desktop, that's fine, " - "your system will start up in text-only mode and you can " - "install a desktop environment later.", - ":/images/no-selection.png" } ); - m_model->addPackage( PackageItem { "kde", "kde", "Plasma", "Plasma Desktop", ":/images/kde.png" } ); - m_model->addPackage( PackageItem { - "gnome", "gnome", "GNOME", "GNU Networked Object Modeling Environment Desktop", ":/images/gnome.png" } ); - } + "No Office Suite", + "Please pick an office suite from the list. " + "If you don't want to install an office suite, that's fine, " + "you can install one later as needed.", + ":/images/choose-office.jpg" } ); + m_model->addPackage( PackageItem { "libreoffice-still", + "libreoffice-still", + "LibreOffice", + "LibreOffice is a powerful and free office suite, used by millions of people around the world. " + "Its clean interface and feature-rich tools help you unleash your creativity and enhance your productivity.", + ":/images/LibreOffice.jpg" } ); + m_model->addPackage( PackageItem { "freeoffice", + "freeoffice", + "FreeOffice", + "FreeOffice 2018 is a full-featured Office suite with word processing, " + "spreadsheet and presentation software. It is seamlessly compatible with Microsoft Office. " + "(Note: You need to register the product for free longterm usage)", + ":/images/FreeOffice.jpg" } ); if ( first_time && m_widget && m_model ) { diff --git a/src/modules/packagechooser/packagechooser.qrc b/src/modules/packagechooser/packagechooser.qrc index 8f211c1bb..f0b5e03fb 100644 --- a/src/modules/packagechooser/packagechooser.qrc +++ b/src/modules/packagechooser/packagechooser.qrc @@ -1,8 +1,7 @@ - images/no-selection.png - images/kde.png - images/gnome.png - images/calamares.png + images/choose-office.jpg + images/LibreOffice.jpg + images/FreeOffice.jpg