GCC Code Coverage Report
Directory: src/ Exec Total Coverage
File: src/gui/windows/quitdialog.cpp Lines: 44 105 41.9 %
Date: 2021-03-17 Branches: 43 155 27.7 %

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/quitdialog.h"
25
26
#include "client.h"
27
#include "configuration.h"
28
#include "soundmanager.h"
29
30
#include "const/sound.h"
31
32
#include "gui/dialogsmanager.h"
33
#include "gui/viewport.h"
34
35
#include "gui/widgets/containerplacer.h"
36
#include "gui/widgets/button.h"
37
#include "gui/widgets/radiobutton.h"
38
39
#include "net/charserverhandler.h"
40
#include "net/gamehandler.h"
41
42
#include "resources/map/map.h"
43
44
#include "utils/delete2.h"
45
#include "utils/gettext.h"
46
#include "utils/process.h"
47
48
#include "debug.h"
49
50
1
QuitDialog::QuitDialog(QuitDialog **const pointerToMe) :
51
    // TRANSLATORS: quit dialog name
52
1
    Window(_("Quit"), Modal_true, nullptr, "quit.xml"),
53
    ActionListener(),
54
    KeyListener(),
55
    mOptions(),
56
    // TRANSLATORS: quit dialog button
57

2
    mLogoutQuit(new RadioButton(this, _("Quit"), "quitdialog", false)),
58
    // TRANSLATORS: quit dialog button
59

2
    mForceQuit(new RadioButton(this, _("Quit"), "quitdialog", false)),
60
    mSwitchAccountServer(new RadioButton(this,
61
        // TRANSLATORS: quit dialog button
62

2
        _("Switch server"), "quitdialog", false)),
63
    mSwitchCharacter(new RadioButton(this,
64
        // TRANSLATORS: quit dialog button
65

2
        _("Switch character"), "quitdialog", false)),
66
    mRate(nullptr),
67
    // TRANSLATORS: quit dialog button
68

2
    mOkButton(new Button(this, _("OK"), "ok", BUTTON_SKIN, this)),
69
    // TRANSLATORS: quit dialog button
70

2
    mCancelButton(new Button(this, _("Cancel"), "cancel", BUTTON_SKIN, this)),
71
    mMyPointer(pointerToMe),
72







52
    mNeedForceQuit(false)
73
{
74
1
    addKeyListener(this);
75
76
1
    ContainerPlacer placer = getPlacer(0, 0);
77
2
    const StateT state = client->getState();
78
1
    mNeedForceQuit = (state == State::CHOOSE_SERVER
79
1
        || state == State::CONNECT_SERVER || state == State::LOGIN
80
        || state == State::PRE_LOGIN || state == State::LOGIN_ATTEMPT
81

1
        || state == State::UPDATE || state == State::LOAD_DATA);
82
83
    // All states, when we're not logged in to someone.
84
1
    if (mNeedForceQuit)
85
    {
86
1
        placeOption(placer, mForceQuit);
87
    }
88
    else
89
    {
90
        // Only added if we are connected to an accountserver or gameserver
91
        placeOption(placer, mLogoutQuit);
92
        placeOption(placer, mSwitchAccountServer);
93
94
        // Only added if we are connected to a gameserver
95
        if (state == State::GAME)
96
            placeOption(placer, mSwitchCharacter);
97
    }
98
99
/*
100
#ifdef ANDROID
101
    if (config.getBoolValue("rated") == false
102
        && config.getIntValue("gamecount") > 3)
103
    {
104
        // TRANSLATORS: rate button
105
        mRate = new RadioButton(this, _("Rate in google play"), "quitdialog",
106
            false);
107
        placeOption(placer, mRate);
108
        mOptions[mOptions.size() - 1]->setSelected(true);
109
    }
110
    else
111
#endif
112
*/
113
    {
114
1
        mOptions[0]->setSelected(true);
115
    }
116
117
1
    placer = getPlacer(0, 1);
118
1
    placer(1, 0, mOkButton, 1, 1);
119
1
    placer(2, 0, mCancelButton, 1, 1);
120
1
    reflowLayout(200, 0);
121
1
}
122
123
1
void QuitDialog::postInit()
124
{
125
1
    Window::postInit();
126
2
    setLocationRelativeTo(getParent());
127
1
    setVisible(Visible_true);
128
1
    soundManager.playGuiSound(SOUND_SHOW_WINDOW);
129
1
    requestModalFocus();
130
1
    mOkButton->requestFocus();
131
1
}
132
133
6
QuitDialog::~QuitDialog()
134
{
135
1
    if (mMyPointer != nullptr)
136
1
        *mMyPointer = nullptr;
137
1
    delete2(mForceQuit)
138
1
    delete2(mLogoutQuit)
139
1
    delete2(mSwitchAccountServer)
140
1
    delete2(mSwitchCharacter)
141
2
}
142
143
1
void QuitDialog::placeOption(ContainerPlacer &placer,
144
                             RadioButton *const option)
