GCC Code Coverage Report
Directory: src/ Exec Total Coverage
File: src/gui/widgets/selldialog.cpp Lines: 93 185 50.3 %
Date: 2017-11-29 Branches: 57 174 32.8 %

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-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/selldialog.h"
24
25
#include "const/resources/currency.h"
26
27
#include "enums/gui/layouttype.h"
28
29
#include "gui/windows/setupwindow.h"
30
31
#include "gui/models/shopitems.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/layout.h"
38
#include "gui/widgets/scrollarea.h"
39
#include "gui/widgets/shoplistbox.h"
40
#include "gui/widgets/slider.h"
41
42
#include "utils/delete2.h"
43
#include "utils/foreach.h"
44
#include "utils/gettext.h"
45
#include "utils/stringutils.h"
46
47
#include "resources/db/unitsdb.h"
48
49
#include "resources/item/shopitem.h"
50
51
#include "debug.h"
52
53
2
SellDialog::DialogList SellDialog::instances;
54
55
8
SellDialog::SellDialog(const IsSell isSell,
56
8
                       const Advanced advanced) :
57
    // TRANSLATORS: sell dialog name
58
8
    Window(_("Sell"), Modal_false, nullptr, "sell.xml"),
59
    ActionListener(),
60
    SelectionListener(),
61
    mSellButton(nullptr),
62
    mQuitButton(nullptr),
63
    mConfirmButton(nullptr),
64
    mAddMaxButton(nullptr),
65
    mIncreaseButton(nullptr),
66
    mDecreaseButton(nullptr),
67
    mShopItemList(nullptr),
68
    mScrollArea(nullptr),
69
    mMoneyLabel(nullptr),
70
    mQuantityLabel(nullptr),
71
    mSlider(nullptr),
72
    mShopItems(nullptr),
73
    mPlayerMoney(0),
74
    mMaxItems(0),
75
    mAmountItems(0),
76
    mIsSell(isSell),
77

72
    mAdvanced(advanced)
