Merge pull request #245 from shainer/netinstall

Netinstall module. See README for complete guide. Allows to configure...groups and packages; selected packages are installed through the 'packages' module.
This commit is contained in:
Teo Mrnjavac 2016-07-15 18:01:43 +02:00 committed by GitHub
commit 92eb947cc5
16 changed files with 1146 additions and 0 deletions

View File

@ -0,0 +1,18 @@
include_directories( ${PROJECT_BINARY_DIR}/src/libcalamaresui )
calamares_add_plugin( netinstall
TYPE viewmodule
EXPORT_MACRO PLUGINDLLEXPORT_PRO
SOURCES
NetInstallViewStep.cpp
NetInstallPage.cpp
widgets/groupselectionwidget.cpp
UI
page_netinst.ui
widgets/groupselectionwidget.ui
RESOURCES
netinstall.qrc
LINK_LIBRARIES
calamaresui
SHARED_LIB
)

View File

@ -0,0 +1,170 @@
/*
* Copyright 2016, Luca Giambonini <almack@chakraos.org>
* Copyright 2016, Lisa Vitolo <shainer@chakraos.org>
*
* 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 <http://www.gnu.org/licenses/>.
*/
#include "NetInstallPage.h"
#include "widgets/groupselectionwidget.h"
#include "ui_page_netinst.h"
#include "GlobalStorage.h"
#include "JobQueue.h"
#include "utils/Logger.h"
#include "utils/YamlUtils.h"
#include <QFile>
#include <QMap>
#include <QTextStream>
#include <QNetworkAccessManager>
#include <QNetworkRequest>
#include <QNetworkReply>
#include <QtDebug>
#include <QtGlobal>
#include <QWidget>
#include <QSignalMapper>
#include <yaml-cpp/yaml.h>
using CalamaresUtils::yamlToVariant;
NetInstallPage::NetInstallPage( QWidget* parent )
: QWidget( parent )
, ui( new Ui::Page_NetInst )
, m_networkManager( this )
{
ui->setupUi( this );
}
bool
NetInstallPage::isReady()
{
// nothing to wait for, the data are immediately ready
// if the user does not select any group nothing is installed
return true;
}
void NetInstallPage::readGroups( const QByteArray& yamlData )
{
YAML::Node groups = YAML::Load( yamlData.constData() );
Q_ASSERT( groups.IsSequence() );
for ( YAML::const_iterator it = groups.begin(); it != groups.end(); ++it )
{
const YAML::Node groupDefinition = *it;
QString name( tr( yamlToVariant(groupDefinition["name"]).toByteArray() ) );
QString description( tr( yamlToVariant(groupDefinition["description"]).toByteArray() ) );
QStringList packages;
for ( YAML::const_iterator it = groupDefinition["packages"].begin();
it != groupDefinition["packages"].end(); ++it )
packages.append( yamlToVariant(*it).toString() );
m_groups[name].name = name;
m_groups[name].description = description;
m_groups[name].packages = packages;
if ( groupDefinition["selected"] )
m_groups[name].selected = yamlToVariant( groupDefinition["selected"] ).toBool();
if ( groupDefinition["hidden"] )
m_groups[name].hidden = yamlToVariant( groupDefinition["hidden"] ).toBool();
m_groupOrder.append( name );
}
}
void
NetInstallPage::dataIsHere( QNetworkReply* reply )
{
if ( reply->error() != QNetworkReply::NoError )
{
cDebug() << reply->errorString();
ui->netinst_status->setText( tr( "Network Installation. (Disabled: Unable to fetch package lists, check your network connection)" ) );
return;
}
readGroups( reply->readAll() );
QSignalMapper* mapper = new QSignalMapper( this );
foreach ( const QString& groupKey, m_groupOrder )
{
Group group = m_groups[groupKey];
if ( group.hidden )
{
// Do not present on view.
continue;
}
GroupSelectionWidget* groupWidget = new GroupSelectionWidget( group.name, group.description, group.packages, this );
m_groupWidgets.insert( groupKey, groupWidget );
ui->groupswidget->layout()->addWidget( groupWidget );
mapper->setMapping( groupWidget, groupKey );
connect( groupWidget, &GroupSelectionWidget::toggled, mapper,
static_cast<void(QSignalMapper::*)()>(&QSignalMapper::map) );
}
reply->deleteLater();
emit checkReady( isReady() );
}
QStringList NetInstallPage::selectedPackages() const
{
QStringList selectedPackages;
// Add all the packages for groups that are toggled in the view.
for ( auto it = m_groupWidgets.constBegin(); it != m_groupWidgets.constEnd(); it++ )
{
if ( it.value()->isToggled() )
selectedPackages += m_groups[it.key()].packages;
}
// Add all the packages for groups that are hidden but selected.
for ( const Group& group : m_groups.values() )
{
if ( group.hidden && group.selected )
selectedPackages += group.packages;
}
return selectedPackages;
}
void NetInstallPage::loadGroupList()
{
QString confUrl(
Calamares::JobQueue::instance()->globalStorage()->value(
"groupsUrl" ).toString() );
QNetworkRequest request;
request.setUrl( QUrl( confUrl ) );
// Follows all redirects except unsafe ones (https to http).
request.setAttribute(QNetworkRequest::FollowRedirectsAttribute, true);
// Not everybody likes the default User Agent used by this class (looking at you,
// sourceforge.net), so let's set a more descriptive one.
request.setRawHeader( "User-Agent", "Mozilla/5.0 (compatible; Calamares)" );
connect(&m_networkManager, &QNetworkAccessManager::finished,
this, &NetInstallPage::dataIsHere);
m_networkManager.get(request);
}
void NetInstallPage::onActivate()
{
ui->groupswidget->setFocus();
}

