GCC Code Coverage Report
Directory: src/ Exec Total Coverage
File: src/gui/widgets/tabs/setup_relations.cpp Lines: 66 128 51.6 %
Date: 2018-06-18 21:15:20 Branches: 61 148 41.2 %

Line Branch Exec Source
1
/*
2
 *  The ManaPlus Client
3
 *  Copyright (C) 2008-2009  The Mana World Development Team
4
 *  Copyright (C) 2009-2010  The Mana Developers
5
 *  Copyright (C) 2011-2018  The ManaPlus Developers
6
 *
7
 *  This file is part of The ManaPlus Client.
8
 *
9
 *  This program is free software; you can redistribute it and/or modify
10
 *  it under the terms of the GNU General Public License as published by
11
 *  the Free Software Foundation; either version 2 of the License, or
12
 *  any later version.
13
 *
14
 *  This program is distributed in the hope that it will be useful,
15
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
16
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17
 *  GNU General Public License for more details.
18
 *
19
 *  You should have received a copy of the GNU General Public License
20
 *  along with this program.  If not, see <http://www.gnu.org/licenses/>.
21
 */
22
23
#include "gui/widgets/tabs/setup_relations.h"
24
25
#include "actormanager.h"
26
27
#include "being/localplayer.h"
28
29
#include "gui/models/ignorechoiceslistmodel.h"
30
#include "gui/models/playertablemodel.h"
31
32
#include "gui/widgets/button.h"
33
#include "gui/widgets/checkbox.h"
34
#include "gui/widgets/containerplacer.h"
35
#include "gui/widgets/dropdown.h"
36
#include "gui/widgets/label.h"
37
#include "gui/widgets/layouthelper.h"
38
#include "gui/widgets/scrollarea.h"
39
#include "gui/widgets/guitable.h"
40
41
#include "utils/delete2.h"
42
43
#include "debug.h"
44
45
static const int COLUMNS_NR = 2;  // name plus listbox
46
static const int NAME_COLUMN = 0;
47
static const unsigned int NAME_COLUMN_WIDTH = 230;
48
static const unsigned int RELATION_CHOICE_COLUMN = 1;
49
static const unsigned int RELATION_CHOICE_COLUMN_WIDTH = 80;
50
51
6
static const std::string ACTION_DELETE("delete");
52
6
static const std::string ACTION_TABLE("table");
53
6
static const std::string ACTION_STRATEGY("strategy");
54
55
static const char *const table_titles[COLUMNS_NR] =
56
{
57
    // TRANSLATORS: relations table header
58
    N_("Name"),
59
    // TRANSLATORS: relations table header
60
    N_("Relation")
61
};
62
63
4
Setup_Relations::Setup_Relations(const Widget2 *const widget) :
64
    SetupTab(widget),
65
    PlayerRelationsListener(),
66

4
    mPlayerTableTitleModel(new StaticTableModel(1, COLUMNS_NR)),
67

4
    mPlayerTableModel(new PlayerTableModel(this)),
68

4
    mPlayerTable(new GuiTable(this, mPlayerTableModel, Opaque_true)),
69

4
    mPlayerTitleTable(new GuiTable(this, mPlayerTableTitleModel, Opaque_true)),
70
    mPlayerScrollArea(new ScrollArea(this,
71

8
        mPlayerTable, Opaque_true, std::string())),
72
    // TRANSLATORS: relation dialog button
73
4
    mDefaultTrading(new CheckBox(this, _("Allow trading"),
74
4
        (playerRelations.getDefault() & PlayerRelation::TRADE) != 0u,
75

8
        nullptr, std::string())),
76
    // TRANSLATORS: relation dialog button
77
4
    mDefaultWhisper(new CheckBox(this, _("Allow whispers"),
78
4
        (playerRelations.getDefault() & PlayerRelation::WHISPER) != 0u,
79

8
        nullptr, std::string())),
80
    // TRANSLATORS: relation dialog button
81
4
    mDeleteButton(new Button(this, _("Delete"), ACTION_DELETE,
82

4
        BUTTON_SKIN, this)),
