diff --git a/src/modules/users/Config.cpp b/src/modules/users/Config.cpp index e97c75f62..c8f205240 100644 --- a/src/modules/users/Config.cpp +++ b/src/modules/users/Config.cpp @@ -56,6 +56,16 @@ hostNameActionNames() Config::Config( QObject* parent ) : QObject( parent ) { + emit readyChanged( m_isReady ); // false + + // Gang together all the changes of status to one readyChanged() signal + connect( this, &Config::hostNameStatusChanged, this, &Config::checkReady ); + connect( this, &Config::loginNameStatusChanged, this, &Config::checkReady ); + connect( this, &Config::fullNameChanged, this, &Config::checkReady ); + connect( this, &Config::userPasswordStatusChanged, this, &Config::checkReady ); + connect( this, &Config::rootPasswordStatusChanged, this, &Config::checkReady ); + connect( this, &Config::reuseUserPasswordForRootChanged, this, &Config::checkReady ); + connect( this, &Config::requireStrongPasswordsChanged, this, &Config::checkReady ); } Config::~Config() {} @@ -404,7 +414,14 @@ Config::setUserPasswordSecondary( const QString& s ) } } -QPair< Config::PasswordValidity, QString > +/** @brief Checks two copies of the password for validity + * + * Given two copies of the password -- generally the password and + * the secondary fields -- checks them for validity and returns + * a pair of . + * + */ +Config::PasswordStatus Config::passwordStatus( const QString& pw1, const QString& pw2 ) const { if ( pw1 != pw2 ) @@ -527,6 +544,33 @@ Config::rootPasswordMessage() const return p.second; } +bool +Config::isReady() const +{ + bool readyFullName = !fullName().isEmpty(); // Needs some text + bool readyHostname = hostNameStatus().isEmpty(); // .. no warning message + bool readyUsername = loginNameStatus().isEmpty(); // .. no warning message + bool readyUserPassword = userPasswordValidity() != Config::PasswordValidity::Invalid; + bool readyRootPassword = rootPasswordValidity() != Config::PasswordValidity::Invalid; + return readyFullName && readyHostname && readyUsername && readyUserPassword && readyRootPassword; +} + +/** @brief Update ready status and emit signal + * + * This is a "concentrator" private slot for all the status-changed + * signals, so that readyChanged() is emitted only when needed. + */ +void +Config::checkReady() +{ + bool b = isReady(); + if ( b != m_isReady ) + { + m_isReady = b; + emit readyChanged( b ); + } +} + STATICTEST void setConfigurationDefaultGroups( const QVariantMap& map, QStringList& defaultGroups ) @@ -646,6 +690,8 @@ Config::setConfigurationMap( const QVariantMap& configurationMap ) addPasswordCheck( i.key(), i.value(), m_passwordChecks ); } std::sort( m_passwordChecks.begin(), m_passwordChecks.end() ); + + checkReady(); } void diff --git a/src/modules/users/Config.h b/src/modules/users/Config.h index ae09f76cc..65ea0e5ba 100644 --- a/src/modules/users/Config.h +++ b/src/modules/users/Config.h @@ -79,6 +79,8 @@ class Config : public QObject Q_PROPERTY( bool requireStrongPasswords READ requireStrongPasswords WRITE setRequireStrongPasswords NOTIFY requireStrongPasswordsChanged ) + Q_PROPERTY( bool ready READ isReady NOTIFY readyChanged STORED false ) + public: /** @brief Validity (status) of a password * @@ -178,6 +180,8 @@ public: QString rootPasswordMessage() const; PasswordStatus rootPasswordStatus() const; + bool isReady() const; + static const QStringList& forbiddenLoginNames(); static const QStringList& forbiddenHostNames(); @@ -236,10 +240,11 @@ signals: void rootPasswordChanged( const QString& ); void rootPasswordSecondaryChanged( const QString& ); void rootPasswordStatusChanged( int, const QString& ); - + void readyChanged( bool ) const; private: PasswordStatus passwordStatus( const QString&, const QString& ) const; + void checkReady(); QStringList m_defaultGroups; QString m_userShell; @@ -265,6 +270,8 @@ private: bool m_customLoginName = false; bool m_customHostName = false; + bool m_isReady = false; ///< Used to reduce readyChanged signals + HostNameActions m_hostNameActions; PasswordCheckList m_passwordChecks; }; diff --git a/src/modules/users/UsersPage.cpp b/src/modules/users/UsersPage.cpp index 541991943..70effca40 100644 --- a/src/modules/users/UsersPage.cpp +++ b/src/modules/users/UsersPage.cpp @@ -186,18 +186,6 @@ UsersPage::retranslate() } -bool -UsersPage::isReady() const -{ - bool readyFullName = !m_config->fullName().isEmpty(); // Needs some text - bool readyHostname = m_config->hostNameStatus().isEmpty(); // .. no warning message - bool readyUsername = m_config->loginNameStatus().isEmpty(); // .. no warning message - bool readyUserPassword = m_config->userPasswordValidity() != Config::PasswordValidity::Invalid; - bool readyRootPassword = m_config->rootPasswordValidity() != Config::PasswordValidity::Invalid; - return readyFullName && readyHostname && readyUsername && readyUserPassword && readyRootPassword; -} - - void UsersPage::onActivate() { @@ -213,21 +201,18 @@ void UsersPage::onFullNameTextEdited( const QString& fullName ) { labelStatus( ui->labelFullName, ui->labelFullNameError, fullName, QString() ); - checkReady( isReady() ); } void UsersPage::reportLoginNameStatus( const QString& status ) { labelStatus( ui->labelUsername, ui->labelUsernameError, m_config->loginName(), status ); - emit checkReady( isReady() ); } void UsersPage::reportHostNameStatus( const QString& status ) { labelStatus( ui->labelHostname, ui->labelHostnameError, m_config->hostName(), status ); - emit checkReady( isReady() ); } static inline void @@ -280,5 +265,4 @@ UsersPage::onReuseUserPasswordChanged( const int checked ) ui->labelRootPasswordError->setVisible( visible ); ui->textBoxRootPassword->setVisible( visible ); ui->textBoxVerifiedRootPassword->setVisible( visible ); - checkReady( isReady() ); } diff --git a/src/modules/users/UsersPage.h b/src/modules/users/UsersPage.h index f8bd3b708..246a08083 100644 --- a/src/modules/users/UsersPage.h +++ b/src/modules/users/UsersPage.h @@ -42,8 +42,6 @@ public: explicit UsersPage( Config* config, QWidget* parent = nullptr ); virtual ~UsersPage(); - bool isReady() const; - void onActivate(); protected slots: @@ -54,9 +52,6 @@ protected slots: void reportUserPasswordStatus( int, const QString& ); void reportRootPasswordStatus( int, const QString& ); -signals: - void checkReady( bool ); - private: void retranslate(); diff --git a/src/modules/users/UsersViewStep.cpp b/src/modules/users/UsersViewStep.cpp index e2271e759..6d3566399 100644 --- a/src/modules/users/UsersViewStep.cpp +++ b/src/modules/users/UsersViewStep.cpp @@ -39,7 +39,9 @@ UsersViewStep::UsersViewStep( QObject* parent ) , m_widget( nullptr ) , m_config( new Config( this ) ) { - emit nextStatusChanged( true ); + connect( m_config, &Config::readyChanged, this, &UsersViewStep::nextStatusChanged ); + + emit nextStatusChanged( m_config->isReady() ); } @@ -65,7 +67,6 @@ UsersViewStep::widget() if ( !m_widget ) { m_widget = new UsersPage( m_config ); - connect( m_widget, &UsersPage::checkReady, this, &UsersViewStep::nextStatusChanged ); } return m_widget; } @@ -74,7 +75,7 @@ UsersViewStep::widget() bool UsersViewStep::isNextEnabled() const { - return m_widget ? m_widget->isReady() : true; + return m_config->isReady(); } @@ -120,7 +121,7 @@ void UsersViewStep::onLeave() { m_jobs.clear(); - if ( !m_widget || !m_widget->isReady() ) + if ( !m_widget || !m_config->isReady() ) { return; }