View File

@ -0,0 +1,101 @@
/*
* Copyright 2016, Luca Giambonini <almack@chakraos.org>
* Copyright 2016, Lisa Vitolo <shainer@chakraos.org>
*
* 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 <http://www.gnu.org/licenses/>.
*/
#ifndef NETINSTALLPAGE_H
#define NETINSTALLPAGE_H
#include "Typedefs.h"
#include <QWidget>
#include <QAbstractButton>
#include <QNetworkAccessManager>
// required forward declarations
class QByteArray;
class QNetworkReply;
class GroupSelectionWidget;
namespace Ui
{
class Page_NetInst;
}
class NetInstallPage : public QWidget
{
Q_OBJECT
// Internal representation of a package group.
struct Group
{
Group()
: Group( "","",false, false ) { }
Group( QString name, QString description, bool selected, bool hidden )
: name( name ), description( description ), selected( selected ), hidden( hidden ) { }
Group( QString name, QString description )
: Group( name, description, false, false ) { }
QString name;
QString description;
QStringList packages;
// See README.md for a description of these two fields.
bool selected = false;
bool hidden = false;
};
public:
NetInstallPage( QWidget* parent = nullptr );
void onActivate();
bool isReady();
// Retrieves the groups, with name, description and packages, from
// the remote URL configured in the settings. Assumes the URL is already
// in the global storage. This should be called before displaying the page.
void loadGroupList();
// Returns the list of packages belonging to groups that are
// selected in the view in this given moment. No data is cached here, so
// this function does not have constant time.
QStringList selectedPackages() const;
public slots:
void dataIsHere( QNetworkReply* );
signals:
void checkReady( bool );
private:
// Takes the YAML data representing the groups and reads them into the
// m_groups and m_groupOrder internal structures. See the README.md
// of this module to know the format expected of the YAML files.
void readGroups( const QByteArray& yamlData );
Ui::Page_NetInst* ui;
// Handles connection with the remote URL storing the configuration.
QNetworkAccessManager m_networkManager;
QHash<QString, Group> m_groups;
// For each group name, store the selection widget to retrieve UI
// properties.
QHash<QString, GroupSelectionWidget*> m_groupWidgets;
QList<QString> m_groupOrder;
};
#endif // NETINSTALLPAGE_H

View File

