diff --git a/src/main.cpp b/src/main.cpp index 8b5a93d0f..0d77ad1a0 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -18,7 +18,6 @@ */ #include "src/audio/audio.h" -#include "src/core/coreav.h" #include "src/ipc.h" #include "src/net/toxuri.h" #include "src/nexus.h" @@ -194,8 +193,8 @@ int main(int argc, char* argv[]) #endif qsrand(time(nullptr)); - Settings::getInstance(); - QString locale = Settings::getInstance().getTranslation(); + Settings& settings = Settings::getInstance(); + QString locale = settings.getTranslation(); Translator::translate(locale); // Process arguments @@ -215,15 +214,14 @@ int main(int argc, char* argv[]) QObject::tr("Starts new instance and opens the login screen."))); parser.process(*a); - uint32_t profileId = Settings::getInstance().getCurrentProfileId(); + uint32_t profileId = settings.getCurrentProfileId(); IPC ipc(profileId); if (!ipc.isAttached()) { qCritical() << "Can't init IPC"; return EXIT_FAILURE; } - QObject::connect(&Settings::getInstance(), &Settings::currentProfileIdChanged, &ipc, - &IPC::setProfileId); + QObject::connect(&settings, &Settings::currentProfileIdChanged, &ipc, &IPC::setProfileId); // For the auto-updater if (sodium_init() < 0) { @@ -232,7 +230,7 @@ int main(int argc, char* argv[]) } #ifdef LOG_TO_FILE - QString logFileDir = Settings::getInstance().getAppCacheDirPath(); + QString logFileDir = settings.getAppCacheDirPath(); QDir(logFileDir).mkpath("."); QString logfile = logFileDir + "qtox.log"; @@ -274,7 +272,7 @@ int main(int argc, char* argv[]) qDebug() << "commit: " << GIT_VERSION; QString profileName; - bool autoLogin = Settings::getInstance().getAutoLogin(); + bool autoLogin = settings.getAutoLogin(); uint32_t ipcDest = 0; bool doIpc = true; @@ -294,10 +292,10 @@ int main(int argc, char* argv[]) doIpc = false; autoLogin = false; } else { - profileName = Settings::getInstance().getCurrentProfile(); + profileName = settings.getCurrentProfile(); } - if (parser.positionalArguments().size() == 0) { + if (parser.positionalArguments().empty()) { eventType = "activate"; } else { firstParam = parser.positionalArguments()[0]; @@ -330,38 +328,27 @@ int main(int argc, char* argv[]) } } - Profile* profile = nullptr; + // TODO(sudden6): remove once we get rid of Nexus + Nexus& nexus = Nexus::getInstance(); + // TODO(kriby): Consider moving application initializing variables into a globalSettings object + // note: Because Settings is shouldering global settings as well as model specific ones it + // cannot be integrated into a central model object yet + nexus.setSettings(&settings); // Autologin + // TODO (kriby): Shift responsibility of linking views to model objects from nexus + // Further: generate view instances separately (loginScreen, mainGUI, audio) if (autoLogin && Profile::exists(profileName) && !Profile::isEncrypted(profileName)) { - profile = Profile::loadProfile(profileName); + Profile* profile = Profile::loadProfile(profileName); + settings.updateProfileData(profile); + nexus.bootstrapWithProfile(profile); } else { - LoginScreen loginScreen{profileName}; - loginScreen.exec(); - profile = loginScreen.getProfile(); - if (profile) { - profileName = profile->getName(); + int returnval = nexus.showLogin(profileName); + if (returnval != 0) { + return returnval; } } - if (!profile) { - return EXIT_FAILURE; - } - - Nexus::getInstance().setProfile(profile); - Settings& s = Settings::getInstance(); - s.setCurrentProfile(profileName); - - auto audio = Audio::makeAudio(s); - assert(audio != nullptr); - // TODO(sudden6): init CoreAV audio backend somewhere else so main doesn't depend on coreav.h - profile->getCore()->getAv()->setAudio(*audio); - - Nexus& nexus = Nexus::getInstance(); - // TODO(sudden6): remove once we get rid of Nexus - nexus.audio = audio.get(); - nexus.start(); - // Start to accept Inter-process communication ipc.registerEventHandler("uri", &toxURIEventHandler); ipc.registerEventHandler("save", &toxSaveEventHandler); diff --git a/src/model/profile/profileinfo.cpp b/src/model/profile/profileinfo.cpp index 1e4397b99..73635325e 100644 --- a/src/model/profile/profileinfo.cpp +++ b/src/model/profile/profileinfo.cpp @@ -226,8 +226,10 @@ QStringList ProfileInfo::removeProfile() */ void ProfileInfo::logout() { + // TODO(kriby): Refactor all of these invokeMethod calls with connect() properly when possible Settings::getInstance().saveGlobal(); - QMetaObject::invokeMethod(&Nexus::getInstance(), "showLogin"); + QMetaObject::invokeMethod(&Nexus::getInstance(), "showLogin", + Q_ARG(QString, Settings::getInstance().getCurrentProfile())); } /** @@ -340,8 +342,8 @@ IProfileInfo::SetAvatarResult ProfileInfo::byteArrayToPng(QByteArray inData, QBy } if (format == "png") { - // FIXME: re-encode the png even though inData is already valid. This strips the metadata since - // we don't have a good png metadata stripping method currently. + // FIXME: re-encode the png even though inData is already valid. This strips the metadata + // since we don't have a good png metadata stripping method currently. outPng = picToPng(image); } else { outPng = picToPng(image); diff --git a/src/nexus.cpp b/src/nexus.cpp index c88da24db..256f81449 100644 --- a/src/nexus.cpp +++ b/src/nexus.cpp @@ -35,6 +35,7 @@ #include #include #include +#include #ifdef Q_OS_MAC #include @@ -67,7 +68,7 @@ Nexus::~Nexus() widget = nullptr; delete profile; profile = nullptr; - Settings::getInstance().saveGlobal(); + emit saveGlobal(); #ifdef Q_OS_MAC delete globalMenuBar; #endif @@ -148,7 +149,7 @@ void Nexus::start() /** * @brief Hides the main GUI, delete the profile, and shows the login screen */ -void Nexus::showLogin() +int Nexus::showLogin(const QString& profileName) { delete widget; widget = nullptr; @@ -156,26 +157,72 @@ void Nexus::showLogin() delete profile; profile = nullptr; - LoginScreen loginScreen; - loginScreen.exec(); + LoginScreen loginScreen{profileName}; + connectLoginScreen(loginScreen); - profile = loginScreen.getProfile(); + // TODO(kriby): Move core out of profile + // This is awkward because the core is in the profile + // The connection order ensures profile will be ready for bootstrap for now + connect(this, &Nexus::currentProfileChanged, this, &Nexus::bootstrapWithProfile); + int returnval = loginScreen.exec(); + disconnect(this, &Nexus::currentProfileChanged, this, &Nexus::bootstrapWithProfile); + return returnval; +} + +void Nexus::bootstrapWithProfile(Profile *p) +{ + // kriby: This is a hack until a proper controller is written + + profile = p; if (profile) { - Nexus::getInstance().setProfile(profile); - Settings::getInstance().setCurrentProfile(profile->getName()); - showMainGUI(); - } else { - qApp->quit(); + audioControl = std::unique_ptr(Audio::makeAudio(*settings)); + assert(audioControl != nullptr); + profile->getCore()->getAv()->setAudio(*audioControl); + start(); } } +void Nexus::setSettings(Settings* settings) +{ + if (this->settings) { + QObject::disconnect(this, &Nexus::currentProfileChanged, this->settings, + &Settings::updateProfileData); + QObject::disconnect(this, &Nexus::saveGlobal, this->settings, &Settings::saveGlobal); + } + this->settings = settings; + if (this->settings) { + QObject::connect(this, &Nexus::currentProfileChanged, this->settings, + &Settings::updateProfileData); + QObject::connect(this, &Nexus::saveGlobal, this->settings, &Settings::saveGlobal); + } +} + +void Nexus::connectLoginScreen(const LoginScreen& loginScreen) +{ + // TODO(kriby): Move connect sequences to a controller class object instead + + // Nexus -> LoginScreen + QObject::connect(this, &Nexus::profileLoaded, &loginScreen, &LoginScreen::onProfileLoaded); + QObject::connect(this, &Nexus::profileLoadFailed, &loginScreen, &LoginScreen::onProfileLoadFailed); + // LoginScreen -> Nexus + QObject::connect(&loginScreen, &LoginScreen::createNewProfile, this, &Nexus::onCreateNewProfile); + QObject::connect(&loginScreen, &LoginScreen::loadProfile, this, &Nexus::onLoadProfile); + // LoginScreen -> Settings + QObject::connect(&loginScreen, &LoginScreen::autoLoginChanged, settings, &Settings::setAutoLogin); + QObject::connect(&loginScreen, &LoginScreen::autoLoginChanged, settings, &Settings::saveGlobal); + // Settings -> LoginScreen + QObject::connect(settings, &Settings::autoLoginChanged, &loginScreen, + &LoginScreen::onAutoLoginChanged); +} + void Nexus::showMainGUI() { + // TODO(kriby): Rewrite as view-model connect sequence only, add to a controller class object assert(profile); // Create GUI - widget = Widget::getInstance(audio); + widget = Widget::getInstance(audioControl.get()); // Start GUI widget->init(); @@ -270,14 +317,36 @@ Profile* Nexus::getProfile() } /** - * @brief Unload the current profile, if any, and replaces it. - * @param profile Profile to set. + * @brief Creates a new profile and replaces the current one. + * @param name New username + * @param pass New password */ -void Nexus::setProfile(Profile* profile) +void Nexus::onCreateNewProfile(const QString& name, const QString& pass) { - getInstance().profile = profile; - if (profile) - Settings::getInstance().loadPersonal(profile->getName(), profile->getPasskey()); + setProfile(Profile::createProfile(name, pass)); +} + +/** + * Loads an existing profile and replaces the current one. + */ +void Nexus::onLoadProfile(const QString& name, const QString& pass) +{ + setProfile(Profile::loadProfile(name, pass)); +} +/** + * Changes the loaded profile and notifies listeners. + * @param p + */ +void Nexus::setProfile(Profile* p) { + if (!p) { + emit profileLoadFailed(); + // Warnings are issued during respective createNew/load calls + return; + } else { + emit profileLoaded(); + } + + emit currentProfileChanged(p); } /** diff --git a/src/nexus.h b/src/nexus.h index 2ce624edf..43ec679a5 100644 --- a/src/nexus.h +++ b/src/nexus.h @@ -27,6 +27,8 @@ class Widget; class Profile; +class Settings; +class LoginScreen; class Core; #ifdef Q_OS_MAC @@ -44,16 +46,13 @@ class Nexus : public QObject public: void start(); void showMainGUI(); - + void setSettings(Settings* settings); static Nexus& getInstance(); static void destroyInstance(); static Core* getCore(); static Profile* getProfile(); - static void setProfile(Profile* profile); static Widget* getDesktopGUI(); -public slots: - void showLogin(); #ifdef Q_OS_MAC public: @@ -81,17 +80,29 @@ private: QSignalMapper* windowMapper; QActionGroup* windowActions = nullptr; #endif -public: - // TODO(sudden6): hack to pass the audio instance - IAudioControl* audio = nullptr; +signals: + void currentProfileChanged(Profile* Profile); + void profileLoaded(); + void profileLoadFailed(); + void saveGlobal(); + +public slots: + void onCreateNewProfile(const QString& name, const QString& pass); + void onLoadProfile(const QString& name, const QString& pass); + int showLogin(const QString& profileName = QString()); + void bootstrapWithProfile(Profile *p); private: explicit Nexus(QObject* parent = nullptr); + void connectLoginScreen(const LoginScreen& loginScreen); + void setProfile(Profile* p); ~Nexus(); private: Profile* profile; + Settings* settings; Widget* widget; + std::unique_ptr audioControl; }; #endif // NEXUS_H diff --git a/src/persistence/profile.cpp b/src/persistence/profile.cpp index b35fa9024..1bc48bda1 100644 --- a/src/persistence/profile.cpp +++ b/src/persistence/profile.cpp @@ -105,13 +105,11 @@ Profile::Profile(QString name, const QString& password, bool isNewProfile, , encrypted{this->passkey != nullptr} { Settings& s = Settings::getInstance(); - s.setCurrentProfile(name); - s.saveGlobal(); - s.loadPersonal(name, this->passkey.get()); + // TODO(kriby): Move/refactor core initialization to remove settings dependency + // note to self: use slots/signals for this? initCore(toxsave, s, isNewProfile); - const ToxId& selfId = core->getSelfId(); - loadDatabase(selfId, password); + loadDatabase(password); } /** @@ -271,21 +269,17 @@ QStringList Profile::getFilesByExt(QString extension) * @brief Scan for profile, automatically importing them if needed. * @warning NOT thread-safe. */ -void Profile::scanProfiles() +const QStringList Profile::getAllProfileNames() { profiles.clear(); QStringList toxfiles = getFilesByExt("tox"), inifiles = getFilesByExt("ini"); - for (QString toxfile : toxfiles) { + for (const QString& toxfile : toxfiles) { if (!inifiles.contains(toxfile)) { Settings::getInstance().createPersonal(toxfile); } profiles.append(toxfile); } -} - -QStringList Profile::getProfiles() -{ return profiles; } @@ -473,14 +467,16 @@ QByteArray Profile::loadAvatarData(const ToxPk& owner) return pic; } -void Profile::loadDatabase(const ToxId& id, QString password) +void Profile::loadDatabase(QString password) { + assert(core); + if (isRemoved) { qDebug() << "Can't load database of removed profile"; return; } - QByteArray salt = id.getPublicKey().getByteArray(); + QByteArray salt = core->getSelfId().getPublicKey().getByteArray(); if (salt.size() != TOX_PASS_SALT_LENGTH) { qWarning() << "Couldn't compute salt from public key" << name; GUI::showError(QObject::tr("Error"), diff --git a/src/persistence/profile.h b/src/persistence/profile.h index b464b6e55..6b8c9dd08 100644 --- a/src/persistence/profile.h +++ b/src/persistence/profile.h @@ -67,8 +67,7 @@ public: bool rename(QString newName); - static void scanProfiles(); - static QStringList getProfiles(); + static const QStringList getAllProfileNames(); static bool exists(QString name); static bool isEncrypted(QString name); @@ -90,7 +89,7 @@ public slots: void onRequestSent(const ToxPk& friendPk, const QString& message); private slots: - void loadDatabase(const ToxId& id, QString password); + void loadDatabase(QString password); void saveAvatar(const ToxPk& owner, const QByteArray& avatar); void removeAvatar(const ToxPk& owner); void onSaveToxSave(); @@ -98,7 +97,8 @@ private slots: void onAvatarOfferReceived(uint32_t friendId, uint32_t fileId, const QByteArray& avatarHash); private: - Profile(QString name, const QString& password, bool newProfile, const QByteArray& toxsave, std::unique_ptr passKey); + Profile(QString name, const QString& password, bool newProfile, const QByteArray& toxsave, + std::unique_ptr passKey); static QStringList getFilesByExt(QString extension); QString avatarPath(const ToxPk& owner, bool forceUnencrypted = false); bool saveToxSave(QByteArray data); diff --git a/src/persistence/settings.cpp b/src/persistence/settings.cpp index df375137a..e86687999 100644 --- a/src/persistence/settings.cpp +++ b/src/persistence/settings.cpp @@ -109,17 +109,7 @@ void Settings::loadGlobal() createSettingsDir(); - QString localSettingsPath = qApp->applicationDirPath() + QDir::separator() + globalSettingsFile; - - if (QFile(localSettingsPath).exists()) { - QSettings ps(localSettingsPath, QSettings::IniFormat); - ps.setIniCodec("UTF-8"); - ps.beginGroup("Advanced"); - makeToxPortable = ps.value("makeToxPortable", false).toBool(); - ps.endGroup(); - } else { - makeToxPortable = false; - } + makeToxPortable = Settings::isToxPortable(); QDir dir(getSettingsDirPath()); QString filePath = dir.filePath(globalSettingsFile); @@ -153,9 +143,11 @@ void Settings::loadGlobal() } autoAwayTime = s.value("autoAwayTime", 10).toInt(); checkUpdates = s.value("checkUpdates", true).toBool(); - notifySound = s.value("notifySound", true).toBool(); // note: notifySound and busySound UI elements are now under UI settings + // note: notifySound and busySound UI elements are now under UI settings + // page, but kept under General in settings file to be backwards compatible + notifySound = s.value("notifySound", true).toBool(); notifyHide = s.value("notifyHide", false).toBool(); - busySound = s.value("busySound", false).toBool(); // page, but kept under General in settings file to be backwards compatible + busySound = s.value("busySound", false).toBool(); autoSaveEnabled = s.value("autoSaveEnabled", false).toBool(); globalAutoAcceptDir = s.value("globalAutoAcceptDir", QStandardPaths::locate(QStandardPaths::HomeLocation, QString(), @@ -273,6 +265,33 @@ void Settings::loadGlobal() loaded = true; } +bool Settings::isToxPortable() +{ + QString localSettingsPath = qApp->applicationDirPath() + QDir::separator() + globalSettingsFile; + if (!QFile(localSettingsPath).exists()) { + return false; + } + QSettings ps(localSettingsPath, QSettings::IniFormat); + ps.setIniCodec("UTF-8"); + ps.beginGroup("Advanced"); + bool result = ps.value("makeToxPortable", false).toBool(); + ps.endGroup(); + return result; +} + +void Settings::updateProfileData(Profile *profile) +{ + QMutexLocker locker{&bigLock}; + + if (profile == nullptr) { + qWarning() << QString("Could not load new settings (profile change to nullptr)"); + return; + } + setCurrentProfile(profile->getName()); + saveGlobal(); + loadPersonal(profile->getName(), profile->getPasskey()); +} + void Settings::loadPersonal(QString profileName, const ToxEncrypt* passKey) { QMutexLocker locker{&bigLock}; @@ -319,7 +338,7 @@ void Settings::loadPersonal(QString profileName, const ToxEncrypt* passKey) fp.circleID = ps.value("circle", -1).toInt(); if (getEnableLogging()) - fp.activity = ps.value("activity", QDateTime()).toDateTime(); + fp.activity = ps.value("activity", QDateTime()).toDateTime(); friendLst.insert(ToxId(fp.addr).getPublicKey().getByteArray(), fp); } ps.endArray(); @@ -346,7 +365,8 @@ void Settings::loadPersonal(QString profileName, const ToxEncrypt* passKey) ps.beginGroup("GUI"); { compactLayout = ps.value("compactLayout", true).toBool(); - sortingMode = static_cast(ps.value("friendSortingMethod", static_cast(FriendListSortingMode::Name)).toInt()); + sortingMode = static_cast( + ps.value("friendSortingMethod", static_cast(FriendListSortingMode::Name)).toInt()); } ps.endGroup(); @@ -1281,7 +1301,7 @@ void Settings::setCurrentProfile(const QString& profile) if (profile != currentProfile) { currentProfile = profile; currentProfileId = makeProfileId(currentProfile); - emit currentProfileChanged(currentProfile); + emit currentProfileIdChanged(currentProfileId); } } diff --git a/src/persistence/settings.h b/src/persistence/settings.h index 4028b7869..5507d6894 100644 --- a/src/persistence/settings.h +++ b/src/persistence/settings.h @@ -154,6 +154,7 @@ public: void savePersonal(); void loadGlobal(); + bool isToxPortable(); void loadPersonal(QString profileName, const ToxEncrypt* passKey); void resetToDefault(); @@ -168,6 +169,8 @@ public: public slots: void saveGlobal(); void sync(); + void setAutoLogin(bool state); + void updateProfileData(Profile *profile); signals: // General @@ -190,7 +193,6 @@ signals: void toxmeBioChanged(const QString& bio); void toxmePrivChanged(bool priv); void toxmePassChanged(); - void currentProfileChanged(const QString& profile); void currentProfileIdChanged(quint32 id); void enableLoggingChanged(bool enabled); void autoAwayTimeChanged(int minutes); @@ -541,7 +543,6 @@ public: void setShowIdenticons(bool value); bool getAutoLogin() const; - void setAutoLogin(bool state); void setEnableGroupChatsColor(bool state); bool getEnableGroupChatsColor() const; diff --git a/src/widget/loginscreen.cpp b/src/widget/loginscreen.cpp index 8c0a72479..2ac1ba083 100644 --- a/src/widget/loginscreen.cpp +++ b/src/widget/loginscreen.cpp @@ -32,7 +32,7 @@ #include #include -LoginScreen::LoginScreen(QString initialProfile, QWidget* parent) +LoginScreen::LoginScreen(const QString& initialProfileName, QWidget* parent) : QDialog(parent) , ui(new Ui::LoginScreen) , quitShortcut{QKeySequence(Qt::CTRL + Qt::Key_Q), this} @@ -56,10 +56,10 @@ LoginScreen::LoginScreen(QString initialProfile, QWidget* parent) connect(ui->loginPassword, &QLineEdit::returnPressed, this, &LoginScreen::onLogin); connect(ui->newPass, &QLineEdit::textChanged, this, &LoginScreen::onPasswordEdited); connect(ui->newPassConfirm, &QLineEdit::textChanged, this, &LoginScreen::onPasswordEdited); - connect(ui->autoLoginCB, &QCheckBox::stateChanged, this, &LoginScreen::onAutoLoginToggled); + connect(ui->autoLoginCB, &QCheckBox::stateChanged, this, &LoginScreen::onAutoLoginCheckboxChanged); connect(ui->importButton, &QPushButton::clicked, this, &LoginScreen::onImportProfile); - reset(initialProfile); + reset(initialProfileName); this->setStyleSheet(Style::getStylesheet("loginScreen/loginScreen.css")); retranslateUi(); @@ -72,10 +72,19 @@ LoginScreen::~LoginScreen() delete ui; } +void LoginScreen::closeEvent(QCloseEvent* event) +{ + + // If we are in the bootstrap, returning -1 will give us something to exit with in main.cpp + this->setResult(-1); + // If we are in application exec, we can quit by closing it, instead. + qApp->quit(); +} + /** * @brief Resets the UI, clears all fields. */ -void LoginScreen::reset(QString initialProfile) +void LoginScreen::reset(const QString& initialProfileName) { ui->newUsername->clear(); ui->newPass->clear(); @@ -83,34 +92,36 @@ void LoginScreen::reset(QString initialProfile) ui->loginPassword->clear(); ui->loginUsernames->clear(); - Profile::scanProfiles(); - if (initialProfile.isEmpty()) { - initialProfile = Settings::getInstance().getCurrentProfile(); - } - QStringList profiles = Profile::getProfiles(); - for (QString profile : profiles) { - ui->loginUsernames->addItem(profile); - if (profile == initialProfile) { - ui->loginUsernames->setCurrentIndex(ui->loginUsernames->count() - 1); - } - } + QStringList allProfileNames = Profile::getAllProfileNames(); - if (profiles.isEmpty()) { + if (allProfileNames.isEmpty()) { ui->stackedWidget->setCurrentIndex(0); ui->newUsername->setFocus(); } else { + for (const QString& profileName : allProfileNames) { + ui->loginUsernames->addItem(profileName); + } + + ui->loginUsernames->setCurrentText(initialProfileName); ui->stackedWidget->setCurrentIndex(1); ui->loginPassword->setFocus(); } - - ui->autoLoginCB->blockSignals(true); - ui->autoLoginCB->setChecked(Settings::getInstance().getAutoLogin()); - ui->autoLoginCB->blockSignals(false); } -Profile *LoginScreen::getProfile() const +void LoginScreen::onProfileLoaded() { - return profile; + done(0); +} + +void LoginScreen::onProfileLoadFailed() { + QMessageBox::critical(this, tr("Couldn't load this profile"), tr("Wrong password.")); + ui->loginPassword->setFocus(); + ui->loginPassword->selectAll(); +} + +void LoginScreen::onAutoLoginChanged(bool state) +{ + ui->autoLoginCB->setChecked(state); } bool LoginScreen::event(QEvent* event) @@ -129,11 +140,6 @@ bool LoginScreen::event(QEvent* event) return QWidget::event(event); } -void LoginScreen::closeEvent(QCloseEvent*) -{ - emit closed(); -} - void LoginScreen::onNewProfilePageClicked() { ui->stackedWidget->setCurrentIndex(0); @@ -174,16 +180,7 @@ void LoginScreen::onCreateNewProfile() return; } - profile = Profile::createProfile(name, pass); - if (!profile) { - // Unknown error - QMessageBox::critical(this, tr("Couldn't create a new profile"), - tr("Unknown error: Couldn't create a new profile.\nIf you " - "encountered this error, please report it.")); - done(-1); - return; - } - done(0); + emit createNewProfile(name, pass); } void LoginScreen::onLoginUsernameSelected(const QString& name) @@ -227,20 +224,7 @@ void LoginScreen::onLogin() return; } - profile = Profile::loadProfile(name, pass); - if (!profile) { - if (!ProfileLocker::isLockable(name)) { - QMessageBox::critical(this, tr("Couldn't load this profile"), - tr("Profile already in use. Close other clients.")); - return; - } else { - QMessageBox::critical(this, tr("Couldn't load this profile"), tr("Wrong password.")); - ui->loginPassword->setFocus(); - ui->loginPassword->selectAll(); - return; - } - } - done(0); + emit loadProfile(name, pass); } void LoginScreen::onPasswordEdited() @@ -248,15 +232,10 @@ void LoginScreen::onPasswordEdited() ui->passStrengthMeter->setValue(SetPasswordDialog::getPasswordStrength(ui->newPass->text())); } -void LoginScreen::onAutoLoginToggled(int state) +void LoginScreen::onAutoLoginCheckboxChanged(int state) { - Qt::CheckState cstate = static_cast(state); - if (cstate == Qt::CheckState::Unchecked) - Settings::getInstance().setAutoLogin(false); - else - Settings::getInstance().setAutoLogin(true); - - Settings::getInstance().saveGlobal(); + auto cstate = static_cast(state); + emit autoLoginChanged(cstate == Qt::CheckState::Checked); } void LoginScreen::retranslateUi() @@ -266,10 +245,8 @@ void LoginScreen::retranslateUi() void LoginScreen::onImportProfile() { - ProfileImporter* pi = new ProfileImporter(this); - - if (pi->importProfile()) + ProfileImporter pi(this); + if (pi.importProfile()) { reset(); - - delete pi; + } } diff --git a/src/widget/loginscreen.h b/src/widget/loginscreen.h index 5b5050e23..53d8d9ea1 100644 --- a/src/widget/loginscreen.h +++ b/src/widget/loginscreen.h @@ -36,22 +36,27 @@ class LoginScreen : public QDialog Q_OBJECT public: - LoginScreen(QString selectedProfile = QString(), QWidget* parent = nullptr); + LoginScreen(const QString& initialProfileName = QString(), QWidget* parent = nullptr); ~LoginScreen(); - void reset(QString selectedProfile = QString()); - Profile* getProfile() const; - bool event(QEvent* event) final override; signals: + void windowStateChanged(Qt::WindowStates states); - void closed(); + void autoLoginChanged(bool state); + void createNewProfile(QString name, const QString& pass); + void loadProfile(QString name, const QString& pass); protected: virtual void closeEvent(QCloseEvent* event) final override; +public slots: + void onProfileLoaded(); + void onProfileLoadFailed(); + void onAutoLoginChanged(bool state); + private slots: - void onAutoLoginToggled(int state); + void onAutoLoginCheckboxChanged(int state); void onLoginUsernameSelected(const QString& name); void onPasswordEdited(); // Buttons to change page @@ -63,6 +68,7 @@ private slots: void onImportProfile(); private: + void reset(const QString& initialProfileName = QString()); void retranslateUi(); void showCapsIndicator(); void hideCapsIndicator(); @@ -71,7 +77,6 @@ private: private: Ui::LoginScreen* ui; QShortcut quitShortcut; - Profile* profile{nullptr}; }; #endif // LOGINSCREEN_H