ManaPlus
registerdialog.cpp
Go to the documentation of this file.
1 /*
2  * The ManaPlus Client
3  * Copyright (C) 2004-2009 The Mana World Development Team
4  * Copyright (C) 2009-2010 The Mana Developers
5  * Copyright (C) 2011-2019 The ManaPlus Developers
6  * Copyright (C) 2019-2021 Andrei Karas
7  *
8  * This file is part of The ManaPlus Client.
9  *
10  * This program is free software; you can redistribute it and/or modify
11  * it under the terms of the GNU General Public License as published by
12  * the Free Software Foundation; either version 2 of the License, or
13  * any later version.
14  *
15  * This program is distributed in the hope that it will be useful,
16  * but WITHOUT ANY WARRANTY; without even the implied warranty of
17  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18  * GNU General Public License for more details.
19  *
20  * You should have received a copy of the GNU General Public License
21  * along with this program. If not, see <http://www.gnu.org/licenses/>.
22  */
23 
25 
26 #include "client.h"
27 #include "configuration.h"
28 
29 #include "being/being.h"
30 
31 #include "gui/windows/okdialog.h"
32 
33 #include "gui/widgets/button.h"
36 #include "gui/widgets/label.h"
37 #include "gui/widgets/layoutcell.h"
40 
42 
43 #include "net/logindata.h"
44 #include "net/loginhandler.h"
45 #include "net/serverfeatures.h"
46 
47 #include "utils/delete2.h"
48 #include "utils/gettext.h"
49 
50 #include "debug.h"
51 
53  // TRANSLATORS: register dialog name
54  Window(_("Register"), Modal_false, nullptr, "register.xml"),
56  KeyListener(),
57  mLoginData(&data),
58  mUserField(new TextField(this, mLoginData->username, LoseFocusOnTab_true,
59  nullptr, std::string(), false)),
60  mPasswordField(new PasswordField(this, mLoginData->password)),
61  mConfirmField(new PasswordField(this, std::string())),
62  mEmailField(nullptr),
63  // TRANSLATORS: register dialog. button.
64  mRegisterButton(new Button(this, _("Register"), "register",
65  BUTTON_SKIN, this)),
66  // TRANSLATORS: register dialog. button.
67  mCancelButton(new Button(this, _("Cancel"), "cancel",
68  BUTTON_SKIN, this)),
69  mMaleButton(nullptr),
70  mFemaleButton(nullptr),
71  mWrongDataNoticeListener(new WrongDataNoticeListener)
72 {
73  setCloseButton(true);
74 
75  // TRANSLATORS: register dialog. label.
76  Label *const userLabel = new Label(this, _("Name:"));
77  // TRANSLATORS: register dialog. label.
78  Label *const passwordLabel = new Label(this, _("Password:"));
79  // TRANSLATORS: register dialog. label.
80  Label *const confirmLabel = new Label(this, _("Confirm:"));
81 
82  ContainerPlacer placer(nullptr, nullptr);
83  placer = getPlacer(0, 0);
84  placer(0, 0, userLabel, 1, 1);
85  placer(0, 1, passwordLabel, 1, 1);
86  placer(0, 2, confirmLabel, 1, 1);
87 
88  placer(1, 0, mUserField, 3, 1).setPadding(2);
89  placer(1, 1, mPasswordField, 3, 1).setPadding(2);
90  placer(1, 2, mConfirmField, 3, 1).setPadding(2);
91 
92  int row = 3;
93 
94  if (features.getIntValue("forceAccountGender") == -1)
95  {
96  // TRANSLATORS: register dialog. button.
97  mMaleButton = new RadioButton(this, _("Male"), "sex", true);
98  // TRANSLATORS: register dialog. button.
99  mFemaleButton = new RadioButton(this, _("Female"), "sex", false);
100  placer(0, row, mMaleButton, 1, 1);
101  placer(1, row, mFemaleButton, 1, 1);
102 
103  row++;
104  }
105 
107  {
108  // TRANSLATORS: register dialog. label.
109  Label *const emailLabel = new Label(this, _("Email:"));
110  mEmailField = new TextField(this,
111  std::string(),
113  nullptr,
114  std::string(),
115  false);
116  placer(0, row, emailLabel, 1, 1);
117  placer(1, row, mEmailField, 3, 1).setPadding(2);
119  mEmailField->setActionEventId("register");
121 // row++;
122  }
123 
124  placer = getPlacer(0, 2);
125  placer(1, 0, mRegisterButton, 1, 1);
126  placer(2, 0, mCancelButton, 1, 1);
127  reflowLayout(250, 0);
128 
129  mUserField->addKeyListener(this);
132 
133  mUserField->setActionEventId("register");
134  mPasswordField->setActionEventId("register");
135  mConfirmField->setActionEventId("register");
136 
140 
141  center();
142 }
143 
145 {
150  mUserField->getText().length()));
151 
153 }
154 
156 {
158 }
159 
161 {
162  const std::string &eventId = event.getId();
163  if (eventId == "cancel")
164  {
165  close();
166  }
167  else if (eventId == "register" && canSubmit())
168  {
169  const std::string &user = mUserField->getText();
170  logger->log("RegisterDialog::register Username is %s", user.c_str());
171 
172  std::string errorMsg;
173  int error = 0;
174 
175  const unsigned int minUser = loginHandler->getMinUserNameLength();
176  const unsigned int maxUser = loginHandler->getMaxUserNameLength();
177  const unsigned int minPass = loginHandler->getMinPasswordLength();
178  const unsigned int maxPass = loginHandler->getMaxPasswordLength();
179 
180  if (user.length() < minUser)
181  {
182  // Name too short
183  errorMsg = strprintf
184  // TRANSLATORS: error message
185  (_("The username needs to be at least %u characters long."),
186  minUser);
187  error = 1;
188  }
189  else if (user.length() > maxUser - 1)
190  {
191  // Name too long
192  errorMsg = strprintf
193  // TRANSLATORS: error message
194  (_("The username needs to be less than %u characters long."),
195  maxUser);
196  error = 1;
197  }
198  else if (mPasswordField->getText().length() < minPass)
199  {
200  // Pass too short
201  errorMsg = strprintf
202  // TRANSLATORS: error message
203  (_("The password needs to be at least %u characters long."),
204  minPass);
205  error = 2;
206  }
207  else if (mPasswordField->getText().length() > maxPass)
208  {
209  // Pass too long
210  errorMsg = strprintf
211  // TRANSLATORS: error message
212  (_("The password needs to be less than %u characters long."),
213  maxPass);
214  error = 2;
215  }
216  else if (mPasswordField->getText() != mConfirmField->getText())
217  {
218  // Password does not match with the confirmation one
219  // TRANSLATORS: error message
220  errorMsg = _("Passwords do not match.");
221  error = 2;
222  }
223  else if ((mEmailField != nullptr) &&
224  mEmailField->getText().find('@') == std::string::npos)
225  {
226  // TRANSLATORS: error message
227  errorMsg = _("Incorrect email.");
228  error = 1;
229  }
230  else if (mEmailField != nullptr &&
231  mEmailField->getText().size() > 40)
232  {
233  // TRANSLATORS: error message
234  errorMsg = _("Email too long.");
235  error = 1;
236  }
237 
238  if (error > 0)
239  {
240  if (error == 1)
241  {
243  }
244  else if (error == 2)
245  {
246  // Reset password confirmation
247  mPasswordField->setText("");
248  mConfirmField->setText("");
250  }
251 
252  OkDialog *const dlg = CREATEWIDGETR(OkDialog,
253  // TRANSLATORS: error message
254  _("Error"), errorMsg, _("OK"),
256  Modal_true,
258  nullptr,
259  260);
261  }
262  else
263  {
264  // No errors detected, register the new user.
265  mRegisterButton->setEnabled(false);
268  if (features.getIntValue("forceAccountGender") == -1)
269  {
270  if ((mFemaleButton != nullptr) && mFemaleButton->isSelected())
272  else
274  }
275  else
276  {
278  CAST_U8(features.getIntValue("forceAccountGender")));
279  }
280 
281  if (mEmailField != nullptr)
283  mLoginData->registerLogin = true;
284 
286  }
287  }
288 }
289 
291 {
292  if (event.isConsumed())
293  {
295  return;
296  }
297  const InputActionT actionId = event.getActionId();
298  if (actionId == InputAction::GUI_CANCEL)
299  {
301  }
302  else if (actionId == InputAction::GUI_SELECT ||
303  actionId == InputAction::GUI_SELECT2)
304  {
306  }
307  else
308  {
310  }
311 }
312 
314 {
315  return !mUserField->getText().empty() &&
316  !mPasswordField->getText().empty() &&
317  !mConfirmField->getText().empty() &&
319  ((mEmailField == nullptr) || !mEmailField->getText().empty());
320 }
321 
323 {
325  Window::close();
326 }
const std::string BUTTON_SKIN
Definition: button.h:89
#define CAST_U32
Definition: cast.h:31
#define CAST_U8
Definition: cast.h:27
static GenderT intToGender(const uint8_t sex) A_CONST
Definition: being.h:941
Definition: button.h:102
void setState(const StateT state)
Definition: client.h:66
StateT getState() const
Definition: client.h:69
int getIntValue(const std::string &key) const
bool isConsumed() const
Definition: label.h:91
void log(const char *const log_text,...)
Definition: logger.cpp:269
GenderT gender
Definition: logindata.h:71
std::string email
Definition: logindata.h:67
std::string username
Definition: logindata.h:59
std::string password
Definition: logindata.h:60
bool registerLogin
Definition: logindata.h:75
virtual unsigned int getMinUserNameLength() const
Definition: loginhandler.h:59
virtual unsigned int getMaxPasswordLength() const
Definition: loginhandler.h:68
virtual unsigned int getMaxUserNameLength() const
Definition: loginhandler.h:62
virtual unsigned int getMinPasswordLength() const
Definition: loginhandler.h:65
virtual bool haveEmailOnRegister() const =0
bool isSelected() const
Definition: radiobutton.h:142
TextField * mPasswordField
TextField * mUserField
RadioButton * mMaleButton
bool canSubmit() const
WrongDataNoticeListener * mWrongDataNoticeListener
TextField * mConfirmField
LoginData * mLoginData
Button * mRegisterButton
void keyPressed(KeyEvent &event)
TextField * mEmailField
RegisterDialog(LoginData &loginData)
void action(const ActionEvent &event)
RadioButton * mFemaleButton
Button * mCancelButton
const std::string & getText() const
Definition: textfield.h:224
void setText(const std::string &text)
Definition: textfield.cpp:803
void setCaretPosition(unsigned int position)
Definition: textfield.cpp:752
void setEnabled(const bool enabled)
Definition: widget.h:352
void setActionEventId(const std::string &actionEventId)
Definition: widget.h:596
void addKeyListener(KeyListener *const keyListener)
Definition: widget.cpp:272
virtual void requestFocus()
Definition: widget.cpp:204
void addActionListener(ActionListener *const actionListener)
Definition: widget.cpp:252
const std::string & getActionEventId() const
Definition: widget.h:605
Definition: window.h:102
void center()
Definition: window.cpp:1417
ContainerPlacer getPlacer(const int x, const int y)
Definition: window.cpp:1391
virtual void close()
Definition: window.cpp:902
virtual void setVisible(Visible visible)
Definition: window.cpp:778
void reflowLayout(int w, int h)
Definition: window.cpp:1396
void postInit()
Definition: window.cpp:249
void setCloseButton(const bool flag)
Definition: window.cpp:749
void setTarget(TextField *const textField)
Configuration features
#define CREATEWIDGETR(type,...)
Definition: createwidget.h:36
#define new
Definition: debug_new.h:147
#define delete2(var)
Definition: delete2.h:25
Client * client
Definition: client.cpp:118
#define _(s)
Definition: gettext.h:35
InputAction ::T InputActionT
Definition: inputaction.h:717
#define nullptr
Definition: localconsts.h:45
Logger * logger
Definition: logger.cpp:89
Net::LoginHandler * loginHandler
Definition: net.cpp:90
const bool LoseFocusOnTab_true
uint32_t data
const bool Modal_false
Definition: modal.h:30
const bool Modal_true
Definition: modal.h:30
bool error(InputEvent &event) __attribute__((noreturn))
Definition: actions.cpp:82
@ MALE
Definition: gender.h:31
@ FEMALE
Definition: gender.h:32
@ REGISTER_ATTEMPT
Definition: state.h:55
@ LOGIN
Definition: state.h:40
@ REGISTER
Definition: state.h:54
Net::ServerFeatures * serverFeatures
Definition: net.cpp:101
const bool ShowCenter_true
Definition: showcenter.h:30
std::string strprintf(const char *const format,...)
const bool Visible_true
Definition: visible.h:30