78
{
79
8
}
80
81
8
void SellDialog::postInit()
82
{
83
8
    Window::postInit();
84
40
    setWindowName("Sell");
85
8
    setResizable(true);
86
8
    setCloseButton(true);
87
8
    setStickyButtonLock(true);
88
8
    setMinWidth(260);
89
8
    setMinHeight(220);
90
8
    setDefaultSize(260, 230, ImagePosition::CENTER);
91
92
8
    if (setupWindow != nullptr)
93
        setupWindow->registerWindowForReset(this);
94
95
    // Create a ShopItems instance, that is aware of duplicate entries.
96
8
    mShopItems = new ShopItems(true,
97
8
        DEFAULT_CURRENCY);
98
99
8
    if (mAdvanced == Advanced_true)
100
2
        mShopItems->setMergeDuplicates(false);
101
102
8
    mShopItemList = CREATEWIDGETR(ShopListBox,
103
        this,
104
        mShopItems,
105
        mShopItems,
106
        ShopListBoxType::Unknown);
107
16
    mShopItemList->setProtectItems(true);
108
48
    mScrollArea = new ScrollArea(this, mShopItemList,
109

32
        fromBool(getOptionBool("showbackground"), Opaque),
110

16
        "sell_background.xml");
111
8
    mScrollArea->setHorizontalScrollPolicy(ScrollArea::SHOW_NEVER);
112
113

64
    mSellButton = new Button(this,
114
        // TRANSLATORS: sell dialog button
115
8
        mAdvanced == Advanced_true ? _("Add") : _("Sell"),
116
        "presell",
117

8
        this);
118
    // TRANSLATORS: sell dialog button
119


56
    mQuitButton = new Button(this, _("Quit"), "quit", this);
120
121
8
    initButtons();
122
123
16
    mSellButton->setEnabled(false);
124
125
16
    mShopItemList->setDistributeMousePressed(false);
126
8
    mShopItemList->setPriceCheck(false);
127
8
    mShopItemList->addSelectionListener(this);
128
40
    mShopItemList->setActionEventId("sell");
129
8
    mShopItemList->addActionListener(this);
130
131
8
    ContainerPlacer placer;
132
8
    placer = getPlacer(0, 0);
133
134
8
    if (mIsSell == IsSell_true)
135
    {
136
        // TRANSLATORS: sell dialog button
137


28
        mIncreaseButton = new Button(this, _("+"), "inc", this);
138
        // TRANSLATORS: sell dialog button
139


20
        mDecreaseButton = new Button(this, _("-"), "dec", this);
140
        // TRANSLATORS: sell dialog button
141


28
        mAddMaxButton = new Button(this, _("Max"), "max", this);
142
4
        mSlider = new Slider(this, 1.0, 1.0);
143
144
12
        mQuantityLabel = new Label(this, strprintf(
145

4
            "%d / %d", mAmountItems, mMaxItems));
146
8
        mQuantityLabel->setAlignment(Graphics::CENTER);
147
        // TRANSLATORS: sell dialog label
148
12
        mMoneyLabel = new Label(this, strprintf(_("Price: %s / Total: %s"),
149

4
            "", ""));
150
4
        if (mAdvanced == Advanced_true)
151
        {
152
            // TRANSLATORS: sell dialog button
153


14
            mConfirmButton = new Button(this, _("Sell"), "confirm", this);
154
2
            mConfirmButton->setEnabled(false);
155
        }
156
157
4
        mDecreaseButton->adjustSize();
158
8
        mDecreaseButton->setWidth(mIncreaseButton->getWidth());
159
8
        mIncreaseButton->setEnabled(false);
160
8
        mDecreaseButton->setEnabled(false);
161
8
        mSlider->setEnabled(false);
162
20
        mSlider->setActionEventId("slider");
163
4
        mSlider->addActionListener(this);
164
165
8
        placer(0, 0, mScrollArea, 8, 5).setPadding(3);
166
4
        placer(0, 5, mDecreaseButton);
167
4
        placer(1, 5, mSlider, 3);
168
4
        placer(4, 5, mIncreaseButton);
169
4
        placer(5, 5, mQuantityLabel, 2);
170
4
        placer(7, 5, mAddMaxButton);
171
4
        placer(0, 6, mMoneyLabel, 8);
172
4
        if (mAdvanced == Advanced_true)
173
        {
174
2
            placer(5, 7, mSellButton);
175
2
            placer(6, 7, mConfirmButton);
176
        }
177
        else
178
        {
179
2
            placer(6, 7, mSellButton);
180
        }
181
4
        placer(7, 7, mQuitButton);
182
    }
183
    else
184
    {
185
8
        placer(0, 0, mScrollArea, 8, 5).setPadding(3);
186
4
        placer(6, 5, mSellButton);
187
4
        placer(7, 5, mQuitButton);
188
    }
189
190
8
    Layout &layout = getLayout();
191
8
    layout.setRowHeight(0, LayoutType::SET);
192
193
8
    center();
194
8
    loadWindowState();
195
196
16
    instances.push_back(this);
197
8
    setVisible(Visible_true);
198
16
    enableVisibleSound(true);
199
8
}
200
201
32
SellDialog::~SellDialog()
202
{
203
8
    delete2(mShopItems);
204
8
    instances.remove(this);
205
8
}
206
207
void SellDialog::reset()
208
{
209
    mShopItems->clear();
210
    if (mSlider != nullptr)
211
        mSlider->setValue(0);
212
    mShopItemList->setSelected(-1);
213
    updateButtonsAndLabels();
214
}
215
216
void SellDialog::addItem(const Item *const item, const int price)
217
{
218
    if (item == nullptr)
219
        return;
220
221
    mShopItems->addItem2(item->getInvIndex(),
222
        item->getId(),
223
        item->getType(),
224
        item->getColor(),
225
        item->getQuantity(),
226
        price);
227
228
    mShopItemList->adjustSize();
229
}
230
231
ShopItem *SellDialog::addItem(const int id,
232
                              const ItemTypeT type,
233
                              const ItemColor color,
234
                              const int amount,
235
                              const int price)
