1 /* === This file is part of Calamares - <https://calamares.io> ===
2  *
3  *   SPDX-FileCopyrightText: 2014-2016 Teo Mrnjavac <teo@kde.org>
4  *   SPDX-FileCopyrightText: 2018-2019 Adriaan de Groot <groot@kde.org>
5  *   SPDX-FileCopyrightText: 2019 Collabora Ltd
6  *   SPDX-License-Identifier: GPL-3.0-or-later
7  *
8  *   Calamares is Free Software: see the License-Identifier above.
9  *
10  */
11 
12 #ifndef CHOICEPAGE_H
13 #define CHOICEPAGE_H
14 
15 #include "ui_ChoicePage.h"
16 
17 
18 #include "Config.h"
19 #include "core/OsproberEntry.h"
20 
21 #include <QMutex>
22 #include <QPointer>
23 #include <QSet>
24 #include <QWidget>
25 
26 class QBoxLayout;
27 class QComboBox;
28 class QLabel;
29 class QListView;
30 
31 namespace Calamares
32 {
33 class PrettyRadioButton;
34 }
35 
36 class Config;
37 class DeviceInfoWidget;
38 class PartitionBarsView;
39 class PartitionSplitterWidget;
40 class PartitionLabelsView;
41 class PartitionCoreModule;
42 
43 class Device;
44 
45 using SwapChoiceSet = Config::SwapChoiceSet;
46 
47 /**
48  * @brief The ChoicePage class is the first page of the partitioning interface.
49  * It offers a choice between partitioning operations and initiates all automated
50  * partitioning modes. For manual partitioning, see PartitionPage.
51  */
52 class ChoicePage : public QWidget, private Ui::ChoicePage
53 {
54     Q_OBJECT
55 public:
56     explicit ChoicePage( Config* config, QWidget* parent = nullptr );
57     ~ChoicePage() override;
58 
59     /**
60      * @brief init runs when the PartitionViewStep and the PartitionCoreModule are
61      *      ready. Sets up the rest of the UI based on os-prober output.
62      * @param core the PartitionCoreModule pointer.
63      */
64     void init( PartitionCoreModule* core );
65 
66     /**
67      * @brief isNextEnabled answers whether the current state of the page is such
68      * that progressing to the next page should be allowed.
69      * @return true if next is allowed, otherwise false.
70      */
71     bool isNextEnabled() const;
72 
73     /**
74      * @brief onLeave runs when control passes from this page to another one.
75      */
76     void onLeave();
77 
78     /**
79      * @brief applyActionChoice reacts to a choice of partitioning mode.
80      * @param choice the partitioning action choice.
81      */
82     void applyActionChoice( Config::InstallChoice choice );
83 
84     int lastSelectedDeviceIndex();
85     void setLastSelectedDeviceIndex( int index );
86 
87 signals:
88     void nextStatusChanged( bool );
89     void actionChosen();
90     void deviceChosen();
91 
92 private slots:
93     void onPartitionToReplaceSelected( const QModelIndex& current, const QModelIndex& previous );
94     void doReplaceSelectedPartition( const QModelIndex& current );
95     void doAlongsideSetupSplitter( const QModelIndex& current, const QModelIndex& previous );
96     void onEncryptWidgetStateChanged();
97     void onHomeCheckBoxStateChanged();
98 
99     /// @brief Calls applyActionChoice() as needed.
100     void onActionChanged();
101     /// @brief Calls onActionChanged() as needed.
102     void onEraseSwapChoiceChanged();
103 
104     void retranslate();
105 
106 private:
107     bool calculateNextEnabled() const;
108     void updateNextEnabled();
109     void setupChoices();
110     void checkInstallChoiceRadioButton( Config::InstallChoice choice );  ///< Sets the chosen button to "on"
111     QComboBox* createBootloaderComboBox( QWidget* parentButton );
112     Device* selectedDevice();
113 
114     /* Change the UI depending on the device selected. */
115     void hideButtons();  // Hide everything when no device
116     void applyDeviceChoice();  // Start scanning new device
117     void continueApplyDeviceChoice();  // .. called after scan
118 
119     void updateDeviceStatePreview();
120     void updateActionChoicePreview( Config::InstallChoice choice );
121     void setupActions();
122     OsproberEntryList getOsproberEntriesForDevice( Device* device ) const;
123     void doAlongsideApply();
124     void setupEfiSystemPartitionSelector();
125 
126     // Translations support
127     void updateSwapChoicesTr();
128     void updateChoiceButtonsTr();
129 
130     Config* m_config;
131     bool m_nextEnabled;
132     PartitionCoreModule* m_core;
133 
134     QMutex m_previewsMutex;
135 
136     bool m_isEfi;
137     QComboBox* m_drivesCombo;
138 
139     QButtonGroup* m_grp;
140     Calamares::PrettyRadioButton* m_alongsideButton;
141     Calamares::PrettyRadioButton* m_eraseButton;
142     Calamares::PrettyRadioButton* m_replaceButton;
143     Calamares::PrettyRadioButton* m_somethingElseButton;
144     QComboBox* m_eraseSwapChoiceComboBox = nullptr;  // UI, see also Config's swap choice
145     QComboBox* m_eraseFsTypesChoiceComboBox = nullptr;  // UI, see also Config's erase-mode FS
146 
147 
148     DeviceInfoWidget* m_deviceInfoWidget;
149 
150     QPointer< PartitionBarsView > m_beforePartitionBarsView;
151     QPointer< PartitionLabelsView > m_beforePartitionLabelsView;
152     QPointer< PartitionBarsView > m_afterPartitionBarsView;
153     QPointer< PartitionLabelsView > m_afterPartitionLabelsView;
154     QPointer< PartitionSplitterWidget > m_afterPartitionSplitterWidget;
155     QPointer< QComboBox > m_bootloaderComboBox;
156     QPointer< QLabel > m_efiLabel;
157     QPointer< QComboBox > m_efiComboBox;
158 
159     int m_lastSelectedDeviceIndex = -1;
160     int m_lastSelectedActionIndex = -1;
161 
162     QStringList m_requiredPartitionTableType;
163     bool m_enableEncryptionWidget;
164 
165     QMutex m_coreMutex;
166 };
167 
168 #endif  // CHOICEPAGE_H
169