@ -0,0 +1,151 @@
/*
* Copyright 2016, Luca Giambonini <almack@chakraos.org>
* Copyright 2016, Lisa Vitolo <shainer@chakraos.org>
*
* 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 <http://www.gnu.org/licenses/>.
*/
#include "NetInstallViewStep.h"
#include "JobQueue.h"
#include "GlobalStorage.h"
#include "utils/Logger.h"
#include "NetInstallPage.h"
CALAMARES_PLUGIN_FACTORY_DEFINITION( NetInstallViewStepFactory, registerPlugin<NetInstallViewStep>(); )
NetInstallViewStep::NetInstallViewStep( QObject* parent )
: Calamares::ViewStep( parent )
, m_widget( new NetInstallPage() )
, m_nextEnabled( true )
{
emit nextStatusChanged( true );
connect( m_widget, &NetInstallPage::checkReady,
this, &NetInstallViewStep::nextStatusChanged );
}
NetInstallViewStep::~NetInstallViewStep()
{
if ( m_widget && m_widget->parent() == nullptr )
m_widget->deleteLater();
}
QString
NetInstallViewStep::prettyName() const
{
return tr( "Package selection" );
}
QString
NetInstallViewStep::prettyStatus() const
{
return m_prettyStatus;
}
QWidget*
NetInstallViewStep::widget()
{
return m_widget;
}
void
NetInstallViewStep::next()
{
emit done();
}
void
NetInstallViewStep::back()
{}
bool
NetInstallViewStep::isNextEnabled() const
{
return m_nextEnabled;
}
bool
NetInstallViewStep::isBackEnabled() const
{
return true;
}
bool
NetInstallViewStep::isAtBeginning() const
{
return true;
}
bool
NetInstallViewStep::isAtEnd() const
{
return true;
}
QList< Calamares::job_ptr >
NetInstallViewStep::jobs() const
{
return m_jobs;
}
void
NetInstallViewStep::onActivate()
{
m_widget->onActivate();
}
void
NetInstallViewStep::onLeave()
{
cDebug() << "Leaving netinstall, adding packages to be installed"
<< "to global storage";
if ( !m_widget->selectedPackages().empty() )
{
QMap<QString, QVariant> packagesWithOperation;
// Gets all packages selected in the page; includes groups that are
// selected by default but not displayed.
packagesWithOperation.insert( "install", m_widget->selectedPackages() );
Calamares::GlobalStorage* gs = Calamares::JobQueue::instance()->globalStorage();
gs->insert( "packageOperations", QVariant( packagesWithOperation ) );
}
}
void
NetInstallViewStep::setConfigurationMap( const QVariantMap& configurationMap )
{
if ( configurationMap.contains( "groupsUrl" ) &&
configurationMap.value( "groupsUrl" ).type() == QVariant::String )
{
Calamares::JobQueue::instance()->globalStorage()->insert(
"groupsUrl", configurationMap.value( "groupsUrl" ).toString() );
m_widget->loadGroupList();
}
}

View File

@ -0,0 +1,72 @@
/*
* Copyright 2016, Luca Giambonini <almack@chakraos.org>
* Copyright 2016, Lisa Vitolo <shainer@chakraos.org>
*
* 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 <http://www.gnu.org/licenses/>.
*/
#ifndef NETINSTALLVIEWSTEP_H
#define NETINSTALLVIEWSTEP_H
#include <utils/PluginFactory.h>
#include <viewpages/ViewStep.h>
#include <PluginDllMacro.h>
#include <QVariant>
class NetInstallPage;
class PLUGINDLLEXPORT NetInstallViewStep : public Calamares::ViewStep
{
Q_OBJECT
public:
explicit NetInstallViewStep( QObject* parent = nullptr );
virtual ~NetInstallViewStep();
QString prettyName() const override;
QString prettyStatus() const override;
QWidget* widget() override;
void next() override;
void back() override;
bool isNextEnabled() const override;
bool isBackEnabled() const override;
bool isAtBeginning() const override;
bool isAtEnd() const override;
QList< Calamares::job_ptr > jobs() const override;
void onActivate() override;
// Leaving the page; store all selected packages for later installation.
void onLeave() override;
void setConfigurationMap( const QVariantMap& configurationMap ) override;
private:
NetInstallPage* m_widget;
bool m_nextEnabled;
QString m_prettyStatus;
QList< Calamares::job_ptr > m_jobs;
};
CALAMARES_PLUGIN_FACTORY_DECLARATION( NetInstallViewStepFactory )
#endif // NETINSTALLVIEWSTEP_H

