GCC Code Coverage Report
Directory: src/ Exec Total Coverage
File: src/gui/widgets/selldialog.cpp Lines: 103 195 52.8 %
Date: 2018-05-19 03:07:18 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-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/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, 0, 0);
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", false), 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
        BUTTON_SKIN,
118

8
        this);
119

64
    mQuitButton = new Button(this,
120
        // TRANSLATORS: sell dialog button
121
8
        _("Quit"),
122
        "quit",
123
        BUTTON_SKIN,
124

8
        this);
125
126
8
    initButtons();
127
128
16
    mSellButton->setEnabled(false);
129
130
16
    mShopItemList->setDistributeMousePressed(false);
131
8
    mShopItemList->setPriceCheck(false);
132
8
    mShopItemList->addSelectionListener(this);
133
40
    mShopItemList->setActionEventId("sell");
134
8
    mShopItemList->addActionListener(this);
135
136
8
    ContainerPlacer placer(nullptr, nullptr);
137
8
    placer = getPlacer(0, 0);
138
139
8
    if (mIsSell == IsSell_true)
140
    {
141

32
        mIncreaseButton = new Button(this,
142
            // TRANSLATORS: sell dialog button
143
4
            _("+"),
144
            "inc",
145
            BUTTON_SKIN,
146

4
            this);
147

32
        mDecreaseButton = new Button(this,
148
            // TRANSLATORS: sell dialog button
149
4
            _("-"),
150
            "dec",
151
            BUTTON_SKIN,
152

4
            this);
153

32
        mAddMaxButton = new Button(this,
154
            // TRANSLATORS: sell dialog button
155
4
            _("Max"),
156
            "max",
157
            BUTTON_SKIN,
158

4
            this);
159
4
        mSlider = new Slider(this, 1.0, 1.0);
160
161
12
        mQuantityLabel = new Label(this, strprintf(
162

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

4
            "", ""));
167
4
        if (mAdvanced == Advanced_true)
168
        {
169

16
            mConfirmButton = new Button(this,
170
                // TRANSLATORS: sell dialog button
171
2
                _("Sell"),
172
                "confirm",
173
                BUTTON_SKIN,
174

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

6
}