GCC Code Coverage Report
Directory: src/ Exec Total Coverage
File: src/gui/windows/socialwindow.cpp Lines: 77 288 26.7 %
Date: 2021-03-17 Branches: 65 322 20.2 %

Line Branch Exec Source
1
/*
2
 *  The ManaPlus Client
3
 *  Copyright (C) 2010  The Mana Developers
4
 *  Copyright (C) 2011-2019  The ManaPlus Developers
5
 *  Copyright (C) 2019-2021  Andrei Karas
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/windows/socialwindow.h"
24
25
#include "gui/popups/popupmenu.h"
26
27
#include "gui/windows/setupwindow.h"
28
29
#include "gui/widgets/button.h"
30
#include "gui/widgets/label.h"
31
#include "gui/widgets/tabbedarea.h"
32
33
#include "gui/widgets/tabs/socialattacktab.h"
34
#include "gui/widgets/tabs/socialfriendstab.h"
35
#include "gui/widgets/tabs/socialguildtab.h"
36
#include "gui/widgets/tabs/socialnavigationtab.h"
37
#include "gui/widgets/tabs/socialpartytab.h"
38
#include "gui/widgets/tabs/socialpickuptab.h"
39
#include "gui/widgets/tabs/socialplayerstab.h"
40
41
#ifdef TMWA_SUPPORT
42
#include "gui/widgets/tabs/socialguildtab2.h"
43
44
#include "net/tmwa/guildmanager.h"
45
#endif  // TMWA_SUPPORT
46
47
#include "debug.h"
48
49
SocialWindow *socialWindow = nullptr;
50
51
1
SocialWindow::SocialWindow() :
52
    // TRANSLATORS: social window name
53
1
    Window(_("Social"), Modal_false, nullptr, "social.xml"),
54
    ActionListener(),
55
    PlayerRelationsListener(),
56
    mGuildInvited(0),
57
    mGuildAcceptDialog(nullptr),
58
    mGuildCreateDialog(nullptr),
59
    mPartyInviter(),
60
    mGuilds(),
61
    mParties(),
62
    mPartyAcceptDialog(nullptr),
63
    mAttackFilter(nullptr),
64
    mPickupFilter(nullptr),
65
    // TRANSLATORS: here P is title for visible players tab in social window
66
1
    mPlayers(new SocialPlayersTab(this, _("P"),
67


4
        fromBool(getOptionBool("showtabbackground", false), Opaque))),
68
    mNavigation(new SocialNavigationTab(this,
69


4
        fromBool(getOptionBool("showtabbackground", false), Opaque))),
70
    // TRANSLATORS: here F is title for friends tab in social window
71
1
    mFriends(new SocialFriendsTab(this, _("F"),
72


4
        fromBool(getOptionBool("showtabbackground", false), Opaque))),
73
    // TRANSLATORS: social window button
74

2
    mMenuButton(new Button(this, _("Menu"), "menu", BUTTON_SKIN, this)),
75

1
    mCountLabel(new Label(this, "1000 / 1000")),
76


1
    mTabs(CREATEWIDGETR(TabbedArea, this)),
77
    mMap(nullptr),
78
    mLastUpdateTime(0),
79
    mPartyId(0),
80
    mNeedUpdate(false),
81



34
    mProcessedPortals(false)
82
{
83
1
}
84
85
1
void SocialWindow::postInit()
86
{
87
1
    Window::postInit();
88
5
    setWindowName("Social");
89
1
    setVisible(Visible_false);
90
2
    setSaveVisible(true);
91
1
    setResizable(true);
92
2
    setSaveVisible(true);
93
1
    setCloseButton(true);
94
1
    setStickyButtonLock(true);
95
96
1
    setMinWidth(120);
97
1
    setMinHeight(55);
98
1
    setDefaultSize(590, 200, 180, 300);
99
1
    if (setupWindow != nullptr)
100
        setupWindow->registerWindowForReset(this);
101
102
1
    place(0, 0, mMenuButton, 1, 1);
103
1
    place(0, 1, mCountLabel, 1, 1);
104
1
    place(0, 2, mTabs, 2, 4);
105
106
1
    widgetResized(Event(nullptr));
107
108
1
    loadWindowState();
109
110
1
    mTabs->addTab(mPlayers, mPlayers->mScroll);
111
1
    mTabs->addTab(mFriends, mFriends->mScroll);
112
1
    mTabs->addTab(mNavigation, mNavigation->mScroll);
113
2
    mTabs->setSelectable(false);
114
3
    mTabs->getTabContainer()->setSelectable(false);
115
3
    mTabs->getWidgetContainer()->setSelectable(false);
116
117

4
    if (config.getBoolValue("enableAttackFilter"))
118
    {
119
1
        mAttackFilter = new SocialAttackTab(this,
120


4
            fromBool(getOptionBool("showtabbackground", false), Opaque));
121
1
        mTabs->addTab(mAttackFilter, mAttackFilter->mScroll);
122
    }
123
    else
124
    {
125
        mAttackFilter = nullptr;
126
    }
127
128

4
    if (config.getBoolValue("enablePickupFilter"))
129
    {
130
1
        mPickupFilter = new SocialPickupTab(this,
131


3
            fromBool(getOptionBool("showtabbackground", false), Opaque));
132
1
        mTabs->addTab(mPickupFilter, mPickupFilter->mScroll);
133
    }
134
    else
135
    {
136
        mPickupFilter = nullptr;
137
    }
138
139

2
    if ((localPlayer != nullptr) && (localPlayer->getParty() != nullptr))
140
        addTab(localPlayer->getParty());
141
142

1
    if ((localPlayer != nullptr) && (localPlayer->getGuild() != nullptr))
143
        addTab(localPlayer->getGuild());
144
145
2
    enableVisibleSound(true);
146
1
    updateButtons();
147
2
    playerRelations.addListener(this);
148
1
}
149
150
8
SocialWindow::~SocialWindow()
151
{
152
2
    playerRelations.removeListener(this);
153
1
    if (mGuildAcceptDialog != nullptr)
154
    {
155
        mGuildAcceptDialog->close();
156
        mGuildAcceptDialog->scheduleDelete();
157
        mGuildAcceptDialog = nullptr;
158
159
        mGuildInvited = 0;
160
    }
161
162
1
    if (mPartyAcceptDialog != nullptr)
163
    {
164
        mPartyAcceptDialog->close();
165
        mPartyAcceptDialog->scheduleDelete();
166
        mPartyAcceptDialog = nullptr;
167
168
        mPartyInviter.clear();
169
    }
170
1
    delete2(mPlayers)
171
1
    delete2(mNavigation)
172
1
    delete2(mAttackFilter)
173
1
    delete2(mPickupFilter)
174
1
    delete2(mFriends)
175
3
    FOR_EACH (GuildMap::iterator, it, mGuilds)
176
    {
177
        delete (*it).second;
178
    }
179
2
    mGuilds.clear();
180
3
    FOR_EACH (PartyMap::iterator, it, mParties)
181
    {
182
        delete (*it).second;
183
    }
184
2
    mParties.clear();
185
2
}
186
187
bool SocialWindow::addTab(Guild *const guild)
188
{
189
    if (guild == nullptr)
190
        return false;
191
192
    if (mGuilds.find(guild) != mGuilds.end())
193
        return false;
194
195
    SocialTab *tab = nullptr;
196
    if (guild->getServerGuild())
197
    {
198
        tab = new SocialGuildTab(this, guild,
199
            fromBool(getOptionBool("showtabbackground", false), Opaque));
200
    }
201
#ifdef TMWA_SUPPORT
202
    else
203
    {
204
        tab = new SocialGuildTab2(this, guild,
205
            fromBool(getOptionBool("showtabbackground", false), Opaque));
206
    }
207
#endif  // TMWA_SUPPORT
208
209
    mGuilds[guild] = tab;
210
    mTabs->addTab(tab, tab->mScroll);
211
212
    updateButtons();
213
214
    return true;
215
}
216
217
bool SocialWindow::removeTab(Guild *const guild)
218
{
219
    const GuildMap::iterator it = mGuilds.find(guild);
220
    if (it == mGuilds.end())
221
        return false;
222
223
    mTabs->removeTab(it->second);
224
    delete it->second;
225
    mGuilds.erase(it);
226
227
    updateButtons();
228
229
    return true;
230
}
231
232
bool SocialWindow::addTab(Party *const party)
233
{
234
    if (party == nullptr)
235
        return false;
236
237
    if (mParties.find(party) != mParties.end())
238
        return false;
239
240
    SocialPartyTab *const tab = new SocialPartyTab(this, party,
241
        fromBool(getOptionBool("showtabbackground", false), Opaque));
242
    mParties[party] = tab;
243
244
    mTabs->addTab(tab, tab->mScroll);
245
246
    updateButtons();
247
248
    return true;
249
}
250
251
bool SocialWindow::removeTab(Party *const party)
252
{
253
    const PartyMap::iterator it = mParties.find(party);
254
    if (it == mParties.end())
255
        return false;
256
257
    mTabs->removeTab(it->second);
258
    delete it->second;
259
    mParties.erase(it);
260
261
    updateButtons();
262
263
    return true;
264
}
265
266
void SocialWindow::action(const ActionEvent &event)
267
{
268
    const std::string &eventId = event.getId();
269
270
    if (event.getSource() == mPartyAcceptDialog)
271
    {
272
        if (eventId == "yes")
273
        {
274
            if (localChatTab != nullptr)
275
            {
276
                localChatTab->chatLog(
277
                    // TRANSLATORS: chat message
278
                    strprintf(_("Accepted party invite from %s."),
279
                    mPartyInviter.c_str()),
280
                    ChatMsgType::BY_SERVER,
281
                    IgnoreRecord_false,
282
                    TryRemoveColors_true);
283
            }
284
            partyHandler->inviteResponse(mPartyId, true);
285
        }
286
        else if (eventId == "no")
287
        {
288
            if (localChatTab != nullptr)
289
            {
290
                localChatTab->chatLog(
291
                    // TRANSLATORS: chat message
292
                    strprintf(_("Rejected party invite from %s."),
293
                    mPartyInviter.c_str()),
294
                    ChatMsgType::BY_SERVER,
295
                    IgnoreRecord_false,
296
                    TryRemoveColors_true);
297
            }
298
            partyHandler->inviteResponse(mPartyId, false);
299
        }
300
301
        mPartyInviter.clear();
302
        mPartyAcceptDialog = nullptr;
303
    }
304
    else if (event.getSource() == mGuildAcceptDialog)
305
    {
306
        if (eventId == "yes")
307
        {
308
            if (localChatTab != nullptr)
309
            {
310
                localChatTab->chatLog(
311
                    // TRANSLATORS: chat message
312
                    strprintf(_("Accepted guild invite from %s."),
313
                    mPartyInviter.c_str()),
314
                    ChatMsgType::BY_SERVER,
315
                    IgnoreRecord_false,
316
                    TryRemoveColors_true);
317
            }
318
#ifdef TMWA_SUPPORT
319
            if (guildManager == nullptr || !GuildManager::getEnableGuildBot())
320
                guildHandler->inviteResponse(mGuildInvited, true);
321
            else
322
                GuildManager::inviteResponse(true);
323
#else  // TMWA_SUPPORT
324
325
            guildHandler->inviteResponse(mGuildInvited, true);
326
#endif  // TMWA_SUPPORT
327
        }
328
        else if (eventId == "no")
329
        {
330
            if (localChatTab != nullptr)
331
            {
332
                localChatTab->chatLog(
333
                    // TRANSLATORS: chat message
334
                    strprintf(_("Rejected guild invite from %s."),
335
                    mPartyInviter.c_str()),
336
                    ChatMsgType::BY_SERVER,
337
                    IgnoreRecord_false,
338
                    TryRemoveColors_true);
339
            }
340
#ifdef TMWA_SUPPORT
341
            if (guildManager == nullptr || !GuildManager::getEnableGuildBot())
342
                guildHandler->inviteResponse(mGuildInvited, false);
343
            else
344
                GuildManager::inviteResponse(false);
345
#else  // TMWA_SUPPORT
346
347
            guildHandler->inviteResponse(mGuildInvited, false);
348
#endif  // TMWA_SUPPORT
349
        }
350
351
        mGuildInvited = 0;
352
        mGuildAcceptDialog = nullptr;
353
    }
354
    else if (eventId == "party")
355
    {
356
        popupMenu->showPartyPopup();
357
    }
358
    else if (eventId == "guild")
359
    {
360
        popupMenu->showGuildPopup();
361
    }
362
    else if (eventId == "attack")
363
    {
364
        popupMenu->showAttackPopup();
365
    }
366
    else if (eventId == "friends")
367
    {
368
        popupMenu->showFriendsPopup();
369
    }
370
    else if (eventId == "navigation")
371
    {
372
        popupMenu->showNavigationPopup();
373
    }
374
    else if (eventId == "pickup")
375
    {
376
        popupMenu->showPickupPopup();
377
    }
378
    else if (eventId == "players")
379
    {
380
        popupMenu->showPlayersPopup();
381
    }
382
}
383
384
void SocialWindow::showGuildInvite(const std::string &restrict guildName,
385
                                   const int guildId,
386
                                   const std::string &restrict inviterName)
387
{
388
    // check there isnt already an invite showing
389
    if (mGuildInvited != 0)
390
    {
391
        if (localChatTab != nullptr)
392
        {
393
            // TRANSLATORS: chat message
394
            localChatTab->chatLog(_("Received guild request, but one already "
395
                "exists."),
396
                ChatMsgType::BY_SERVER,
397
                IgnoreRecord_false,
398
                TryRemoveColors_true);
399
        }
400
        return;
401
    }
402
403
    const std::string msg = strprintf(
404
        // TRANSLATORS: chat message
405
        _("%s has invited you to join the guild %s."),
406
        inviterName.c_str(), guildName.c_str());
407
408
    if (localChatTab != nullptr)
409
    {
410
        localChatTab->chatLog(msg,
411
            ChatMsgType::BY_SERVER,
412
            IgnoreRecord_false,
413
            TryRemoveColors_true);
414
    }
415
416
    CREATEWIDGETV(mGuildAcceptDialog, ConfirmDialog,
417
        // TRANSLATORS: guild invite message
418
        _("Accept Guild Invite"),
419
        msg,
420
        SOUND_REQUEST,
421
        false,
422
        Modal_false,
423
        this);
424
    mGuildAcceptDialog->addActionListener(this);
425
    mGuildInvited = guildId;
426
}
427
428
void SocialWindow::showPartyInvite(const std::string &restrict partyName,
429
                                   const std::string &restrict inviter,
430
                                   const int partyId)
431
{
432
    // check there isnt already an invite showing
433
    if (!mPartyInviter.empty())
434
    {
435
        if (localChatTab != nullptr)
436
        {
437
            // TRANSLATORS: chat message
438
            localChatTab->chatLog(_("Received party request, but one already "
439
                "exists."),
440
                ChatMsgType::BY_SERVER,
441
                IgnoreRecord_false,
442
                TryRemoveColors_true);
443
        }
444
        return;
445
    }
446
447
    std::string msg;
448
    if (inviter.empty())
449
    {
450
        if (partyName.empty())
451
        {
452
            // TRANSLATORS: party invite message
453
            msg = _("You have been invited you to join a party.");
454
        }
455
        else
456
        {
457
            // TRANSLATORS: party invite message
458
            msg = strprintf(_("You have been invited to join the %s party."),
459
                partyName.c_str());
460
        }
461
    }
462
    else
463
    {
464
        if (partyName.empty())
465
        {
466
            // TRANSLATORS: party invite message
467
            msg = strprintf(_("%s has invited you to join their party."),
468
                inviter.c_str());
469
        }
470
        else
471
        {
472
            // TRANSLATORS: party invite message
473
            msg = strprintf(_("%s has invited you to join the %s party."),
474
                inviter.c_str(), partyName.c_str());
475
        }
476
    }
477
478
    if (localChatTab != nullptr)
479
    {
480
        localChatTab->chatLog(msg,
481
            ChatMsgType::BY_SERVER,
482
            IgnoreRecord_false,
483
            TryRemoveColors_true);
484
    }
485
486
    // show invite
487
    CREATEWIDGETV(mPartyAcceptDialog, ConfirmDialog,
488
        // TRANSLATORS: party invite message
489
        _("Accept Party Invite"),
490
        msg,
491
        SOUND_REQUEST,
492
        false,
493
        Modal_false,
494
        this);
495
    mPartyAcceptDialog->addActionListener(this);
496
    mPartyInviter = inviter;
497
    mPartyId = partyId;
498
}
499
500
void SocialWindow::updateActiveList()
501
{
502
    mNeedUpdate = true;
503
}
504
505
void SocialWindow::slowLogic()
506
{
507
    BLOCK_START("SocialWindow::slowLogic")
508
    const time_t nowTime = cur_time;
509
    if (mNeedUpdate && nowTime - mLastUpdateTime > 1)
510
    {
511
        mPlayers->updateList();
512
        mFriends->updateList();
513
        mNeedUpdate = false;
514
        mLastUpdateTime = nowTime;
515
    }
516
    else if (nowTime - mLastUpdateTime > 5)
517
    {
518
        mPlayers->updateList();
519
        mNeedUpdate = false;
520
        mLastUpdateTime = nowTime;
521
    }
522
    BLOCK_END("SocialWindow::slowLogic")
523
}
524
525
void SocialWindow::updateAvatar(const std::string &name)
526
{
527
    mPlayers->updateAvatar(name);
528
}
529
530
void SocialWindow::resetDamage(const std::string &name)
531
{
532
    mPlayers->resetDamage(name);
533
}
534
535
void SocialWindow::updateButtons()
536
{
537
//    if (!mTabs)
538
//        return;
539
540
//    const bool hasTabs = mTabs->getNumberOfTabs() > 0;
541
}
542
543
void SocialWindow::updatePortals()
544
{
545
    if (mNavigation != nullptr)
546
        mNavigation->updateList();
547
}
548
549
void SocialWindow::updatePortalNames()
550
{
551
    if (mNavigation != nullptr)
552
        static_cast<SocialNavigationTab*>(mNavigation)->updateNames();
553
}
554
555
void SocialWindow::selectPortal(const unsigned num)
556
{
557
    if (mNavigation != nullptr)
558
        mNavigation->selectIndex(num);
559
}
560
561
int SocialWindow::getPortalIndex(const int x, const int y)
562
{
563
    if (mNavigation != nullptr)
564
    {
565
        return static_cast<SocialNavigationTab*>(
566
            mNavigation)->getPortalIndex(x, y);
567
    }
568
    return -1;
569
}
570
571
void SocialWindow::addPortal(const int x, const int y)
572
{
573
    if (mNavigation != nullptr)
574
        static_cast<SocialNavigationTab*>(mNavigation)->addPortal(x, y);
575
}
576
577
void SocialWindow::removePortal(const int x, const int y)
578
{
579
    if (mNavigation != nullptr)
580
        static_cast<SocialNavigationTab*>(mNavigation)->removePortal(x, y);
581
}
582
583
void SocialWindow::nextTab()
584
{
585
    if (mTabs != nullptr)
586
        mTabs->selectNextTab();
587
}
588
589
void SocialWindow::prevTab()
590
{
591
    if (mTabs != nullptr)
592
        mTabs->selectPrevTab();
593
}
594
595
void SocialWindow::updateAttackFilter()
596
{
597
    if (mAttackFilter != nullptr)
598
        mAttackFilter->updateList();
599
}
600
601
void SocialWindow::updatePickupFilter()
602
{
603
    if (mPickupFilter != nullptr)
604
        mPickupFilter->updateList();
605
}
606
607
void SocialWindow::updateParty()
608
{
609
    if (localPlayer == nullptr)
610
        return;
611
612
    Party *const party = localPlayer->getParty();
613
    if (party != nullptr)
614
    {
615
        const PartyMap::iterator it = mParties.find(party);
616
        if (it != mParties.end())
617
        {
618
            SocialTab *const tab = (*it).second;
619
            tab->buildCounter(0, 0);
620
        }
621
    }
622
}
623
624
2
void SocialWindow::widgetResized(const Event &event)
625
{
626
2
    Window::widgetResized(event);
627
2
    if (mTabs != nullptr)
628
2
        mTabs->adjustSize();
629
2
}
630
631
1
void SocialWindow::updateCounter(const SocialTab *const tab,
632
                                 const std::string &counter)
633
{
634
2
    if (mTabs->getSelectedTab() == tab)
635
    {
636
1
        mCountLabel->setCaption(counter);
637
1
        mCountLabel->adjustSize();
638
    }
639
1
}
640
641
void SocialWindow::updateMenu(const SocialTab *const tab,
642
                              const std::string &menu)
643
{
644

2
    if (mTabs->getSelectedTab() == tab)
645
1
        mMenuButton->setActionEventId(menu);
646
}
647
648
void SocialWindow::updateGuildCounter(const int online, const int total)
649
{
650
    if (localPlayer == nullptr)
651
        return;
652
653
    Guild *const guild = localPlayer->getGuild();
654
    if (guild != nullptr)
655
    {
656
        const GuildMap::iterator it = mGuilds.find(guild);
657
        if (it != mGuilds.end())
658
        {
659
            SocialTab *const tab = (*it).second;
660
            tab->buildCounter(online, total);
661
        }
662
    }
663
}
664
665
void SocialWindow::updatedPlayer(const std::string &name A_UNUSED)
666
{
667
    mNeedUpdate = true;
668
}
669
670
void SocialWindow::updateAll()
671
{
672
    mNeedUpdate = true;
673

3
}
674
675
#ifdef USE_PROFILER
676
void SocialWindow::logicChildren()
677
{
678
    BLOCK_START("SocialWindow::logicChildren")
679
    BasicContainer::logicChildren();
680
    BLOCK_END("SocialWindow::logicChildren")
681
}
682
#endif  // USE_PROFILER