View File

@ -0,0 +1,66 @@
# Netinstall module
The netinstall module allows distribution maintainers to ship minimal ISOs with only a basic set of preinstall packages.
At installation time, the user is presented with the choice to install groups of packages from a predefined list.
Calamares will then invoke the correct backend to install the packages.
## Configuration of the packages
Every distribution can choose which groups to display and which packages should be in the groups.
The *netinstall.conf* file should have this format:
----
groupsUrl: <URL to YAML file>
The URL must point to a YAML file. Here is a short example of how the YAML file should look.
- name: "Group name"
description: "Description of the group"
packages:
- lsb-release
- avahi
- grub
- name: "Second group name"
...
The file is composed of a list of entry, each describing one group. The keys *name*, *description* and *packages* are required.
Two more keys are supported, *hidden* (if true, do not show the group on the page) and *selected* (if true, display the group as selected). Both default to false if not present.
If both keys are set to true for the same group, you are basically creating a "default" group of packages which will always be installed in the user's system.
## Configuration of the module
Here is the set of instructions to have the module work in your Calamares. As of July 2016, this has been successfully
tested using the live installation of Chakra Fermi.
First, if the module is used, we need to require a working Internet connection, otherwise the module will be
unable to fetch the package groups and to perform the installation. Requirements for the Calamares instance
are configured in the **welcome.conf** file (configuration for the **welcome** module). Make sure *internet*
is listed below *required*.
In the *settings.conf* file, decide where the **netinstall** page should be displayed. I put it just after the
**welcome** page, but any position between that and just before **partition** should make no difference.
If not present, add the **packages** job in the **exec** list. This is the job that calls the package manager
to install packages. Make sure it is configured to use the correct package manager for your distribution; this
is configured in src/modules/packages/packages.conf.
The exec list should be:
- unpackfs
- networkcfg
- packages
**unpackfs** creates the chroot where the installation is performed, and unpacks the root image with the filesystem
structure; **networkcfg** set ups a working network in the chroot; and finally **packages** can install packages
in the chroot.
## Common issues
If launching the package manager command returns you negative exit statuses and nothing is actually invoked, this
is likely an error in the setup of the chroot; check that the parameter **rootMountPoint** is set to the correct
value in the Calamares configuration.
If the command is run, but exits with error, check that the network is working in the chroot. Make sure /etc/resolv.conf
exists and that it's not empty.

Binary file not shown.

After

Width:  |  Height:  |  Size: 28 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 28 KiB

View File

@ -0,0 +1,7 @@
# Module metadata file for netinstall module
# Syntax is YAML 1.2
---
type: "view"
name: "netinstall"
interface: "qtplugin"
load: "libcalamares_viewmodule_netinstall.so"

View File

@ -0,0 +1,2 @@
---
groupsUrl: http://chakraos.org/netinstall.php

View File

@ -0,0 +1,6 @@
<RCC>
<qresource prefix="/">
<file>images/arrow-up.png</file>
<file>images/arrow-down.png</file>
</qresource>
</RCC>

View File