236
{
237
    ShopItem *const item = mShopItems->addItem(id,
238
        type,
239
        color,
240
        amount,
241
        price);
242
    mShopItemList->adjustSize();
243
    return item;
244
}
245
246
247
void SellDialog::action(const ActionEvent &event)
248
{
249
    const std::string &eventId = event.getId();
250
251
    if (eventId == "quit")
252
    {
253
        close();
254
        return;
255
    }
256
257
    const int selectedItem = mShopItemList->getSelected();
258
259
    // The following actions require a valid item selection
260
    if (selectedItem == -1
261
        || selectedItem >= mShopItems->getNumberOfElements())
262
    {
263
        return;
264
    }
265
266
    if (eventId == "slider")
267
    {
268
        if (mSlider != nullptr)
269
        {
270
            mAmountItems = CAST_S32(mSlider->getValue());
271
            updateButtonsAndLabels();
272
        }
273
    }
274
    else if (eventId == "inc" &&
275
             mSlider != nullptr &&
276
             mAmountItems < mMaxItems)
277
    {
278
        mAmountItems++;
279
        mSlider->setValue(mAmountItems);
280
        updateButtonsAndLabels();
281
    }
282
    else if (eventId == "dec" &&
283
             mSlider != nullptr &&
284
             mAmountItems > 1)
285
    {
286
        mAmountItems--;
287
        mSlider->setValue(mAmountItems);
288
        updateButtonsAndLabels();
289
    }
290
    else if (eventId == "max" &&
291
             mSlider != nullptr)
292
    {
293
        mAmountItems = mMaxItems;
294
        mSlider->setValue(mAmountItems);
295
        updateButtonsAndLabels();
296
    }
297
    else if (eventId == "presell" ||
298
             eventId == "sell" ||
299
             eventId == "yes" ||
300
             eventId == "confirm")
301
    {
302
        sellAction(event);
303
    }
304
}
305
306
void SellDialog::valueChanged(const SelectionEvent &event A_UNUSED)
307
{
308
    // Reset amount of items and update labels
309
    mAmountItems = 1;
310
    if (mSlider != nullptr)
311
    {
312
        mSlider->setValue(0);
313
        mSlider->setScale(1, mMaxItems);
314
    }
315
    updateButtonsAndLabels();
316
}
317
318
void SellDialog::setMoney(const int amount)
319
{
320
    mPlayerMoney = amount;
321
    mShopItemList->setPlayersMoney(amount);
322
}
323
324
void SellDialog::updateButtonsAndLabels()
325
{
326
    const int selectedItem = mShopItemList->getSelected();
327
    int income = 0;
328
    ShopItem *item = nullptr;
329
330
    if (selectedItem > -1 && (mShopItems->at(selectedItem) != nullptr))
331
    {
332
        item = mShopItems->at(selectedItem);
333
        if (item != nullptr)
334
        {
335
            mMaxItems = item->getQuantity();
336
            if (mAmountItems > mMaxItems)
337
                mAmountItems = mMaxItems;
338
            income = mAmountItems * mShopItems->at(selectedItem)->getPrice();
339
        }
340
        else
341
        {
342
            mMaxItems = 0;
343
            mAmountItems = 0;
344
        }
345
    }
346
    else
347
    {
348
        mMaxItems = 0;
349
        mAmountItems = 0;
350
    }
351
352
    // Update Buttons and slider
353
    mSellButton->setEnabled(mAmountItems > 0);
354
    if (mDecreaseButton != nullptr)
355
        mDecreaseButton->setEnabled(mAmountItems > 1);
356
    if (mIncreaseButton != nullptr)
357
        mIncreaseButton->setEnabled(mAmountItems < mMaxItems);
358
    if (mSlider != nullptr)
359
        mSlider->setEnabled(mMaxItems > 1);
360
361
    if (mQuantityLabel != nullptr)
362
    {
363
        // Update the quantity and money labels
364
        mQuantityLabel->setCaption(strprintf("%d / %d",
365
            mAmountItems, mMaxItems));
366
    }
367
    if (mMoneyLabel != nullptr)
368
    {
369
        // TRANSLATORS: sell dialog label
370
        mMoneyLabel->setCaption(strprintf(_("Price: %s / Total: %s"),
371
            UnitsDb::formatCurrency(income).c_str(),
372
            UnitsDb::formatCurrency(mPlayerMoney + income).c_str()));
373
    }
374
    if (item != nullptr)
375
        item->update();
376
}
377
378
8
void SellDialog::setVisible(Visible visible)
379
{
380
8
    Window::setVisible(visible);
381
382
8
    if (visible == Visible_true)
383
    {
384
8
        if (mShopItemList != nullptr)
385
8
            mShopItemList->requestFocus();
386
    }
387
    else
388
    {
389
        scheduleDelete();
390
    }
391
8
}
392
393
void SellDialog::closeAll()
394
{
395
    FOR_EACH (DialogList::const_iterator, it, instances)
396
        (*it)->close();
397

6
}