GCC Code Coverage Report
Directory: src/ Exec Total Coverage
File: src/gui/windows/registerdialog.cpp Lines: 60 143 42.0 %
Date: 2021-03-17 Branches: 68 270 25.2 %

Line Branch Exec Source
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
24
#include "gui/windows/registerdialog.h"
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"
34
#include "gui/widgets/containerplacer.h"
35
#include "gui/widgets/createwidget.h"
36
#include "gui/widgets/label.h"
37
#include "gui/widgets/layoutcell.h"
38
#include "gui/widgets/passwordfield.h"
39
#include "gui/widgets/radiobutton.h"
40
41
#include "listeners/wrongdatanoticelistener.h"
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
52
1
RegisterDialog::RegisterDialog(LoginData &data) :
53
    // TRANSLATORS: register dialog name
54
1
    Window(_("Register"), Modal_false, nullptr, "register.xml"),
55
    ActionListener(),
56
    KeyListener(),
57
    mLoginData(&data),
58
1
    mUserField(new TextField(this, mLoginData->username, LoseFocusOnTab_true,
59

3
        nullptr, std::string(), false)),
60

1
    mPasswordField(new PasswordField(this, mLoginData->password)),
61

2
    mConfirmField(new PasswordField(this, std::string())),
62
    mEmailField(nullptr),
63
    // TRANSLATORS: register dialog. button.
64
1
    mRegisterButton(new Button(this, _("Register"), "register",
65

1
        BUTTON_SKIN, this)),
66
    // TRANSLATORS: register dialog. button.
67
1
    mCancelButton(new Button(this, _("Cancel"), "cancel",
68

1
        BUTTON_SKIN, this)),
69
    mMaleButton(nullptr),
70
    mFemaleButton(nullptr),
71




27
    mWrongDataNoticeListener(new WrongDataNoticeListener)
72
{
73
1
    setCloseButton(true);
74
75
    // TRANSLATORS: register dialog. label.
76

4
    Label *const userLabel = new Label(this, _("Name:"));
77
    // TRANSLATORS: register dialog. label.
78

4
    Label *const passwordLabel = new Label(this, _("Password:"));
79
    // TRANSLATORS: register dialog. label.
80

4
    Label *const confirmLabel = new Label(this, _("Confirm:"));
81
82
1
    ContainerPlacer placer(nullptr, nullptr);
83
1
    placer = getPlacer(0, 0);
84
1
    placer(0, 0, userLabel, 1, 1);
85
1
    placer(0, 1, passwordLabel, 1, 1);
86
1
    placer(0, 2, confirmLabel, 1, 1);
87
88
2
    placer(1, 0, mUserField, 3, 1).setPadding(2);
89
2
    placer(1, 1, mPasswordField, 3, 1).setPadding(2);
90
2
    placer(1, 2, mConfirmField, 3, 1).setPadding(2);
91
92
1
    int row = 3;
93
94

4
    if (features.getIntValue("forceAccountGender") == -1)
95
    {
96
        // TRANSLATORS: register dialog. button.
97


7
        mMaleButton = new RadioButton(this, _("Male"), "sex", true);
98
        // TRANSLATORS: register dialog. button.
99


7
        mFemaleButton = new RadioButton(this, _("Female"), "sex", false);
100
1
        placer(0, row, mMaleButton, 1, 1);
101
1
        placer(1, row, mFemaleButton, 1, 1);
102
103
        row++;
104
    }
105
106

1
    if (serverFeatures->haveEmailOnRegister())
107
    {
108
        // TRANSLATORS: register dialog. label.
109
        Label *const emailLabel = new Label(this, _("Email:"));
110
        mEmailField = new TextField(this,
111
            std::string(),
112
            LoseFocusOnTab_true,
113
            nullptr,
114
            std::string(),
115
            false);
116
        placer(0, row, emailLabel, 1, 1);
117
        placer(1, row, mEmailField, 3, 1).setPadding(2);
118
        mEmailField->addKeyListener(this);
119
        mEmailField->setActionEventId("register");
120
        mEmailField->addActionListener(this);
121
//        row++;
122
    }
123
124
1
    placer = getPlacer(0, 2);
125
1
    placer(1, 0, mRegisterButton, 1, 1);
126
1
    placer(2, 0, mCancelButton, 1, 1);
127
1
    reflowLayout(250, 0);
128
129
1
    mUserField->addKeyListener(this);
130
1
    mPasswordField->addKeyListener(this);
131
1
    mConfirmField->addKeyListener(this);
132
133
5
    mUserField->setActionEventId("register");
134
5
    mPasswordField->setActionEventId("register");
135
5
    mConfirmField->setActionEventId("register");
136
137
1
    mUserField->addActionListener(this);
138
1
    mPasswordField->addActionListener(this);
139
1
    mConfirmField->addActionListener(this);
140
141
1
    center();
142
1
}
143
144
1
void RegisterDialog::postInit()
145
{
146
1
    Window::postInit();
147
1
    setVisible(Visible_true);
148
1
    mUserField->requestFocus();
149
1
    mUserField->setCaretPosition(CAST_U32(
150
2
                                 mUserField->getText().length()));
151
152
2
    mRegisterButton->setEnabled(canSubmit());
153
1
}
154
155
5
RegisterDialog::~RegisterDialog()
156
{
157
2
    delete2(mWrongDataNoticeListener)
158
2
}
159
160
void RegisterDialog::action(const ActionEvent &event)
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
            {
242
                mWrongDataNoticeListener->setTarget(this->mUserField);
243
            }