@ -0,0 +1,246 @@
- name: "Default"
description: "Default group"
hidden: true
selected: true
packages:
- base
- chakra-live-skel
- cdemu-client
- lsb-release
- avahi
- grub
# disk utils
- dosfstools
- e2fsprogs
- fuse
- gptfdisk
- jfsutils
- ntfs-3g
- reiserfsprogs
- xfsprogs
# power
- acpi_call
- pmtools
# network
- dnsutils
- iputils
- netcfg
- xinetd
# firmwares
- alsa-firmware
- linux-firmware
# sound
- alsa-lib
- alsa-utils
- gstreamer
- gst-plugins-good
- gst-plugins-bad
- libao
- libcanberra-gstreamer
- libcanberra-pulse
- pulseaudio
- pulseaudio-alsa
# tools
- bash-completion
- hwinfo
- lsof
- man-db
- mlocate
- nano
- openssh
- sudo
- vim
- zsh # :D
# archivers
- p7zip
- unarj
- unrar
- unzip
- zip
# xorg base
- xorg
- xorg-apps
- xorg-fonts-alias
- xorg-fonts-encodings
- xorg-fonts-misc
- xorg-res-utils
- xorg-server
- xorg-server-utils
- xorg-xauth
- xorg-xinit
- xorg-xkb-utils
# xorg video drivers
- xf86-video-apm
- xf86-video-ark
- xf86-video-ati
- xf86-video-chips
- xf86-video-cirrus
- xf86-video-glint
- xf86-video-i128
- xf86-video-i740
- xf86-video-intel
- xf86-video-mach64
- xf86-video-mga
- xf86-video-neomagic
- xf86-video-nouveau
- xf86-video-nv
- xf86-video-openchrome
- xf86-video-r128
- xf86-video-rendition
- xf86-video-s3
- xf86-video-s3virge
- xf86-video-savage
- xf86-video-siliconmotion
- xf86-video-sisusb
- xf86-video-tdfx
- xf86-video-trident
- xf86-video-tseng
- xf86-video-v4l
- xf86-video-vesa
- xf86-video-voodoo
- mesa-libgl
# xorg input drivers
- xf86-input-synaptics
- xf86-input-wacom
- xf86-input-evdev
- xf86-input-keyboard
- xf86-input-mouse
# fonts
- terminus-font
- ttf-dejavu
- ttf-liberation
- wqy-microhei
- xorg-fonts-100dpi
- xorg-fonts-75dpi
- xorg-fonts-cyrillic
# additional stuff that needs xorg
- hicolor-icon-theme
# kde
- chakra-common
- qt
- kde-baseapps
- kde-baseapps-dolphin
- kde-baseapps-konsole
- kde-runtime
- kde-workspace
- kdelibs
- kdepimlibs
- kdemultimedia-kmix
- oxygen-icons
- phonon-backend-gstreamer
# chakra theme (including kapudan options)
- chakra-wallpapers-dharma
- chakra-wallpapers-curie
- chakra-wallpapers-descartes
- grub2-themes-sirius
- kapudan-kde-themes-caledonia
- kde-kdm-themes-sirius
- kde-ksplash-themes-sirius
- kde-plasma-themes-caledonia
- python2-imaging
- python2-v4l2capture
- python2-xlib
- caledonia-colors
- yakuake-themes-ronak
# kde (everything else)
- kdeadmin-kcron
- kdeadmin-kuser
- kdeplasma-addons-applets-icontasks
- kdesdk-kate
- kdeutils-ark
- kdeutils-kgpg
- kdeutils-sweeper
# kde network
- kdeplasma-applets-plasma-nm
- networkmanager-dispatcher-ntpd
- kcm-ufw
# applications
- rekonq
- yakuake
# enable systemd-units
- chakra-init-live
# overlay pkgs
- partitionmanager
- octopi-notifier
- kapudan
- name: "Wireless"
description: "Tools for wireless connections"
packages:
- crda
- ndiswrapper
- usb-modeswitch
- wireless-regdb
- wireless_tools
- wpa_supplicant
- name: "CCR"
description: "Tools for the Chakra Community Repository"
packages:
- ccr
- base-devel
- name: "Graphics"
description: "Applications to work with graphics"
packages:
- kdegraphics-gwenview
- kdegraphics-kamera
- kdegraphics-kcolorchooser
- kdegraphics-kgamma
- kdegraphics-kolourpaint
- kdegraphics-kruler
- kdegraphics-ksaneplugin
- kdegraphics-ksnapshot
- kdegraphics-libkdcraw
- kdegraphics-libkexiv2
- kdegraphics-libkipi
- kdegraphics-libksane
- kdegraphics-mobipocket
- kdegraphics-okular
- kdegraphics-strigi-analyzer
- kdegraphics-svgpart
- kdegraphics-thumbnailers
- imagemagick
- name: "Burning"
description: "Set of packages for disc burning"
packages:
- dvd+rw-tools
- vcdimager
- transcode
- emovix
- k3b
- libdvdcss
- name: "Printing"
description: "Print much?"
packages:
- cups
- gutenprint
- cups-pdf
- kdeadmin-print-manager
- hplip
- epsoneplijs
- epson-inkjet-printer-escpr
- python2-gobject2
- samba
- name: "Multimedia"
description: "Music and video players"
packages:
- kdemultimedia-dragonplayer
- kdenlive
- amarok
- name: "Miscellaneous"
description: "Useful tools and apps"
packages:
- imagewriter
- tomoyo-tools
- python2-gobject ## needed for systemd-analyze
- clamav
- kdenetwork-kget ## maybe move to a network group?
- kdeplasma-addons-applets-lancelot
- kdeplasma-applets-homerun
- kdeplasma-applets-appmenu-qml
- kdeplasma-addons-runners-characters
- kdeplasma-addons-runners-converter
- kdeplasma-addons-runners-datetime
- kdeplasma-addons-runners-dictionary ##4.10 option
- kdeplasma-addons-runners-spellchecker
- appmenu-qt ## needed for menubar options in 4.10
- kscreen

