qTox  Version: nightly | Commit: bc751c8e1cac455f9690654fcfe0f560d2d7dfdd
loginscreen.cpp
Go to the documentation of this file.
1 /*
2  Copyright © 2015-2019 by The qTox Project Contributors
3 
4  This file is part of qTox, a Qt-based graphical interface for Tox.
5 
6  qTox is libre software: you can redistribute it and/or modify
7  it under the terms of the GNU General Public License as published by
8  the Free Software Foundation, either version 3 of the License, or
9  (at your option) any later version.
10 
11  qTox is distributed in the hope that it will be useful,
12  but WITHOUT ANY WARRANTY; without even the implied warranty of
13  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14  GNU General Public License for more details.
15 
16  You should have received a copy of the GNU General Public License
17  along with qTox. If not, see <http://www.gnu.org/licenses/>.
18 */
19 
20 
21 #include "loginscreen.h"
22 #include "ui_loginscreen.h"
27 #include "src/widget/style.h"
29 #include "src/widget/translator.h"
30 #include <QDebug>
31 #include <QDialog>
32 #include <QMessageBox>
33 #include <QToolButton>
34 
35 LoginScreen::LoginScreen(const QString& initialProfileName, QWidget* parent)
36  : QDialog(parent)
37  , ui(new Ui::LoginScreen)
38  , quitShortcut{QKeySequence(Qt::CTRL + Qt::Key_Q), this}
39 {
40  ui->setupUi(this);
41 
42  // permanently disables maximize button https://github.com/qTox/qTox/issues/1973
43  this->setWindowFlags(windowFlags() & ~Qt::WindowMaximizeButtonHint);
44  this->setFixedSize(this->size());
45 
46  connect(&quitShortcut, &QShortcut::activated, this, &LoginScreen::close);
47  connect(ui->newProfilePgbtn, &QPushButton::clicked, this, &LoginScreen::onNewProfilePageClicked);
48  connect(ui->loginPgbtn, &QPushButton::clicked, this, &LoginScreen::onLoginPageClicked);
49  connect(ui->createAccountButton, &QPushButton::clicked, this, &LoginScreen::onCreateNewProfile);
50  connect(ui->newUsername, &QLineEdit::returnPressed, this, &LoginScreen::onCreateNewProfile);
51  connect(ui->newPass, &QLineEdit::returnPressed, this, &LoginScreen::onCreateNewProfile);
52  connect(ui->newPassConfirm, &QLineEdit::returnPressed, this, &LoginScreen::onCreateNewProfile);
53  connect(ui->loginButton, &QPushButton::clicked, this, &LoginScreen::onLogin);
54  connect(ui->loginUsernames, &QComboBox::currentTextChanged, this,
56  connect(ui->loginPassword, &QLineEdit::returnPressed, this, &LoginScreen::onLogin);
57  connect(ui->newPass, &QLineEdit::textChanged, this, &LoginScreen::onPasswordEdited);
58  connect(ui->newPassConfirm, &QLineEdit::textChanged, this, &LoginScreen::onPasswordEdited);
59  connect(ui->autoLoginCB, &QCheckBox::stateChanged, this, &LoginScreen::onAutoLoginCheckboxChanged);
60  connect(ui->importButton, &QPushButton::clicked, this, &LoginScreen::onImportProfile);
61 
62  reset(initialProfileName);
63  this->setStyleSheet(Style::getStylesheet("loginScreen/loginScreen.css"));
64 
65  retranslateUi();
67 }
68 
70 {
72  delete ui;
73 }
74 
78 void LoginScreen::reset(const QString& initialProfileName)
79 {
80  ui->newUsername->clear();
81  ui->newPass->clear();
82  ui->newPassConfirm->clear();
83  ui->loginPassword->clear();
84  ui->loginUsernames->clear();
85 
86  QStringList allProfileNames = Profile::getAllProfileNames();
87 
88  if (allProfileNames.isEmpty()) {
89  ui->stackedWidget->setCurrentIndex(0);
90  ui->newUsername->setFocus();
91  } else {
92  for (const QString& profileName : allProfileNames) {
93  ui->loginUsernames->addItem(profileName);
94  }
95 
96  ui->loginUsernames->setCurrentText(initialProfileName);
97  ui->stackedWidget->setCurrentIndex(1);
98  ui->loginPassword->setFocus();
99  }
100 }
101 
103 {
104  done(QDialog::Accepted);
105 }
106 
108 {
109  QMessageBox::critical(this, tr("Couldn't load this profile"), tr("Wrong password."));
110  ui->loginPassword->setFocus();
111  ui->loginPassword->selectAll();
112 }
113 
115 {
116  ui->autoLoginCB->setChecked(state);
117 }
118 
119 bool LoginScreen::event(QEvent* event)
120 {
121  switch (event->type()) {
122 #ifdef Q_OS_MAC
123  case QEvent::WindowActivate:
124  case QEvent::WindowStateChange:
125  emit windowStateChanged(windowState());
126  break;
127 #endif
128  default:
129  break;
130  }
131 
132  return QWidget::event(event);
133 }
134 
136 {
137  ui->stackedWidget->setCurrentIndex(0);
138 }
139 
141 {
142  ui->stackedWidget->setCurrentIndex(1);
143 }
144 
146 {
147  QString name = ui->newUsername->text();
148  QString pass = ui->newPass->text();
149 
150  if (name.isEmpty()) {
151  QMessageBox::critical(this, tr("Couldn't create a new profile"),
152  tr("The username must not be empty."));
153  return;
154  }
155 
156  if (pass.size() != 0 && pass.size() < 6) {
157  QMessageBox::critical(this, tr("Couldn't create a new profile"),
158  tr("The password must be at least 6 characters long."));
159  return;
160  }
161 
162  if (ui->newPassConfirm->text() != pass) {
163  QMessageBox::critical(this, tr("Couldn't create a new profile"),
164  tr("The passwords you've entered are different.\nPlease make sure to "
165  "enter the same password twice."));
166  return;
167  }
168 
169  if (Profile::exists(name)) {
170  QMessageBox::critical(this, tr("Couldn't create a new profile"),
171  tr("A profile with this name already exists."));
172  return;
173  }
174 
175  emit createNewProfile(name, pass);
176 }
177 
178 void LoginScreen::onLoginUsernameSelected(const QString& name)
179 {
180  if (name.isEmpty())
181  return;
182 
183  ui->loginPassword->clear();
184  if (Profile::isEncrypted(name)) {
185  ui->loginPasswordLabel->show();
186  ui->loginPassword->show();
187  // there is no way to do autologin if profile is encrypted, and
188  // visible option confuses users into thinking that it is possible,
189  // thus hide it
190  ui->autoLoginCB->hide();
191  } else {
192  ui->loginPasswordLabel->hide();
193  ui->loginPassword->hide();
194  ui->autoLoginCB->show();
195  ui->autoLoginCB->setToolTip(
196  tr("Password protected profiles can't be automatically loaded."));
197  }
198 }
199 
201 {
202  QString name = ui->loginUsernames->currentText();
203  QString pass = ui->loginPassword->text();
204 
205  // name can be empty when there are no profiles
206  if (name.isEmpty()) {
207  QMessageBox::critical(this, tr("Couldn't load profile"),
208  tr("There is no selected profile.\n\n"
209  "You may want to create one."));
210  return;
211  }
212 
213  if (!ProfileLocker::isLockable(name)) {
214  QMessageBox::critical(this, tr("Couldn't load this profile"),
215  tr("This profile is already in use."));
216  return;
217  }
218 
219  emit loadProfile(name, pass);
220 }
221 
223 {
224  ui->passStrengthMeter->setValue(SetPasswordDialog::getPasswordStrength(ui->newPass->text()));
225 }
226 
228 {
229  auto cstate = static_cast<Qt::CheckState>(state);
230  emit autoLoginChanged(cstate == Qt::CheckState::Checked);
231 }
232 
234 {
235  ui->retranslateUi(this);
236 }
237 
239 {
240  ProfileImporter pi(this);
241  if (pi.importProfile()) {
242  reset();
243  }
244 }
profile.h
SetPasswordDialog::getPasswordStrength
static int getPasswordStrength(QString pass)
Definition: setpassworddialog.cpp:78
LoginScreen::onImportProfile
void onImportProfile()
Definition: loginscreen.cpp:238
style.h
LoginScreen::loadProfile
void loadProfile(QString name, const QString &pass)
LoginScreen
Definition: loginscreen.h:33
settings.h
LoginScreen::onPasswordEdited
void onPasswordEdited()
Definition: loginscreen.cpp:222
loginscreen.h
LoginScreen::ui
Ui::LoginScreen * ui
Definition: loginscreen.h:74
LoginScreen::event
bool event(QEvent *event) final
Definition: loginscreen.cpp:119
setpassworddialog.h
Translator::unregister
static void unregister(void *owner)
Unregisters all handlers of an owner.
Definition: translator.cpp:103
ProfileImporter::importProfile
bool importProfile(const QString &path)
Try to import Tox profile.
Definition: profileimporter.cpp:85
LoginScreen::autoLoginChanged
void autoLoginChanged(bool state)
ProfileImporter
This class provides the ability to import profile.
Definition: profileimporter.h:24
LoginScreen::onProfileLoaded
void onProfileLoaded()
Definition: loginscreen.cpp:102
LoginScreen::onCreateNewProfile
void onCreateNewProfile()
Definition: loginscreen.cpp:145
Profile::exists
static bool exists(QString name)
Definition: profile.cpp:804
Ui
Definition: filetransferwidget.h:30
LoginScreen::onNewProfilePageClicked
void onNewProfilePageClicked()
Definition: loginscreen.cpp:135
profileimporter.h
profilelocker.h
LoginScreen::onLoginPageClicked
void onLoginPageClicked()
Definition: loginscreen.cpp:140
LoginScreen::createNewProfile
void createNewProfile(QString name, const QString &pass)
Translator::registerHandler
static void registerHandler(const std::function< void()> &, void *owner)
Register a function to be called when the UI needs to be retranslated.
Definition: translator.cpp:93
LoginScreen::onProfileLoadFailed
void onProfileLoadFailed()
Definition: loginscreen.cpp:107
LoginScreen::onAutoLoginChanged
void onAutoLoginChanged(bool state)
Definition: loginscreen.cpp:114
LoginScreen::onLoginUsernameSelected
void onLoginUsernameSelected(const QString &name)
Definition: loginscreen.cpp:178
LoginScreen::onLogin
void onLogin()
Definition: loginscreen.cpp:200
LoginScreen::windowStateChanged
void windowStateChanged(Qt::WindowStates states)
Style::getStylesheet
static const QString getStylesheet(const QString &filename, const QFont &baseFont=QFont())
Definition: style.cpp:165
LoginScreen::onAutoLoginCheckboxChanged
void onAutoLoginCheckboxChanged(int state)
Definition: loginscreen.cpp:227
LoginScreen::retranslateUi
void retranslateUi()
Definition: loginscreen.cpp:233
LoginScreen::LoginScreen
LoginScreen(const QString &initialProfileName=QString(), QWidget *parent=nullptr)
Definition: loginscreen.cpp:35
Profile::getAllProfileNames
static const QStringList getAllProfileNames()
Scan for profile, automatically importing them if needed.
Definition: profile.cpp:414
Profile::isEncrypted
bool isEncrypted() const
Checks, if profile has a password.
Definition: profile.cpp:814
translator.h
ProfileLocker::isLockable
static bool isLockable(QString profile)
Checks if a profile is currently locked by another instance. If we own the lock, we consider it locka...
Definition: profilelocker.cpp:52
LoginScreen::reset
void reset(const QString &initialProfileName=QString())
Resets the UI, clears all fields.
Definition: loginscreen.cpp:78
LoginScreen::~LoginScreen
~LoginScreen()
Definition: loginscreen.cpp:69