Merge branch 'master' of https://github.com/calamares/calamares into development
This commit is contained in:
commit
af4a7086df
@ -7,6 +7,16 @@ charset = utf-8
|
|||||||
end_of_line = lf
|
end_of_line = lf
|
||||||
trim_trailing_whitespace = true
|
trim_trailing_whitespace = true
|
||||||
|
|
||||||
|
[CMakeLists.txt]
|
||||||
|
indent_style = space
|
||||||
|
indent_size = 4
|
||||||
|
insert_final_newline = true
|
||||||
|
|
||||||
|
[*.cmake]
|
||||||
|
indent_style = space
|
||||||
|
indent_size = 4
|
||||||
|
insert_final_newline = true
|
||||||
|
|
||||||
[*.{py,cpp,h}]
|
[*.{py,cpp,h}]
|
||||||
indent_style = space
|
indent_style = space
|
||||||
indent_size = 4
|
indent_size = 4
|
||||||
|
6
CHANGES
6
CHANGES
@ -6,6 +6,7 @@ website will have to do for older versions.
|
|||||||
# 3.2.21 (unreleased) #
|
# 3.2.21 (unreleased) #
|
||||||
|
|
||||||
This release contains contributions from (alphabetically by first name):
|
This release contains contributions from (alphabetically by first name):
|
||||||
|
- Anke Boersma
|
||||||
- Camilo Higuita
|
- Camilo Higuita
|
||||||
- Gabriel Craciunescu
|
- Gabriel Craciunescu
|
||||||
- Gaël PORTAY
|
- Gaël PORTAY
|
||||||
@ -25,6 +26,11 @@ This release contains contributions from (alphabetically by first name):
|
|||||||
more configurable: the branding key *sidebar* controls it. The sidebar
|
more configurable: the branding key *sidebar* controls it. The sidebar
|
||||||
can be shown as a widget (default, as it has been), hidden, or use a
|
can be shown as a widget (default, as it has been), hidden, or use a
|
||||||
new QML view which is more easily customised.
|
new QML view which is more easily customised.
|
||||||
|
- A new `settings.conf` key *quit-at-end* will automatically close
|
||||||
|
Calamares (by clicking on the *Done* button) when the end of the
|
||||||
|
sequence is reached. If *finished* is the last module in the sequence,
|
||||||
|
this will run whatever it is configured for; you can also leave out
|
||||||
|
the finished page and Calamares will close after the exec parts.
|
||||||
|
|
||||||
## Modules ##
|
## Modules ##
|
||||||
- *packages* now reports more details in the installation progress-bar.
|
- *packages* now reports more details in the installation progress-bar.
|
||||||
|
@ -181,3 +181,11 @@ disable-cancel: false
|
|||||||
#
|
#
|
||||||
# YAML: boolean.
|
# YAML: boolean.
|
||||||
disable-cancel-during-exec: false
|
disable-cancel-during-exec: false
|
||||||
|
|
||||||
|
# If this is set to true, then once the end of the sequence has
|
||||||
|
# been reached, the quit (done) button is clicked automatically
|
||||||
|
# and Calamares will close. Default is false: the user will see
|
||||||
|
# that the end of installation has been reached, and that things are ok.
|
||||||
|
#
|
||||||
|
#
|
||||||
|
quit-at-end: false
|
||||||
|
@ -6,26 +6,72 @@ In principle, all parts can be styled through CSS.
|
|||||||
Missing parts should be filed as issues.
|
Missing parts should be filed as issues.
|
||||||
|
|
||||||
The IDs are based on the object names in the C++ code.
|
The IDs are based on the object names in the C++ code.
|
||||||
|
You can use the Debug Dialog to find out object names:
|
||||||
|
- Open the debug dialog
|
||||||
|
- Choose tab *Tools*
|
||||||
|
- Click *Widget Tree* button
|
||||||
|
The list of object names is printed in the log.
|
||||||
|
|
||||||
Documentation for styling Qt Widgets through a stylesheet
|
Documentation for styling Qt Widgets through a stylesheet
|
||||||
can be found at
|
can be found at
|
||||||
https://doc.qt.io/qt-5/stylesheet-examples.html
|
https://doc.qt.io/qt-5/stylesheet-examples.html
|
||||||
|
https://doc.qt.io/qt-5/stylesheet-reference.html
|
||||||
In Calamares, styling widget classes is supported (e.g.
|
In Calamares, styling widget classes is supported (e.g.
|
||||||
using `QComboBox` as a selector). You can also use specific
|
using `QComboBox` as a selector).
|
||||||
object names (ids), which you can find through debugging tools.
|
|
||||||
|
This example stylesheet has all the actual styling commented out.
|
||||||
|
The examples are not exhaustive.
|
||||||
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/* Main application window.
|
/*** Generic Widgets.
|
||||||
|
*
|
||||||
|
* You can style **all** widgets of a given class by selecting
|
||||||
|
* the class name. Some widgets have specialized sub-selectors.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
QPushButton { background-color: green; }
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*** Main application window.
|
||||||
|
*
|
||||||
|
* The main application window has the sidebar, which in turn
|
||||||
|
* contains a logo and a list of items -- note that the list
|
||||||
|
* can **not** be styled, since it has its own custom C++
|
||||||
|
* delegate code.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
#mainApp { }
|
#mainApp { }
|
||||||
#logoApp { }
|
|
||||||
#sidebarApp { }
|
#sidebarApp { }
|
||||||
#sidebarMenuApp { }
|
#logoApp { }
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/* Partitioning module.
|
/*** Welcome module.
|
||||||
|
*
|
||||||
|
* There are plenty of parts, but the buttons are the most interesting
|
||||||
|
* ones (donate, release notes, ...). The little icon image can be
|
||||||
|
* styled through *qproperty-icon*, which is a little obscure.
|
||||||
|
* URLs can reference the QRC paths of the Calamares application
|
||||||
|
* or loaded via plugins or within the filesystem. There is no
|
||||||
|
* comprehensive list of available icons, though.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
QPushButton#aboutButton { qproperty-icon: url(:/data/images/release.svg); }
|
||||||
|
#donateButton,
|
||||||
|
#supportButton,
|
||||||
|
#releaseNotesButton,
|
||||||
|
#knownIssuesButton { qproperty-icon: url(:/data/images/help.svg); }
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*** Partitioning module.
|
||||||
|
*
|
||||||
|
* Many moving parts, which you will need to experiment with.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
#bootInfoIcon { }
|
#bootInfoIcon { }
|
||||||
#bootInfoLable { }
|
#bootInfoLable { }
|
||||||
#deviceInfoIcon { }
|
#deviceInfoIcon { }
|
||||||
@ -34,8 +80,13 @@ object names (ids), which you can find through debugging tools.
|
|||||||
#partitionBarView { }
|
#partitionBarView { }
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/* Licensing module.
|
/*** Licensing module.
|
||||||
|
*
|
||||||
|
* The licensing module paints individual widgets for each of
|
||||||
|
* the licenses. The item can be collapsed or expanded.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
#licenseItem { }
|
#licenseItem { }
|
||||||
#licenseItemFullText { }
|
#licenseItemFullText { }
|
||||||
*/
|
*/
|
||||||
|
@ -83,7 +83,7 @@ CalamaresApplication::init()
|
|||||||
initQmlPath();
|
initQmlPath();
|
||||||
initBranding();
|
initBranding();
|
||||||
|
|
||||||
CalamaresUtils::installTranslator( QLocale::system(), QString(), this );
|
CalamaresUtils::installTranslator( QLocale::system(), QString() );
|
||||||
|
|
||||||
setQuitOnLastWindowClosed( false );
|
setQuitOnLastWindowClosed( false );
|
||||||
setWindowIcon( QIcon( Calamares::Branding::instance()->imagePath( Calamares::Branding::ProductIcon ) ) );
|
setWindowIcon( QIcon( Calamares::Branding::instance()->imagePath( Calamares::Branding::ProductIcon ) ) );
|
||||||
|
@ -69,6 +69,7 @@ public:
|
|||||||
if ( anyFailed && !job->isEmergency() )
|
if ( anyFailed && !job->isEmergency() )
|
||||||
{
|
{
|
||||||
cDebug() << "Skipping non-emergency job" << job->prettyName();
|
cDebug() << "Skipping non-emergency job" << job->prettyName();
|
||||||
|
++m_jobIndex;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -83,10 +84,8 @@ public:
|
|||||||
message = result.message();
|
message = result.message();
|
||||||
details = result.details();
|
details = result.details();
|
||||||
}
|
}
|
||||||
if ( !anyFailed )
|
emitProgress( 1.0 );
|
||||||
{
|
++m_jobIndex;
|
||||||
++m_jobIndex;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
if ( anyFailed )
|
if ( anyFailed )
|
||||||
{
|
{
|
||||||
@ -141,7 +140,7 @@ private:
|
|||||||
m_queue, "failed", Qt::QueuedConnection, Q_ARG( QString, message ), Q_ARG( QString, details ) );
|
m_queue, "failed", Qt::QueuedConnection, Q_ARG( QString, message ), Q_ARG( QString, details ) );
|
||||||
}
|
}
|
||||||
|
|
||||||
void emitFinished() { QMetaObject::invokeMethod( m_queue, "finished", Qt::QueuedConnection ); }
|
void emitFinished() { QMetaObject::invokeMethod( m_queue, "finish", Qt::QueuedConnection ); }
|
||||||
};
|
};
|
||||||
|
|
||||||
JobThread::~JobThread() {}
|
JobThread::~JobThread() {}
|
||||||
@ -196,6 +195,7 @@ JobQueue::start()
|
|||||||
Q_ASSERT( !m_thread->isRunning() );
|
Q_ASSERT( !m_thread->isRunning() );
|
||||||
m_thread->setJobs( std::move( m_jobs ) );
|
m_thread->setJobs( std::move( m_jobs ) );
|
||||||
m_jobs.clear();
|
m_jobs.clear();
|
||||||
|
m_finished = false;
|
||||||
m_thread->start();
|
m_thread->start();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -217,4 +217,11 @@ JobQueue::enqueue( const JobList& jobs )
|
|||||||
emit queueChanged( m_jobs );
|
emit queueChanged( m_jobs );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
JobQueue::finish()
|
||||||
|
{
|
||||||
|
m_finished = true;
|
||||||
|
emit finished();
|
||||||
|
}
|
||||||
|
|
||||||
} // namespace Calamares
|
} // namespace Calamares
|
||||||
|
@ -45,6 +45,11 @@ public:
|
|||||||
void enqueue( const JobList& jobs );
|
void enqueue( const JobList& jobs );
|
||||||
void start();
|
void start();
|
||||||
|
|
||||||
|
bool isRunning() const { return !m_finished; }
|
||||||
|
|
||||||
|
public slots:
|
||||||
|
void finish();
|
||||||
|
|
||||||
signals:
|
signals:
|
||||||
void queueChanged( const JobList& jobs );
|
void queueChanged( const JobList& jobs );
|
||||||
void progress( qreal percent, const QString& prettyName );
|
void progress( qreal percent, const QString& prettyName );
|
||||||
@ -57,6 +62,7 @@ private:
|
|||||||
JobList m_jobs;
|
JobList m_jobs;
|
||||||
JobThread* m_thread;
|
JobThread* m_thread;
|
||||||
GlobalStorage* m_storage;
|
GlobalStorage* m_storage;
|
||||||
|
bool m_finished = true; ///< Initially, not running
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace Calamares
|
} // namespace Calamares
|
||||||
|
@ -232,6 +232,7 @@ Settings::Settings( const QString& settingsFilePath, bool debugMode )
|
|||||||
m_isSetupMode = requireBool( config, "oem-setup", !m_doChroot );
|
m_isSetupMode = requireBool( config, "oem-setup", !m_doChroot );
|
||||||
m_disableCancel = requireBool( config, "disable-cancel", false );
|
m_disableCancel = requireBool( config, "disable-cancel", false );
|
||||||
m_disableCancelDuringExec = requireBool( config, "disable-cancel-during-exec", false );
|
m_disableCancelDuringExec = requireBool( config, "disable-cancel-during-exec", false );
|
||||||
|
m_quitAtEnd = requireBool( config, "quit-at-end", false );
|
||||||
}
|
}
|
||||||
catch ( YAML::Exception& e )
|
catch ( YAML::Exception& e )
|
||||||
{
|
{
|
||||||
|
@ -101,6 +101,9 @@ public:
|
|||||||
/** @brief Temporary setting of disable-cancel: can't cancel during exec. */
|
/** @brief Temporary setting of disable-cancel: can't cancel during exec. */
|
||||||
bool disableCancelDuringExec() const { return m_disableCancelDuringExec; }
|
bool disableCancelDuringExec() const { return m_disableCancelDuringExec; }
|
||||||
|
|
||||||
|
/** @brief Is quit-at-end set? (Quit automatically when done) */
|
||||||
|
bool quitAtEnd() const { return m_quitAtEnd; }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
static Settings* s_instance;
|
static Settings* s_instance;
|
||||||
|
|
||||||
@ -117,6 +120,7 @@ private:
|
|||||||
bool m_promptInstall;
|
bool m_promptInstall;
|
||||||
bool m_disableCancel;
|
bool m_disableCancel;
|
||||||
bool m_disableCancelDuringExec;
|
bool m_disableCancelDuringExec;
|
||||||
|
bool m_quitAtEnd;
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace Calamares
|
} // namespace Calamares
|
||||||
|
@ -33,9 +33,7 @@ Label::Label( const QString& locale, LabelFormat format, QObject* parent )
|
|||||||
: QObject( parent )
|
: QObject( parent )
|
||||||
, m_locale( Label::getLocale( locale ) )
|
, m_locale( Label::getLocale( locale ) )
|
||||||
, m_localeId( locale.isEmpty() ? m_locale.name() : locale )
|
, m_localeId( locale.isEmpty() ? m_locale.name() : locale )
|
||||||
|
|
||||||
{
|
{
|
||||||
//: language[name] (country[name])
|
|
||||||
QString longFormat = QObject::tr( "%1 (%2)" );
|
QString longFormat = QObject::tr( "%1 (%2)" );
|
||||||
|
|
||||||
QString languageName = m_locale.nativeLanguageName();
|
QString languageName = m_locale.nativeLanguageName();
|
||||||
|
@ -40,10 +40,6 @@ class Label : public QObject
|
|||||||
{
|
{
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
|
|
||||||
Q_PROPERTY( QString label READ label CONSTANT FINAL )
|
|
||||||
Q_PROPERTY( QString englishLabel READ englishLabel CONSTANT FINAL )
|
|
||||||
Q_PROPERTY( QString localeId MEMBER m_localeId CONSTANT FINAL )
|
|
||||||
|
|
||||||
public:
|
public:
|
||||||
/** @brief Formatting option for label -- add (country) to label. */
|
/** @brief Formatting option for label -- add (country) to label. */
|
||||||
enum class LabelFormat
|
enum class LabelFormat
|
||||||
@ -65,6 +61,7 @@ public:
|
|||||||
LabelFormat format = LabelFormat::IfNeededWithCountry,
|
LabelFormat format = LabelFormat::IfNeededWithCountry,
|
||||||
QObject* parent = nullptr );
|
QObject* parent = nullptr );
|
||||||
|
|
||||||
|
|
||||||
/** @brief Define a sorting order.
|
/** @brief Define a sorting order.
|
||||||
*
|
*
|
||||||
* Locales are sorted by their id, which means the ISO 2-letter code + country.
|
* Locales are sorted by their id, which means the ISO 2-letter code + country.
|
||||||
|
@ -239,7 +239,13 @@ CStringListModel::CStringListModel( CStringPairList l )
|
|||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
CStringListModel::~CStringListModel() {}
|
void
|
||||||
|
CStringListModel::setList( CalamaresUtils::Locale::CStringPairList l )
|
||||||
|
{
|
||||||
|
beginResetModel();
|
||||||
|
m_list = l;
|
||||||
|
endResetModel();
|
||||||
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
CStringListModel::rowCount( const QModelIndex& ) const
|
CStringListModel::rowCount( const QModelIndex& ) const
|
||||||
@ -264,6 +270,30 @@ CStringListModel::data( const QModelIndex& index, int role ) const
|
|||||||
return item ? ( role == Qt::DisplayRole ? item->tr() : item->key() ) : QVariant();
|
return item ? ( role == Qt::DisplayRole ? item->tr() : item->key() ) : QVariant();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
CStringListModel::setCurrentIndex( int index )
|
||||||
|
{
|
||||||
|
if ( ( index < 0 ) || ( index >= m_list.count() ) )
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
m_currentIndex = index;
|
||||||
|
emit currentIndexChanged();
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
CStringListModel::currentIndex() const
|
||||||
|
{
|
||||||
|
return m_currentIndex;
|
||||||
|
}
|
||||||
|
|
||||||
|
QHash< int, QByteArray >
|
||||||
|
CStringListModel::roleNames() const
|
||||||
|
{
|
||||||
|
return { { Qt::DisplayRole, "label" }, { Qt::UserRole, "key" } };
|
||||||
|
}
|
||||||
|
|
||||||
const CStringPair*
|
const CStringPair*
|
||||||
CStringListModel::item( int index ) const
|
CStringListModel::item( int index ) const
|
||||||
{
|
{
|
||||||
|
@ -44,8 +44,9 @@ namespace Locale
|
|||||||
* QPair<QString, QString> because there is API that needs
|
* QPair<QString, QString> because there is API that needs
|
||||||
* C-style strings.
|
* C-style strings.
|
||||||
*/
|
*/
|
||||||
class CStringPair
|
class CStringPair : public QObject
|
||||||
{
|
{
|
||||||
|
Q_OBJECT
|
||||||
public:
|
public:
|
||||||
/// @brief An empty pair
|
/// @brief An empty pair
|
||||||
CStringPair() {}
|
CStringPair() {}
|
||||||
@ -86,6 +87,7 @@ public:
|
|||||||
/// @brief A pair of strings for timezone regions (e.g. "America")
|
/// @brief A pair of strings for timezone regions (e.g. "America")
|
||||||
class TZRegion : public CStringPair
|
class TZRegion : public CStringPair
|
||||||
{
|
{
|
||||||
|
Q_OBJECT
|
||||||
public:
|
public:
|
||||||
using CStringPair::CStringPair;
|
using CStringPair::CStringPair;
|
||||||
virtual ~TZRegion() override;
|
virtual ~TZRegion() override;
|
||||||
@ -117,6 +119,7 @@ private:
|
|||||||
/// @brief A pair of strings for specific timezone names (e.g. "New_York")
|
/// @brief A pair of strings for specific timezone names (e.g. "New_York")
|
||||||
class TZZone : public CStringPair
|
class TZZone : public CStringPair
|
||||||
{
|
{
|
||||||
|
Q_OBJECT
|
||||||
public:
|
public:
|
||||||
using CStringPair::CStringPair;
|
using CStringPair::CStringPair;
|
||||||
QString tr() const override;
|
QString tr() const override;
|
||||||
@ -137,21 +140,52 @@ protected:
|
|||||||
|
|
||||||
class CStringListModel : public QAbstractListModel
|
class CStringListModel : public QAbstractListModel
|
||||||
{
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
Q_PROPERTY( int currentIndex READ currentIndex WRITE setCurrentIndex NOTIFY currentIndexChanged )
|
||||||
|
|
||||||
public:
|
public:
|
||||||
/// @brief Create empty model
|
/// @brief Create empty model
|
||||||
CStringListModel();
|
CStringListModel() {}
|
||||||
/// @brief Create model from list (non-owning)
|
/// @brief Create model from list (non-owning)
|
||||||
CStringListModel( CStringPairList );
|
CStringListModel( CStringPairList );
|
||||||
virtual ~CStringListModel() override;
|
|
||||||
|
|
||||||
int rowCount( const QModelIndex& parent ) const override;
|
int rowCount( const QModelIndex& parent ) const override;
|
||||||
|
|
||||||
QVariant data( const QModelIndex& index, int role ) const override;
|
QVariant data( const QModelIndex& index, int role ) const override;
|
||||||
|
|
||||||
const CStringPair* item( int index ) const;
|
const CStringPair* item( int index ) const;
|
||||||
|
QHash< int, QByteArray > roleNames() const override;
|
||||||
|
|
||||||
|
void setCurrentIndex( int index );
|
||||||
|
int currentIndex() const;
|
||||||
|
|
||||||
|
void setList( CStringPairList );
|
||||||
|
|
||||||
|
inline int indexOf( const QString& key )
|
||||||
|
{
|
||||||
|
const auto it = std::find_if(
|
||||||
|
m_list.constBegin(), m_list.constEnd(), [&]( const CalamaresUtils::Locale::CStringPair* item ) -> bool {
|
||||||
|
return item->key() == key;
|
||||||
|
} );
|
||||||
|
|
||||||
|
if ( it != m_list.constEnd() )
|
||||||
|
{
|
||||||
|
// distance() is usually a long long
|
||||||
|
return int( std::distance( m_list.constBegin(), it ) );
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
CStringPairList m_list;
|
CStringPairList m_list;
|
||||||
|
int m_currentIndex = -1;
|
||||||
|
|
||||||
|
signals:
|
||||||
|
void currentIndexChanged();
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace Locale
|
} // namespace Locale
|
||||||
|
@ -276,7 +276,7 @@ Manager::synchronousGet( const QUrl& url, const RequestOptions& options )
|
|||||||
}
|
}
|
||||||
|
|
||||||
QNetworkReply*
|
QNetworkReply*
|
||||||
Manager::asynchronouseGet( const QUrl& url, const CalamaresUtils::Network::RequestOptions& options )
|
Manager::asynchronousGet( const QUrl& url, const CalamaresUtils::Network::RequestOptions& options )
|
||||||
{
|
{
|
||||||
return asynchronousRun( d->nam(), url, options );
|
return asynchronousRun( d->nam(), url, options );
|
||||||
}
|
}
|
||||||
|
@ -146,7 +146,7 @@ public:
|
|||||||
* This may be a nullptr if an error occurs immediately.
|
* This may be a nullptr if an error occurs immediately.
|
||||||
* The caller is responsible for cleaning up the reply (eventually).
|
* The caller is responsible for cleaning up the reply (eventually).
|
||||||
*/
|
*/
|
||||||
QNetworkReply* asynchronouseGet( const QUrl& url, const RequestOptions& options = RequestOptions() );
|
QNetworkReply* asynchronousGet( const QUrl& url, const RequestOptions& options = RequestOptions() );
|
||||||
|
|
||||||
private:
|
private:
|
||||||
class Private;
|
class Private;
|
||||||
|
@ -197,7 +197,7 @@ static QTranslator* s_tztranslator = nullptr;
|
|||||||
static QString s_translatorLocaleName;
|
static QString s_translatorLocaleName;
|
||||||
|
|
||||||
void
|
void
|
||||||
installTranslator( const QLocale& locale, const QString& brandingTranslationsPrefix, QObject* )
|
installTranslator( const QLocale& locale, const QString& brandingTranslationsPrefix )
|
||||||
{
|
{
|
||||||
loadSingletonTranslator( BrandingLoader( locale, brandingTranslationsPrefix ), s_brandingTranslator );
|
loadSingletonTranslator( BrandingLoader( locale, brandingTranslationsPrefix ), s_brandingTranslator );
|
||||||
loadSingletonTranslator( TZLoader( locale ), s_tztranslator );
|
loadSingletonTranslator( TZLoader( locale ), s_tztranslator );
|
||||||
|
@ -36,9 +36,8 @@ namespace CalamaresUtils
|
|||||||
* @brief installTranslator changes the application language.
|
* @brief installTranslator changes the application language.
|
||||||
* @param locale the new locale.
|
* @param locale the new locale.
|
||||||
* @param brandingTranslationsPrefix the branding path prefix, from Calamares::Branding.
|
* @param brandingTranslationsPrefix the branding path prefix, from Calamares::Branding.
|
||||||
* @param parent the parent QObject.
|
|
||||||
*/
|
*/
|
||||||
DLLEXPORT void installTranslator( const QLocale& locale, const QString& brandingTranslationsPrefix, QObject* parent );
|
DLLEXPORT void installTranslator( const QLocale& locale, const QString& brandingTranslationsPrefix );
|
||||||
|
|
||||||
DLLEXPORT QString translatorLocaleName();
|
DLLEXPORT QString translatorLocaleName();
|
||||||
|
|
||||||
|
@ -29,8 +29,8 @@
|
|||||||
#include "utils/Paste.h"
|
#include "utils/Paste.h"
|
||||||
#include "utils/Retranslator.h"
|
#include "utils/Retranslator.h"
|
||||||
#include "viewpages/BlankViewStep.h"
|
#include "viewpages/BlankViewStep.h"
|
||||||
#include "viewpages/ViewStep.h"
|
|
||||||
#include "viewpages/ExecutionViewStep.h"
|
#include "viewpages/ExecutionViewStep.h"
|
||||||
|
#include "viewpages/ViewStep.h"
|
||||||
|
|
||||||
#include <QApplication>
|
#include <QApplication>
|
||||||
#include <QBoxLayout>
|
#include <QBoxLayout>
|
||||||
@ -309,6 +309,13 @@ stepIsExecute( const ViewStepList& steps, int index )
|
|||||||
&& ( qobject_cast< ExecutionViewStep* >( steps.at( index ) ) != nullptr );
|
&& ( qobject_cast< ExecutionViewStep* >( steps.at( index ) ) != nullptr );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static inline bool
|
||||||
|
isAtVeryEnd( const ViewStepList& steps, int index )
|
||||||
|
|
||||||
|
{
|
||||||
|
return ( index >= steps.count() ) || ( index == steps.count() - 1 && steps.last()->isAtEnd() );
|
||||||
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
ViewManager::next()
|
ViewManager::next()
|
||||||
{
|
{
|
||||||
@ -412,13 +419,17 @@ ViewManager::updateButtonLabels()
|
|||||||
m_back->setText( tr( "&Back" ) );
|
m_back->setText( tr( "&Back" ) );
|
||||||
|
|
||||||
// Cancel button changes label at the end
|
// Cancel button changes label at the end
|
||||||
if ( isAtVeryEnd() )
|
if ( isAtVeryEnd( m_steps, m_currentStep ) )
|
||||||
{
|
{
|
||||||
m_quit->setText( tr( "&Done" ) );
|
m_quit->setText( tr( "&Done" ) );
|
||||||
m_quit->setToolTip( quitOnCompleteTooltip );
|
m_quit->setToolTip( quitOnCompleteTooltip );
|
||||||
m_quit->setVisible( true ); // At end, always visible and enabled.
|
m_quit->setVisible( true ); // At end, always visible and enabled.
|
||||||
setButtonIcon( m_quit, "dialog-ok-apply" );
|
setButtonIcon( m_quit, "dialog-ok-apply" );
|
||||||
updateCancelEnabled( true );
|
updateCancelEnabled( true );
|
||||||
|
if ( settings->quitAtEnd() )
|
||||||
|
{
|
||||||
|
m_quit->click();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@ -473,7 +484,7 @@ ViewManager::confirmCancelInstallation()
|
|||||||
const auto* const settings = Calamares::Settings::instance();
|
const auto* const settings = Calamares::Settings::instance();
|
||||||
|
|
||||||
// When we're at the very end, then it's always OK to exit.
|
// When we're at the very end, then it's always OK to exit.
|
||||||
if ( isAtVeryEnd() )
|
if ( isAtVeryEnd( m_steps, m_currentStep ) )
|
||||||
{
|
{
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -132,12 +132,6 @@ private:
|
|||||||
void updateButtonLabels();
|
void updateButtonLabels();
|
||||||
void updateCancelEnabled( bool enabled );
|
void updateCancelEnabled( bool enabled );
|
||||||
|
|
||||||
bool isAtVeryEnd() const
|
|
||||||
{
|
|
||||||
return ( m_currentStep >= m_steps.count() )
|
|
||||||
|| ( m_currentStep == m_steps.count() - 1 && m_steps.last()->isAtEnd() );
|
|
||||||
}
|
|
||||||
|
|
||||||
static ViewManager* s_instance;
|
static ViewManager* s_instance;
|
||||||
|
|
||||||
ViewStepList m_steps;
|
ViewStepList m_steps;
|
||||||
|
@ -136,7 +136,7 @@ ExecutionViewStep::isAtBeginning() const
|
|||||||
bool
|
bool
|
||||||
ExecutionViewStep::isAtEnd() const
|
ExecutionViewStep::isAtEnd() const
|
||||||
{
|
{
|
||||||
return true;
|
return !JobQueue::instance()->isRunning();
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
@ -102,7 +102,7 @@ def run():
|
|||||||
status = _("Dummy python step {}").format(str(c) + ":" + repr(k))
|
status = _("Dummy python step {}").format(str(c) + ":" + repr(k))
|
||||||
libcalamares.utils.debug(_("Dummy python step {}").format(str(k)))
|
libcalamares.utils.debug(_("Dummy python step {}").format(str(k)))
|
||||||
sleep(1)
|
sleep(1)
|
||||||
libcalamares.job.setprogress(c * 1.0 / len(configlist))
|
libcalamares.job.setprogress(c * 1.0 / (len(configlist)+1))
|
||||||
c += 1
|
c += 1
|
||||||
|
|
||||||
sleep(3)
|
sleep(3)
|
||||||
|
@ -18,12 +18,12 @@
|
|||||||
|
|
||||||
#include "KeyboardViewStep.h"
|
#include "KeyboardViewStep.h"
|
||||||
|
|
||||||
#include "JobQueue.h"
|
|
||||||
#include "GlobalStorage.h"
|
|
||||||
|
|
||||||
#include "KeyboardPage.h"
|
#include "KeyboardPage.h"
|
||||||
|
|
||||||
CALAMARES_PLUGIN_FACTORY_DEFINITION( KeyboardViewStepFactory, registerPlugin<KeyboardViewStep>(); )
|
#include "GlobalStorage.h"
|
||||||
|
#include "JobQueue.h"
|
||||||
|
|
||||||
|
CALAMARES_PLUGIN_FACTORY_DEFINITION( KeyboardViewStepFactory, registerPlugin< KeyboardViewStep >(); )
|
||||||
|
|
||||||
KeyboardViewStep::KeyboardViewStep( QObject* parent )
|
KeyboardViewStep::KeyboardViewStep( QObject* parent )
|
||||||
: Calamares::ViewStep( parent )
|
: Calamares::ViewStep( parent )
|
||||||
@ -40,7 +40,9 @@ KeyboardViewStep::KeyboardViewStep( QObject* parent )
|
|||||||
KeyboardViewStep::~KeyboardViewStep()
|
KeyboardViewStep::~KeyboardViewStep()
|
||||||
{
|
{
|
||||||
if ( m_widget && m_widget->parent() == nullptr )
|
if ( m_widget && m_widget->parent() == nullptr )
|
||||||
|
{
|
||||||
m_widget->deleteLater();
|
m_widget->deleteLater();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -111,9 +113,7 @@ void
|
|||||||
KeyboardViewStep::onLeave()
|
KeyboardViewStep::onLeave()
|
||||||
{
|
{
|
||||||
m_widget->finalize();
|
m_widget->finalize();
|
||||||
m_jobs = m_widget->createJobs( m_xOrgConfFileName,
|
m_jobs = m_widget->createJobs( m_xOrgConfFileName, m_convertedKeymapPath, m_writeEtcDefaultKeyboard );
|
||||||
m_convertedKeymapPath,
|
|
||||||
m_writeEtcDefaultKeyboard );
|
|
||||||
m_prettyStatus = m_widget->prettyStatus();
|
m_prettyStatus = m_widget->prettyStatus();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -121,29 +121,35 @@ KeyboardViewStep::onLeave()
|
|||||||
void
|
void
|
||||||
KeyboardViewStep::setConfigurationMap( const QVariantMap& configurationMap )
|
KeyboardViewStep::setConfigurationMap( const QVariantMap& configurationMap )
|
||||||
{
|
{
|
||||||
if ( configurationMap.contains( "xOrgConfFileName" ) &&
|
if ( configurationMap.contains( "xOrgConfFileName" )
|
||||||
configurationMap.value( "xOrgConfFileName" ).type() == QVariant::String &&
|
&& configurationMap.value( "xOrgConfFileName" ).type() == QVariant::String
|
||||||
!configurationMap.value( "xOrgConfFileName" ).toString().isEmpty() )
|
&& !configurationMap.value( "xOrgConfFileName" ).toString().isEmpty() )
|
||||||
{
|
{
|
||||||
m_xOrgConfFileName = configurationMap.value( "xOrgConfFileName" )
|
m_xOrgConfFileName = configurationMap.value( "xOrgConfFileName" ).toString();
|
||||||
.toString();
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
{
|
||||||
m_xOrgConfFileName = "00-keyboard.conf";
|
m_xOrgConfFileName = "00-keyboard.conf";
|
||||||
|
}
|
||||||
|
|
||||||
if ( configurationMap.contains( "convertedKeymapPath" ) &&
|
if ( configurationMap.contains( "convertedKeymapPath" )
|
||||||
configurationMap.value( "convertedKeymapPath" ).type() == QVariant::String &&
|
&& configurationMap.value( "convertedKeymapPath" ).type() == QVariant::String
|
||||||
!configurationMap.value( "convertedKeymapPath" ).toString().isEmpty() )
|
&& !configurationMap.value( "convertedKeymapPath" ).toString().isEmpty() )
|
||||||
{
|
{
|
||||||
m_convertedKeymapPath = configurationMap.value( "convertedKeymapPath" )
|
m_convertedKeymapPath = configurationMap.value( "convertedKeymapPath" ).toString();
|
||||||
.toString();
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
{
|
||||||
m_convertedKeymapPath = QString();
|
m_convertedKeymapPath = QString();
|
||||||
|
}
|
||||||
|
|
||||||
if ( configurationMap.contains( "writeEtcDefaultKeyboard" ) &&
|
if ( configurationMap.contains( "writeEtcDefaultKeyboard" )
|
||||||
configurationMap.value( "writeEtcDefaultKeyboard" ).type() == QVariant::Bool )
|
&& configurationMap.value( "writeEtcDefaultKeyboard" ).type() == QVariant::Bool )
|
||||||
|
{
|
||||||
m_writeEtcDefaultKeyboard = configurationMap.value( "writeEtcDefaultKeyboard" ).toBool();
|
m_writeEtcDefaultKeyboard = configurationMap.value( "writeEtcDefaultKeyboard" ).toBool();
|
||||||
|
}
|
||||||
else
|
else
|
||||||
|
{
|
||||||
m_writeEtcDefaultKeyboard = true;
|
m_writeEtcDefaultKeyboard = true;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -20,12 +20,11 @@
|
|||||||
#ifndef KEYBOARDVIEWSTEP_H
|
#ifndef KEYBOARDVIEWSTEP_H
|
||||||
#define KEYBOARDVIEWSTEP_H
|
#define KEYBOARDVIEWSTEP_H
|
||||||
|
|
||||||
#include <QObject>
|
#include "DllMacro.h"
|
||||||
|
|
||||||
#include "utils/PluginFactory.h"
|
#include "utils/PluginFactory.h"
|
||||||
#include "viewpages/ViewStep.h"
|
#include "viewpages/ViewStep.h"
|
||||||
|
|
||||||
#include "DllMacro.h"
|
#include <QObject>
|
||||||
|
|
||||||
class KeyboardPage;
|
class KeyboardPage;
|
||||||
|
|
||||||
@ -48,7 +47,7 @@ public:
|
|||||||
bool isAtBeginning() const override;
|
bool isAtBeginning() const override;
|
||||||
bool isAtEnd() const override;
|
bool isAtEnd() const override;
|
||||||
|
|
||||||
QList< Calamares::job_ptr > jobs() const override;
|
Calamares::JobList jobs() const override;
|
||||||
|
|
||||||
void onActivate() override;
|
void onActivate() override;
|
||||||
void onLeave() override;
|
void onLeave() override;
|
||||||
@ -64,9 +63,9 @@ private:
|
|||||||
QString m_convertedKeymapPath;
|
QString m_convertedKeymapPath;
|
||||||
bool m_writeEtcDefaultKeyboard;
|
bool m_writeEtcDefaultKeyboard;
|
||||||
|
|
||||||
QList< Calamares::job_ptr > m_jobs;
|
Calamares::JobList m_jobs;
|
||||||
};
|
};
|
||||||
|
|
||||||
CALAMARES_PLUGIN_FACTORY_DECLARATION( KeyboardViewStepFactory )
|
CALAMARES_PLUGIN_FACTORY_DECLARATION( KeyboardViewStepFactory )
|
||||||
|
|
||||||
#endif // KEYBOARDVIEWSTEP_H
|
#endif // KEYBOARDVIEWSTEP_H
|
||||||
|
@ -13,6 +13,7 @@ calamares_add_plugin( locale
|
|||||||
EXPORT_MACRO PLUGINDLLEXPORT_PRO
|
EXPORT_MACRO PLUGINDLLEXPORT_PRO
|
||||||
SOURCES
|
SOURCES
|
||||||
${geoip_src}
|
${geoip_src}
|
||||||
|
Config.cpp
|
||||||
LCLocaleDialog.cpp
|
LCLocaleDialog.cpp
|
||||||
LocaleConfiguration.cpp
|
LocaleConfiguration.cpp
|
||||||
LocalePage.cpp
|
LocalePage.cpp
|
||||||
|
324
src/modules/locale/Config.cpp
Normal file
324
src/modules/locale/Config.cpp
Normal file
@ -0,0 +1,324 @@
|
|||||||
|
/* === This file is part of Calamares - <https://github.com/calamares> ===
|
||||||
|
*
|
||||||
|
* Copyright 2019-2020, Adriaan de Groot <groot@kde.org>
|
||||||
|
* Copyright 2020, Camilo Higuita <milo.h@aol.com>
|
||||||
|
*
|
||||||
|
* 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 "Config.h"
|
||||||
|
|
||||||
|
#include "LCLocaleDialog.h"
|
||||||
|
#include "SetTimezoneJob.h"
|
||||||
|
#include "timezonewidget/timezonewidget.h"
|
||||||
|
|
||||||
|
#include "GlobalStorage.h"
|
||||||
|
#include "JobQueue.h"
|
||||||
|
#include "Settings.h"
|
||||||
|
|
||||||
|
#include "locale/Label.h"
|
||||||
|
#include "locale/TimeZone.h"
|
||||||
|
#include "utils/CalamaresUtilsGui.h"
|
||||||
|
#include "utils/Logger.h"
|
||||||
|
#include "utils/Retranslator.h"
|
||||||
|
|
||||||
|
#include <QDebug>
|
||||||
|
#include <QProcess>
|
||||||
|
|
||||||
|
Config::Config( QObject* parent )
|
||||||
|
: QObject( parent )
|
||||||
|
, m_regionList( CalamaresUtils::Locale::TZRegion::fromZoneTab() )
|
||||||
|
, m_regionModel( new CalamaresUtils::Locale::CStringListModel( m_regionList ) )
|
||||||
|
, m_zonesModel( new CalamaresUtils::Locale::CStringListModel() )
|
||||||
|
, m_blockTzWidgetSet( false )
|
||||||
|
{
|
||||||
|
connect( m_regionModel, &CalamaresUtils::Locale::CStringListModel::currentIndexChanged, [&]() {
|
||||||
|
m_zonesModel->setList( static_cast< const CalamaresUtils::Locale::TZRegion* >(
|
||||||
|
m_regionModel->item( m_regionModel->currentIndex() ) )
|
||||||
|
->zones() );
|
||||||
|
updateLocaleLabels();
|
||||||
|
} );
|
||||||
|
|
||||||
|
connect(
|
||||||
|
m_zonesModel, &CalamaresUtils::Locale::CStringListModel::currentIndexChanged, [&]() { updateLocaleLabels(); } );
|
||||||
|
}
|
||||||
|
|
||||||
|
Config::~Config()
|
||||||
|
{
|
||||||
|
qDeleteAll( m_regionList );
|
||||||
|
}
|
||||||
|
|
||||||
|
CalamaresUtils::Locale::CStringListModel*
|
||||||
|
Config::zonesModel() const
|
||||||
|
{
|
||||||
|
return m_zonesModel;
|
||||||
|
}
|
||||||
|
|
||||||
|
CalamaresUtils::Locale::CStringListModel*
|
||||||
|
Config::regionModel() const
|
||||||
|
{
|
||||||
|
return m_regionModel;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
Config::setLocaleInfo( const QString& initialRegion, const QString& initialZone, const QString& localeGenPath )
|
||||||
|
{
|
||||||
|
using namespace CalamaresUtils::Locale;
|
||||||
|
|
||||||
|
cDebug() << "REGION MODEL SIZE" << initialRegion << initialZone;
|
||||||
|
auto* region = m_regionList.find< TZRegion >( initialRegion );
|
||||||
|
if ( region && region->zones().find< TZZone >( initialZone ) )
|
||||||
|
{
|
||||||
|
this->m_regionModel->setCurrentIndex( m_regionModel->indexOf( initialRegion ) );
|
||||||
|
m_zonesModel->setList( region->zones() );
|
||||||
|
this->m_zonesModel->setCurrentIndex( m_zonesModel->indexOf( initialZone ) );
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
this->m_regionModel->setCurrentIndex( m_regionModel->indexOf( "America" ) );
|
||||||
|
m_zonesModel->setList(
|
||||||
|
static_cast< const TZRegion* >( m_regionModel->item( m_regionModel->currentIndex() ) )->zones() );
|
||||||
|
this->m_zonesModel->setCurrentIndex( m_zonesModel->indexOf( "New_York" ) );
|
||||||
|
}
|
||||||
|
|
||||||
|
// Some distros come with a meaningfully commented and easy to parse locale.gen,
|
||||||
|
// and others ship a separate file /usr/share/i18n/SUPPORTED with a clean list of
|
||||||
|
// supported locales. We first try that one, and if it doesn't exist, we fall back
|
||||||
|
// to parsing the lines from locale.gen
|
||||||
|
m_localeGenLines.clear();
|
||||||
|
QFile supported( "/usr/share/i18n/SUPPORTED" );
|
||||||
|
QByteArray ba;
|
||||||
|
|
||||||
|
if ( supported.exists() && supported.open( QIODevice::ReadOnly | QIODevice::Text ) )
|
||||||
|
{
|
||||||
|
ba = supported.readAll();
|
||||||
|
supported.close();
|
||||||
|
|
||||||
|
const auto lines = ba.split( '\n' );
|
||||||
|
for ( const QByteArray& line : lines )
|
||||||
|
{
|
||||||
|
m_localeGenLines.append( QString::fromLatin1( line.simplified() ) );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
QFile localeGen( localeGenPath );
|
||||||
|
if ( localeGen.open( QIODevice::ReadOnly | QIODevice::Text ) )
|
||||||
|
{
|
||||||
|
ba = localeGen.readAll();
|
||||||
|
localeGen.close();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
cWarning() << "Cannot open file" << localeGenPath
|
||||||
|
<< ". Assuming the supported languages are already built into "
|
||||||
|
"the locale archive.";
|
||||||
|
QProcess localeA;
|
||||||
|
localeA.start( "locale", QStringList() << "-a" );
|
||||||
|
localeA.waitForFinished();
|
||||||
|
ba = localeA.readAllStandardOutput();
|
||||||
|
}
|
||||||
|
const auto lines = ba.split( '\n' );
|
||||||
|
for ( const QByteArray& line : lines )
|
||||||
|
{
|
||||||
|
if ( line.startsWith( "## " ) || line.startsWith( "# " ) || line.simplified() == "#" )
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
QString lineString = QString::fromLatin1( line.simplified() );
|
||||||
|
if ( lineString.startsWith( "#" ) )
|
||||||
|
{
|
||||||
|
lineString.remove( '#' );
|
||||||
|
}
|
||||||
|
lineString = lineString.simplified();
|
||||||
|
|
||||||
|
if ( lineString.isEmpty() )
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
m_localeGenLines.append( lineString );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( m_localeGenLines.isEmpty() )
|
||||||
|
{
|
||||||
|
cWarning() << "cannot acquire a list of available locales."
|
||||||
|
<< "The locale and localecfg modules will be broken as long as this "
|
||||||
|
"system does not provide"
|
||||||
|
<< "\n\t "
|
||||||
|
<< "* a well-formed" << supported.fileName() << "\n\tOR"
|
||||||
|
<< "* a well-formed"
|
||||||
|
<< ( localeGenPath.isEmpty() ? QLatin1String( "/etc/locale.gen" ) : localeGenPath ) << "\n\tOR"
|
||||||
|
<< "* a complete pre-compiled locale-gen database which allows complete locale -a output.";
|
||||||
|
return; // something went wrong and there's nothing we can do about it.
|
||||||
|
}
|
||||||
|
|
||||||
|
// Assuming we have a list of supported locales, we usually only want UTF-8 ones
|
||||||
|
// because it's not 1995.
|
||||||
|
for ( auto it = m_localeGenLines.begin(); it != m_localeGenLines.end(); )
|
||||||
|
{
|
||||||
|
if ( !it->contains( "UTF-8", Qt::CaseInsensitive ) && !it->contains( "utf8", Qt::CaseInsensitive ) )
|
||||||
|
{
|
||||||
|
it = m_localeGenLines.erase( it );
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
++it;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// We strip " UTF-8" from "en_US.UTF-8 UTF-8" because it's redundant redundant.
|
||||||
|
for ( auto it = m_localeGenLines.begin(); it != m_localeGenLines.end(); ++it )
|
||||||
|
{
|
||||||
|
if ( it->endsWith( " UTF-8" ) )
|
||||||
|
{
|
||||||
|
it->chop( 6 );
|
||||||
|
}
|
||||||
|
*it = it->simplified();
|
||||||
|
}
|
||||||
|
updateGlobalStorage();
|
||||||
|
updateLocaleLabels();
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
Config::updateGlobalLocale()
|
||||||
|
{
|
||||||
|
auto* gs = Calamares::JobQueue::instance()->globalStorage();
|
||||||
|
const QString bcp47 = m_selectedLocaleConfiguration.toBcp47();
|
||||||
|
gs->insert( "locale", bcp47 );
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
Config::updateGlobalStorage()
|
||||||
|
{
|
||||||
|
auto* gs = Calamares::JobQueue::instance()->globalStorage();
|
||||||
|
|
||||||
|
const auto* location = currentLocation();
|
||||||
|
bool locationChanged = ( location->region() != gs->value( "locationRegion" ) )
|
||||||
|
|| ( location->zone() != gs->value( "locationZone" ) );
|
||||||
|
|
||||||
|
gs->insert( "locationRegion", location->region() );
|
||||||
|
gs->insert( "locationZone", location->zone() );
|
||||||
|
|
||||||
|
updateGlobalLocale();
|
||||||
|
|
||||||
|
// If we're in chroot mode (normal install mode), then we immediately set the
|
||||||
|
// timezone on the live system. When debugging timezones, don't bother.
|
||||||
|
#ifndef DEBUG_TIMEZONES
|
||||||
|
if ( locationChanged && Calamares::Settings::instance()->doChroot() )
|
||||||
|
{
|
||||||
|
QProcess::execute( "timedatectl", // depends on systemd
|
||||||
|
{ "set-timezone", location->region() + '/' + location->zone() } );
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// Preserve those settings that have been made explicit.
|
||||||
|
auto newLocale = guessLocaleConfiguration();
|
||||||
|
if ( !m_selectedLocaleConfiguration.isEmpty() && m_selectedLocaleConfiguration.explicit_lang )
|
||||||
|
{
|
||||||
|
newLocale.setLanguage( m_selectedLocaleConfiguration.language() );
|
||||||
|
}
|
||||||
|
if ( !m_selectedLocaleConfiguration.isEmpty() && m_selectedLocaleConfiguration.explicit_lc )
|
||||||
|
{
|
||||||
|
newLocale.lc_numeric = m_selectedLocaleConfiguration.lc_numeric;
|
||||||
|
newLocale.lc_time = m_selectedLocaleConfiguration.lc_time;
|
||||||
|
newLocale.lc_monetary = m_selectedLocaleConfiguration.lc_monetary;
|
||||||
|
newLocale.lc_paper = m_selectedLocaleConfiguration.lc_paper;
|
||||||
|
newLocale.lc_name = m_selectedLocaleConfiguration.lc_name;
|
||||||
|
newLocale.lc_address = m_selectedLocaleConfiguration.lc_address;
|
||||||
|
newLocale.lc_telephone = m_selectedLocaleConfiguration.lc_telephone;
|
||||||
|
newLocale.lc_measurement = m_selectedLocaleConfiguration.lc_measurement;
|
||||||
|
newLocale.lc_identification = m_selectedLocaleConfiguration.lc_identification;
|
||||||
|
}
|
||||||
|
newLocale.explicit_lang = m_selectedLocaleConfiguration.explicit_lang;
|
||||||
|
newLocale.explicit_lc = m_selectedLocaleConfiguration.explicit_lc;
|
||||||
|
|
||||||
|
m_selectedLocaleConfiguration = newLocale;
|
||||||
|
updateLocaleLabels();
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
Config::updateLocaleLabels()
|
||||||
|
{
|
||||||
|
LocaleConfiguration lc
|
||||||
|
= m_selectedLocaleConfiguration.isEmpty() ? guessLocaleConfiguration() : m_selectedLocaleConfiguration;
|
||||||
|
auto labels = prettyLocaleStatus( lc );
|
||||||
|
emit prettyStatusChanged();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
std::pair< QString, QString >
|
||||||
|
Config::prettyLocaleStatus( const LocaleConfiguration& lc ) const
|
||||||
|
{
|
||||||
|
using CalamaresUtils::Locale::Label;
|
||||||
|
|
||||||
|
Label lang( lc.language(), Label::LabelFormat::AlwaysWithCountry );
|
||||||
|
Label num( lc.lc_numeric, Label::LabelFormat::AlwaysWithCountry );
|
||||||
|
|
||||||
|
return std::make_pair< QString, QString >(
|
||||||
|
tr( "The system language will be set to %1." ).arg( lang.label() ),
|
||||||
|
tr( "The numbers and dates locale will be set to %1." ).arg( num.label() ) );
|
||||||
|
}
|
||||||
|
|
||||||
|
Calamares::JobList
|
||||||
|
Config::createJobs()
|
||||||
|
{
|
||||||
|
QList< Calamares::job_ptr > list;
|
||||||
|
const CalamaresUtils::Locale::TZZone* location = currentLocation();
|
||||||
|
|
||||||
|
Calamares::Job* j = new SetTimezoneJob( location->region(), location->zone() );
|
||||||
|
list.append( Calamares::job_ptr( j ) );
|
||||||
|
|
||||||
|
return list;
|
||||||
|
}
|
||||||
|
|
||||||
|
LocaleConfiguration
|
||||||
|
Config::guessLocaleConfiguration() const
|
||||||
|
{
|
||||||
|
return LocaleConfiguration::fromLanguageAndLocation(
|
||||||
|
QLocale().name(), m_localeGenLines, currentLocation() ? currentLocation()->country() : "" );
|
||||||
|
}
|
||||||
|
|
||||||
|
QMap< QString, QString >
|
||||||
|
Config::localesMap()
|
||||||
|
{
|
||||||
|
return m_selectedLocaleConfiguration.isEmpty() ? guessLocaleConfiguration().toMap()
|
||||||
|
: m_selectedLocaleConfiguration.toMap();
|
||||||
|
}
|
||||||
|
|
||||||
|
QString
|
||||||
|
Config::prettyStatus() const
|
||||||
|
{
|
||||||
|
QString status;
|
||||||
|
status += tr( "Set timezone to %1/%2.<br/>" )
|
||||||
|
.arg( m_regionModel->item( m_regionModel->currentIndex() )->tr() )
|
||||||
|
.arg( m_zonesModel->item( m_zonesModel->currentIndex() )->tr() );
|
||||||
|
|
||||||
|
LocaleConfiguration lc
|
||||||
|
= m_selectedLocaleConfiguration.isEmpty() ? guessLocaleConfiguration() : m_selectedLocaleConfiguration;
|
||||||
|
auto labels = prettyLocaleStatus( lc );
|
||||||
|
status += labels.first + "<br/>";
|
||||||
|
status += labels.second + "<br/>";
|
||||||
|
|
||||||
|
return status;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
const CalamaresUtils::Locale::TZZone*
|
||||||
|
Config::currentLocation() const
|
||||||
|
{
|
||||||
|
return static_cast< const CalamaresUtils::Locale::TZZone* >( m_zonesModel->item( m_zonesModel->currentIndex() ) );
|
||||||
|
}
|
87
src/modules/locale/Config.h
Normal file
87
src/modules/locale/Config.h
Normal file
@ -0,0 +1,87 @@
|
|||||||
|
/* === This file is part of Calamares - <https://github.com/calamares> ===
|
||||||
|
*
|
||||||
|
* Copyright 2019-2020, Adriaan de Groot <groot@kde.org>
|
||||||
|
* Copyright 2020, Camilo Higuita <milo.h@aol.com>
|
||||||
|
*
|
||||||
|
* 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 LOCALE_CONFIG_H
|
||||||
|
#define LOCALE_CONFIG_H
|
||||||
|
|
||||||
|
#include "LocaleConfiguration.h"
|
||||||
|
#include "timezonewidget/localeglobal.h"
|
||||||
|
|
||||||
|
#include "Job.h"
|
||||||
|
#include "locale/TimeZone.h"
|
||||||
|
|
||||||
|
#include <QAbstractListModel>
|
||||||
|
#include <QObject>
|
||||||
|
|
||||||
|
#include <memory>
|
||||||
|
|
||||||
|
class Config : public QObject
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
Q_PROPERTY( CalamaresUtils::Locale::CStringListModel* zonesModel READ zonesModel CONSTANT FINAL )
|
||||||
|
Q_PROPERTY( CalamaresUtils::Locale::CStringListModel* regionModel READ regionModel CONSTANT FINAL )
|
||||||
|
Q_PROPERTY( QString prettyStatus READ prettyStatus NOTIFY prettyStatusChanged FINAL )
|
||||||
|
|
||||||
|
public:
|
||||||
|
Config( QObject* parent = nullptr );
|
||||||
|
~Config();
|
||||||
|
CalamaresUtils::Locale::CStringListModel* regionModel() const;
|
||||||
|
CalamaresUtils::Locale::CStringListModel* zonesModel() const;
|
||||||
|
|
||||||
|
void setLocaleInfo( const QString& initialRegion, const QString& initialZone, const QString& localeGenPath );
|
||||||
|
|
||||||
|
Calamares::JobList createJobs();
|
||||||
|
QMap< QString, QString > localesMap();
|
||||||
|
QString prettyStatus() const;
|
||||||
|
|
||||||
|
private:
|
||||||
|
CalamaresUtils::Locale::CStringPairList m_regionList;
|
||||||
|
CalamaresUtils::Locale::CStringListModel* m_regionModel;
|
||||||
|
CalamaresUtils::Locale::CStringListModel* m_zonesModel;
|
||||||
|
|
||||||
|
LocaleConfiguration m_selectedLocaleConfiguration;
|
||||||
|
|
||||||
|
QStringList m_localeGenLines;
|
||||||
|
int m_currentRegion = -1;
|
||||||
|
|
||||||
|
bool m_blockTzWidgetSet;
|
||||||
|
|
||||||
|
LocaleConfiguration guessLocaleConfiguration() const;
|
||||||
|
|
||||||
|
// For the given locale config, return two strings describing
|
||||||
|
// the settings for language and numbers.
|
||||||
|
std::pair< QString, QString > prettyLocaleStatus( const LocaleConfiguration& ) const;
|
||||||
|
|
||||||
|
/** @brief Update the GS *locale* key with the selected system language.
|
||||||
|
*
|
||||||
|
* This uses whatever is set in m_selectedLocaleConfiguration as the language,
|
||||||
|
* and writes it to GS *locale* key (as a string, in BCP47 format).
|
||||||
|
*/
|
||||||
|
void updateGlobalLocale();
|
||||||
|
void updateGlobalStorage();
|
||||||
|
void updateLocaleLabels();
|
||||||
|
|
||||||
|
const CalamaresUtils::Locale::TZZone* currentLocation() const;
|
||||||
|
|
||||||
|
signals:
|
||||||
|
void prettyStatusChanged();
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
#endif
|
29
src/modules/localeq/CMakeLists.txt
Normal file
29
src/modules/localeq/CMakeLists.txt
Normal file
@ -0,0 +1,29 @@
|
|||||||
|
# When debugging the timezone widget, add this debugging definition
|
||||||
|
# to have a debugging-friendly timezone widget, debug logging,
|
||||||
|
# and no intrusive timezone-setting while clicking around.
|
||||||
|
option( DEBUG_TIMEZONES "Debug-friendly timezone widget." OFF )
|
||||||
|
if( DEBUG_TIMEZONES )
|
||||||
|
add_definitions( -DDEBUG_TIMEZONES )
|
||||||
|
endif()
|
||||||
|
|
||||||
|
# Because we're sharing sources with the regular locale module
|
||||||
|
set( _locale ${CMAKE_CURRENT_SOURCE_DIR}/../locale )
|
||||||
|
|
||||||
|
include_directories( ${_locale} )
|
||||||
|
|
||||||
|
calamares_add_plugin( localeq
|
||||||
|
TYPE viewmodule
|
||||||
|
EXPORT_MACRO PLUGINDLLEXPORT_PRO
|
||||||
|
SOURCES
|
||||||
|
LocaleQmlViewStep.cpp
|
||||||
|
${_locale}/LocaleConfiguration.cpp
|
||||||
|
${_locale}/Config.cpp
|
||||||
|
${_locale}/SetTimezoneJob.cpp
|
||||||
|
${_locale}/timezonewidget/localeglobal.cpp
|
||||||
|
RESOURCES
|
||||||
|
${_locale}/locale.qrc
|
||||||
|
LINK_PRIVATE_LIBRARIES
|
||||||
|
calamaresui
|
||||||
|
Qt5::Network
|
||||||
|
SHARED_LIB
|
||||||
|
)
|
203
src/modules/localeq/LocaleQmlViewStep.cpp
Normal file
203
src/modules/localeq/LocaleQmlViewStep.cpp
Normal file
@ -0,0 +1,203 @@
|
|||||||
|
/* === This file is part of Calamares - <https://github.com/calamares> ===
|
||||||
|
*
|
||||||
|
* Copyright 2014-2015, Teo Mrnjavac <teo@kde.org>
|
||||||
|
* Copyright 2018,2020 Adriaan de Groot <groot@kde.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 "LocaleQmlViewStep.h"
|
||||||
|
|
||||||
|
#include "GlobalStorage.h"
|
||||||
|
#include "JobQueue.h"
|
||||||
|
|
||||||
|
#include "geoip/Handler.h"
|
||||||
|
#include "network/Manager.h"
|
||||||
|
#include "utils/CalamaresUtilsGui.h"
|
||||||
|
#include "utils/Logger.h"
|
||||||
|
#include "utils/Variant.h"
|
||||||
|
#include "utils/Yaml.h"
|
||||||
|
|
||||||
|
#include "timezonewidget/localeglobal.h"
|
||||||
|
|
||||||
|
#include "Branding.h"
|
||||||
|
#include "modulesystem/ModuleManager.h"
|
||||||
|
#include <QQmlEngine>
|
||||||
|
#include <QFutureWatcher>
|
||||||
|
#include <QPixmap>
|
||||||
|
#include <QVariant>
|
||||||
|
|
||||||
|
CALAMARES_PLUGIN_FACTORY_DEFINITION( LocaleQmlViewStepFactory, registerPlugin< LocaleQmlViewStep >(); )
|
||||||
|
|
||||||
|
LocaleQmlViewStep::LocaleQmlViewStep( QObject* parent )
|
||||||
|
: Calamares::QmlViewStep( parent )
|
||||||
|
, m_config( new Config( this ) )
|
||||||
|
, m_nextEnabled( false )
|
||||||
|
, m_geoip( nullptr )
|
||||||
|
{
|
||||||
|
emit nextStatusChanged( m_nextEnabled );
|
||||||
|
}
|
||||||
|
|
||||||
|
QObject*
|
||||||
|
LocaleQmlViewStep::getConfig()
|
||||||
|
{
|
||||||
|
return m_config;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
LocaleQmlViewStep::fetchGeoIpTimezone()
|
||||||
|
{
|
||||||
|
if ( m_geoip && m_geoip->isValid() )
|
||||||
|
{
|
||||||
|
m_startingTimezone = m_geoip->get();
|
||||||
|
if ( !m_startingTimezone.isValid() )
|
||||||
|
{
|
||||||
|
cWarning() << "GeoIP lookup at" << m_geoip->url() << "failed.";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
m_config->setLocaleInfo(m_startingTimezone.first, m_startingTimezone.second, m_localeGenPath);
|
||||||
|
}
|
||||||
|
|
||||||
|
Calamares::RequirementsList LocaleQmlViewStep::checkRequirements()
|
||||||
|
{
|
||||||
|
LocaleGlobal::init();
|
||||||
|
if ( m_geoip && m_geoip->isValid() )
|
||||||
|
{
|
||||||
|
auto& network = CalamaresUtils::Network::Manager::instance();
|
||||||
|
if ( network.hasInternet() )
|
||||||
|
{
|
||||||
|
fetchGeoIpTimezone();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if ( network.synchronousPing( m_geoip->url() ) )
|
||||||
|
{
|
||||||
|
fetchGeoIpTimezone();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return Calamares::RequirementsList();
|
||||||
|
}
|
||||||
|
|
||||||
|
QString
|
||||||
|
LocaleQmlViewStep::prettyName() const
|
||||||
|
{
|
||||||
|
return tr( "Location" );
|
||||||
|
}
|
||||||
|
|
||||||
|
bool
|
||||||
|
LocaleQmlViewStep::isNextEnabled() const
|
||||||
|
{
|
||||||
|
// TODO: should return true
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool
|
||||||
|
LocaleQmlViewStep::isBackEnabled() const
|
||||||
|
{
|
||||||
|
// TODO: should return true (it's weird that you are not allowed to have welcome *after* anything
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool
|
||||||
|
LocaleQmlViewStep::isAtBeginning() const
|
||||||
|
{
|
||||||
|
// TODO: adjust to "pages" in the QML
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool
|
||||||
|
LocaleQmlViewStep::isAtEnd() const
|
||||||
|
{
|
||||||
|
// TODO: adjust to "pages" in the QML
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
Calamares::JobList
|
||||||
|
LocaleQmlViewStep::jobs() const
|
||||||
|
{
|
||||||
|
return m_jobs;
|
||||||
|
}
|
||||||
|
|
||||||
|
void LocaleQmlViewStep::onActivate()
|
||||||
|
{
|
||||||
|
// TODO no sure if it is needed at all or for the abstract class to start something
|
||||||
|
}
|
||||||
|
|
||||||
|
void LocaleQmlViewStep::onLeave()
|
||||||
|
{
|
||||||
|
if ( true )
|
||||||
|
{
|
||||||
|
m_jobs = m_config->createJobs();
|
||||||
|
// m_prettyStatus = m_actualWidget->prettyStatus();
|
||||||
|
|
||||||
|
auto map = m_config->localesMap();
|
||||||
|
QVariantMap vm;
|
||||||
|
for ( auto it = map.constBegin(); it != map.constEnd(); ++it )
|
||||||
|
{
|
||||||
|
vm.insert( it.key(), it.value() );
|
||||||
|
}
|
||||||
|
|
||||||
|
Calamares::JobQueue::instance()->globalStorage()->insert( "localeConf", vm );
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
m_jobs.clear();
|
||||||
|
Calamares::JobQueue::instance()->globalStorage()->remove( "localeConf" );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void LocaleQmlViewStep::setConfigurationMap(const QVariantMap& configurationMap)
|
||||||
|
{
|
||||||
|
QString region = CalamaresUtils::getString( configurationMap, "region" );
|
||||||
|
QString zone = CalamaresUtils::getString( configurationMap, "zone" );
|
||||||
|
if ( !region.isEmpty() && !zone.isEmpty() )
|
||||||
|
{
|
||||||
|
m_startingTimezone = CalamaresUtils::GeoIP::RegionZonePair( region, zone );
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
m_startingTimezone
|
||||||
|
= CalamaresUtils::GeoIP::RegionZonePair( QStringLiteral( "America" ), QStringLiteral( "New_York" ) );
|
||||||
|
}
|
||||||
|
|
||||||
|
m_localeGenPath = CalamaresUtils::getString( configurationMap, "localeGenPath" );
|
||||||
|
if ( m_localeGenPath.isEmpty() )
|
||||||
|
{
|
||||||
|
m_localeGenPath = QStringLiteral( "/etc/locale.gen" );
|
||||||
|
}
|
||||||
|
|
||||||
|
bool ok = false;
|
||||||
|
QVariantMap geoip = CalamaresUtils::getSubMap( configurationMap, "geoip", ok );
|
||||||
|
if ( ok )
|
||||||
|
{
|
||||||
|
QString url = CalamaresUtils::getString( geoip, "url" );
|
||||||
|
QString style = CalamaresUtils::getString( geoip, "style" );
|
||||||
|
QString selector = CalamaresUtils::getString( geoip, "selector" );
|
||||||
|
|
||||||
|
m_geoip = std::make_unique< CalamaresUtils::GeoIP::Handler >( style, url, selector );
|
||||||
|
if ( !m_geoip->isValid() )
|
||||||
|
{
|
||||||
|
cWarning() << "GeoIP Style" << style << "is not recognized.";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
checkRequirements();
|
||||||
|
Calamares::QmlViewStep::setConfigurationMap( configurationMap ); // call parent implementation last
|
||||||
|
setContextProperty( "Localeq", m_config );
|
||||||
|
}
|
76
src/modules/localeq/LocaleQmlViewStep.h
Normal file
76
src/modules/localeq/LocaleQmlViewStep.h
Normal file
@ -0,0 +1,76 @@
|
|||||||
|
/* === This file is part of Calamares - <https://github.com/calamares> ===
|
||||||
|
*
|
||||||
|
* Copyright 2019-2020 Adriaan de Groot <groot@kde.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 LOCALE_QMLVIEWSTEP_H
|
||||||
|
#define LOCALE_QMLVIEWSTEP_H
|
||||||
|
|
||||||
|
#include "Config.h"
|
||||||
|
#include "geoip/Handler.h"
|
||||||
|
#include "geoip/Interface.h"
|
||||||
|
#include "utils/PluginFactory.h"
|
||||||
|
#include "viewpages/QmlViewStep.h"
|
||||||
|
#include <DllMacro.h>
|
||||||
|
|
||||||
|
#include <QFutureWatcher>
|
||||||
|
#include <QObject>
|
||||||
|
|
||||||
|
#include <memory>
|
||||||
|
|
||||||
|
class PLUGINDLLEXPORT LocaleQmlViewStep : public Calamares::QmlViewStep
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
|
||||||
|
public:
|
||||||
|
explicit LocaleQmlViewStep( QObject* parent = nullptr );
|
||||||
|
|
||||||
|
QString prettyName() const override;
|
||||||
|
|
||||||
|
bool isNextEnabled() const override;
|
||||||
|
bool isBackEnabled() const override;
|
||||||
|
|
||||||
|
bool isAtBeginning() const override;
|
||||||
|
bool isAtEnd() const override;
|
||||||
|
|
||||||
|
Calamares::JobList jobs() const override;
|
||||||
|
void onActivate() override;
|
||||||
|
void onLeave() override;
|
||||||
|
|
||||||
|
void setConfigurationMap( const QVariantMap& configurationMap ) override;
|
||||||
|
QObject* getConfig() override;
|
||||||
|
|
||||||
|
virtual Calamares::RequirementsList checkRequirements() override;
|
||||||
|
|
||||||
|
private:
|
||||||
|
// TODO: a generic QML viewstep should return a config object from a method
|
||||||
|
Config *m_config;
|
||||||
|
|
||||||
|
bool m_nextEnabled;
|
||||||
|
QString m_prettyStatus;
|
||||||
|
|
||||||
|
CalamaresUtils::GeoIP::RegionZonePair m_startingTimezone;
|
||||||
|
QString m_localeGenPath;
|
||||||
|
|
||||||
|
Calamares::JobList m_jobs;
|
||||||
|
std::unique_ptr< CalamaresUtils::GeoIP::Handler > m_geoip;
|
||||||
|
|
||||||
|
void fetchGeoIpTimezone();
|
||||||
|
};
|
||||||
|
|
||||||
|
CALAMARES_PLUGIN_FACTORY_DECLARATION( LocaleQmlViewStepFactory )
|
||||||
|
|
||||||
|
#endif
|
97
src/modules/localeq/localeq.conf
Normal file
97
src/modules/localeq/localeq.conf
Normal file
@ -0,0 +1,97 @@
|
|||||||
|
---
|
||||||
|
# This settings are used to set your default system time zone.
|
||||||
|
# Time zones are usually located under /usr/share/zoneinfo and
|
||||||
|
# provided by the 'tzdata' package of your Distribution.
|
||||||
|
#
|
||||||
|
# Distributions using systemd can list available
|
||||||
|
# time zones by using the timedatectl command.
|
||||||
|
# timedatectl list-timezones
|
||||||
|
#
|
||||||
|
# The starting timezone (e.g. the pin-on-the-map) when entering
|
||||||
|
# the locale page can be set through keys *region* and *zone*.
|
||||||
|
# If either is not set, defaults to America/New_York.
|
||||||
|
#
|
||||||
|
region: "America"
|
||||||
|
zone: "New_York"
|
||||||
|
|
||||||
|
|
||||||
|
# System locales are detected in the following order:
|
||||||
|
#
|
||||||
|
# - /usr/share/i18n/SUPPORTED
|
||||||
|
# - localeGenPath (defaults to /etc/locale.gen if not set)
|
||||||
|
# - 'locale -a' output
|
||||||
|
#
|
||||||
|
# Enable only when your Distribution is using an
|
||||||
|
# custom path for locale.gen
|
||||||
|
#
|
||||||
|
#localeGenPath: "PATH_TO/locale.gen"
|
||||||
|
|
||||||
|
# GeoIP based Language settings: Leave commented out to disable GeoIP.
|
||||||
|
#
|
||||||
|
# GeoIP needs a working Internet connection.
|
||||||
|
# This can be managed from `welcome.conf` by adding
|
||||||
|
# internet to the list of required conditions.
|
||||||
|
#
|
||||||
|
# The configuration
|
||||||
|
# is in three parts: a *style*, which can be "json" or "xml"
|
||||||
|
# depending on the kind of data returned by the service, and
|
||||||
|
# a *url* where the data is retrieved, and an optional *selector*
|
||||||
|
# to pick the right field out of the returned data (e.g. field
|
||||||
|
# name in JSON or element name in XML).
|
||||||
|
#
|
||||||
|
# The default selector (when the setting is blank) is picked to
|
||||||
|
# work with existing JSON providers (which use "time_zone") and
|
||||||
|
# Ubiquity's XML providers (which use "TimeZone").
|
||||||
|
#
|
||||||
|
# If the service configured via *url* uses
|
||||||
|
# a different attribute name (e.g. "timezone") in JSON or a
|
||||||
|
# different element tag (e.g. "<Time_Zone>") in XML, set this
|
||||||
|
# string to the name or tag to be used.
|
||||||
|
#
|
||||||
|
# In JSON:
|
||||||
|
# - if the string contains "." characters, this is used as a
|
||||||
|
# multi-level selector, e.g. "a.b" will select the timezone
|
||||||
|
# from data "{a: {b: "Europe/Amsterdam" } }".
|
||||||
|
# - each part of the string split by "." characters is used as
|
||||||
|
# a key into the JSON data.
|
||||||
|
# In XML:
|
||||||
|
# - all elements with the named tag (e.g. all TimeZone) elements
|
||||||
|
# from the document are checked; the first one with non-empty
|
||||||
|
# text value is used.
|
||||||
|
#
|
||||||
|
#
|
||||||
|
# An HTTP(S) request is made to *url*. The request should return
|
||||||
|
# valid data in a suitable format, depending on *style*;
|
||||||
|
# generally this includes a string value with the timezone
|
||||||
|
# in <region>/<zone> format. For services that return data which
|
||||||
|
# does not follow the conventions of "suitable data" described
|
||||||
|
# below, *selector* may be used to pick different data.
|
||||||
|
#
|
||||||
|
# Note that this example URL works, but the service is shutting
|
||||||
|
# down in June 2018.
|
||||||
|
#
|
||||||
|
# Suitable JSON data looks like
|
||||||
|
# ```
|
||||||
|
# {"time_zone":"America/New_York"}
|
||||||
|
# ```
|
||||||
|
# Suitable XML data looks like
|
||||||
|
# ```
|
||||||
|
# <Response><TimeZone>Europe/Brussels</TimeZone></Response>
|
||||||
|
# ```
|
||||||
|
#
|
||||||
|
# To accommodate providers of GeoIP timezone data with peculiar timezone
|
||||||
|
# naming conventions, the following cleanups are performed automatically:
|
||||||
|
# - backslashes are removed
|
||||||
|
# - spaces are replaced with _
|
||||||
|
#
|
||||||
|
# Legacy settings "geoipStyle", "geoipUrl" and "geoipSelector"
|
||||||
|
# in the top-level are still supported, but I'd advise against.
|
||||||
|
#
|
||||||
|
# To disable GeoIP checking, either comment-out the entire geoip section,
|
||||||
|
# or set the *style* key to an unsupported format (e.g. `none`).
|
||||||
|
# Also, note the analogous feature in src/modules/welcome/welcome.conf.
|
||||||
|
#
|
||||||
|
geoip:
|
||||||
|
style: "json"
|
||||||
|
url: "https://geoip.kde.org/v1/calamares"
|
||||||
|
selector: "" # leave blank for the default
|
113
src/modules/localeq/localeq.qml
Normal file
113
src/modules/localeq/localeq.qml
Normal file
@ -0,0 +1,113 @@
|
|||||||
|
import io.calamares.modules 1.0 as Modules
|
||||||
|
import io.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
|
||||||
|
|
||||||
|
ResponsiveBase
|
||||||
|
{
|
||||||
|
id: control
|
||||||
|
|
||||||
|
Modules.Locale //locale handler
|
||||||
|
{
|
||||||
|
id: _locale
|
||||||
|
}
|
||||||
|
|
||||||
|
title: stackView.currentItem.title
|
||||||
|
subtitle: stackView.currentItem.subtitle
|
||||||
|
message: stackView.currentItem.message
|
||||||
|
|
||||||
|
stackView.initialItem: Item
|
||||||
|
{
|
||||||
|
id: _regionsListComponent
|
||||||
|
|
||||||
|
property string title: qsTr("Region")
|
||||||
|
property string subtitle: qsTr("Pick your preferred region or use the default one based on your current location")
|
||||||
|
property string message: qsTr("Select your preferred zone within your location to continue with the installation")
|
||||||
|
|
||||||
|
ListViewTemplate
|
||||||
|
{
|
||||||
|
id: _regionListView
|
||||||
|
anchors.centerIn: parent
|
||||||
|
implicitWidth: Math.min(parent.width, 500)
|
||||||
|
implicitHeight: Math.min(contentHeight, 500)
|
||||||
|
currentIndex: model.currentIndex
|
||||||
|
model: _locale.Config.regionModel
|
||||||
|
|
||||||
|
delegate: ListItemDelegate
|
||||||
|
{
|
||||||
|
id: _delegate
|
||||||
|
label1.text: model.label
|
||||||
|
onClicked:
|
||||||
|
{
|
||||||
|
_regionListView.model.currentIndex = index
|
||||||
|
_stackView.push(_zonesListComponent)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
footer: RowLayout
|
||||||
|
{
|
||||||
|
width: parent.width
|
||||||
|
z: 99999
|
||||||
|
Button
|
||||||
|
{
|
||||||
|
Layout.fillWidth: true
|
||||||
|
text: qsTr("Timezones")
|
||||||
|
icon.name: "go-previous"
|
||||||
|
onClicked: control.stackView.push(_zonesListComponent)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
Component
|
||||||
|
{
|
||||||
|
id: _zonesListComponent
|
||||||
|
|
||||||
|
Item
|
||||||
|
{
|
||||||
|
property string title: qsTr("Timezone")
|
||||||
|
property string subtitle: _locale.Config.prettyStatus
|
||||||
|
property string message: ""
|
||||||
|
ListViewTemplate
|
||||||
|
{
|
||||||
|
id: _zonesListView
|
||||||
|
anchors.centerIn: parent
|
||||||
|
implicitWidth: Math.min(parent.width, 500)
|
||||||
|
implicitHeight: Math.min(contentHeight, 500)
|
||||||
|
currentIndex: model.currentIndex
|
||||||
|
model: _locale.Config.zonesModel
|
||||||
|
|
||||||
|
delegate: ListItemDelegate
|
||||||
|
{
|
||||||
|
id: _delegate
|
||||||
|
label1.text: model.label
|
||||||
|
onClicked:
|
||||||
|
{
|
||||||
|
_zonesListView.model.currentIndex = index
|
||||||
|
positionViewAtIndex(index, ListView.Center)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
footer: RowLayout
|
||||||
|
{
|
||||||
|
width: parent.width
|
||||||
|
z: 99999
|
||||||
|
|
||||||
|
Button
|
||||||
|
{
|
||||||
|
Layout.fillWidth: true
|
||||||
|
icon.name: "go-previous"
|
||||||
|
text: qsTr("Regions")
|
||||||
|
onClicked: control.stackView.pop()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -187,7 +187,7 @@ NetInstallPage::loadGroupList( const QString& confUrl )
|
|||||||
using namespace CalamaresUtils::Network;
|
using namespace CalamaresUtils::Network;
|
||||||
|
|
||||||
cDebug() << "NetInstall loading groups from" << confUrl;
|
cDebug() << "NetInstall loading groups from" << confUrl;
|
||||||
QNetworkReply* reply = Manager::instance().asynchronouseGet(
|
QNetworkReply* reply = Manager::instance().asynchronousGet(
|
||||||
QUrl( confUrl ),
|
QUrl( confUrl ),
|
||||||
RequestOptions( RequestOptions::FakeUserAgent | RequestOptions::FollowRedirect, std::chrono::seconds( 30 ) ) );
|
RequestOptions( RequestOptions::FakeUserAgent | RequestOptions::FollowRedirect, std::chrono::seconds( 30 ) ) );
|
||||||
|
|
||||||
|
@ -2,8 +2,9 @@
|
|||||||
*
|
*
|
||||||
* Copyright 2014, Aurélien Gâteau <agateau@kde.org>
|
* Copyright 2014, Aurélien Gâteau <agateau@kde.org>
|
||||||
* Copyright 2014-2017, Teo Mrnjavac <teo@kde.org>
|
* Copyright 2014-2017, Teo Mrnjavac <teo@kde.org>
|
||||||
* Copyright 2018-2019, Adriaan de Groot <groot@kde.org>
|
* Copyright 2018-2019, 2020, Adriaan de Groot <groot@kde.org>
|
||||||
* Copyright 2019, Collabora Ltd <arnaud.ferraris@collabora.com>
|
* Copyright 2019, Collabora Ltd <arnaud.ferraris@collabora.com>
|
||||||
|
* Copyright 2020, Anke Boersma <demm@kaosx.us
|
||||||
*
|
*
|
||||||
* Calamares is free software: you can redistribute it and/or modify
|
* Calamares is free software: you can redistribute it and/or modify
|
||||||
* it under the terms of the GNU General Public License as published by
|
* it under the terms of the GNU General Public License as published by
|
||||||
@ -22,23 +23,22 @@
|
|||||||
#include "gui/PartitionViewStep.h"
|
#include "gui/PartitionViewStep.h"
|
||||||
|
|
||||||
#include "core/DeviceModel.h"
|
#include "core/DeviceModel.h"
|
||||||
#include "core/PartitionActions.h"
|
|
||||||
#include "core/PartitionCoreModule.h"
|
|
||||||
#include "core/PartitionModel.h"
|
|
||||||
#include "core/KPMHelpers.h"
|
#include "core/KPMHelpers.h"
|
||||||
#include "core/OsproberEntry.h"
|
#include "core/OsproberEntry.h"
|
||||||
#include "core/PartUtils.h"
|
#include "core/PartUtils.h"
|
||||||
|
#include "core/PartitionActions.h"
|
||||||
|
#include "core/PartitionCoreModule.h"
|
||||||
|
#include "core/PartitionModel.h"
|
||||||
#include "gui/ChoicePage.h"
|
#include "gui/ChoicePage.h"
|
||||||
#include "gui/PartitionPage.h"
|
|
||||||
#include "gui/PartitionBarsView.h"
|
#include "gui/PartitionBarsView.h"
|
||||||
#include "gui/PartitionLabelsView.h"
|
#include "gui/PartitionLabelsView.h"
|
||||||
|
#include "gui/PartitionPage.h"
|
||||||
|
|
||||||
#include "Branding.h"
|
#include "Branding.h"
|
||||||
#include "CalamaresVersion.h"
|
#include "CalamaresVersion.h"
|
||||||
#include "GlobalStorage.h"
|
#include "GlobalStorage.h"
|
||||||
#include "Job.h"
|
#include "Job.h"
|
||||||
#include "JobQueue.h"
|
#include "JobQueue.h"
|
||||||
|
|
||||||
#include "utils/CalamaresUtilsGui.h"
|
#include "utils/CalamaresUtilsGui.h"
|
||||||
#include "utils/Logger.h"
|
#include "utils/Logger.h"
|
||||||
#include "utils/NamedEnum.h"
|
#include "utils/NamedEnum.h"
|
||||||
@ -51,17 +51,16 @@
|
|||||||
#include <kpmcore/core/partition.h>
|
#include <kpmcore/core/partition.h>
|
||||||
#include <kpmcore/fs/filesystem.h>
|
#include <kpmcore/fs/filesystem.h>
|
||||||
|
|
||||||
// Qt
|
|
||||||
#include <QApplication>
|
#include <QApplication>
|
||||||
#include <QDir>
|
#include <QDir>
|
||||||
#include <QFormLayout>
|
#include <QFormLayout>
|
||||||
|
#include <QFutureWatcher>
|
||||||
#include <QLabel>
|
#include <QLabel>
|
||||||
#include <QMessageBox>
|
#include <QMessageBox>
|
||||||
#include <QProcess>
|
#include <QProcess>
|
||||||
#include <QStackedWidget>
|
#include <QStackedWidget>
|
||||||
#include <QTimer>
|
#include <QTimer>
|
||||||
#include <QtConcurrent/QtConcurrent>
|
#include <QtConcurrent/QtConcurrent>
|
||||||
#include <QFutureWatcher>
|
|
||||||
|
|
||||||
PartitionViewStep::PartitionViewStep( QObject* parent )
|
PartitionViewStep::PartitionViewStep( QObject* parent )
|
||||||
: Calamares::ViewStep( parent )
|
: Calamares::ViewStep( parent )
|
||||||
@ -77,7 +76,7 @@ PartitionViewStep::PartitionViewStep( QObject* parent )
|
|||||||
m_widget->addWidget( m_waitingWidget );
|
m_widget->addWidget( m_waitingWidget );
|
||||||
CALAMARES_RETRANSLATE( m_waitingWidget->setText( tr( "Gathering system information..." ) ); )
|
CALAMARES_RETRANSLATE( m_waitingWidget->setText( tr( "Gathering system information..." ) ); )
|
||||||
|
|
||||||
m_core = new PartitionCoreModule( this ); // Unusable before init is complete!
|
m_core = new PartitionCoreModule( this ); // Unusable before init is complete!
|
||||||
// We're not done loading, but we need the configuration map first.
|
// We're not done loading, but we need the configuration map first.
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -108,19 +107,21 @@ PartitionViewStep::continueLoading()
|
|||||||
m_waitingWidget->deleteLater();
|
m_waitingWidget->deleteLater();
|
||||||
m_waitingWidget = nullptr;
|
m_waitingWidget = nullptr;
|
||||||
|
|
||||||
connect( m_core, &PartitionCoreModule::hasRootMountPointChanged,
|
connect( m_core, &PartitionCoreModule::hasRootMountPointChanged, this, &PartitionViewStep::nextStatusChanged );
|
||||||
this, &PartitionViewStep::nextStatusChanged );
|
connect( m_choicePage, &ChoicePage::nextStatusChanged, this, &PartitionViewStep::nextStatusChanged );
|
||||||
connect( m_choicePage, &ChoicePage::nextStatusChanged,
|
|
||||||
this, &PartitionViewStep::nextStatusChanged );
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
PartitionViewStep::~PartitionViewStep()
|
PartitionViewStep::~PartitionViewStep()
|
||||||
{
|
{
|
||||||
if ( m_choicePage && m_choicePage->parent() == nullptr )
|
if ( m_choicePage && m_choicePage->parent() == nullptr )
|
||||||
|
{
|
||||||
m_choicePage->deleteLater();
|
m_choicePage->deleteLater();
|
||||||
|
}
|
||||||
if ( m_manualPartitionPage && m_manualPartitionPage->parent() == nullptr )
|
if ( m_manualPartitionPage && m_manualPartitionPage->parent() == nullptr )
|
||||||
|
{
|
||||||
m_manualPartitionPage->deleteLater();
|
m_manualPartitionPage->deleteLater();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -154,7 +155,7 @@ PartitionViewStep::createSummaryWidget() const
|
|||||||
mainLayout->addLayout( formLayout );
|
mainLayout->addLayout( formLayout );
|
||||||
|
|
||||||
QList< PartitionCoreModule::SummaryInfo > list = m_core->createSummaryInfo();
|
QList< PartitionCoreModule::SummaryInfo > list = m_core->createSummaryInfo();
|
||||||
if ( list.length() > 1 ) // There are changes on more than one disk
|
if ( list.length() > 1 ) // There are changes on more than one disk
|
||||||
{
|
{
|
||||||
//NOTE: all of this should only happen when Manual partitioning is active.
|
//NOTE: all of this should only happen when Manual partitioning is active.
|
||||||
// Any other choice should result in a list.length() == 1.
|
// Any other choice should result in a list.length() == 1.
|
||||||
@ -165,15 +166,15 @@ PartitionViewStep::createSummaryWidget() const
|
|||||||
{
|
{
|
||||||
case ChoicePage::Alongside:
|
case ChoicePage::Alongside:
|
||||||
modeText = tr( "Install %1 <strong>alongside</strong> another operating system." )
|
modeText = tr( "Install %1 <strong>alongside</strong> another operating system." )
|
||||||
.arg( *Calamares::Branding::ShortVersionedName );
|
.arg( *Calamares::Branding::ShortVersionedName );
|
||||||
break;
|
break;
|
||||||
case ChoicePage::Erase:
|
case ChoicePage::Erase:
|
||||||
modeText = tr( "<strong>Erase</strong> disk and install %1." )
|
modeText
|
||||||
.arg( *Calamares::Branding::ShortVersionedName );
|
= tr( "<strong>Erase</strong> disk and install %1." ).arg( *Calamares::Branding::ShortVersionedName );
|
||||||
break;
|
break;
|
||||||
case ChoicePage::Replace:
|
case ChoicePage::Replace:
|
||||||
modeText = tr( "<strong>Replace</strong> a partition with %1." )
|
modeText
|
||||||
.arg( *Calamares::Branding::ShortVersionedName );
|
= tr( "<strong>Replace</strong> a partition with %1." ).arg( *Calamares::Branding::ShortVersionedName );
|
||||||
break;
|
break;
|
||||||
case ChoicePage::NoChoice:
|
case ChoicePage::NoChoice:
|
||||||
case ChoicePage::Manual:
|
case ChoicePage::Manual:
|
||||||
@ -184,42 +185,42 @@ PartitionViewStep::createSummaryWidget() const
|
|||||||
for ( const auto& info : list )
|
for ( const auto& info : list )
|
||||||
{
|
{
|
||||||
QLabel* diskInfoLabel = new QLabel;
|
QLabel* diskInfoLabel = new QLabel;
|
||||||
if ( list.length() == 1 ) // this is the only disk preview
|
if ( list.length() == 1 ) // this is the only disk preview
|
||||||
{
|
{
|
||||||
QString modeText;
|
QString modeText;
|
||||||
switch ( choice )
|
switch ( choice )
|
||||||
{
|
{
|
||||||
case ChoicePage::Alongside:
|
case ChoicePage::Alongside:
|
||||||
modeText = tr( "Install %1 <strong>alongside</strong> another operating system on disk <strong>%2</strong> (%3)." )
|
modeText = tr( "Install %1 <strong>alongside</strong> another operating system on disk "
|
||||||
.arg( *Calamares::Branding::ShortVersionedName )
|
"<strong>%2</strong> (%3)." )
|
||||||
.arg( info.deviceNode )
|
.arg( *Calamares::Branding::ShortVersionedName )
|
||||||
.arg( info.deviceName );
|
.arg( info.deviceNode )
|
||||||
|
.arg( info.deviceName );
|
||||||
break;
|
break;
|
||||||
case ChoicePage::Erase:
|
case ChoicePage::Erase:
|
||||||
modeText = tr( "<strong>Erase</strong> disk <strong>%2</strong> (%3) and install %1." )
|
modeText = tr( "<strong>Erase</strong> disk <strong>%2</strong> (%3) and install %1." )
|
||||||
.arg( *Calamares::Branding::ShortVersionedName )
|
.arg( *Calamares::Branding::ShortVersionedName )
|
||||||
.arg( info.deviceNode )
|
.arg( info.deviceNode )
|
||||||
.arg( info.deviceName );
|
.arg( info.deviceName );
|
||||||
break;
|
break;
|
||||||
case ChoicePage::Replace:
|
case ChoicePage::Replace:
|
||||||
modeText = tr( "<strong>Replace</strong> a partition on disk <strong>%2</strong> (%3) with %1." )
|
modeText = tr( "<strong>Replace</strong> a partition on disk <strong>%2</strong> (%3) with %1." )
|
||||||
.arg( *Calamares::Branding::ShortVersionedName )
|
.arg( *Calamares::Branding::ShortVersionedName )
|
||||||
.arg( info.deviceNode )
|
.arg( info.deviceNode )
|
||||||
.arg( info.deviceName );
|
.arg( info.deviceName );
|
||||||
break;
|
break;
|
||||||
case ChoicePage::NoChoice:
|
case ChoicePage::NoChoice:
|
||||||
case ChoicePage::Manual:
|
case ChoicePage::Manual:
|
||||||
modeText = tr( "<strong>Manual</strong> partitioning on disk <strong>%1</strong> (%2)." )
|
modeText = tr( "<strong>Manual</strong> partitioning on disk <strong>%1</strong> (%2)." )
|
||||||
.arg( info.deviceNode )
|
.arg( info.deviceNode )
|
||||||
.arg( info.deviceName );
|
.arg( info.deviceName );
|
||||||
}
|
}
|
||||||
diskInfoLabel->setText( modeText );
|
diskInfoLabel->setText( modeText );
|
||||||
}
|
}
|
||||||
else // multiple disk previews!
|
else // multiple disk previews!
|
||||||
{
|
{
|
||||||
diskInfoLabel->setText( tr( "Disk <strong>%1</strong> (%2)" )
|
diskInfoLabel->setText(
|
||||||
.arg( info.deviceNode )
|
tr( "Disk <strong>%1</strong> (%2)" ).arg( info.deviceNode ).arg( info.deviceName ) );
|
||||||
.arg( info.deviceName ) );
|
|
||||||
}
|
}
|
||||||
formLayout->addRow( diskInfoLabel );
|
formLayout->addRow( diskInfoLabel );
|
||||||
|
|
||||||
@ -227,10 +228,10 @@ PartitionViewStep::createSummaryWidget() const
|
|||||||
PartitionLabelsView* previewLabels;
|
PartitionLabelsView* previewLabels;
|
||||||
QVBoxLayout* field;
|
QVBoxLayout* field;
|
||||||
|
|
||||||
PartitionBarsView::NestedPartitionsMode mode = Calamares::JobQueue::instance()->globalStorage()->
|
PartitionBarsView::NestedPartitionsMode mode
|
||||||
value( "drawNestedPartitions" ).toBool() ?
|
= Calamares::JobQueue::instance()->globalStorage()->value( "drawNestedPartitions" ).toBool()
|
||||||
PartitionBarsView::DrawNestedPartitions :
|
? PartitionBarsView::DrawNestedPartitions
|
||||||
PartitionBarsView::NoNestedPartitions;
|
: PartitionBarsView::NoNestedPartitions;
|
||||||
preview = new PartitionBarsView;
|
preview = new PartitionBarsView;
|
||||||
preview->setNestedPartitionsMode( mode );
|
preview->setNestedPartitionsMode( mode );
|
||||||
previewLabels = new PartitionLabelsView;
|
previewLabels = new PartitionLabelsView;
|
||||||
@ -268,7 +269,9 @@ PartitionViewStep::createSummaryWidget() const
|
|||||||
foreach ( const Calamares::job_ptr& job, jobs() )
|
foreach ( const Calamares::job_ptr& job, jobs() )
|
||||||
{
|
{
|
||||||
if ( !job->prettyDescription().isEmpty() )
|
if ( !job->prettyDescription().isEmpty() )
|
||||||
|
{
|
||||||
jobsLines.append( job->prettyDescription() );
|
jobsLines.append( job->prettyDescription() );
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if ( !jobsLines.isEmpty() )
|
if ( !jobsLines.isEmpty() )
|
||||||
{
|
{
|
||||||
@ -301,7 +304,9 @@ PartitionViewStep::next()
|
|||||||
m_widget->setCurrentWidget( m_manualPartitionPage );
|
m_widget->setCurrentWidget( m_manualPartitionPage );
|
||||||
m_manualPartitionPage->selectDeviceByIndex( m_choicePage->lastSelectedDeviceIndex() );
|
m_manualPartitionPage->selectDeviceByIndex( m_choicePage->lastSelectedDeviceIndex() );
|
||||||
if ( m_core->isDirty() )
|
if ( m_core->isDirty() )
|
||||||
|
{
|
||||||
m_manualPartitionPage->onRevertClicked();
|
m_manualPartitionPage->onRevertClicked();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
cDebug() << "Choice applied: " << m_choicePage->currentChoice();
|
cDebug() << "Choice applied: " << m_choicePage->currentChoice();
|
||||||
}
|
}
|
||||||
@ -329,10 +334,14 @@ bool
|
|||||||
PartitionViewStep::isNextEnabled() const
|
PartitionViewStep::isNextEnabled() const
|
||||||
{
|
{
|
||||||
if ( m_choicePage && m_widget->currentWidget() == m_choicePage )
|
if ( m_choicePage && m_widget->currentWidget() == m_choicePage )
|
||||||
|
{
|
||||||
return m_choicePage->isNextEnabled();
|
return m_choicePage->isNextEnabled();
|
||||||
|
}
|
||||||
|
|
||||||
if ( m_manualPartitionPage && m_widget->currentWidget() == m_manualPartitionPage )
|
if ( m_manualPartitionPage && m_widget->currentWidget() == m_manualPartitionPage )
|
||||||
|
{
|
||||||
return m_core->hasRootMountPoint();
|
return m_core->hasRootMountPoint();
|
||||||
|
}
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@ -349,7 +358,9 @@ bool
|
|||||||
PartitionViewStep::isAtBeginning() const
|
PartitionViewStep::isAtBeginning() const
|
||||||
{
|
{
|
||||||
if ( m_widget->currentWidget() != m_choicePage )
|
if ( m_widget->currentWidget() != m_choicePage )
|
||||||
|
{
|
||||||
return false;
|
return false;
|
||||||
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -359,10 +370,11 @@ PartitionViewStep::isAtEnd() const
|
|||||||
{
|
{
|
||||||
if ( m_widget->currentWidget() == m_choicePage )
|
if ( m_widget->currentWidget() == m_choicePage )
|
||||||
{
|
{
|
||||||
if ( m_choicePage->currentChoice() == ChoicePage::Erase ||
|
if ( m_choicePage->currentChoice() == ChoicePage::Erase || m_choicePage->currentChoice() == ChoicePage::Replace
|
||||||
m_choicePage->currentChoice() == ChoicePage::Replace ||
|
|| m_choicePage->currentChoice() == ChoicePage::Alongside )
|
||||||
m_choicePage->currentChoice() == ChoicePage::Alongside )
|
{
|
||||||
return true;
|
return true;
|
||||||
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
@ -381,11 +393,10 @@ PartitionViewStep::onActivate()
|
|||||||
}
|
}
|
||||||
|
|
||||||
// if we're coming back to PVS from the next VS
|
// if we're coming back to PVS from the next VS
|
||||||
if ( m_widget->currentWidget() == m_choicePage &&
|
if ( m_widget->currentWidget() == m_choicePage && m_choicePage->currentChoice() == ChoicePage::Alongside )
|
||||||
m_choicePage->currentChoice() == ChoicePage::Alongside )
|
|
||||||
{
|
{
|
||||||
m_choicePage->applyActionChoice( ChoicePage::Alongside );
|
m_choicePage->applyActionChoice( ChoicePage::Alongside );
|
||||||
// m_choicePage->reset();
|
// m_choicePage->reset();
|
||||||
//FIXME: ReplaceWidget should be reset maybe?
|
//FIXME: ReplaceWidget should be reset maybe?
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -404,8 +415,8 @@ PartitionViewStep::onLeave()
|
|||||||
{
|
{
|
||||||
if ( PartUtils::isEfiSystem() )
|
if ( PartUtils::isEfiSystem() )
|
||||||
{
|
{
|
||||||
QString espMountPoint = Calamares::JobQueue::instance()->globalStorage()->
|
QString espMountPoint
|
||||||
value( "efiSystemPartition" ).toString();
|
= Calamares::JobQueue::instance()->globalStorage()->value( "efiSystemPartition" ).toString();
|
||||||
Partition* esp = m_core->findPartitionByMountPoint( espMountPoint );
|
Partition* esp = m_core->findPartitionByMountPoint( espMountPoint );
|
||||||
|
|
||||||
QString message;
|
QString message;
|
||||||
@ -421,8 +432,8 @@ PartitionViewStep::onLeave()
|
|||||||
"<strong>%2</strong>.<br/><br/>"
|
"<strong>%2</strong>.<br/><br/>"
|
||||||
"You can continue without setting up an EFI system "
|
"You can continue without setting up an EFI system "
|
||||||
"partition but your system may fail to start." )
|
"partition but your system may fail to start." )
|
||||||
.arg( *Calamares::Branding::ShortProductName )
|
.arg( *Calamares::Branding::ShortProductName )
|
||||||
.arg( espMountPoint );
|
.arg( espMountPoint );
|
||||||
}
|
}
|
||||||
else if ( esp && !PartUtils::isEfiBootable( esp ) )
|
else if ( esp && !PartUtils::isEfiBootable( esp ) )
|
||||||
{
|
{
|
||||||
@ -436,18 +447,39 @@ PartitionViewStep::onLeave()
|
|||||||
"<br/><br/>"
|
"<br/><br/>"
|
||||||
"You can continue without setting the flag but your "
|
"You can continue without setting the flag but your "
|
||||||
"system may fail to start." )
|
"system may fail to start." )
|
||||||
.arg( *Calamares::Branding::ShortProductName )
|
.arg( *Calamares::Branding::ShortProductName )
|
||||||
.arg( espMountPoint );
|
.arg( espMountPoint );
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( !message.isEmpty() )
|
if ( !message.isEmpty() )
|
||||||
{
|
{
|
||||||
cWarning() << message;
|
cWarning() << message;
|
||||||
QMessageBox::warning( m_manualPartitionPage,
|
QMessageBox::warning( m_manualPartitionPage, message, description );
|
||||||
message,
|
|
||||||
description );
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
|
||||||
|
cDebug() << "device: BIOS";
|
||||||
|
// TODO: this *always* warns, which might be annoying, so it'd be
|
||||||
|
// best to find a way to detect that bios_grub partition.
|
||||||
|
|
||||||
|
QString message = tr( "Option to use GPT on BIOS" );
|
||||||
|
QString description = tr( "A GPT partition table is the best option for all "
|
||||||
|
"systems. This installer supports such a setup for "
|
||||||
|
"BIOS systems too."
|
||||||
|
"<br/><br/>"
|
||||||
|
"To configure a GPT partition table on BIOS, "
|
||||||
|
"(if not done so already) go back "
|
||||||
|
"and set the partion table to GPT, next create a 8 MB "
|
||||||
|
"unformatted partition with the "
|
||||||
|
"<strong>bios_grub</strong> flag enabled.<br/><br/>"
|
||||||
|
"An unformatted 8 MB partition is necessary "
|
||||||
|
"to start %1 on a BIOS system with GPT." )
|
||||||
|
.arg( *Calamares::Branding::ShortProductName );
|
||||||
|
|
||||||
|
QMessageBox::information( m_manualPartitionPage, message, description );
|
||||||
|
}
|
||||||
|
|
||||||
Partition* root_p = m_core->findPartitionByMountPoint( "/" );
|
Partition* root_p = m_core->findPartitionByMountPoint( "/" );
|
||||||
Partition* boot_p = m_core->findPartitionByMountPoint( "/boot" );
|
Partition* boot_p = m_core->findPartitionByMountPoint( "/boot" );
|
||||||
@ -459,8 +491,7 @@ PartitionViewStep::onLeave()
|
|||||||
|
|
||||||
// If the root partition is encrypted, and there's a separate boot
|
// If the root partition is encrypted, and there's a separate boot
|
||||||
// partition which is not encrypted
|
// partition which is not encrypted
|
||||||
if ( root_p->fileSystem().type() == FileSystem::Luks &&
|
if ( root_p->fileSystem().type() == FileSystem::Luks && boot_p->fileSystem().type() != FileSystem::Luks )
|
||||||
boot_p->fileSystem().type() != FileSystem::Luks )
|
|
||||||
{
|
{
|
||||||
message = tr( "Boot partition not encrypted" );
|
message = tr( "Boot partition not encrypted" );
|
||||||
description = tr( "A separate boot partition was set up together with "
|
description = tr( "A separate boot partition was set up together with "
|
||||||
@ -476,9 +507,7 @@ PartitionViewStep::onLeave()
|
|||||||
"recreate it, selecting <strong>Encrypt</strong> "
|
"recreate it, selecting <strong>Encrypt</strong> "
|
||||||
"in the partition creation window." );
|
"in the partition creation window." );
|
||||||
|
|
||||||
QMessageBox::warning( m_manualPartitionPage,
|
QMessageBox::warning( m_manualPartitionPage, message, description );
|
||||||
message,
|
|
||||||
description );
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -493,7 +522,9 @@ PartitionViewStep::setConfigurationMap( const QVariantMap& configurationMap )
|
|||||||
Calamares::GlobalStorage* gs = Calamares::JobQueue::instance()->globalStorage();
|
Calamares::GlobalStorage* gs = Calamares::JobQueue::instance()->globalStorage();
|
||||||
QString efiSP = CalamaresUtils::getString( configurationMap, "efiSystemPartition" );
|
QString efiSP = CalamaresUtils::getString( configurationMap, "efiSystemPartition" );
|
||||||
if ( efiSP.isEmpty() )
|
if ( efiSP.isEmpty() )
|
||||||
|
{
|
||||||
efiSP = QStringLiteral( "/boot/efi" );
|
efiSP = QStringLiteral( "/boot/efi" );
|
||||||
|
}
|
||||||
gs->insert( "efiSystemPartition", efiSP );
|
gs->insert( "efiSystemPartition", efiSP );
|
||||||
|
|
||||||
// Set up firmwareType global storage entry. This is used, e.g. by the bootloader module.
|
// Set up firmwareType global storage entry. This is used, e.g. by the bootloader module.
|
||||||
@ -511,16 +542,22 @@ PartitionViewStep::setConfigurationMap( const QVariantMap& configurationMap )
|
|||||||
//
|
//
|
||||||
// This is a bit convoluted because there's legacy settings to handle as well
|
// This is a bit convoluted because there's legacy settings to handle as well
|
||||||
// as the new-style list of choices, with mapping back-and-forth.
|
// as the new-style list of choices, with mapping back-and-forth.
|
||||||
if ( configurationMap.contains( "userSwapChoices" ) &&
|
if ( configurationMap.contains( "userSwapChoices" )
|
||||||
( configurationMap.contains( "ensureSuspendToDisk" ) || configurationMap.contains( "neverCreateSwap" ) ) )
|
&& ( configurationMap.contains( "ensureSuspendToDisk" ) || configurationMap.contains( "neverCreateSwap" ) ) )
|
||||||
|
{
|
||||||
cError() << "Partition-module configuration mixes old- and new-style swap settings.";
|
cError() << "Partition-module configuration mixes old- and new-style swap settings.";
|
||||||
|
}
|
||||||
|
|
||||||
if ( configurationMap.contains( "ensureSuspendToDisk" ) )
|
if ( configurationMap.contains( "ensureSuspendToDisk" ) )
|
||||||
|
{
|
||||||
cWarning() << "Partition-module setting *ensureSuspendToDisk* is deprecated.";
|
cWarning() << "Partition-module setting *ensureSuspendToDisk* is deprecated.";
|
||||||
|
}
|
||||||
bool ensureSuspendToDisk = CalamaresUtils::getBool( configurationMap, "ensureSuspendToDisk", true );
|
bool ensureSuspendToDisk = CalamaresUtils::getBool( configurationMap, "ensureSuspendToDisk", true );
|
||||||
|
|
||||||
if ( configurationMap.contains( "neverCreateSwap" ) )
|
if ( configurationMap.contains( "neverCreateSwap" ) )
|
||||||
|
{
|
||||||
cWarning() << "Partition-module setting *neverCreateSwap* is deprecated.";
|
cWarning() << "Partition-module setting *neverCreateSwap* is deprecated.";
|
||||||
|
}
|
||||||
bool neverCreateSwap = CalamaresUtils::getBool( configurationMap, "neverCreateSwap", false );
|
bool neverCreateSwap = CalamaresUtils::getBool( configurationMap, "neverCreateSwap", false );
|
||||||
|
|
||||||
QSet< PartitionActions::Choices::SwapChoice > choices; // Available swap choices
|
QSet< PartitionActions::Choices::SwapChoice > choices; // Available swap choices
|
||||||
@ -535,7 +572,9 @@ PartitionViewStep::setConfigurationMap( const QVariantMap& configurationMap )
|
|||||||
bool ok = false;
|
bool ok = false;
|
||||||
auto v = PartitionActions::Choices::nameToChoice( item, ok );
|
auto v = PartitionActions::Choices::nameToChoice( item, ok );
|
||||||
if ( ok )
|
if ( ok )
|
||||||
|
{
|
||||||
choices.insert( v );
|
choices.insert( v );
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( choices.isEmpty() )
|
if ( choices.isEmpty() )
|
||||||
@ -553,19 +592,28 @@ PartitionViewStep::setConfigurationMap( const QVariantMap& configurationMap )
|
|||||||
{
|
{
|
||||||
// Convert the legacy settings into a single setting for now.
|
// Convert the legacy settings into a single setting for now.
|
||||||
if ( neverCreateSwap )
|
if ( neverCreateSwap )
|
||||||
|
{
|
||||||
choices.insert( PartitionActions::Choices::SwapChoice::NoSwap );
|
choices.insert( PartitionActions::Choices::SwapChoice::NoSwap );
|
||||||
|
}
|
||||||
else if ( ensureSuspendToDisk )
|
else if ( ensureSuspendToDisk )
|
||||||
|
{
|
||||||
choices.insert( PartitionActions::Choices::SwapChoice::FullSwap );
|
choices.insert( PartitionActions::Choices::SwapChoice::FullSwap );
|
||||||
|
}
|
||||||
else
|
else
|
||||||
|
{
|
||||||
choices.insert( PartitionActions::Choices::SwapChoice::SmallSwap );
|
choices.insert( PartitionActions::Choices::SwapChoice::SmallSwap );
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Not all are supported right now // FIXME
|
// Not all are supported right now // FIXME
|
||||||
static const char unsupportedSetting[] = "Partition-module does not support *userSwapChoices* setting";
|
static const char unsupportedSetting[] = "Partition-module does not support *userSwapChoices* setting";
|
||||||
|
|
||||||
#define COMPLAIN_UNSUPPORTED(x) \
|
#define COMPLAIN_UNSUPPORTED( x ) \
|
||||||
if ( choices.contains( x ) ) \
|
if ( choices.contains( x ) ) \
|
||||||
{ cWarning() << unsupportedSetting << PartitionActions::Choices::choiceToName( x ); choices.remove( x ); }
|
{ \
|
||||||
|
cWarning() << unsupportedSetting << PartitionActions::Choices::choiceToName( x ); \
|
||||||
|
choices.remove( x ); \
|
||||||
|
}
|
||||||
|
|
||||||
COMPLAIN_UNSUPPORTED( PartitionActions::Choices::SwapChoice::SwapFile )
|
COMPLAIN_UNSUPPORTED( PartitionActions::Choices::SwapChoice::SwapFile )
|
||||||
COMPLAIN_UNSUPPORTED( PartitionActions::Choices::SwapChoice::ReuseSwap )
|
COMPLAIN_UNSUPPORTED( PartitionActions::Choices::SwapChoice::ReuseSwap )
|
||||||
@ -584,23 +632,35 @@ PartitionViewStep::setConfigurationMap( const QVariantMap& configurationMap )
|
|||||||
// OTHER SETTINGS
|
// OTHER SETTINGS
|
||||||
//
|
//
|
||||||
gs->insert( "drawNestedPartitions", CalamaresUtils::getBool( configurationMap, "drawNestedPartitions", false ) );
|
gs->insert( "drawNestedPartitions", CalamaresUtils::getBool( configurationMap, "drawNestedPartitions", false ) );
|
||||||
gs->insert( "alwaysShowPartitionLabels", CalamaresUtils::getBool( configurationMap, "alwaysShowPartitionLabels", true ) );
|
gs->insert( "alwaysShowPartitionLabels",
|
||||||
gs->insert( "enableLuksAutomatedPartitioning", CalamaresUtils::getBool( configurationMap, "enableLuksAutomatedPartitioning", true ) );
|
CalamaresUtils::getBool( configurationMap, "alwaysShowPartitionLabels", true ) );
|
||||||
gs->insert( "allowManualPartitioning", CalamaresUtils::getBool( configurationMap, "allowManualPartitioning", true ) );
|
gs->insert( "enableLuksAutomatedPartitioning",
|
||||||
|
CalamaresUtils::getBool( configurationMap, "enableLuksAutomatedPartitioning", true ) );
|
||||||
|
gs->insert( "allowManualPartitioning",
|
||||||
|
CalamaresUtils::getBool( configurationMap, "allowManualPartitioning", true ) );
|
||||||
|
|
||||||
// The defaultFileSystemType setting needs a bit more processing,
|
// The defaultFileSystemType setting needs a bit more processing,
|
||||||
// as we want to cover various cases (such as different cases)
|
// as we want to cover various cases (such as different cases)
|
||||||
QString fsName = CalamaresUtils::getString( configurationMap, "defaultFileSystemType" );
|
QString fsName = CalamaresUtils::getString( configurationMap, "defaultFileSystemType" );
|
||||||
FileSystem::Type fsType;
|
FileSystem::Type fsType;
|
||||||
if ( fsName.isEmpty() )
|
if ( fsName.isEmpty() )
|
||||||
cWarning() << "Partition-module setting *defaultFileSystemType* is missing, will use ext4";
|
{
|
||||||
|
cWarning() << "Partition-module setting *defaultFileSystemType* is missing, will use ext4";
|
||||||
|
}
|
||||||
QString fsRealName = PartUtils::findFS( fsName, &fsType );
|
QString fsRealName = PartUtils::findFS( fsName, &fsType );
|
||||||
if ( fsRealName == fsName )
|
if ( fsRealName == fsName )
|
||||||
|
{
|
||||||
cDebug() << "Partition-module setting *defaultFileSystemType*" << fsRealName;
|
cDebug() << "Partition-module setting *defaultFileSystemType*" << fsRealName;
|
||||||
|
}
|
||||||
else if ( fsType != FileSystem::Unknown )
|
else if ( fsType != FileSystem::Unknown )
|
||||||
|
{
|
||||||
cWarning() << "Partition-module setting *defaultFileSystemType* changed" << fsRealName;
|
cWarning() << "Partition-module setting *defaultFileSystemType* changed" << fsRealName;
|
||||||
|
}
|
||||||
else
|
else
|
||||||
cWarning() << "Partition-module setting *defaultFileSystemType* is bad (" << fsName << ") using" << fsRealName << "instead.";
|
{
|
||||||
|
cWarning() << "Partition-module setting *defaultFileSystemType* is bad (" << fsName << ") using" << fsRealName
|
||||||
|
<< "instead.";
|
||||||
|
}
|
||||||
gs->insert( "defaultFileSystemType", fsRealName );
|
gs->insert( "defaultFileSystemType", fsRealName );
|
||||||
|
|
||||||
|
|
||||||
@ -608,21 +668,18 @@ PartitionViewStep::setConfigurationMap( const QVariantMap& configurationMap )
|
|||||||
// because it could take a while. Then when it's done, we can set up the widgets
|
// because it could take a while. Then when it's done, we can set up the widgets
|
||||||
// and remove the spinner.
|
// and remove the spinner.
|
||||||
m_future = new QFutureWatcher< void >();
|
m_future = new QFutureWatcher< void >();
|
||||||
connect( m_future, &QFutureWatcher< void >::finished,
|
connect( m_future, &QFutureWatcher< void >::finished, this, [this] {
|
||||||
this, [ this ]
|
|
||||||
{
|
|
||||||
continueLoading();
|
continueLoading();
|
||||||
this->m_future->deleteLater();
|
this->m_future->deleteLater();
|
||||||
this->m_future = nullptr;
|
this->m_future = nullptr;
|
||||||
} );
|
} );
|
||||||
|
|
||||||
QFuture< void > future =
|
QFuture< void > future = QtConcurrent::run( this, &PartitionViewStep::initPartitionCoreModule );
|
||||||
QtConcurrent::run( this, &PartitionViewStep::initPartitionCoreModule );
|
|
||||||
m_future->setFuture( future );
|
m_future->setFuture( future );
|
||||||
|
|
||||||
if ( configurationMap.contains( "partitionLayout" ) )
|
if ( configurationMap.contains( "partitionLayout" ) )
|
||||||
{
|
{
|
||||||
m_core->initLayout( configurationMap.values( "partitionLayout" ).at(0).toList() );
|
m_core->initLayout( configurationMap.values( "partitionLayout" ).at( 0 ).toList() );
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@ -641,19 +698,20 @@ Calamares::RequirementsList
|
|||||||
PartitionViewStep::checkRequirements()
|
PartitionViewStep::checkRequirements()
|
||||||
{
|
{
|
||||||
if ( m_future )
|
if ( m_future )
|
||||||
|
{
|
||||||
m_future->waitForFinished();
|
m_future->waitForFinished();
|
||||||
|
}
|
||||||
|
|
||||||
Calamares::RequirementsList l;
|
Calamares::RequirementsList l;
|
||||||
l.append(
|
l.append( {
|
||||||
{
|
|
||||||
QLatin1String( "partitions" ),
|
QLatin1String( "partitions" ),
|
||||||
[]{ return tr( "has at least one disk device available." ); },
|
[] { return tr( "has at least one disk device available." ); },
|
||||||
[]{ return tr( "There are no partitions to install on." ); },
|
[] { return tr( "There are no partitions to install on." ); },
|
||||||
m_core->deviceModel()->rowCount() > 0, // satisfied
|
m_core->deviceModel()->rowCount() > 0, // satisfied
|
||||||
#ifdef DEBUG_PARTITION_UNSAFE
|
#ifdef DEBUG_PARTITION_UNSAFE
|
||||||
false // optional
|
false // optional
|
||||||
#else
|
#else
|
||||||
true // required
|
true // required
|
||||||
#endif
|
#endif
|
||||||
} );
|
} );
|
||||||
|
|
||||||
@ -661,4 +719,4 @@ PartitionViewStep::checkRequirements()
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
CALAMARES_PLUGIN_FACTORY_DEFINITION( PartitionViewStepFactory, registerPlugin<PartitionViewStep>(); )
|
CALAMARES_PLUGIN_FACTORY_DEFINITION( PartitionViewStepFactory, registerPlugin< PartitionViewStep >(); )
|
||||||
|
@ -12,8 +12,6 @@ else()
|
|||||||
add_definitions( -DWITHOUT_LIBPARTED )
|
add_definitions( -DWITHOUT_LIBPARTED )
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
include_directories( ${PROJECT_BINARY_DIR}/src/libcalamaresui )
|
|
||||||
|
|
||||||
set( CHECKER_SOURCES
|
set( CHECKER_SOURCES
|
||||||
checker/CheckerContainer.cpp
|
checker/CheckerContainer.cpp
|
||||||
checker/GeneralRequirements.cpp
|
checker/GeneralRequirements.cpp
|
||||||
|
@ -17,27 +17,27 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
#include "Config.h"
|
#include "Config.h"
|
||||||
#include "utils/Logger.h"
|
|
||||||
#include "utils/Retranslator.h"
|
|
||||||
#include "Branding.h"
|
#include "Branding.h"
|
||||||
#include "Settings.h"
|
#include "Settings.h"
|
||||||
|
#include "utils/Logger.h"
|
||||||
#include <QApplication>
|
#include "utils/Retranslator.h"
|
||||||
|
|
||||||
void
|
void
|
||||||
RequirementsModel::setRequirementsList( const Calamares::RequirementsList& requirements )
|
RequirementsModel::setRequirementsList( const Calamares::RequirementsList& requirements )
|
||||||
{
|
{
|
||||||
|
CALAMARES_RETRANSLATE_SLOT( &RequirementsModel::retranslate )
|
||||||
|
|
||||||
emit beginResetModel();
|
emit beginResetModel();
|
||||||
m_requierements = requirements;
|
m_requirements = requirements;
|
||||||
m_satisfiedRequirements = true;
|
|
||||||
|
|
||||||
auto isUnSatisfied = []( const Calamares::RequirementEntry& e ) { return !e.satisfied; };
|
auto isUnSatisfied = []( const Calamares::RequirementEntry& e ) { return !e.satisfied; };
|
||||||
auto isMandatoryAndUnSatisfied = []( const Calamares::RequirementEntry& e ) { return e.mandatory && !e.satisfied; };
|
auto isMandatoryAndUnSatisfied = []( const Calamares::RequirementEntry& e ) { return e.mandatory && !e.satisfied; };
|
||||||
|
|
||||||
m_satisfiedRequirements = std::none_of( m_requierements.begin(), m_requierements.end(), isUnSatisfied );
|
m_satisfiedRequirements = std::none_of( m_requirements.begin(), m_requirements.end(), isUnSatisfied );
|
||||||
m_satisfiedMandatory = std::none_of( m_requierements.begin(), m_requierements.end(), isMandatoryAndUnSatisfied );
|
m_satisfiedMandatory = std::none_of( m_requirements.begin(), m_requirements.end(), isMandatoryAndUnSatisfied );
|
||||||
|
|
||||||
emit satisfiedRequirementsChanged(m_satisfiedRequirements);
|
emit satisfiedRequirementsChanged( m_satisfiedRequirements );
|
||||||
emit satisfiedMandatoryChanged();
|
emit satisfiedMandatoryChanged();
|
||||||
emit endResetModel();
|
emit endResetModel();
|
||||||
}
|
}
|
||||||
@ -45,89 +45,74 @@ RequirementsModel::setRequirementsList( const Calamares::RequirementsList& requi
|
|||||||
int
|
int
|
||||||
RequirementsModel::rowCount( const QModelIndex& ) const
|
RequirementsModel::rowCount( const QModelIndex& ) const
|
||||||
{
|
{
|
||||||
return m_requierements.count();
|
return m_requirements.count();
|
||||||
}
|
}
|
||||||
|
|
||||||
QVariant
|
QVariant
|
||||||
RequirementsModel::data( const QModelIndex& index, int role ) const
|
RequirementsModel::data( const QModelIndex& index, int role ) const
|
||||||
{
|
{
|
||||||
const auto requirement = m_requierements.at( index.row() );
|
const auto requirement = m_requirements.at( index.row() );
|
||||||
|
|
||||||
switch ( role )
|
switch ( role )
|
||||||
{
|
{
|
||||||
case Roles::Name:
|
case Roles::Name:
|
||||||
return requirement.name;
|
return requirement.name;
|
||||||
case Roles::Details:
|
case Roles::Details:
|
||||||
return requirement.enumerationText();
|
return requirement.enumerationText();
|
||||||
case Roles::NegatedText:
|
case Roles::NegatedText:
|
||||||
return requirement.negatedText();
|
return requirement.negatedText();
|
||||||
case Roles::Satisfied:
|
case Roles::Satisfied:
|
||||||
return requirement.satisfied;
|
return requirement.satisfied;
|
||||||
case Roles::Mandatory:
|
case Roles::Mandatory:
|
||||||
return requirement.mandatory;
|
return requirement.mandatory;
|
||||||
default:
|
default:
|
||||||
return QVariant();
|
return QVariant();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
QHash<int, QByteArray>
|
QHash< int, QByteArray >
|
||||||
RequirementsModel::roleNames() const
|
RequirementsModel::roleNames() const
|
||||||
{
|
{
|
||||||
static QHash<int, QByteArray> roles;
|
static QHash< int, QByteArray > roles;
|
||||||
roles[Roles::Name] = "name";
|
roles[ Roles::Name ] = "name";
|
||||||
roles[Roles::Details] = "details";
|
roles[ Roles::Details ] = "details";
|
||||||
roles[Roles::NegatedText] = "negatedText";
|
roles[ Roles::NegatedText ] = "negatedText";
|
||||||
roles[Roles::Satisfied] = "satisfied";
|
roles[ Roles::Satisfied ] = "satisfied";
|
||||||
roles[Roles::Mandatory] = "mandatory";
|
roles[ Roles::Mandatory ] = "mandatory";
|
||||||
return roles;
|
return roles;
|
||||||
}
|
}
|
||||||
|
|
||||||
Config::Config( QObject* parent ) : QObject( parent )
|
Config::Config( QObject* parent )
|
||||||
, m_requirementsModel( new RequirementsModel( this ))
|
: QObject( parent )
|
||||||
|
, m_requirementsModel( new RequirementsModel( this ) )
|
||||||
, m_languages( CalamaresUtils::Locale::availableTranslations() )
|
, m_languages( CalamaresUtils::Locale::availableTranslations() )
|
||||||
{
|
{
|
||||||
connect(m_requirementsModel, &RequirementsModel::satisfiedRequirementsChanged, this, &Config::setIsNextEnabled);
|
connect( m_requirementsModel, &RequirementsModel::satisfiedRequirementsChanged, this, &Config::setIsNextEnabled );
|
||||||
|
|
||||||
initLanguages();
|
initLanguages();
|
||||||
|
|
||||||
CALAMARES_RETRANSLATE_SLOT( &Config::retranslate )
|
CALAMARES_RETRANSLATE_SLOT( &Config::retranslate )
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
Config::retranslate()
|
Config::retranslate()
|
||||||
{
|
{
|
||||||
QString message;
|
m_genericWelcomeMessage = genericWelcomeMessage().arg( *Calamares::Branding::VersionedName );
|
||||||
|
|
||||||
if ( Calamares::Settings::instance()->isSetupMode() )
|
|
||||||
{
|
|
||||||
message = Calamares::Branding::instance()->welcomeStyleCalamares()
|
|
||||||
? tr( "<h1>Welcome to the Calamares setup program for %1.</h1>" )
|
|
||||||
: tr( "<h1>Welcome to %1 setup.</h1>" );
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
message = Calamares::Branding::instance()->welcomeStyleCalamares()
|
|
||||||
? tr( "<h1>Welcome to the Calamares installer for %1.</h1>" )
|
|
||||||
: tr( "<h1>Welcome to the %1 installer.</h1>" );
|
|
||||||
}
|
|
||||||
|
|
||||||
m_genericWelcomeMessage = message.arg( *Calamares::Branding::VersionedName );
|
|
||||||
emit genericWelcomeMessageChanged();
|
emit genericWelcomeMessageChanged();
|
||||||
|
|
||||||
// ui->supportButton->setText( tr( "%1 support" ).arg( *Calamares::Branding::ShortProductName ) );
|
m_requirementsModel->retranslate();
|
||||||
}
|
}
|
||||||
|
|
||||||
CalamaresUtils::Locale::LabelModel*
|
CalamaresUtils::Locale::LabelModel*
|
||||||
Config::languagesModel() const
|
Config::languagesModel() const
|
||||||
{
|
{
|
||||||
return m_languages;
|
return m_languages;
|
||||||
}
|
}
|
||||||
|
|
||||||
QString
|
QString
|
||||||
Config::languageIcon() const
|
Config::languageIcon() const
|
||||||
{
|
{
|
||||||
return m_languageIcon;
|
return m_languageIcon;
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
@ -146,7 +131,7 @@ Config::initLanguages()
|
|||||||
cDebug() << Logger::SubEntry << "Matching approximate locale" << defaultLocale.language();
|
cDebug() << Logger::SubEntry << "Matching approximate locale" << defaultLocale.language();
|
||||||
|
|
||||||
matchedLocaleIndex
|
matchedLocaleIndex
|
||||||
= m_languages->find( [&]( const QLocale& x ) { return x.language() == defaultLocale.language(); } );
|
= m_languages->find( [&]( const QLocale& x ) { return x.language() == defaultLocale.language(); } );
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( matchedLocaleIndex < 0 )
|
if ( matchedLocaleIndex < 0 )
|
||||||
@ -168,8 +153,8 @@ Config::initLanguages()
|
|||||||
QString name = m_languages->locale( matchedLocaleIndex ).name();
|
QString name = m_languages->locale( matchedLocaleIndex ).name();
|
||||||
cDebug() << Logger::SubEntry << "Matched with index" << matchedLocaleIndex << name;
|
cDebug() << Logger::SubEntry << "Matched with index" << matchedLocaleIndex << name;
|
||||||
|
|
||||||
CalamaresUtils::installTranslator( name, Calamares::Branding::instance()->translationsDirectory(), qApp );
|
CalamaresUtils::installTranslator( name, Calamares::Branding::instance()->translationsDirectory() );
|
||||||
setLocaleIndex( matchedLocaleIndex );
|
setLocaleIndex( matchedLocaleIndex );
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@ -180,23 +165,26 @@ Config::initLanguages()
|
|||||||
void
|
void
|
||||||
Config::setCountryCode( const QString& countryCode )
|
Config::setCountryCode( const QString& countryCode )
|
||||||
{
|
{
|
||||||
m_countryCode = countryCode;
|
m_countryCode = countryCode;
|
||||||
setLocaleIndex(CalamaresUtils::Locale::availableTranslations()->find( m_countryCode ));
|
setLocaleIndex( CalamaresUtils::Locale::availableTranslations()->find( m_countryCode ) );
|
||||||
|
|
||||||
emit countryCodeChanged( m_countryCode );
|
emit countryCodeChanged( m_countryCode );
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
Config::setLanguageIcon(const QString &languageIcon )
|
Config::setLanguageIcon( const QString& languageIcon )
|
||||||
{
|
{
|
||||||
m_languageIcon = languageIcon;
|
m_languageIcon = languageIcon;
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
Config::setLocaleIndex(const int& index)
|
Config::setLocaleIndex( const int& index )
|
||||||
{
|
{
|
||||||
if(index == m_localeIndex || index > CalamaresUtils::Locale::availableTranslations()->rowCount(QModelIndex()) || index < 0)
|
if ( index == m_localeIndex || index > CalamaresUtils::Locale::availableTranslations()->rowCount( QModelIndex() )
|
||||||
|
|| index < 0 )
|
||||||
|
{
|
||||||
return;
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
m_localeIndex = index;
|
m_localeIndex = index;
|
||||||
|
|
||||||
@ -204,8 +192,7 @@ Config::setLocaleIndex(const int& index)
|
|||||||
cDebug() << "Selected locale" << selectedLocale;
|
cDebug() << "Selected locale" << selectedLocale;
|
||||||
|
|
||||||
QLocale::setDefault( selectedLocale );
|
QLocale::setDefault( selectedLocale );
|
||||||
CalamaresUtils::installTranslator(
|
CalamaresUtils::installTranslator( selectedLocale, Calamares::Branding::instance()->translationsDirectory() );
|
||||||
selectedLocale, Calamares::Branding::instance()->translationsDirectory(), qApp );
|
|
||||||
|
|
||||||
emit localeIndexChanged( m_localeIndex );
|
emit localeIndexChanged( m_localeIndex );
|
||||||
}
|
}
|
||||||
@ -223,51 +210,118 @@ Config::setIsNextEnabled( const bool& isNextEnabled )
|
|||||||
emit isNextEnabledChanged( m_isNextEnabled );
|
emit isNextEnabledChanged( m_isNextEnabled );
|
||||||
}
|
}
|
||||||
|
|
||||||
QString Config::donateUrl() const
|
QString
|
||||||
|
Config::donateUrl() const
|
||||||
{
|
{
|
||||||
return m_donateUrl;
|
return m_donateUrl;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Config::setDonateUrl(const QString& url)
|
void
|
||||||
|
Config::setDonateUrl( const QString& url )
|
||||||
{
|
{
|
||||||
m_donateUrl = url;
|
m_donateUrl = url;
|
||||||
|
emit donateUrlChanged();
|
||||||
}
|
}
|
||||||
|
|
||||||
QString Config::knownIssuesUrl() const
|
QString
|
||||||
|
Config::knownIssuesUrl() const
|
||||||
{
|
{
|
||||||
return m_knownIssuesUrl;
|
return m_knownIssuesUrl;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Config::setKnownIssuesUrl(const QString& url)
|
void
|
||||||
|
Config::setKnownIssuesUrl( const QString& url )
|
||||||
{
|
{
|
||||||
m_knownIssuesUrl = url;
|
m_knownIssuesUrl = url;
|
||||||
|
emit knownIssuesUrlChanged();
|
||||||
}
|
}
|
||||||
|
|
||||||
void Config::setReleaseNotesUrl(const QString& url)
|
void
|
||||||
|
Config::setReleaseNotesUrl( const QString& url )
|
||||||
{
|
{
|
||||||
m_releaseNotesUrl = url;
|
m_releaseNotesUrl = url;
|
||||||
|
emit releaseNotesUrlChanged();
|
||||||
}
|
}
|
||||||
|
|
||||||
QString Config::releaseNotesUrl() const
|
QString
|
||||||
|
Config::releaseNotesUrl() const
|
||||||
{
|
{
|
||||||
return m_releaseNotesUrl;
|
return m_releaseNotesUrl;
|
||||||
}
|
}
|
||||||
|
|
||||||
QString Config::supportUrl() const
|
QString
|
||||||
|
Config::supportUrl() const
|
||||||
{
|
{
|
||||||
return m_supportUrl;
|
return m_supportUrl;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Config::setSupportUrl(const QString& url)
|
void
|
||||||
|
Config::setSupportUrl( const QString& url )
|
||||||
{
|
{
|
||||||
m_supportUrl = url;
|
m_supportUrl = url;
|
||||||
|
emit supportUrlChanged();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
RequirementsModel::retranslate()
|
||||||
|
{
|
||||||
|
if ( !m_satisfiedRequirements )
|
||||||
|
{
|
||||||
|
QString message;
|
||||||
|
const bool setup = Calamares::Settings::instance()->isSetupMode();
|
||||||
|
|
||||||
|
if ( !m_satisfiedMandatory )
|
||||||
|
{
|
||||||
|
message = setup ? tr( "This computer does not satisfy the minimum "
|
||||||
|
"requirements for setting up %1.<br/>"
|
||||||
|
"Setup cannot continue. "
|
||||||
|
"<a href=\"#details\">Details...</a>" )
|
||||||
|
: tr( "This computer does not satisfy the minimum "
|
||||||
|
"requirements for installing %1.<br/>"
|
||||||
|
"Installation cannot continue. "
|
||||||
|
"<a href=\"#details\">Details...</a>" );
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
message = setup ? tr( "This computer does not satisfy some of the "
|
||||||
|
"recommended requirements for setting up %1.<br/>"
|
||||||
|
"Setup can continue, but some features "
|
||||||
|
"might be disabled." )
|
||||||
|
: tr( "This computer does not satisfy some of the "
|
||||||
|
"recommended requirements for installing %1.<br/>"
|
||||||
|
"Installation can continue, but some features "
|
||||||
|
"might be disabled." );
|
||||||
|
}
|
||||||
|
|
||||||
|
m_warningMessage = message.arg( *Calamares::Branding::ShortVersionedName );
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
m_warningMessage = tr( "This program will ask you some questions and "
|
||||||
|
"set up %2 on your computer." )
|
||||||
|
.arg( *Calamares::Branding::ProductName );
|
||||||
|
}
|
||||||
|
|
||||||
|
emit warningMessageChanged();
|
||||||
|
}
|
||||||
|
|
||||||
|
QString
|
||||||
|
Config::genericWelcomeMessage()
|
||||||
|
{
|
||||||
|
QString message;
|
||||||
|
|
||||||
|
if ( Calamares::Settings::instance()->isSetupMode() )
|
||||||
|
{
|
||||||
|
message = Calamares::Branding::instance()->welcomeStyleCalamares()
|
||||||
|
? tr( "<h1>Welcome to the Calamares setup program for %1.</h1>" )
|
||||||
|
: tr( "<h1>Welcome to %1 setup.</h1>" );
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
message = Calamares::Branding::instance()->welcomeStyleCalamares()
|
||||||
|
? tr( "<h1>Welcome to the Calamares installer for %1.</h1>" )
|
||||||
|
: tr( "<h1>Welcome to the %1 installer.</h1>" );
|
||||||
|
}
|
||||||
|
|
||||||
|
return message;
|
||||||
|
}
|
||||||
|
@ -19,21 +19,23 @@
|
|||||||
#ifndef WELCOME_CONFIG_H
|
#ifndef WELCOME_CONFIG_H
|
||||||
#define WELCOME_CONFIG_H
|
#define WELCOME_CONFIG_H
|
||||||
|
|
||||||
#include <QObject>
|
|
||||||
#include <QUrl>
|
|
||||||
#include "modulesystem/Requirement.h"
|
#include "modulesystem/Requirement.h"
|
||||||
|
|
||||||
#include "locale/LabelModel.h"
|
#include "locale/LabelModel.h"
|
||||||
|
|
||||||
|
#include <QObject>
|
||||||
|
#include <QUrl>
|
||||||
|
|
||||||
|
// TODO: move this (and modulesystem/Requirement) to libcalamares
|
||||||
class RequirementsModel : public QAbstractListModel
|
class RequirementsModel : public QAbstractListModel
|
||||||
{
|
{
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
using QAbstractListModel::QAbstractListModel;
|
Q_PROPERTY( bool satisfiedRequirements READ satisfiedRequirements NOTIFY satisfiedRequirementsChanged FINAL )
|
||||||
Q_PROPERTY(bool satisfiedRequirements READ satisfiedRequirements NOTIFY satisfiedRequirementsChanged FINAL)
|
Q_PROPERTY( bool satisfiedMandatory READ satisfiedMandatory NOTIFY satisfiedMandatoryChanged FINAL )
|
||||||
|
Q_PROPERTY( QString warningMessage READ warningMessage NOTIFY warningMessageChanged FINAL )
|
||||||
Q_PROPERTY(bool satisfiedMandatory READ satisfiedMandatory NOTIFY satisfiedMandatoryChanged FINAL)
|
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
using QAbstractListModel::QAbstractListModel;
|
||||||
|
|
||||||
enum Roles : short
|
enum Roles : short
|
||||||
{
|
{
|
||||||
Name,
|
Name,
|
||||||
@ -44,90 +46,92 @@ public:
|
|||||||
HasDetails
|
HasDetails
|
||||||
};
|
};
|
||||||
|
|
||||||
bool satisfiedRequirements() const
|
bool satisfiedRequirements() const { return m_satisfiedRequirements; }
|
||||||
|
|
||||||
|
bool satisfiedMandatory() const { return m_satisfiedMandatory; }
|
||||||
|
|
||||||
|
const Calamares::RequirementEntry& getEntry( const int& index ) const
|
||||||
{
|
{
|
||||||
return m_satisfiedRequirements;
|
if ( index > count() || index < 0 )
|
||||||
}
|
{
|
||||||
|
return *( new Calamares::RequirementEntry() );
|
||||||
bool satisfiedMandatory() const
|
}
|
||||||
{
|
|
||||||
return m_satisfiedMandatory;
|
|
||||||
}
|
|
||||||
|
|
||||||
const Calamares::RequirementEntry& getEntry(const int& index) const
|
|
||||||
{
|
|
||||||
|
|
||||||
if(index > count() || index < 0)
|
|
||||||
return *(new Calamares::RequirementEntry());
|
|
||||||
|
|
||||||
return m_requierements.at(index);
|
|
||||||
|
|
||||||
|
return m_requirements.at( index );
|
||||||
}
|
}
|
||||||
|
|
||||||
void setRequirementsList( const Calamares::RequirementsList& requirements );
|
void setRequirementsList( const Calamares::RequirementsList& requirements );
|
||||||
int rowCount(const QModelIndex&) const override;
|
int rowCount( const QModelIndex& ) const override;
|
||||||
int count() const
|
int count() const { return m_requirements.count(); }
|
||||||
{
|
|
||||||
return m_requierements.count();
|
|
||||||
}
|
|
||||||
|
|
||||||
QVariant data(const QModelIndex& index, int role) const override;
|
QString warningMessage() const { return m_warningMessage; }
|
||||||
|
|
||||||
|
void retranslate();
|
||||||
|
|
||||||
|
QVariant data( const QModelIndex& index, int role ) const override;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
QHash<int, QByteArray> roleNames() const override;
|
QHash< int, QByteArray > roleNames() const override;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
Calamares::RequirementsList m_requierements;
|
Calamares::RequirementsList m_requirements;
|
||||||
bool m_satisfiedRequirements = false;
|
bool m_satisfiedRequirements = false;
|
||||||
bool m_satisfiedMandatory = false;
|
bool m_satisfiedMandatory = false;
|
||||||
|
|
||||||
|
QString m_warningMessage;
|
||||||
|
|
||||||
signals:
|
signals:
|
||||||
void satisfiedRequirementsChanged(bool value);
|
void satisfiedRequirementsChanged( bool value );
|
||||||
void satisfiedMandatoryChanged();
|
void satisfiedMandatoryChanged();
|
||||||
|
void warningMessageChanged();
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
class Config : public QObject
|
class Config : public QObject
|
||||||
{
|
{
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
Q_PROPERTY( CalamaresUtils::Locale::LabelModel* languagesModel READ languagesModel CONSTANT FINAL)
|
Q_PROPERTY( CalamaresUtils::Locale::LabelModel* languagesModel READ languagesModel CONSTANT FINAL )
|
||||||
Q_PROPERTY( RequirementsModel* requirementsModel MEMBER m_requirementsModel CONSTANT FINAL )
|
Q_PROPERTY( RequirementsModel* requirementsModel MEMBER m_requirementsModel CONSTANT FINAL )
|
||||||
|
|
||||||
Q_PROPERTY( QString languageIcon READ languageIcon CONSTANT FINAL )
|
Q_PROPERTY( QString languageIcon READ languageIcon CONSTANT FINAL )
|
||||||
|
|
||||||
Q_PROPERTY( QString countryCode MEMBER m_countryCode NOTIFY countryCodeChanged FINAL )
|
Q_PROPERTY( QString countryCode MEMBER m_countryCode NOTIFY countryCodeChanged FINAL )
|
||||||
Q_PROPERTY (int localeIndex READ localeIndex WRITE setLocaleIndex NOTIFY localeIndexChanged)
|
Q_PROPERTY( int localeIndex READ localeIndex WRITE setLocaleIndex NOTIFY localeIndexChanged )
|
||||||
|
|
||||||
Q_PROPERTY( QString genericWelcomeMessage MEMBER m_genericWelcomeMessage NOTIFY genericWelcomeMessageChanged FINAL )
|
Q_PROPERTY( QString genericWelcomeMessage MEMBER m_genericWelcomeMessage NOTIFY genericWelcomeMessageChanged FINAL )
|
||||||
Q_PROPERTY( QString warningMessage MEMBER m_warningMessage CONSTANT FINAL )
|
|
||||||
|
|
||||||
Q_PROPERTY(QString supportUrl MEMBER m_supportUrl CONSTANT FINAL)
|
Q_PROPERTY( QString supportUrl MEMBER m_supportUrl NOTIFY supportUrlChanged FINAL )
|
||||||
Q_PROPERTY(QString knownIssuesUrl MEMBER m_knownIssuesUrl CONSTANT FINAL)
|
Q_PROPERTY( QString knownIssuesUrl MEMBER m_knownIssuesUrl NOTIFY knownIssuesUrlChanged FINAL )
|
||||||
Q_PROPERTY(QString releaseNotesUrl MEMBER m_releaseNotesUrl CONSTANT FINAL)
|
Q_PROPERTY( QString releaseNotesUrl MEMBER m_releaseNotesUrl NOTIFY releaseNotesUrlChanged FINAL )
|
||||||
Q_PROPERTY(QString donateUrl MEMBER m_donateUrl CONSTANT FINAL)
|
Q_PROPERTY( QString donateUrl MEMBER m_donateUrl NOTIFY donateUrlChanged FINAL )
|
||||||
|
|
||||||
|
Q_PROPERTY( bool isNextEnabled MEMBER m_isNextEnabled NOTIFY isNextEnabledChanged FINAL )
|
||||||
|
|
||||||
public:
|
public:
|
||||||
Config( QObject* parent = nullptr );
|
Config( QObject* parent = nullptr );
|
||||||
void setCountryCode( const QString &countryCode );
|
void setCountryCode( const QString& countryCode );
|
||||||
void setLanguageIcon( const QString &languageIcon );
|
void setLanguageIcon( const QString& languageIcon );
|
||||||
RequirementsModel& requirementsModel () const;
|
RequirementsModel& requirementsModel() const;
|
||||||
|
|
||||||
void setIsNextEnabled( const bool& isNextEnabled );
|
void setIsNextEnabled( const bool& isNextEnabled );
|
||||||
|
|
||||||
void setLocaleIndex(const int &index);
|
void setLocaleIndex( const int& index );
|
||||||
int localeIndex() const { return m_localeIndex; }
|
int localeIndex() const { return m_localeIndex; }
|
||||||
|
|
||||||
QString supportUrl() const;
|
QString supportUrl() const;
|
||||||
void setSupportUrl(const QString &url);
|
void setSupportUrl( const QString& url );
|
||||||
|
|
||||||
QString knownIssuesUrl() const;
|
QString knownIssuesUrl() const;
|
||||||
void setKnownIssuesUrl(const QString &url);
|
void setKnownIssuesUrl( const QString& url );
|
||||||
|
|
||||||
QString releaseNotesUrl() const;
|
QString releaseNotesUrl() const;
|
||||||
void setReleaseNotesUrl(const QString &url);
|
void setReleaseNotesUrl( const QString& url );
|
||||||
|
|
||||||
QString donateUrl() const;
|
QString donateUrl() const;
|
||||||
void setDonateUrl(const QString &url);
|
void setDonateUrl( const QString& url );
|
||||||
|
|
||||||
|
QString genericWelcomeMessage();
|
||||||
|
|
||||||
|
|
||||||
public slots:
|
public slots:
|
||||||
CalamaresUtils::Locale::LabelModel* languagesModel() const;
|
CalamaresUtils::Locale::LabelModel* languagesModel() const;
|
||||||
@ -144,9 +148,7 @@ private:
|
|||||||
bool m_isNextEnabled = false;
|
bool m_isNextEnabled = false;
|
||||||
CalamaresUtils::Locale::LabelModel* m_languages;
|
CalamaresUtils::Locale::LabelModel* m_languages;
|
||||||
|
|
||||||
QString m_genericWelcomeMessage = tr("This program will ask you some questions and set up your installation");
|
QString m_genericWelcomeMessage;
|
||||||
|
|
||||||
QString m_warningMessage = tr("This program does not satisfy the minimum requirements for installing.\nInstallation can not continue");
|
|
||||||
|
|
||||||
QString m_supportUrl;
|
QString m_supportUrl;
|
||||||
QString m_knownIssuesUrl;
|
QString m_knownIssuesUrl;
|
||||||
@ -158,6 +160,10 @@ signals:
|
|||||||
void localeIndexChanged( int localeIndex );
|
void localeIndexChanged( int localeIndex );
|
||||||
void isNextEnabledChanged( bool isNextEnabled );
|
void isNextEnabledChanged( bool isNextEnabled );
|
||||||
void genericWelcomeMessageChanged();
|
void genericWelcomeMessageChanged();
|
||||||
|
void supportUrlChanged();
|
||||||
|
void knownIssuesUrlChanged();
|
||||||
|
void releaseNotesUrlChanged();
|
||||||
|
void donateUrlChanged();
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
@ -25,9 +25,9 @@
|
|||||||
|
|
||||||
#include "Branding.h"
|
#include "Branding.h"
|
||||||
#include "CalamaresVersion.h"
|
#include "CalamaresVersion.h"
|
||||||
|
#include "Config.h"
|
||||||
#include "Settings.h"
|
#include "Settings.h"
|
||||||
#include "ViewManager.h"
|
#include "ViewManager.h"
|
||||||
#include "Config.h"
|
|
||||||
|
|
||||||
#include "locale/LabelModel.h"
|
#include "locale/LabelModel.h"
|
||||||
#include "modulesystem/ModuleManager.h"
|
#include "modulesystem/ModuleManager.h"
|
||||||
@ -44,7 +44,7 @@
|
|||||||
#include <QLabel>
|
#include <QLabel>
|
||||||
#include <QMessageBox>
|
#include <QMessageBox>
|
||||||
|
|
||||||
WelcomePage::WelcomePage( Config *conf, QWidget* parent )
|
WelcomePage::WelcomePage( Config* conf, QWidget* parent )
|
||||||
: QWidget( parent )
|
: QWidget( parent )
|
||||||
, ui( new Ui::WelcomePage )
|
, ui( new Ui::WelcomePage )
|
||||||
, m_checkingWidget( new CheckerContainer( conf->requirementsModel(), this ) )
|
, m_checkingWidget( new CheckerContainer( conf->requirementsModel(), this ) )
|
||||||
@ -84,13 +84,14 @@ WelcomePage::WelcomePage( Config *conf, QWidget* parent )
|
|||||||
ui->verticalLayout->insertWidget( welcome_text_idx + 1, m_checkingWidget );
|
ui->verticalLayout->insertWidget( welcome_text_idx + 1, m_checkingWidget );
|
||||||
}
|
}
|
||||||
|
|
||||||
void WelcomePage::init()
|
void
|
||||||
|
WelcomePage::init()
|
||||||
{
|
{
|
||||||
//setup the url buttons
|
//setup the url buttons
|
||||||
setupButton( WelcomePage::Button::Support, m_conf->supportUrl());
|
setupButton( WelcomePage::Button::Support, m_conf->supportUrl() );
|
||||||
setupButton( WelcomePage::Button::KnownIssues, m_conf->knownIssuesUrl() );
|
setupButton( WelcomePage::Button::KnownIssues, m_conf->knownIssuesUrl() );
|
||||||
setupButton( WelcomePage::Button::ReleaseNotes, m_conf->releaseNotesUrl() );
|
setupButton( WelcomePage::Button::ReleaseNotes, m_conf->releaseNotesUrl() );
|
||||||
setupButton( WelcomePage::Button::Donate, m_conf->donateUrl());
|
setupButton( WelcomePage::Button::Donate, m_conf->donateUrl() );
|
||||||
|
|
||||||
//language icon
|
//language icon
|
||||||
auto icon = Calamares::Branding::instance()->image( m_conf->languageIcon(), QSize( 48, 48 ) );
|
auto icon = Calamares::Branding::instance()->image( m_conf->languageIcon(), QSize( 48, 48 ) );
|
||||||
@ -113,7 +114,9 @@ WelcomePage::initLanguages()
|
|||||||
ui->languageWidget->setCurrentIndex( m_conf->localeIndex() );
|
ui->languageWidget->setCurrentIndex( m_conf->localeIndex() );
|
||||||
|
|
||||||
connect( ui->languageWidget,
|
connect( ui->languageWidget,
|
||||||
static_cast< void ( QComboBox::* )( int ) >( &QComboBox::currentIndexChanged ), m_conf, &Config::setLocaleIndex );
|
static_cast< void ( QComboBox::* )( int ) >( &QComboBox::currentIndexChanged ),
|
||||||
|
m_conf,
|
||||||
|
&Config::setLocaleIndex );
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
@ -232,7 +235,7 @@ WelcomePage::showAboutBox()
|
|||||||
"<strong>%2<br/>"
|
"<strong>%2<br/>"
|
||||||
"for %3</strong><br/><br/>"
|
"for %3</strong><br/><br/>"
|
||||||
"Copyright 2014-2017 Teo Mrnjavac <teo@kde.org><br/>"
|
"Copyright 2014-2017 Teo Mrnjavac <teo@kde.org><br/>"
|
||||||
"Copyright 2017-2019 Adriaan de Groot <groot@kde.org><br/>"
|
"Copyright 2017-2020 Adriaan de Groot <groot@kde.org><br/>"
|
||||||
"Thanks to <a href=\"https://calamares.io/team/\">the Calamares team</a> "
|
"Thanks to <a href=\"https://calamares.io/team/\">the Calamares team</a> "
|
||||||
"and the <a href=\"https://www.transifex.com/calamares/calamares/\">Calamares "
|
"and the <a href=\"https://www.transifex.com/calamares/calamares/\">Calamares "
|
||||||
"translators team</a>.<br/><br/>"
|
"translators team</a>.<br/><br/>"
|
||||||
|
@ -36,7 +36,7 @@ class WelcomePage : public QWidget
|
|||||||
{
|
{
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
public:
|
public:
|
||||||
explicit WelcomePage( Config *conf, QWidget* parent = nullptr );
|
explicit WelcomePage( Config* conf, QWidget* parent = nullptr );
|
||||||
|
|
||||||
enum class Button
|
enum class Button
|
||||||
{
|
{
|
||||||
@ -75,7 +75,7 @@ private:
|
|||||||
CheckerContainer* m_checkingWidget;
|
CheckerContainer* m_checkingWidget;
|
||||||
CalamaresUtils::Locale::LabelModel* m_languages;
|
CalamaresUtils::Locale::LabelModel* m_languages;
|
||||||
|
|
||||||
Config *m_conf;
|
Config* m_conf;
|
||||||
};
|
};
|
||||||
|
|
||||||
/** @brief Delegate to display language information in two columns.
|
/** @brief Delegate to display language information in two columns.
|
||||||
|
@ -18,92 +18,91 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
#include "WelcomeViewStep.h"
|
#include "WelcomeViewStep.h"
|
||||||
#include "Config.h"
|
|
||||||
|
|
||||||
|
#include "Config.h"
|
||||||
#include "WelcomePage.h"
|
#include "WelcomePage.h"
|
||||||
#include "checker/GeneralRequirements.h"
|
#include "checker/GeneralRequirements.h"
|
||||||
|
|
||||||
|
#include "Branding.h"
|
||||||
#include "geoip/Handler.h"
|
#include "geoip/Handler.h"
|
||||||
#include "locale/Lookup.h"
|
#include "locale/Lookup.h"
|
||||||
|
#include "modulesystem/ModuleManager.h"
|
||||||
#include "utils/Logger.h"
|
#include "utils/Logger.h"
|
||||||
#include "utils/Variant.h"
|
#include "utils/Variant.h"
|
||||||
|
|
||||||
#include "Branding.h"
|
|
||||||
#include "modulesystem/ModuleManager.h"
|
|
||||||
|
|
||||||
#include <QFutureWatcher>
|
#include <QFutureWatcher>
|
||||||
#include <QVariant>
|
#include <QVariant>
|
||||||
|
|
||||||
CALAMARES_PLUGIN_FACTORY_DEFINITION( WelcomeViewStepFactory, registerPlugin< WelcomeViewStep >(); )
|
CALAMARES_PLUGIN_FACTORY_DEFINITION( WelcomeViewStepFactory, registerPlugin< WelcomeViewStep >(); )
|
||||||
|
|
||||||
WelcomeViewStep::WelcomeViewStep( QObject* parent )
|
WelcomeViewStep::WelcomeViewStep( QObject* parent )
|
||||||
: Calamares::ViewStep( parent )
|
: Calamares::ViewStep( parent )
|
||||||
, m_requirementsChecker( new GeneralRequirements( this ) )
|
, m_requirementsChecker( new GeneralRequirements( this ) )
|
||||||
, m_conf( new Config(this) )
|
, m_conf( new Config( this ) )
|
||||||
{
|
{
|
||||||
connect( Calamares::ModuleManager::instance(),
|
connect( Calamares::ModuleManager::instance(),
|
||||||
&Calamares::ModuleManager::requirementsComplete,
|
&Calamares::ModuleManager::requirementsComplete,
|
||||||
this,
|
this,
|
||||||
&WelcomeViewStep::nextStatusChanged );
|
&WelcomeViewStep::nextStatusChanged );
|
||||||
|
|
||||||
// the instance of the qqc2 or qwidgets page
|
// the instance of the qqc2 or qwidgets page
|
||||||
m_widget = new WelcomePage(m_conf);
|
m_widget = new WelcomePage( m_conf );
|
||||||
}
|
}
|
||||||
|
|
||||||
WelcomeViewStep::~WelcomeViewStep()
|
WelcomeViewStep::~WelcomeViewStep()
|
||||||
{
|
{
|
||||||
if ( m_widget && m_widget->parent() == nullptr )
|
if ( m_widget && m_widget->parent() == nullptr )
|
||||||
{
|
{
|
||||||
m_widget->deleteLater();
|
m_widget->deleteLater();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
QString
|
QString
|
||||||
WelcomeViewStep::prettyName() const
|
WelcomeViewStep::prettyName() const
|
||||||
{
|
{
|
||||||
return tr( "Welcome" );
|
return tr( "Welcome" );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
QWidget*
|
QWidget*
|
||||||
WelcomeViewStep::widget()
|
WelcomeViewStep::widget()
|
||||||
{
|
{
|
||||||
return m_widget;
|
return m_widget;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
bool
|
bool
|
||||||
WelcomeViewStep::isNextEnabled() const
|
WelcomeViewStep::isNextEnabled() const
|
||||||
{
|
{
|
||||||
return m_widget->verdict();
|
return m_widget->verdict();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
bool
|
bool
|
||||||
WelcomeViewStep::isBackEnabled() const
|
WelcomeViewStep::isBackEnabled() const
|
||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
bool
|
bool
|
||||||
WelcomeViewStep::isAtBeginning() const
|
WelcomeViewStep::isAtBeginning() const
|
||||||
{
|
{
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
bool
|
bool
|
||||||
WelcomeViewStep::isAtEnd() const
|
WelcomeViewStep::isAtEnd() const
|
||||||
{
|
{
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
Calamares::JobList
|
Calamares::JobList
|
||||||
WelcomeViewStep::jobs() const
|
WelcomeViewStep::jobs() const
|
||||||
{
|
{
|
||||||
return Calamares::JobList();
|
return Calamares::JobList();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -122,125 +121,127 @@ WelcomeViewStep::jobs() const
|
|||||||
static QString
|
static QString
|
||||||
jobOrBrandingSetting( Calamares::Branding::StringEntry e, const QVariantMap& map, const QString& key )
|
jobOrBrandingSetting( Calamares::Branding::StringEntry e, const QVariantMap& map, const QString& key )
|
||||||
{
|
{
|
||||||
if ( !map.contains( key ) )
|
if ( !map.contains( key ) )
|
||||||
{
|
{
|
||||||
return QString();
|
return QString();
|
||||||
}
|
}
|
||||||
auto v = map.value( key );
|
auto v = map.value( key );
|
||||||
if ( v.type() == QVariant::Bool )
|
if ( v.type() == QVariant::Bool )
|
||||||
{
|
{
|
||||||
return v.toBool() ? ( *e ) : QString();
|
return v.toBool() ? ( *e ) : QString();
|
||||||
}
|
}
|
||||||
if ( v.type() == QVariant::String )
|
if ( v.type() == QVariant::String )
|
||||||
{
|
{
|
||||||
return v.toString();
|
return v.toString();
|
||||||
}
|
}
|
||||||
|
|
||||||
return QString();
|
return QString();
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
WelcomeViewStep::setConfigurationMap( const QVariantMap& configurationMap )
|
WelcomeViewStep::setConfigurationMap( const QVariantMap& configurationMap )
|
||||||
{
|
{
|
||||||
using Calamares::Branding;
|
using Calamares::Branding;
|
||||||
|
|
||||||
m_conf->setSupportUrl( jobOrBrandingSetting( Branding::SupportUrl, configurationMap, "showSupportUrl" ) );
|
m_conf->setSupportUrl( jobOrBrandingSetting( Branding::SupportUrl, configurationMap, "showSupportUrl" ) );
|
||||||
m_conf->setKnownIssuesUrl( jobOrBrandingSetting( Branding::KnownIssuesUrl, configurationMap, "showKnownIssuesUrl" ) );
|
m_conf->setKnownIssuesUrl(
|
||||||
m_conf->setReleaseNotesUrl( jobOrBrandingSetting( Branding::ReleaseNotesUrl, configurationMap, "showReleaseNotesUrl" ) );
|
jobOrBrandingSetting( Branding::KnownIssuesUrl, configurationMap, "showKnownIssuesUrl" ) );
|
||||||
m_conf->setDonateUrl( CalamaresUtils::getString( configurationMap, "showDonateUrl" ) );
|
m_conf->setReleaseNotesUrl(
|
||||||
|
jobOrBrandingSetting( Branding::ReleaseNotesUrl, configurationMap, "showReleaseNotesUrl" ) );
|
||||||
|
m_conf->setDonateUrl( CalamaresUtils::getString( configurationMap, "showDonateUrl" ) );
|
||||||
|
|
||||||
if ( configurationMap.contains( "requirements" )
|
if ( configurationMap.contains( "requirements" )
|
||||||
&& configurationMap.value( "requirements" ).type() == QVariant::Map )
|
&& configurationMap.value( "requirements" ).type() == QVariant::Map )
|
||||||
{
|
{
|
||||||
m_requirementsChecker->setConfigurationMap( configurationMap.value( "requirements" ).toMap() );
|
m_requirementsChecker->setConfigurationMap( configurationMap.value( "requirements" ).toMap() );
|
||||||
|
|
||||||
m_conf->requirementsModel().setRequirementsList( checkRequirements() );
|
m_conf->requirementsModel().setRequirementsList( checkRequirements() );
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
cWarning() << "no valid requirements map found in welcome "
|
cWarning() << "no valid requirements map found in welcome "
|
||||||
"module configuration.";
|
"module configuration.";
|
||||||
|
|
||||||
bool ok = false;
|
bool ok = false;
|
||||||
QVariantMap geoip = CalamaresUtils::getSubMap( configurationMap, "geoip", ok );
|
QVariantMap geoip = CalamaresUtils::getSubMap( configurationMap, "geoip", ok );
|
||||||
if ( ok )
|
if ( ok )
|
||||||
{
|
{
|
||||||
using FWString = QFutureWatcher< QString >;
|
using FWString = QFutureWatcher< QString >;
|
||||||
|
|
||||||
auto* handler = new CalamaresUtils::GeoIP::Handler( CalamaresUtils::getString( geoip, "style" ),
|
auto* handler = new CalamaresUtils::GeoIP::Handler( CalamaresUtils::getString( geoip, "style" ),
|
||||||
CalamaresUtils::getString( geoip, "url" ),
|
CalamaresUtils::getString( geoip, "url" ),
|
||||||
CalamaresUtils::getString( geoip, "selector" ) );
|
CalamaresUtils::getString( geoip, "selector" ) );
|
||||||
if ( handler->type() != CalamaresUtils::GeoIP::Handler::Type::None )
|
if ( handler->type() != CalamaresUtils::GeoIP::Handler::Type::None )
|
||||||
{
|
{
|
||||||
auto* future = new FWString();
|
auto* future = new FWString();
|
||||||
connect( future, &FWString::finished, [view = this, f = future, h = handler]() {
|
connect( future, &FWString::finished, [view = this, f = future, h = handler]() {
|
||||||
QString countryResult = f->future().result();
|
QString countryResult = f->future().result();
|
||||||
cDebug() << "GeoIP result for welcome=" << countryResult;
|
cDebug() << "GeoIP result for welcome=" << countryResult;
|
||||||
view->setCountry( countryResult, h );
|
view->setCountry( countryResult, h );
|
||||||
f->deleteLater();
|
f->deleteLater();
|
||||||
delete h;
|
delete h;
|
||||||
} );
|
} );
|
||||||
future->setFuture( handler->queryRaw() );
|
future->setFuture( handler->queryRaw() );
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
// Would not produce useful country code anyway.
|
// Would not produce useful country code anyway.
|
||||||
delete handler;
|
delete handler;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
QString language = CalamaresUtils::getString( configurationMap, "languageIcon" );
|
QString language = CalamaresUtils::getString( configurationMap, "languageIcon" );
|
||||||
if ( !language.isEmpty() )
|
if ( !language.isEmpty() )
|
||||||
{
|
{
|
||||||
m_conf->setLanguageIcon( language );
|
m_conf->setLanguageIcon( language );
|
||||||
}
|
}
|
||||||
|
|
||||||
//here init the qml or qwidgets needed bits
|
//here init the qml or qwidgets needed bits
|
||||||
m_widget->init();
|
m_widget->init();
|
||||||
}
|
}
|
||||||
|
|
||||||
Calamares::RequirementsList
|
Calamares::RequirementsList
|
||||||
WelcomeViewStep::checkRequirements()
|
WelcomeViewStep::checkRequirements()
|
||||||
{
|
{
|
||||||
return m_requirementsChecker->checkRequirements();
|
return m_requirementsChecker->checkRequirements();
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline void
|
static inline void
|
||||||
logGeoIPHandler( CalamaresUtils::GeoIP::Handler* handler )
|
logGeoIPHandler( CalamaresUtils::GeoIP::Handler* handler )
|
||||||
{
|
{
|
||||||
if ( handler )
|
if ( handler )
|
||||||
{
|
{
|
||||||
cDebug() << Logger::SubEntry << "Obtained from" << handler->url() << " ("
|
cDebug() << Logger::SubEntry << "Obtained from" << handler->url() << " ("
|
||||||
<< static_cast< int >( handler->type() ) << handler->selector() << ')';
|
<< static_cast< int >( handler->type() ) << handler->selector() << ')';
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
WelcomeViewStep::setCountry( const QString& countryCode, CalamaresUtils::GeoIP::Handler* handler )
|
WelcomeViewStep::setCountry( const QString& countryCode, CalamaresUtils::GeoIP::Handler* handler )
|
||||||
{
|
{
|
||||||
if ( countryCode.length() != 2 )
|
if ( countryCode.length() != 2 )
|
||||||
{
|
{
|
||||||
cDebug() << "Unusable country code" << countryCode;
|
cDebug() << "Unusable country code" << countryCode;
|
||||||
logGeoIPHandler( handler );
|
logGeoIPHandler( handler );
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
auto c_l = CalamaresUtils::Locale::countryData( countryCode );
|
auto c_l = CalamaresUtils::Locale::countryData( countryCode );
|
||||||
if ( c_l.first == QLocale::Country::AnyCountry )
|
if ( c_l.first == QLocale::Country::AnyCountry )
|
||||||
{
|
{
|
||||||
cDebug() << "Unusable country code" << countryCode;
|
cDebug() << "Unusable country code" << countryCode;
|
||||||
logGeoIPHandler( handler );
|
logGeoIPHandler( handler );
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
int r = CalamaresUtils::Locale::availableTranslations()->find( countryCode );
|
int r = CalamaresUtils::Locale::availableTranslations()->find( countryCode );
|
||||||
if ( r < 0 )
|
if ( r < 0 )
|
||||||
{
|
{
|
||||||
cDebug() << "Unusable country code" << countryCode << "(no suitable translation)";
|
cDebug() << "Unusable country code" << countryCode << "(no suitable translation)";
|
||||||
}
|
}
|
||||||
if ( ( r >= 0 ) && m_conf )
|
if ( ( r >= 0 ) && m_conf )
|
||||||
{
|
{
|
||||||
m_conf->setCountryCode( countryCode );
|
m_conf->setCountryCode( countryCode );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -16,22 +16,22 @@
|
|||||||
* along with Calamares. If not, see <http://www.gnu.org/licenses/>.
|
* along with Calamares. If not, see <http://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef WELCOMEPAGEPLUGIN_H
|
#ifndef WELCOMEVIEWSTEP_H
|
||||||
#define WELCOMEPAGEPLUGIN_H
|
#define WELCOMEVIEWSTEP_H
|
||||||
|
|
||||||
|
|
||||||
|
#include "DllMacro.h"
|
||||||
|
#include "modulesystem/Requirement.h"
|
||||||
|
#include "utils/PluginFactory.h"
|
||||||
|
#include "viewpages/ViewStep.h"
|
||||||
|
|
||||||
#include <QObject>
|
#include <QObject>
|
||||||
|
|
||||||
#include <modulesystem/Requirement.h>
|
|
||||||
#include <utils/PluginFactory.h>
|
|
||||||
#include <viewpages/ViewStep.h>
|
|
||||||
|
|
||||||
#include <DllMacro.h>
|
|
||||||
|
|
||||||
#include <QVariantMap>
|
#include <QVariantMap>
|
||||||
|
|
||||||
class WelcomePage;
|
class WelcomePage;
|
||||||
class GeneralRequirements;
|
class GeneralRequirements;
|
||||||
class Config;
|
class Config;
|
||||||
|
|
||||||
namespace CalamaresUtils
|
namespace CalamaresUtils
|
||||||
{
|
{
|
||||||
namespace GeoIP
|
namespace GeoIP
|
||||||
@ -75,9 +75,9 @@ public:
|
|||||||
private:
|
private:
|
||||||
WelcomePage* m_widget;
|
WelcomePage* m_widget;
|
||||||
GeneralRequirements* m_requirementsChecker;
|
GeneralRequirements* m_requirementsChecker;
|
||||||
Config *m_conf;
|
Config* m_conf;
|
||||||
};
|
};
|
||||||
|
|
||||||
CALAMARES_PLUGIN_FACTORY_DECLARATION( WelcomeViewStepFactory )
|
CALAMARES_PLUGIN_FACTORY_DECLARATION( WelcomeViewStepFactory )
|
||||||
|
|
||||||
#endif // WELCOMEPAGEPLUGIN_H
|
#endif // WELCOMEVIEWSTEP_H
|
||||||
|
@ -288,4 +288,6 @@ ResultsListWidget::retranslate()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#include "utils/moc-warnings.h"
|
||||||
|
|
||||||
#include "ResultsListWidget.moc"
|
#include "ResultsListWidget.moc"
|
||||||
|
@ -41,7 +41,7 @@ CALAMARES_PLUGIN_FACTORY_DEFINITION( WelcomeQmlViewStepFactory, registerPlugin<
|
|||||||
|
|
||||||
WelcomeQmlViewStep::WelcomeQmlViewStep( QObject* parent )
|
WelcomeQmlViewStep::WelcomeQmlViewStep( QObject* parent )
|
||||||
: Calamares::QmlViewStep(parent )
|
: Calamares::QmlViewStep(parent )
|
||||||
, m_config( new Config( ) ) // the qml singleton takes ownership and deletes it
|
, m_config( new Config( this ) ) // the qml singleton takes ownership and deletes it
|
||||||
// , m_nextEnabled( false )
|
// , m_nextEnabled( false )
|
||||||
, m_requirementsChecker( new GeneralRequirements( this ) )
|
, m_requirementsChecker( new GeneralRequirements( this ) )
|
||||||
|
|
||||||
@ -98,10 +98,46 @@ WelcomeQmlViewStep::jobs() const
|
|||||||
return Calamares::JobList();
|
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
|
||||||
|
* assume an old-style configuration, and fetch the string from
|
||||||
|
* the branding settings @p e. If it is a string, not a boolean,
|
||||||
|
* use it as-is. If not found, or a weird type, returns empty.
|
||||||
|
*
|
||||||
|
* This allows switching the showKnownIssuesUrl and similar settings
|
||||||
|
* in welcome.conf from a boolean (deferring to branding) to an
|
||||||
|
* actual string for immediate use. Empty strings, as well as
|
||||||
|
* "false" as a setting, will hide the buttons as before.
|
||||||
|
*/
|
||||||
|
static QString
|
||||||
|
jobOrBrandingSetting( Calamares::Branding::StringEntry e, const QVariantMap& map, const QString& key )
|
||||||
|
{
|
||||||
|
if ( !map.contains( key ) )
|
||||||
|
{
|
||||||
|
return QString();
|
||||||
|
}
|
||||||
|
auto v = map.value( key );
|
||||||
|
if ( v.type() == QVariant::Bool )
|
||||||
|
{
|
||||||
|
return v.toBool() ? ( *e ) : QString();
|
||||||
|
}
|
||||||
|
if ( v.type() == QVariant::String )
|
||||||
|
{
|
||||||
|
return v.toString();
|
||||||
|
}
|
||||||
|
|
||||||
|
return QString();
|
||||||
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
WelcomeQmlViewStep::setConfigurationMap( const QVariantMap& configurationMap )
|
WelcomeQmlViewStep::setConfigurationMap( const QVariantMap& configurationMap )
|
||||||
{
|
{
|
||||||
using Calamares::Branding;
|
using Calamares::Branding;
|
||||||
|
m_config->setSupportUrl( jobOrBrandingSetting( Branding::SupportUrl, configurationMap, "showSupportUrl" ) );
|
||||||
|
m_config->setKnownIssuesUrl( jobOrBrandingSetting( Branding::KnownIssuesUrl, configurationMap, "showKnownIssuesUrl" ) );
|
||||||
|
m_config->setReleaseNotesUrl( jobOrBrandingSetting( Branding::ReleaseNotesUrl, configurationMap, "showReleaseNotesUrl" ) );
|
||||||
|
m_config->setDonateUrl( CalamaresUtils::getString( configurationMap, "showDonateUrl" ) );
|
||||||
|
|
||||||
// TODO: expand Config class and set the remaining fields // with the configurationMap all those properties can be accesed withouth having to declare a property, get and setter for each
|
// TODO: expand Config class and set the remaining fields // with the configurationMap all those properties can be accesed withouth having to declare a property, get and setter for each
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user