View File

@ -0,0 +1,52 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>Page_NetInst</class>
<widget class="QWidget" name="Page_NetInst">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>997</width>
<height>474</height>
</rect>
</property>
<property name="windowTitle">
<string/>
</property>
<layout class="QVBoxLayout" name="verticalLayout_2">
<item>
<widget class="QScrollArea" name="scrollArea">
<property name="maximumSize">
<size>
<width>16777215</width>
<height>16777215</height>
</size>
</property>
<property name="widgetResizable">
<bool>true</bool>
</property>
<widget class="QWidget" name="groupswidget">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>981</width>
<height>434</height>
</rect>
</property>
<layout class="QVBoxLayout" name="verticalLayout_3"/>
</widget>
</widget>
</item>
<item>
<widget class="QLabel" name="netinst_status">
<property name="text">
<string/>
</property>
</widget>
</item>
</layout>
</widget>
<resources/>
<connections/>
</ui>

View File

@ -0,0 +1,66 @@
/*
* Copyright 2016, Luca Giambonini <almack@chakraos.org>
* Copyright 2016, Lisa Vitolo <shainer@chakraos.org>
*
* 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 <http://www.gnu.org/licenses/>.
*/
#include "groupselectionwidget.h"
#include <QtDebug>
GroupSelectionWidget::GroupSelectionWidget( QString name, QString description, QStringList packages, QWidget* parent ) :
QWidget( parent ),
m_isToggled( false )
{
ui.setupUi( this );
connect( ui.group, &QCheckBox::toggled, this, &GroupSelectionWidget::toggleGroup );
ui.group->setText( name );
ui.description->setText( description );
const int columns = 4;
const int rows = ( packages.size() - 1 ) / columns + 1;
ui.packageview->setRowCount( rows );
ui.packageview->setColumnCount( columns );
ui.packageview->horizontalHeader()->setSectionResizeMode( QHeaderView::Stretch );
int r = 0, c = 0;
for ( int i = 0; i < packages.size(); ++i )
{
ui.packageview->setItem( r++,c, new QTableWidgetItem( packages.at( i ) ) );
if ( r == ui.packageview->rowCount() )
{
++c;
r = 0;
}
}
int rowsShown = 6;
rowsShown = rows < rowsShown ? rows : 6;
ui.packageview->setFixedHeight( rowsShown * ui.packageview->rowHeight( 0 ) );
ui.packageview->hide();
}
void GroupSelectionWidget::toggleGroup( bool isToggled )
{
m_isToggled = isToggled;
emit toggled( isToggled );
}
bool GroupSelectionWidget::isToggled() const
{
return m_isToggled;
}