244
            else if (error == 2)
245
            {
246
                // Reset password confirmation
247
                mPasswordField->setText("");
248
                mConfirmField->setText("");
249
                mWrongDataNoticeListener->setTarget(this->mPasswordField);
250
            }
251
252
            OkDialog *const dlg = CREATEWIDGETR(OkDialog,
253
                // TRANSLATORS: error message
254
                _("Error"), errorMsg, _("OK"),
255
                DialogType::ERROR,
256
                Modal_true,
257
                ShowCenter_true,
258
                nullptr,
259
                260);
260
            dlg->addActionListener(mWrongDataNoticeListener);
261
        }
262
        else
263
        {
264
            // No errors detected, register the new user.
265
            mRegisterButton->setEnabled(false);
266
            mLoginData->username = mUserField->getText();
267
            mLoginData->password = mPasswordField->getText();
268
            if (features.getIntValue("forceAccountGender") == -1)
269
            {
270
                if ((mFemaleButton != nullptr) && mFemaleButton->isSelected())
271
                    mLoginData->gender = Gender::FEMALE;
272
                else
273
                    mLoginData->gender = Gender::MALE;
274
            }
275
            else
276
            {
277
                mLoginData->gender = Being::intToGender(
278
                    CAST_U8(features.getIntValue("forceAccountGender")));
279
            }
280
281
            if (mEmailField != nullptr)
282
                mLoginData->email = mEmailField->getText();
283
            mLoginData->registerLogin = true;
284
285
            client->setState(State::REGISTER_ATTEMPT);
286
        }
287
    }
288
}
289
290
void RegisterDialog::keyPressed(KeyEvent &event)
291
{
292
    if (event.isConsumed())
293
    {
294
        mRegisterButton->setEnabled(canSubmit());
295
        return;
296
    }
297
    const InputActionT actionId = event.getActionId();
298
    if (actionId == InputAction::GUI_CANCEL)
299
    {
300
        action(ActionEvent(nullptr, mCancelButton->getActionEventId()));
301
    }
302
    else if (actionId == InputAction::GUI_SELECT ||
303
             actionId == InputAction::GUI_SELECT2)
304
    {
305
        action(ActionEvent(nullptr, mRegisterButton->getActionEventId()));
306
    }
307
    else
308
    {
309
        mRegisterButton->setEnabled(canSubmit());
310
    }
311
}
312
313
1
bool RegisterDialog::canSubmit() const
314
{
315
1
    return !mUserField->getText().empty() &&
316
           !mPasswordField->getText().empty() &&
317
           !mConfirmField->getText().empty() &&
318

1
           client->getState() == State::REGISTER &&
319
           ((mEmailField == nullptr) || !mEmailField->getText().empty());
320
}
321
322
void RegisterDialog::close()
323
{
324
    client->setState(State::LOGIN);
325
    Window::close();
326

3
}