GCC Code Coverage Report
Directory: src/ Exec Total Coverage
File: src/gui/widgets/tabs/setup_relations.cpp Lines: 63 125 50.4 %
Date: 2017-11-29 Branches: 65 156 41.7 %

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-2017  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)),
69

4
    mPlayerTitleTable(new GuiTable(this, mPlayerTableTitleModel)),
70

4
    mPlayerScrollArea(new ScrollArea(this, mPlayerTable)),
71
    // TRANSLATORS: relation dialog button
72
4
    mDefaultTrading(new CheckBox(this, _("Allow trading"),
73

8
        (playerRelations.getDefault() & PlayerRelation::TRADE) != 0u)),
74
    // TRANSLATORS: relation dialog button
75
4
    mDefaultWhisper(new CheckBox(this, _("Allow whispers"),
76

8
       (playerRelations.getDefault() & PlayerRelation::WHISPER) != 0u)),
77
    // TRANSLATORS: relation dialog button
78

8
    mDeleteButton(new Button(this, _("Delete"), ACTION_DELETE, this)),
79
8
    mIgnoreActionChoicesModel(new IgnoreChoicesListModel),
80




136
    mIgnoreActionChoicesBox(new DropDown(widget, mIgnoreActionChoicesModel))
81
{
82
    // TRANSLATORS: relation dialog name
83
20
    setName(_("Relations"));
84
85
8
    mPlayerTable->setOpaque(Opaque_false);
86
87
4
    mPlayerTableTitleModel->fixColumnWidth(NAME_COLUMN, NAME_COLUMN_WIDTH);
88
4
    mPlayerTableTitleModel->fixColumnWidth(RELATION_CHOICE_COLUMN,
89
                                           RELATION_CHOICE_COLUMN_WIDTH);
90
12
    mPlayerTitleTable->setBackgroundColor(getThemeColor(
91
        ThemeColorId::TABLE_BACKGROUND));
92
8
    mPlayerTitleTable->setSelectableGui(false);
93
94
12
    for (int i = 0; i < COLUMNS_NR; i++)
95
    {
96

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

16
            this, gettext(table_titles[i])));
98
    }
99
100
8
    mPlayerTitleTable->setLinewiseSelection(true);
101
102
4
    mPlayerScrollArea->setHorizontalScrollPolicy(ScrollArea::SHOW_NEVER);
103
8
    mPlayerTable->setActionEventId(ACTION_TABLE);
104
8
    mPlayerTable->setLinewiseSelection(true);
105
4
    mPlayerTable->addActionListener(this);
106
107
    // TRANSLATORS: relation dialog label
108

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

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

6
}