View File

@ -0,0 +1,50 @@
/*
* Copyright 2016, Luca Giambonini <almack@chakraos.org>
* Copyright 2016, Lisa Vitolo <shainer@chakraos.org>
*
* 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 <http://www.gnu.org/licenses/>.
*/
#ifndef GROUPSELECTIONWIDGET_H
#define GROUPSELECTIONWIDGET_H
#include "ui_groupselectionwidget.h"
#include <QSignalMapper>
#include <QWidget>
// Represents a widget to display and select a group.
class GroupSelectionWidget : public QWidget
{
Q_OBJECT
public:
explicit GroupSelectionWidget( QString name, QString description, QStringList packages, QWidget* parent = nullptr );
// Current status of the group: is it selected in the view?
bool isToggled() const;
signals:
void toggled( bool );
public slots:
void toggleGroup( bool isToggled );
private:
Ui::GroupSelectionWidget ui;
static QSignalMapper* m_mapper;
bool m_isToggled;
};
#endif // GROUPSELECTIONWIDGET_H

View File

@ -0,0 +1,139 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>GroupSelectionWidget</class>
<widget class="QWidget" name="GroupSelectionWidget">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>805</width>
<height>62</height>
</rect>
</property>
<property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="Preferred">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="windowTitle">
<string>Frame</string>
</property>
<layout class="QVBoxLayout" name="verticalLayout">
<item>
<widget class="QWidget" name="widget" native="true">
<layout class="QHBoxLayout" name="horizontalLayout">
<item>
<widget class="QCheckBox" name="group">
<property name="text">
<string>group</string>
</property>
</widget>
</item>
<item>
<widget class="QLabel" name="description">
<property name="text">
<string>description</string>
</property>
</widget>
</item>
<item>
<widget class="QPushButton" name="pushButton">
<property name="sizePolicy">
<sizepolicy hsizetype="Fixed" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="text">
<string/>
</property>
<property name="icon">
<iconset resource="../netinstall.qrc">
<normaloff>:/images/arrow-up.png</normaloff>
<normalon>:/images/arrow-down.png</normalon>:/images/arrow-up.png</iconset>
</property>
<property name="checkable">
<bool>true</bool>
</property>
<property name="checked">
<bool>true</bool>
</property>
</widget>
</item>
</layout>
</widget>
</item>
<item>
<widget class="QTableWidget" name="packageview">
<property name="enabled">
<bool>true</bool>
</property>
<property name="sizePolicy">
<sizepolicy hsizetype="Expanding" vsizetype="Maximum">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="minimumSize">
<size>
<width>0</width>
<height>0</height>
</size>
</property>
<property name="maximumSize">
<size>
<width>16777215</width>
<height>0</height>
</size>
</property>
<property name="editTriggers">
<set>QAbstractItemView::NoEditTriggers</set>
</property>
<property name="tabKeyNavigation">
<bool>false</bool>
</property>
<property name="showDropIndicator" stdset="0">
<bool>false</bool>
</property>
<property name="dragDropOverwriteMode">
<bool>false</bool>
</property>
<property name="selectionMode">
<enum>QAbstractItemView::NoSelection</enum>
</property>
<attribute name="horizontalHeaderVisible">
<bool>false</bool>
</attribute>
<attribute name="verticalHeaderVisible">
<bool>false</bool>
</attribute>
</widget>
</item>
</layout>
</widget>
<resources>
<include location="../netinstall.qrc"/>
</resources>
<connections>
<connection>
<sender>pushButton</sender>
<signal>toggled(bool)</signal>
<receiver>packageview</receiver>
<slot>setHidden(bool)</slot>
<hints>
<hint type="sourcelabel">
<x>772</x>
<y>25</y>
</hint>
<hint type="destinationlabel">
<x>653</x>
<y>61</y>
</hint>
</hints>
</connection>
</connections>
<slots>
<signal>toggled(bool)</signal>
</slots>
</ui>