83
8
    mIgnoreActionChoicesModel(new IgnoreChoicesListModel),
84
    mIgnoreActionChoicesBox(new DropDown(widget, mIgnoreActionChoicesModel,
85


92
        false, Modal_false, nullptr, std::string()))
86
{
87
    // TRANSLATORS: relation dialog name
88
20
    setName(_("Relations"));
89
90
8
    mPlayerTable->setOpaque(Opaque_false);
91
92
4
    mPlayerTableTitleModel->fixColumnWidth(NAME_COLUMN, NAME_COLUMN_WIDTH);
93
4
    mPlayerTableTitleModel->fixColumnWidth(RELATION_CHOICE_COLUMN,
94
                                           RELATION_CHOICE_COLUMN_WIDTH);
95
12
    mPlayerTitleTable->setBackgroundColor(getThemeColor(
96
        ThemeColorId::TABLE_BACKGROUND, 255U));
97
8
    mPlayerTitleTable->setSelectableGui(false);
98
99
12
    for (int i = 0; i < COLUMNS_NR; i++)
100
    {
101

40
        mPlayerTableTitleModel->set(0, i, new Label(
102

16
            this, gettext(table_titles[i])));
103
    }
104
105
8
    mPlayerTitleTable->setLinewiseSelection(true);
106
107
4
    mPlayerScrollArea->setHorizontalScrollPolicy(ScrollArea::SHOW_NEVER);
108
8
    mPlayerTable->setActionEventId(ACTION_TABLE);
109
8
    mPlayerTable->setLinewiseSelection(true);
110
4
    mPlayerTable->addActionListener(this);
111
112
    // TRANSLATORS: relation dialog label
113

16
    Label *const ignore_action_label = new Label(this, _("When ignoring:"));
114
115
8
    mIgnoreActionChoicesBox->setActionEventId(ACTION_STRATEGY);
116
4
    mIgnoreActionChoicesBox->addActionListener(this);
117
118
4
    int ignore_strategy_index = 0;  // safe default
119
120
4
    if (playerRelations.getPlayerIgnoreStrategy() != nullptr)
121
    {
122
        ignore_strategy_index = playerRelations.getPlayerIgnoreStrategyIndex(
123
            playerRelations.getPlayerIgnoreStrategy()->mShortName);
124
        if (ignore_strategy_index < 0)
125
            ignore_strategy_index = 0;
126
    }
127
4
    mIgnoreActionChoicesBox->setSelected(ignore_strategy_index);
128
4
    mIgnoreActionChoicesBox->adjustHeight();
129
130
4
    reset();
131
132
    // Do the layout
133
8
    LayoutHelper h(this);
134
4
    ContainerPlacer place = h.getPlacer(0, 0);
135
136
4
    place(0, 0, mPlayerTitleTable, 6, 1);
137
8
    place(0, 1, mPlayerScrollArea, 6, 4).setPadding(2);
138
4
    place(0, 5, mDeleteButton, 1, 1);
139
4
    place(3, 5, ignore_action_label, 1, 1);
140

8
    place(4, 5, mIgnoreActionChoicesBox, 2, 1).setPadding(2);
141
4
    place(3, 6, mDefaultTrading, 3, 1);
142
4
    place(3, 7, mDefaultWhisper, 3, 1);
143
144
8
    playerRelations.addListener(this);
145
146
8
    setDimension(Rect(0, 0, 500, 350));
147
4
}
148
149
16
Setup_Relations::~Setup_Relations()
150
{
151
8
    playerRelations.removeListener(this);
152
4
    delete2(mIgnoreActionChoicesModel);
153
8
}
154
155
156
4
void Setup_Relations::reset()
157
{
158
    // We now have to search through the list of ignore choices to find the
159
    // current selection. We could use an index into the table of config
160
    // options in playerRelations instead of strategies to sidestep this.
161
4
    int selection = 0;
162
24
    for (size_t i = 0, sz = playerRelations.getPlayerIgnoreStrategies()
163
8
         ->size(); i < sz; ++ i)
164
    {
165
60
        if ((*playerRelations.getPlayerIgnoreStrategies())[i] ==
166
20
            playerRelations.getPlayerIgnoreStrategy())
167
        {
168
            selection = CAST_S32(i);
169
            break;
170
        }
171
    }
172
4
    mIgnoreActionChoicesBox->setSelected(selection);
173
4
}
174
175
void Setup_Relations::apply()
176
{
177
    playerRelations.store();
178
179
    const unsigned int old_default_relations = playerRelations.getDefault() &
180
        ~(PlayerRelation::TRADE | PlayerRelation::WHISPER);
181
    playerRelations.setDefault(old_default_relations
182
        | (mDefaultTrading->isSelected() ? PlayerRelation::TRADE : 0)
183
        | (mDefaultWhisper->isSelected() ? PlayerRelation::WHISPER : 0));
184
185
    if (actorManager != nullptr)
186
        actorManager->updatePlayerNames();
187
188
    if (localPlayer != nullptr)
189
        localPlayer->setCheckNameSetting(true);
190
}
191
192
void Setup_Relations::cancel()
193
{
194
}
195
196
void Setup_Relations::action(const ActionEvent &event)
197
{
198
    const std::string &eventId = event.getId();
199
    if (eventId == ACTION_TABLE)
200
    {
201
        // temporarily eliminate ourselves: we are fully aware of this change,
202
        // so there is no need for asynchronous updates.  (In fact, thouse
203
        // might destroy the widet that triggered them, which would be rather
204
        // embarrassing.)
205
        playerRelations.removeListener(this);
206
207
        const int row = mPlayerTable->getSelectedRow();
208
        if (row >= 0)
209
            mPlayerTableModel->updateModelInRow(row);
210
211
        playerRelations.addListener(this);
212
    }
213
    else if (eventId == ACTION_DELETE)
214
    {
215
        const int player_index = mPlayerTable->getSelectedRow();
216
217
        if (player_index < 0)
218
            return;
219
220
        playerRelations.removePlayer(mPlayerTableModel->getPlayerAt(
221
            player_index));
222
    }
223
    else if (eventId == ACTION_STRATEGY)
224
    {
225
        const int sel = mIgnoreActionChoicesBox->getSelected();
226
        if (sel < 0)
227
            return;
228
        PlayerIgnoreStrategy *const s =
229
            (*playerRelations.getPlayerIgnoreStrategies())[sel];
230
231
        playerRelations.setPlayerIgnoreStrategy(s);
232
    }
233
}
234
235
void Setup_Relations::updatedPlayer(const std::string &name A_UNUSED)
236
{
237
    mPlayerTableModel->playerRelationsUpdated();
238
    mDefaultTrading->setSelected(
239
            (playerRelations.getDefault() & PlayerRelation::TRADE) != 0u);
240
    mDefaultWhisper->setSelected(
241
            (playerRelations.getDefault() & PlayerRelation::WHISPER) != 0u);
242
    if (localPlayer != nullptr)
243
        localPlayer->updateName();
244
}
245
246
void Setup_Relations::updateAll()
247
{
248
    PlayerTableModel *const model = new PlayerTableModel(this);
249
    mPlayerTable->setModel(model);
250
    delete mPlayerTableModel;
251
    mPlayerTableModel = model;
252
    int ignore_strategy_index = 0;  // safe default
253
254
    if (playerRelations.getPlayerIgnoreStrategy() != nullptr)
255
    {
256
        ignore_strategy_index = playerRelations.getPlayerIgnoreStrategyIndex(
257
                playerRelations.getPlayerIgnoreStrategy()->mShortName);
258
        if (ignore_strategy_index < 0)
259
            ignore_strategy_index = 0;
260
    }
261
    mIgnoreActionChoicesBox->setSelected(ignore_strategy_index);
262
    mIgnoreActionChoicesBox->adjustHeight();
263
    reset();
264
}
265
void Setup_Relations::externalUpdated()
266
{
267
    mDefaultTrading->setSelected(
268
        (playerRelations.getDefault() & PlayerRelation::TRADE) != 0u);
269
    mDefaultWhisper->setSelected(
270
        (playerRelations.getDefault() & PlayerRelation::WHISPER) != 0u);
271

6
}