145
{
146
2
    placer(0, CAST_S32(mOptions.size()), option, 3, 1);
147
1
    mOptions.push_back(option);
148
1
}
149
150
void QuitDialog::action(const ActionEvent &event)
151
{
152
    soundManager.playGuiSound(SOUND_HIDE_WINDOW);
153
    if (event.getId() == "ok")
154
    {
155
        if (viewport != nullptr)
156
        {
157
            const Map *const map = viewport->getMap();
158
            if (map != nullptr)
159
                map->saveExtraLayer();
160
        }
161
162
        if (mForceQuit->isSelected())
163
        {
164
            client->setState(State::FORCE_QUIT);
165
        }
166
        else if (mLogoutQuit->isSelected())
167
        {
168
            DialogsManager::closeDialogs();
169
            client->setState(State::EXIT);
170
        }
171
        else if ((mRate != nullptr) && mRate->isSelected())
172
        {
173
            openBrowser("https://play.google.com/store/apps/details?"
174
                "id=org.evolonline.beta.manaplus");
175
            config.setValue("rated", true);
176
            if (mNeedForceQuit)
177
            {
178
                client->setState(State::FORCE_QUIT);
179
            }
180
            else
181
            {
182
                DialogsManager::closeDialogs();
183
                client->setState(State::EXIT);
184
            }
185
        }
186
        else if (gameHandler->isConnected()
187
                 && mSwitchAccountServer->isSelected())
188
        {
189
            DialogsManager::closeDialogs();
190
            client->setState(State::SWITCH_SERVER);
191
        }
192
        else if (mSwitchCharacter->isSelected())
193
        {
194
            if (client->getState() == State::GAME)
195
            {
196
                charServerHandler->switchCharacter();
197
                DialogsManager::closeDialogs();
198
                serverConfig.write();
199
            }
200
        }
201
    }
202
    scheduleDelete();
203
}
204
205
void QuitDialog::keyPressed(KeyEvent &event)
206
{
207
    const InputActionT actionId = event.getActionId();
208
    int dir = 0;
209
210
    PRAGMA45(GCC diagnostic push)
211
    PRAGMA45(GCC diagnostic ignored "-Wswitch-enum")
212
    switch (actionId)
213
    {
214
        case InputAction::GUI_SELECT:
215
        case InputAction::GUI_SELECT2:
216
            action(ActionEvent(nullptr, mOkButton->getActionEventId()));
217
            break;
218
        case InputAction::GUI_CANCEL:
219
            action(ActionEvent(nullptr, mCancelButton->getActionEventId()));
220
            break;
221
        case InputAction::GUI_UP:
222
            dir = -1;
223
            break;
224
        case InputAction::GUI_DOWN:
225
            dir = 1;
226
            break;
227
        default:
228
            break;
229
    }
230
    PRAGMA45(GCC diagnostic pop)
231
232
    if (dir != 0)
233
    {
234
        STD_VECTOR<RadioButton*>::const_iterator it = mOptions.begin();
235
        const STD_VECTOR<RadioButton*>::const_iterator
236
            it_end = mOptions.end();
237
238
        for (; it < it_end; ++it)
239
        {
240
            if ((*it)->isSelected())
241
                break;
242
        }
243
244
        if (it == mOptions.end())
245
        {
246
            if (mOptions[0] != nullptr)
247
                mOptions[0]->setSelected(true);
248
            return;
249
        }
250
        else if (it == mOptions.begin() && dir < 0)
251
        {
252
            it = mOptions.end();
253
        }
254
255
        it += dir;
256
257
        if (it == mOptions.end())
258
            it = mOptions.begin();
259
260
        (*it)->setSelected(true);
261
    }
262

3
}