summaryrefslogtreecommitdiff
path: root/src/gui/popups/popupmenu.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/gui/popups/popupmenu.cpp')
-rw-r--r--src/gui/popups/popupmenu.cpp2914
1 files changed, 2914 insertions, 0 deletions
diff --git a/src/gui/popups/popupmenu.cpp b/src/gui/popups/popupmenu.cpp
new file mode 100644
index 000000000..6771e7e3e
--- /dev/null
+++ b/src/gui/popups/popupmenu.cpp
@@ -0,0 +1,2914 @@
+/*
+ * The ManaPlus Client
+ * Copyright (C) 2004-2009 The Mana World Development Team
+ * Copyright (C) 2009-2010 The Mana Developers
+ * Copyright (C) 2011-2013 The ManaPlus Developers
+ *
+ * This file is part of The ManaPlus Client.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include "gui/popups/popupmenu.h"
+
+#include "actorspritemanager.h"
+#include "commandhandler.h"
+#include "configuration.h"
+#include "dropshortcut.h"
+#include "game.h"
+#include "guild.h"
+#include "guildmanager.h"
+#include "item.h"
+#include "maplayer.h"
+#include "party.h"
+#include "spellmanager.h"
+
+#include "being/localplayer.h"
+#include "being/playerinfo.h"
+#include "being/playerrelations.h"
+
+#include "input/inputmanager.h"
+
+#include "gui/windows/chatwindow.h"
+#include "gui/windows/equipmentwindow.h"
+#include "gui/windows/inventorywindow.h"
+#include "gui/windows/itemamountwindow.h"
+#include "gui/windows/ministatuswindow.h"
+#include "gui/windows/npcdialog.h"
+#include "gui/windows/outfitwindow.h"
+#include "gui/windows/skilldialog.h"
+#include "gui/windows/socialwindow.h"
+#include "gui/windows/textcommandeditor.h"
+#include "gui/windows/textdialog.h"
+#include "gui/windows/tradewindow.h"
+#include "gui/windowmenu.h"
+
+#include "gui/viewport.h"
+
+#include "gui/widgets/browserbox.h"
+#include "gui/widgets/chattab.h"
+#include "gui/widgets/progressbar.h"
+#include "gui/widgets/scrollarea.h"
+#include "gui/widgets/textfield.h"
+#include "gui/widgets/whispertab.h"
+
+#include "net/adminhandler.h"
+#include "net/beinghandler.h"
+#include "net/buysellhandler.h"
+#include "net/guildhandler.h"
+#include "net/inventoryhandler.h"
+#include "net/net.h"
+#include "net/npchandler.h"
+#include "net/partyhandler.h"
+#include "net/tradehandler.h"
+
+#include "resources/iteminfo.h"
+
+#include "utils/copynpaste.h"
+#include "utils/gettext.h"
+#include "utils/process.h"
+
+#include <guichan/listmodel.hpp>
+
+#include "debug.h"
+
+extern int serverVersion;
+
+std::string tradePartnerName;
+
+PopupMenu::PopupMenu() :
+ Popup("PopupMenu", "popupmenu.xml"),
+ mBrowserBox(new BrowserBox(this)),
+ mScrollArea(nullptr),
+ mBeingId(0),
+ mFloorItemId(0),
+ mItem(nullptr),
+ mItemId(0),
+ mItemColor(1),
+ mMapItem(nullptr),
+ mTab(nullptr),
+ mSpell(nullptr),
+ mWindow(nullptr),
+ mRenameListener(),
+ mPlayerListener(),
+ mDialog(nullptr),
+ mButton(nullptr),
+ mNick(),
+ mTextField(nullptr),
+ mType(static_cast<int>(Being::UNKNOWN)),
+ mX(0),
+ mY(0)
+{
+ mBrowserBox->setHighlightMode(BrowserBox::BACKGROUND);
+ mBrowserBox->setOpaque(false);
+ mBrowserBox->setLinkHandler(this);
+ mRenameListener.setMapItem(nullptr);
+ mRenameListener.setDialog(nullptr);
+ mPlayerListener.setNick("");
+ mPlayerListener.setDialog(nullptr);
+ mPlayerListener.setType(static_cast<int>(Being::UNKNOWN));
+ mScrollArea = new ScrollArea(mBrowserBox, false);
+ mScrollArea->setVerticalScrollPolicy(ScrollArea::SHOW_AUTO);
+ add(mScrollArea);
+}
+
+void PopupMenu::showPopup(const int x, const int y, const Being *const being)
+{
+ if (!being || !player_node || !actorSpriteManager)
+ return;
+
+ mBeingId = being->getId();
+ mNick = being->getName();
+ mType = static_cast<int>(being->getType());
+ mBrowserBox->clearRows();
+ mX = x;
+ mY = y;
+
+ const std::string &name = mNick;
+ mBrowserBox->addRow(name + being->getGenderSignWithSpace());
+
+ switch (being->getType())
+ {
+ case ActorSprite::PLAYER:
+ {
+ // TRANSLATORS: popup menu item
+ // TRANSLATORS: trade with player
+ mBrowserBox->addRow("trade", _("Trade"));
+ // TRANSLATORS: popup menu item
+ // TRANSLATORS: trade attack player
+ mBrowserBox->addRow("attack", _("Attack"));
+ // TRANSLATORS: popup menu item
+ // TRANSLATORS: send whisper to player
+ mBrowserBox->addRow("whisper", _("Whisper"));
+ addGmCommands();
+ mBrowserBox->addRow("##3---");
+
+ // TRANSLATORS: popup menu item
+ // TRANSLATORS: heal player
+ mBrowserBox->addRow("heal", _("Heal"));
+ mBrowserBox->addRow("##3---");
+
+ addPlayerRelation(name);
+ mBrowserBox->addRow("##3---");
+
+ addFollow();
+ addParty(being->getPartyName());
+
+ const Guild *const guild1 = being->getGuild();
+ const Guild *const guild2 = player_node->getGuild();
+ if (guild2)
+ {
+ if (guild1)
+ {
+ if (guild1->getId() == guild2->getId())
+ {
+ mBrowserBox->addRow("guild-kick",
+ // TRANSLATORS: popup menu item
+ // TRANSLATORS: kick player from guild
+ _("Kick from guild"));
+ if (guild2->getServerGuild())
+ {
+ mBrowserBox->addRow(strprintf(
+ "@@guild-pos|%s >@@",
+ // TRANSLATORS: popup menu item
+ // TRANSLATORS: change player position in guild
+ _("Change pos in guild")));
+ }
+ }
+ }
+ else if (guild2->getMember(mNick))
+ {
+ mBrowserBox->addRow("guild-kick",
+ // TRANSLATORS: popup menu item
+ // TRANSLATORS: kick player from guild
+ _("Kick from guild"));
+ if (guild2->getServerGuild())
+ {
+ mBrowserBox->addRow(strprintf(
+ "@@guild-pos|%s >@@",
+ // TRANSLATORS: popup menu item
+ // TRANSLATORS: change player position in guild
+ _("Change pos in guild")));
+ }
+ }
+ else
+ {
+ if (guild2->getServerGuild()
+ || (guildManager && guildManager->havePower()))
+ {
+ // TRANSLATORS: popup menu item
+ // TRANSLATORS: invite player to guild
+ mBrowserBox->addRow("guild", _("Invite to guild"));
+ }
+ }
+ }
+
+ // TRANSLATORS: popup menu item
+ // TRANSLATORS: set player invisible for self by id
+ mBrowserBox->addRow("nuke", _("Nuke"));
+ // TRANSLATORS: popup menu item
+ // TRANSLATORS: move to player location
+ mBrowserBox->addRow("move", _("Move"));
+ addPlayerMisc();
+ addBuySell(being);
+ break;
+ }
+
+ case ActorSprite::NPC:
+ // NPCs can be talked to (single option, candidate for removal
+ // unless more options would be added)
+ // TRANSLATORS: popup menu item
+ // TRANSLATORS: talk with npc
+ mBrowserBox->addRow("talk", _("Talk"));
+ // TRANSLATORS: popup menu item
+ // TRANSLATORS: buy from npc
+ mBrowserBox->addRow("buy", _("Buy"));
+ // TRANSLATORS: popup menu item
+ // TRANSLATORS: sell to npc
+ mBrowserBox->addRow("sell", _("Sell"));
+ mBrowserBox->addRow("##3---");
+ // TRANSLATORS: popup menu item
+ // TRANSLATORS: move to npc location
+ mBrowserBox->addRow("move", _("Move"));
+ // TRANSLATORS: popup menu item
+ // TRANSLATORS: add comment to npc
+ mBrowserBox->addRow("addcomment", _("Add comment"));
+ break;
+
+ case ActorSprite::MONSTER:
+ {
+ // Monsters can be attacked
+ // TRANSLATORS: popup menu item
+ // TRANSLATORS: attack monster
+ mBrowserBox->addRow("attack", _("Attack"));
+
+ if (config.getBoolValue("enableAttackFilter"))
+ {
+ mBrowserBox->addRow("##3---");
+ if (actorSpriteManager->isInAttackList(name)
+ || actorSpriteManager->isInIgnoreAttackList(name)
+ || actorSpriteManager->isInPriorityAttackList(name))
+ {
+ mBrowserBox->addRow("remove attack",
+ // TRANSLATORS: remove monster from attack list
+ // TRANSLATORS: popup menu item
+ _("Remove from attack list"));
+ }
+ else
+ {
+ mBrowserBox->addRow("add attack priority",
+ // TRANSLATORS: popup menu item
+ // TRANSLATORS: add monster to priotiry attack list
+ _("Add to priority attack list"));
+ mBrowserBox->addRow("add attack",
+ // TRANSLATORS: popup menu item
+ // TRANSLATORS: add monster to attack list
+ _("Add to attack list"));
+ mBrowserBox->addRow("add attack ignore",
+ // TRANSLATORS: popup menu item
+ // TRANSLATORS: add monster to ignore list
+ _("Add to ignore list"));
+ }
+ }
+ break;
+ }
+
+ case ActorSprite::AVATAR:
+ case ActorSprite::UNKNOWN:
+ case ActorSprite::FLOOR_ITEM:
+ case ActorSprite::PORTAL:
+ case ActorSprite::PET:
+ default:
+ /* Other beings aren't interesting... */
+ return;
+ }
+ // TRANSLATORS: popup menu item
+ // TRANSLATORS: add being name to chat
+ mBrowserBox->addRow("name", _("Add name to chat"));
+ mBrowserBox->addRow("##3---");
+
+ // TRANSLATORS: popup menu item
+ // TRANSLATORS: close menu
+ mBrowserBox->addRow("cancel", _("Cancel"));
+
+ showPopup(x, y);
+}
+
+void PopupMenu::showPopup(const int x, const int y,
+ std::vector<ActorSprite*> &beings)
+{
+ mX = x;
+ mY = y;
+ mBrowserBox->clearRows();
+ // TRANSLATORS: popup menu header
+ mBrowserBox->addRow(_("Players"));
+ FOR_EACH (std::vector<ActorSprite*>::const_iterator, it, beings)
+ {
+ const Being *const being = dynamic_cast<Being*>(*it);
+ const ActorSprite *const actor = *it;
+ if (being && !being->getName().empty())
+ {
+ mBrowserBox->addRow(strprintf("@@player_%u|%s >@@",
+ static_cast<unsigned>(being->getId()), (being->getName()
+ + being->getGenderSignWithSpace()).c_str()));
+ }
+ else if (actor->getType() == ActorSprite::FLOOR_ITEM)
+ {
+ const FloorItem *const floorItem
+ = static_cast<const FloorItem*>(actor);
+ mBrowserBox->addRow(strprintf("@@flooritem_%u|%s >@@",
+ static_cast<unsigned>(actor->getId()),
+ floorItem->getName().c_str()));
+ }
+ }
+ mBrowserBox->addRow("##3---");
+ // TRANSLATORS: popup menu item
+ // TRANSLATORS: close menu
+ mBrowserBox->addRow("cancel", _("Cancel"));
+ showPopup(x, y);
+}
+
+void PopupMenu::showPlayerPopup(const int x, const int y,
+ const std::string &nick)
+{
+ if (nick.empty() || !player_node)
+ return;
+
+ mNick = nick;
+ mBeingId = 0;
+ mType = static_cast<int>(Being::PLAYER);
+ mX = x;
+ mY = y;
+ mBrowserBox->clearRows();
+
+ const std::string &name = mNick;
+
+ mBrowserBox->addRow(name);
+
+ // TRANSLATORS: popup menu item
+ // TRANSLATORS: send whisper to player
+ mBrowserBox->addRow("whisper", _("Whisper"));
+ addGmCommands();
+ mBrowserBox->addRow("##3---");
+
+ addPlayerRelation(name);
+ mBrowserBox->addRow("##3---");
+
+ addFollow();
+ // TRANSLATORS: popup menu item
+ // TRANSLATORS: add comment to player
+ mBrowserBox->addRow("addcomment", _("Add comment"));
+
+ if (player_node->isInParty())
+ {
+ const Party *const party = player_node->getParty();
+ if (party)
+ {
+ const PartyMember *const member = party->getMember(mNick);
+ if (member)
+ {
+ // TRANSLATORS: popup menu item
+ // TRANSLATORS: kick player from party
+ mBrowserBox->addRow("kick party", _("Kick from party"));
+ mBrowserBox->addRow("##3---");
+ const PartyMember *const o = party->getMember(
+ player_node->getName());
+ if (o && member->getMap() == o->getMap())
+ {
+ // TRANSLATORS: popup menu item
+ // TRANSLATORS: move to player position
+ mBrowserBox->addRow("move", _("Move"));
+ }
+ }
+ }
+ }
+
+ const Guild *const guild2 = player_node->getGuild();
+ if (guild2)
+ {
+ if (guild2->getMember(mNick))
+ {
+ if (guild2->getServerGuild() || (guildManager
+ && guildManager->havePower()))
+ {
+ // TRANSLATORS: popup menu item
+ // TRANSLATORS: kick player from guild
+ mBrowserBox->addRow("guild-kick", _("Kick from guild"));
+ }
+ if (guild2->getServerGuild())
+ {
+ // TRANSLATORS: popup menu item
+ // TRANSLATORS: change player position in guild
+ mBrowserBox->addRow(strprintf(
+ "@@guild-pos|%s >@@", _("Change pos in guild")));
+ }
+ }
+ else
+ {
+ if (guild2->getServerGuild() || (guildManager
+ && guildManager->havePower()))
+ {
+ // TRANSLATORS: popup menu item
+ // TRANSLATORS: invite player to guild
+ mBrowserBox->addRow("guild", _("Invite to guild"));
+ }
+ }
+ }
+
+ addBuySellDefault();
+ // TRANSLATORS: popup menu item
+ // TRANSLATORS: add player name to chat
+ mBrowserBox->addRow("name", _("Add name to chat"));
+ mBrowserBox->addRow("##3---");
+ // TRANSLATORS: popup menu item
+ // TRANSLATORS: close menu
+ mBrowserBox->addRow("cancel", _("Cancel"));
+
+ showPopup(x, y);
+}
+
+void PopupMenu::showPopup(const int x, const int y,
+ const FloorItem *const floorItem)
+{
+ if (!floorItem)
+ return;
+
+ mFloorItemId = floorItem->getId();
+ mX = x;
+ mY = y;
+ mType = static_cast<int>(Being::FLOOR_ITEM);
+ mBrowserBox->clearRows();
+ const std::string name = floorItem->getName();
+ mNick = name;
+
+ mBrowserBox->addRow(name);
+
+ if (config.getBoolValue("enablePickupFilter"))
+ {
+ if (actorSpriteManager->isInPickupList(name)
+ || (actorSpriteManager->isInPickupList("")
+ && !actorSpriteManager->isInIgnorePickupList(name)))
+ {
+ // TRANSLATORS: popup menu item
+ // TRANSLATORS: pickup item from ground
+ mBrowserBox->addRow("pickup", _("Pick up"));
+ mBrowserBox->addRow("##3---");
+ }
+ addPickupFilter(name);
+ }
+ else
+ {
+ // TRANSLATORS: popup menu item
+ // TRANSLATORS: pickup item from ground
+ mBrowserBox->addRow("pickup", _("Pick up"));
+ }
+ addProtection();
+ // TRANSLATORS: popup menu item
+ // TRANSLATORS: add item name to chat
+ mBrowserBox->addRow("chat", _("Add to chat"));
+ mBrowserBox->addRow("##3---");
+ // TRANSLATORS: popup menu item
+ // TRANSLATORS: close menu
+ mBrowserBox->addRow("cancel", _("Cancel"));
+
+ showPopup(x, y);
+}
+
+void PopupMenu::showPopup(const int x, const int y, MapItem *const mapItem)
+{
+ if (!mapItem)
+ return;
+
+ mMapItem = mapItem;
+ mX = x;
+ mY = y;
+
+ mBrowserBox->clearRows();
+
+ // TRANSLATORS: popup menu header
+ mBrowserBox->addRow(_("Map Item"));
+ // TRANSLATORS: popup menu item
+ // TRANSLATORS: rename map item
+ mBrowserBox->addRow("rename map", _("Rename"));
+ // TRANSLATORS: popup menu item
+ // TRANSLATORS: remove map item
+ mBrowserBox->addRow("remove map", _("Remove"));
+
+ if (player_node && player_node->isGM())
+ {
+ mBrowserBox->addRow("##3---");
+ // TRANSLATORS: popup menu item
+ // TRANSLATORS: warp to map item
+ mBrowserBox->addRow("warp map", _("Warp"));
+ }
+ mBrowserBox->addRow("##3---");
+ // TRANSLATORS: popup menu item
+ // TRANSLATORS: close menu
+ mBrowserBox->addRow("cancel", _("Cancel"));
+
+ showPopup(x, y);
+}
+
+void PopupMenu::showMapPopup(const int x, const int y,
+ const int x2, const int y2)
+{
+ mX = x2;
+ mY = y2;
+
+ mBrowserBox->clearRows();
+
+ // TRANSLATORS: popup menu header
+ mBrowserBox->addRow(_("Map Item"));
+
+ if (player_node && player_node->isGM())
+ {
+ // TRANSLATORS: popup menu item
+ // TRANSLATORS: warp to map item
+ mBrowserBox->addRow("warp map", _("Warp"));
+ }
+ // TRANSLATORS: popup menu item
+ // TRANSLATORS: move to map item
+ mBrowserBox->addRow("move", _("Move"));
+ // TRANSLATORS: popup menu item
+ // TRANSLATORS: move camera to map item
+ mBrowserBox->addRow("movecamera", _("Move camera"));
+ mBrowserBox->addRow("##3---");
+ // TRANSLATORS: popup menu item
+ // TRANSLATORS: close menu
+ mBrowserBox->addRow("cancel", _("Cancel"));
+
+ showPopup(x, y);
+}
+
+void PopupMenu::showOutfitsPopup(const int x, const int y)
+{
+ mX = x;
+ mY = y;
+
+ mBrowserBox->clearRows();
+
+ // TRANSLATORS: popup menu header
+ mBrowserBox->addRow(_("Outfits"));
+ // TRANSLATORS: popup menu item
+ // TRANSLATORS: clear selected outfit
+ mBrowserBox->addRow("clear outfit", _("Clear outfit"));
+ mBrowserBox->addRow("##3---");
+ // TRANSLATORS: popup menu item
+ // TRANSLATORS: close menu
+ mBrowserBox->addRow("cancel", _("Cancel"));
+
+ showPopup(x, y);
+}
+
+void PopupMenu::showSpellPopup(const int x, const int y,
+ TextCommand *const cmd)
+{
+ if (!cmd)
+ return;
+
+ mBrowserBox->clearRows();
+
+ mSpell = cmd;
+ mX = x;
+ mY = y;
+
+ // TRANSLATORS: popup menu header
+ mBrowserBox->addRow(_("Spells"));
+ // TRANSLATORS: popup menu item
+ // TRANSLATORS: edit selected spell
+ mBrowserBox->addRow("edit spell", _("Edit spell"));
+ mBrowserBox->addRow("##3---");
+ // TRANSLATORS: popup menu item
+ // TRANSLATORS: close menu
+ mBrowserBox->addRow("cancel", _("Cancel"));
+
+ showPopup(x, y);
+}
+
+void PopupMenu::showChatPopup(const int x, const int y, ChatTab *const tab)
+{
+ if (!tab || !actorSpriteManager || !player_node)
+ return;
+
+ mTab = tab;
+ mX = x;
+ mY = y;
+
+ mBrowserBox->clearRows();
+
+ if (tab->getType() == static_cast<int>(ChatTab::TAB_WHISPER))
+ {
+ // TRANSLATORS: popup menu item
+ // TRANSLATORS: close chat tab
+ mBrowserBox->addRow("chat close", _("Close"));
+ }
+
+ // TRANSLATORS: popup menu item
+ // TRANSLATORS: remove all text from chat tab
+ mBrowserBox->addRow("chat clear", _("Clear"));
+ mBrowserBox->addRow("##3---");
+
+ if (tab->getAllowHighlight())
+ {
+ // TRANSLATORS: popup menu item
+ // TRANSLATORS: disable chat tab highlight
+ mBrowserBox->addRow("disable highlight", _("Disable highlight"));
+ }
+ else
+ {
+ // TRANSLATORS: popup menu item
+ // TRANSLATORS: enable chat tab highlight
+ mBrowserBox->addRow("enable highlight", _("Enable highlight"));
+ }
+ if (tab->getRemoveNames())
+ {
+ // TRANSLATORS: popup menu item
+ // TRANSLATORS: do not remove player names from chat tab
+ mBrowserBox->addRow("dont remove name", _("Don't remove name"));
+ }
+ else
+ {
+ // TRANSLATORS: popup menu item
+ // TRANSLATORS: remove player names from chat tab
+ mBrowserBox->addRow("remove name", _("Remove name"));
+ }
+ if (tab->getNoAway())
+ {
+ // TRANSLATORS: popup menu item
+ // TRANSLATORS: enable away messages in chat tab
+ mBrowserBox->addRow("enable away", _("Enable away"));
+ }
+ else
+ {
+ // TRANSLATORS: popup menu item
+ // TRANSLATORS: disable away messages in chat tab
+ mBrowserBox->addRow("disable away", _("Disable away"));
+ }
+ mBrowserBox->addRow("##3---");
+ if (tab->getType() == static_cast<int>(ChatTab::TAB_PARTY))
+ {
+ // TRANSLATORS: popup menu item
+ // TRANSLATORS: enable away messages in chat tab
+ mBrowserBox->addRow("leave party", _("Leave"));
+ mBrowserBox->addRow("##3---");
+ }
+ // TRANSLATORS: popup menu item
+ // TRANSLATORS: copy selected text to clipboard
+ mBrowserBox->addRow("chat clipboard", _("Copy to clipboard"));
+ mBrowserBox->addRow("##3---");
+
+ if (tab->getType() == static_cast<int>(ChatTab::TAB_WHISPER))
+ {
+ const WhisperTab *const wTab = static_cast<WhisperTab*>(tab);
+ std::string name = wTab->getNick();
+
+ const Being* const being = actorSpriteManager->findBeingByName(
+ name, Being::PLAYER);
+
+ if (being)
+ {
+ mBeingId = being->getId();
+ mNick = being->getName();
+ mType = static_cast<int>(being->getType());
+
+ // TRANSLATORS: popup menu item
+ // TRANSLATORS: trade with player
+ mBrowserBox->addRow("trade", _("Trade"));
+ // TRANSLATORS: popup menu item
+ // TRANSLATORS: attack player
+ mBrowserBox->addRow("attack", _("Attack"));
+ mBrowserBox->addRow("##3---");
+ // TRANSLATORS: popup menu item
+ // TRANSLATORS: heal player
+ mBrowserBox->addRow("heal", _("Heal"));
+ mBrowserBox->addRow("##3---");
+ addPlayerRelation(name);
+ mBrowserBox->addRow("##3---");
+ addFollow();
+ // TRANSLATORS: popup menu item
+ // TRANSLATORS: move to player position
+ mBrowserBox->addRow("move", _("Move"));
+ addPlayerMisc();
+ addBuySell(being);
+ mBrowserBox->addRow("##3---");
+
+ if (player_node->isInParty())
+ {
+ const Party *const party = player_node->getParty();
+ if (party)
+ {
+ if (!party->isMember(wTab->getNick()))
+ {
+ // TRANSLATORS: popup menu item
+ // TRANSLATORS: invite player to party
+ mBrowserBox->addRow("party", _("Invite to party"));
+ }
+ else
+ {
+ // TRANSLATORS: popup menu item
+ // TRANSLATORS: kick player from party
+ mBrowserBox->addRow("kick party",
+ _("Kick from party"));
+ }
+ mBrowserBox->addRow("##3---");
+ }
+ }
+ const Guild *const guild1 = being->getGuild();
+ const Guild *const guild2 = player_node->getGuild();
+ if (guild2)
+ {
+ if (guild1)
+ {
+ if (guild1->getId() == guild2->getId())
+ {
+ if (guild2->getServerGuild() || (guildManager
+ && guildManager->havePower()))
+ {
+ // TRANSLATORS: popup menu item
+ // TRANSLATORS: kick player from guild
+ mBrowserBox->addRow(strprintf(
+ "@@guild-kick|%s@@", _("Kick from guild")));
+ }
+ if (guild2->getServerGuild())
+ {
+ // TRANSLATORS: popup menu item
+ // TRANSLATORS: change player position in guild
+ mBrowserBox->addRow(strprintf("@@guild-pos|%s >@@",
+ _("Change pos in guild")));
+ }
+ }
+ }
+ else
+ {
+ if (guild2->getServerGuild() || (guildManager
+ && guildManager->havePower()))
+ {
+ // TRANSLATORS: popup menu item
+ // TRANSLATORS: invite player to guild
+ mBrowserBox->addRow("guild", _("Invite to guild"));
+ }
+ }
+ }
+ }
+ else
+ {
+ mNick = name;
+ mType = static_cast<int>(Being::PLAYER);
+ addPlayerRelation(name);
+ mBrowserBox->addRow("##3---");
+ addFollow();
+
+ if (player_node->isInParty())
+ {
+ const Party *const party = player_node->getParty();
+ if (party)
+ {
+ const PartyMember *const m = party->getMember(mNick);
+ if (m)
+ {
+ // TRANSLATORS: popup menu item
+ // TRANSLATORS: move to player location
+ mBrowserBox->addRow("move", _("Move"));
+ }
+ }
+ }
+ addPlayerMisc();
+ addBuySellDefault();
+ mBrowserBox->addRow("##3---");
+ }
+ }
+ // TRANSLATORS: popup menu item
+ // TRANSLATORS: close menu
+ mBrowserBox->addRow("cancel", _("Cancel"));
+
+ showPopup(x, y);
+}
+
+void PopupMenu::showChangePos(const int x, const int y)
+{
+ mBrowserBox->clearRows();
+ // TRANSLATORS: popup menu header
+ mBrowserBox->addRow(_("Change guild position"));
+
+ if (!player_node)
+ return;
+
+ mX = x;
+ mY = y;
+ const Guild *const guild = player_node->getGuild();
+ if (guild)
+ {
+ const PositionsMap map = guild->getPositions();
+ FOR_EACH (PositionsMap::const_iterator, itr, map)
+ {
+ mBrowserBox->addRow(strprintf("@@guild-pos-%u|%s@@",
+ itr->first, itr->second.c_str()));
+ }
+ // TRANSLATORS: popup menu item
+ // TRANSLATORS: close menu
+ mBrowserBox->addRow("cancel", _("Cancel"));
+
+ showPopup(x, y);
+ }
+ else
+ {
+ mBeingId = 0;
+ mFloorItemId = 0;
+ mItem = nullptr;
+ mMapItem = nullptr;
+ mNick.clear();
+ mType = static_cast<int>(Being::UNKNOWN);
+ mX = 0;
+ mY = 0;
+ setVisible(false);
+ }
+}
+
+void PopupMenu::handleLink(const std::string &link,
+ gcn::MouseEvent *event A_UNUSED)
+{
+ Being *being = nullptr;
+ if (actorSpriteManager)
+ being = actorSpriteManager->findBeing(mBeingId);
+
+ // Talk To action
+ if (link == "talk" && being && being->canTalk())
+ {
+ being->talkTo();
+ }
+ // Trade action
+ else if (link == "trade" && being &&
+ being->getType() == ActorSprite::PLAYER)
+ {
+ Net::getTradeHandler()->request(being);
+ tradePartnerName = being->getName();
+ if (tradeWindow)
+ tradeWindow->clear();
+ }
+ else if (link == "buy" && being && mBeingId != 0)
+ {
+ if (being->getType() == Being::NPC)
+ Net::getNpcHandler()->buy(mBeingId);
+ else if (being->getType() == Being::PLAYER)
+ Net::getBuySellHandler()->requestSellList(being->getName());
+ }
+ else if (link == "buy" && !mNick.empty())
+ {
+ Net::getBuySellHandler()->requestSellList(mNick);
+ }
+ else if (link == "sell" && being && mBeingId != 0)
+ {
+ if (being->getType() == Being::NPC)
+ Net::getNpcHandler()->sell(mBeingId);
+ else if (being->getType() == Being::PLAYER)
+ Net::getBuySellHandler()->requestBuyList(being->getName());
+ }
+ else if (link == "sell" && !mNick.empty())
+ {
+ Net::getBuySellHandler()->requestBuyList(mNick);
+ }
+ else if (link == "attack" && being)
+ {
+ if (player_node)
+ player_node->attack(being, true);
+ }
+ else if (link == "heal" && being && being->getType() != Being::MONSTER)
+ {
+ if (actorSpriteManager)
+ actorSpriteManager->heal(being);
+ }
+ else if (link == "unignore" && being &&
+ being->getType() == ActorSprite::PLAYER)
+ {
+ player_relations.setRelation(being->getName(),
+ PlayerRelation::NEUTRAL);
+ }
+ else if (link == "unignore" && !mNick.empty())
+ {
+ player_relations.setRelation(mNick, PlayerRelation::NEUTRAL);
+ }
+ else if (link == "ignore" && being &&
+ being->getType() == ActorSprite::PLAYER)
+ {
+ player_relations.setRelation(being->getName(),
+ PlayerRelation::IGNORED);
+ }
+ else if (link == "ignore" && !mNick.empty())
+ {
+ player_relations.setRelation(mNick, PlayerRelation::IGNORED);
+ }
+
+ else if (link == "blacklist" && being &&
+ being->getType() == ActorSprite::PLAYER)
+ {
+ player_relations.setRelation(being->getName(),
+ PlayerRelation::BLACKLISTED);
+ }
+ else if (link == "blacklist" && !mNick.empty())
+ {
+ player_relations.setRelation(mNick, PlayerRelation::BLACKLISTED);
+ }
+ else if (link == "enemy" && being &&
+ being->getType() == ActorSprite::PLAYER)
+ {
+ player_relations.setRelation(being->getName(),
+ PlayerRelation::ENEMY2);
+ }
+ else if (link == "enemy" && !mNick.empty())
+ {
+ player_relations.setRelation(mNick, PlayerRelation::ENEMY2);
+ }
+ else if (link == "erase" && being &&
+ being->getType() == ActorSprite::PLAYER)
+ {
+ player_relations.setRelation(being->getName(), PlayerRelation::ERASED);
+ being->updateName();
+ }
+ else if (link == "erase" && !mNick.empty())
+ {
+ player_relations.setRelation(mNick, PlayerRelation::ERASED);
+ }
+ else if (link == "disregard" && being &&
+ being->getType() == ActorSprite::PLAYER)
+ {
+ player_relations.setRelation(being->getName(),
+ PlayerRelation::DISREGARDED);
+ }
+ else if (link == "disregard" && !mNick.empty())
+ {
+ player_relations.setRelation(mNick, PlayerRelation::DISREGARDED);
+ }
+ else if (link == "friend" && being &&
+ being->getType() == ActorSprite::PLAYER)
+ {
+ player_relations.setRelation(being->getName(), PlayerRelation::FRIEND);
+ }
+ else if (link == "friend" && !mNick.empty())
+ {
+ player_relations.setRelation(mNick, PlayerRelation::FRIEND);
+ }
+ // Guild action
+ else if (link == "guild" && !mNick.empty())
+ {
+ if (player_node)
+ {
+ const Guild *const guild = player_node->getGuild();
+ if (guild)
+ {
+ if (guild->getServerGuild())
+ Net::getGuildHandler()->invite(guild->getId(), mNick);
+ else if (guildManager)
+ guildManager->invite(mNick);
+ }
+ }
+ }
+ else if (link == "nuke" && being)
+ {
+ if (actorSpriteManager)
+ {
+ actorSpriteManager->addBlock(static_cast<uint32_t>(
+ being->getId()));
+ actorSpriteManager->destroy(being);
+ }
+ }
+ // Follow Player action
+ else if (link == "follow" && !mNick.empty())
+ {
+ if (player_node)
+ player_node->setFollow(mNick);
+ }
+ else if (link == "imitation" && !mNick.empty())
+ {
+ if (player_node)
+ player_node->setImitate(mNick);
+ }
+ // Pick Up Floor Item action
+ else if ((link == "pickup") && mFloorItemId)
+ {
+ if (player_node && actorSpriteManager)
+ {
+ FloorItem *const item = actorSpriteManager->findItem(
+ mFloorItemId);
+ if (item)
+ player_node->pickUp(item);
+ }
+ }
+ else if (link == "use" && mItemId)
+ {
+ if (mItemId < SPELL_MIN_ID)
+ {
+ const Inventory *const inv = PlayerInfo::getInventory();
+ if (inv)
+ {
+ const Item *const item = inv->findItem(mItemId, mItemColor);
+ if (item)
+ {
+ if (item->isEquipment())
+ {
+ if (item->isEquipped())
+ Net::getInventoryHandler()->unequipItem(item);
+ else
+ Net::getInventoryHandler()->equipItem(item);
+ }
+ else
+ {
+ if (!PlayerInfo::isItemProtected(item->getId()))
+ Net::getInventoryHandler()->useItem(item);
+ }
+ }
+ }
+ }
+ else if (mItemId < SKILL_MIN_ID && spellManager)
+ {
+ spellManager->useItem(mItemId);
+ }
+ else if (skillDialog)
+ {
+ skillDialog->useItem(mItemId);
+ }
+ }
+ else if (link == "chat")
+ {
+ if (chatWindow)
+ {
+ if (mItem)
+ {
+ if (serverVersion > 0)
+ {
+ chatWindow->addItemText(mItem->getInfo().getName(
+ mItem->getColor()));
+ }
+ else
+ {
+ chatWindow->addItemText(mItem->getInfo().getName());
+ }
+ }
+ else if (mFloorItemId && actorSpriteManager)
+ {
+ const FloorItem *const item = actorSpriteManager->findItem(
+ mFloorItemId);
+
+ if (item)
+ {
+ if (serverVersion > 0)
+ {
+ chatWindow->addItemText(item->getInfo().getName(
+ item->getColor()));
+ }
+ else
+ {
+ chatWindow->addItemText(item->getInfo().getName());
+ }
+ }
+ }
+ }
+ }
+ else if (link == "whisper" && !mNick.empty() && chatWindow)
+ {
+ if (chatWindow)
+ {
+ if (config.getBoolValue("whispertab"))
+ {
+ chatWindow->localChatInput("/q " + mNick);
+ }
+ else
+ {
+ chatWindow->addInputText(std::string("/w \"").append(
+ mNick).append("\" "));
+ }
+ }
+ }
+ else if (link == "move" && !mNick.empty())
+ {
+ if (player_node)
+ {
+ if (being)
+ {
+ player_node->navigateTo(being->getTileX(), being->getTileY());
+ }
+ else if (player_node->isInParty())
+ {
+ const Party *const party = player_node->getParty();
+ if (party)
+ {
+ const PartyMember *const m = party->getMember(mNick);
+ const PartyMember *const o = party->getMember(
+ player_node->getName());
+ if (m && o && m->getMap() == o->getMap())
+ player_node->navigateTo(m->getX(), m->getY());
+ }
+ }
+ }
+ }
+ else if (link == "move" && (mX || mY))
+ {
+ if (player_node)
+ player_node->navigateTo(mX, mY);
+ }
+ else if (link == "movecamera" && (mX || mY))
+ {
+ if (viewport)
+ viewport->moveCameraToPosition(mX * 32, mY * 32);
+ }
+ else if (link == "split" && mItem)
+ {
+ ItemAmountWindow::showWindow(ItemAmountWindow::ItemSplit,
+ inventoryWindow, mItem);
+ }
+ else if (link == "drop" && mItem)
+ {
+ if (!PlayerInfo::isItemProtected(mItem->getId()))
+ {
+ ItemAmountWindow::showWindow(ItemAmountWindow::ItemDrop,
+ inventoryWindow, mItem);
+ }
+ }
+ else if (link == "drop all" && mItem)
+ {
+ if (!PlayerInfo::isItemProtected(mItem->getId()))
+ Net::getInventoryHandler()->dropItem(mItem, mItem->getQuantity());
+ }
+ else if (link == "store" && mItem)
+ {
+ ItemAmountWindow::showWindow(ItemAmountWindow::StoreAdd,
+ inventoryWindow, mItem);
+ }
+ else if (link == "store 10" && mItem)
+ {
+ int cnt = 10;
+ if (cnt > mItem->getQuantity())
+ cnt = mItem->getQuantity();
+ Net::getInventoryHandler()->moveItem2(Inventory::INVENTORY,
+ mItem->getInvIndex(), cnt,
+ Inventory::STORAGE);
+ }
+ else if (link == "store half" && mItem)
+ {
+ Net::getInventoryHandler()->moveItem2(Inventory::INVENTORY,
+ mItem->getInvIndex(), mItem->getQuantity() / 2,
+ Inventory::STORAGE);
+ }
+ else if (link == "store all-1" && mItem)
+ {
+ Net::getInventoryHandler()->moveItem2(Inventory::INVENTORY,
+ mItem->getInvIndex(), mItem->getQuantity() - 1,
+ Inventory::STORAGE);
+ }
+ else if (link == "store all" && mItem)
+ {
+ Net::getInventoryHandler()->moveItem2(Inventory::INVENTORY,
+ mItem->getInvIndex(), mItem->getQuantity(),
+ Inventory::STORAGE);
+ }
+ else if (link == "addtrade" && mItem)
+ {
+ if (!PlayerInfo::isItemProtected(mItem->getId()))
+ {
+ ItemAmountWindow::showWindow(ItemAmountWindow::TradeAdd,
+ tradeWindow, mItem);
+ }
+ }
+ else if (link == "addtrade 10" && mItem)
+ {
+ if (tradeWindow && !PlayerInfo::isItemProtected(mItem->getId()))
+ {
+ int cnt = 10;
+ if (cnt > mItem->getQuantity())
+ cnt = mItem->getQuantity();
+ tradeWindow->tradeItem(mItem, cnt, true);
+ }
+ }
+ else if (link == "addtrade half" && mItem)
+ {
+ if (tradeWindow && !PlayerInfo::isItemProtected(mItem->getId()))
+ tradeWindow->tradeItem(mItem, mItem->getQuantity() / 2, true);
+ }
+ else if (link == "addtrade all-1" && mItem)
+ {
+ if (tradeWindow && !PlayerInfo::isItemProtected(mItem->getId()))
+ tradeWindow->tradeItem(mItem, mItem->getQuantity() - 1, true);
+ }
+ else if (link == "addtrade all" && mItem)
+ {
+ if (tradeWindow && !PlayerInfo::isItemProtected(mItem->getId()))
+ tradeWindow->tradeItem(mItem, mItem->getQuantity(), true);
+ }
+ else if (link == "retrieve" && mItem)
+ {
+ ItemAmountWindow::showWindow(ItemAmountWindow::StoreRemove,
+ mWindow, mItem);
+ }
+ else if (link == "retrieve 10" && mItem)
+ {
+ int cnt = 10;
+ if (cnt > mItem->getQuantity())
+ cnt = mItem->getQuantity();
+ Net::getInventoryHandler()->moveItem2(Inventory::STORAGE,
+ mItem->getInvIndex(), cnt,
+ Inventory::INVENTORY);
+ }
+ else if (link == "retrieve half" && mItem)
+ {
+ Net::getInventoryHandler()->moveItem2(Inventory::STORAGE,
+ mItem->getInvIndex(), mItem->getQuantity() / 2,
+ Inventory::INVENTORY);
+ }
+ else if (link == "retrieve all-1" && mItem)
+ {
+ Net::getInventoryHandler()->moveItem2(Inventory::STORAGE,
+ mItem->getInvIndex(), mItem->getQuantity() - 1,
+ Inventory::INVENTORY);
+ }
+ else if (link == "retrieve all" && mItem)
+ {
+ Net::getInventoryHandler()->moveItem2(Inventory::STORAGE,
+ mItem->getInvIndex(), mItem->getQuantity(),
+ Inventory::INVENTORY);
+ }
+ else if (link == "protect item" && mItemId)
+ {
+ PlayerInfo::protectItem(mItemId);
+ }
+ else if (link == "unprotect item" && mItemId)
+ {
+ PlayerInfo::unprotectItem(mItemId);
+ }
+ else if (link == "party" && being &&
+ being->getType() == ActorSprite::PLAYER)
+ {
+ Net::getPartyHandler()->invite(being);
+ }
+ else if (link == "kick party" && being
+ && being->getType() == Being::PLAYER)
+ {
+ Net::getPartyHandler()->kick(being);
+ }
+ else if (link == "kick party" && !mNick.empty())
+ {
+ if (player_node && player_node->getParty())
+ {
+ const PartyMember *const member = player_node->
+ getParty()->getMember(mNick);
+ if (member)
+ Net::getPartyHandler()->kick(mNick);
+ }
+ }
+ else if (link == "name" && !mNick.empty())
+ {
+ const std::string &name = mNick;
+ if (chatWindow)
+ chatWindow->addInputText(name);
+ }
+ else if (link == "admin-kick" && being &&
+ (being->getType() == ActorSprite::PLAYER ||
+ being->getType() == ActorSprite::MONSTER))
+ {
+ Net::getAdminHandler()->kick(being->getId());
+ }
+ else if (link == "chat close" && mTab)
+ {
+ if (commandHandler)
+ commandHandler->invokeCommand("close", "", mTab);
+ }
+ else if (link == "leave party" && mTab)
+ {
+ Net::getPartyHandler()->leave();
+ }
+ else if (link == "chat clear" && mTab)
+ {
+ if (chatWindow)
+ chatWindow->clearTab();
+ }
+ else if (link == "warp map" && mMapItem)
+ {
+ if (Game::instance())
+ {
+ Net::getAdminHandler()->warp(Game::instance()->getCurrentMapName(),
+ mMapItem->getX(), mMapItem->getY());
+ }
+ }
+ else if (link == "warp map" && (mX || mY))
+ {
+ if (Game::instance())
+ {
+ Net::getAdminHandler()->warp(Game::instance()->getCurrentMapName(),
+ mX, mY);
+ }
+ }
+ else if (link == "remove map" && mMapItem)
+ {
+ if (viewport)
+ {
+ const Map *const map = viewport->getMap();
+ if (map)
+ {
+ SpecialLayer *const specialLayer = map->getSpecialLayer();
+ if (specialLayer)
+ {
+ const bool isHome = (mMapItem->getType()
+ == static_cast<int>(MapItem::HOME));
+ const int x = static_cast<const int>(mMapItem->getX());
+ const int y = static_cast<const int>(mMapItem->getY());
+ specialLayer->setTile(x, y,
+ static_cast<int>(MapItem::EMPTY));
+ if (socialWindow)
+ socialWindow->removePortal(x, y);
+ if (isHome && player_node)
+ {
+ player_node->removeHome();
+ player_node->saveHomes();
+ }
+ }
+ }
+ }
+ }
+ else if (link == "rename map" && mMapItem)
+ {
+ mRenameListener.setMapItem(mMapItem);
+ // TRANSLATORS: number of chars in string should be near original
+ mDialog = new TextDialog(_("Rename map sign "),
+ // TRANSLATORS: number of chars in string should be near original
+ _("Name: "));
+ mRenameListener.setDialog(mDialog);
+ mDialog->setText(mMapItem->getComment());
+ mDialog->setActionEventId("ok");
+ mDialog->addActionListener(&mRenameListener);
+ }
+ else if (link == "clear drops")
+ {
+ if (dropShortcut)
+ dropShortcut->clear();
+ }
+ else if (link == "edit spell" && mSpell)
+ {
+ new TextCommandEditor(mSpell);
+ }
+ else if (link == "undress" && being)
+ {
+ Net::getBeingHandler()->undress(being);
+ }
+ else if (link == "addcomment" && !mNick.empty())
+ {
+ // TRANSLATORS: number of chars in string should be near original
+ TextDialog *const dialog = new TextDialog(
+ _("Player comment "),
+ // TRANSLATORS: number of chars in string should be near original
+ _("Comment: "));
+ mPlayerListener.setDialog(dialog);
+ mPlayerListener.setNick(mNick);
+ mPlayerListener.setType(mType);
+
+ if (being)
+ {
+ being->updateComment();
+ dialog->setText(being->getComment());
+ }
+ else
+ {
+ dialog->setText(Being::loadComment(mNick, mType));
+ }
+ dialog->setActionEventId("ok");
+ dialog->addActionListener(&mPlayerListener);
+ }
+ else if (link == "guild-kick" && !mNick.empty())
+ {
+ if (player_node)
+ {
+ const Guild *const guild = player_node->getGuild();
+ if (guild)
+ {
+ if (guild->getServerGuild())
+ Net::getGuildHandler()->kick(guild->getMember(mNick), "");
+ else if (guildManager)
+ guildManager->kick(mNick);
+ }
+ }
+ }
+ else if (link == "enable highlight" && mTab)
+ {
+ if (commandHandler)
+ commandHandler->invokeCommand(COMMAND_ENABLEHIGHLIGHT, mTab);
+ }
+ else if (link == "disable highlight" && mTab)
+ {
+ if (commandHandler)
+ commandHandler->invokeCommand(COMMAND_DISABLEHIGHLIGHT, mTab);
+ }
+ else if (link == "dont remove name" && mTab)
+ {
+ if (commandHandler)
+ commandHandler->invokeCommand(COMMAND_DONTREMOVENAME, mTab);
+ }
+ else if (link == "remove name" && mTab)
+ {
+ if (commandHandler)
+ commandHandler->invokeCommand(COMMAND_REMOVENAME, mTab);
+ }
+ else if (link == "disable away" && mTab)
+ {
+ if (commandHandler)
+ commandHandler->invokeCommand(COMMAND_DISABLEAWAY, mTab);
+ }
+ else if (link == "enable away" && mTab)
+ {
+ if (commandHandler)
+ commandHandler->invokeCommand(COMMAND_ENABLEAWAY, mTab);
+ }
+ else if (link == "chat clipboard" && mTab)
+ {
+ if (chatWindow)
+ chatWindow->copyToClipboard(mX, mY);
+ }
+ else if (link == "npc clipboard" && mBeingId)
+ {
+ NpcDialog::copyToClipboard(mBeingId, mX, mY);
+ }
+ else if (link == "remove attack" && being)
+ {
+ if (actorSpriteManager && being->getType() == Being::MONSTER)
+ {
+ actorSpriteManager->removeAttackMob(being->getName());
+ if (socialWindow)
+ socialWindow->updateAttackFilter();
+ }
+ }
+ else if (link == "add attack" && being)
+ {
+ if (actorSpriteManager && being->getType() == Being::MONSTER)
+ {
+ actorSpriteManager->addAttackMob(being->getName());
+ if (socialWindow)
+ socialWindow->updateAttackFilter();
+ }
+ }
+ else if (link == "add attack priority" && being)
+ {
+ if (actorSpriteManager && being->getType() == Being::MONSTER)
+ {
+ actorSpriteManager->addPriorityAttackMob(being->getName());
+ if (socialWindow)
+ socialWindow->updateAttackFilter();
+ }
+ }
+ else if (link == "add attack ignore" && being)
+ {
+ if (actorSpriteManager && being->getType() == Being::MONSTER)
+ {
+ actorSpriteManager->addIgnoreAttackMob(being->getName());
+ if (socialWindow)
+ socialWindow->updateAttackFilter();
+ }
+ }
+ else if (link == "remove pickup" && !mNick.empty())
+ {
+ if (actorSpriteManager)
+ {
+ actorSpriteManager->removePickupItem(mNick);
+ if (socialWindow)
+ socialWindow->updatePickupFilter();
+ }
+ }
+ else if (link == "add pickup" && !mNick.empty())
+ {
+ if (actorSpriteManager)
+ {
+ actorSpriteManager->addPickupItem(mNick);
+ if (socialWindow)
+ socialWindow->updatePickupFilter();
+ }
+ }
+ else if (link == "add pickup ignore" && !mNick.empty())
+ {
+ if (actorSpriteManager)
+ {
+ actorSpriteManager->addIgnorePickupItem(mNick);
+ if (socialWindow)
+ socialWindow->updatePickupFilter();
+ }
+ }
+ else if (link == "attack moveup")
+ {
+ if (actorSpriteManager)
+ {
+ const int idx = actorSpriteManager->getAttackMobIndex(mNick);
+ if (idx > 0)
+ {
+ std::list<std::string> mobs
+ = actorSpriteManager->getAttackMobs();
+ std::list<std::string>::iterator it = mobs.begin();
+ std::list<std::string>::iterator it2 = mobs.begin();
+ while (it != mobs.end())
+ {
+ if (*it == mNick)
+ {
+ -- it2;
+ mobs.splice(it2, mobs, it);
+ actorSpriteManager->setAttackMobs(mobs);
+ actorSpriteManager->rebuildAttackMobs();
+ break;
+ }
+ ++ it;
+ ++ it2;
+ }
+
+ if (socialWindow)
+ socialWindow->updateAttackFilter();
+ }
+ }
+ }
+ else if (link == "priority moveup")
+ {
+ if (actorSpriteManager)
+ {
+ const int idx = actorSpriteManager->
+ getPriorityAttackMobIndex(mNick);
+ if (idx > 0)
+ {
+ std::list<std::string> mobs
+ = actorSpriteManager->getPriorityAttackMobs();
+ std::list<std::string>::iterator it = mobs.begin();
+ std::list<std::string>::iterator it2 = mobs.begin();
+ while (it != mobs.end())
+ {
+ if (*it == mNick)
+ {
+ -- it2;
+ mobs.splice(it2, mobs, it);
+ actorSpriteManager->setPriorityAttackMobs(mobs);
+ actorSpriteManager->rebuildPriorityAttackMobs();
+ break;
+ }
+ ++ it;
+ ++ it2;
+ }
+
+ if (socialWindow)
+ socialWindow->updateAttackFilter();
+ }
+ }
+ }
+ else if (link == "attack movedown")
+ {
+ if (actorSpriteManager)
+ {
+ const int idx = actorSpriteManager->getAttackMobIndex(mNick);
+ const int size = actorSpriteManager->getAttackMobsSize();
+ if (idx + 1 < size)
+ {
+ std::list<std::string> mobs
+ = actorSpriteManager->getAttackMobs();
+ std::list<std::string>::iterator it = mobs.begin();
+ std::list<std::string>::iterator it2 = mobs.begin();
+ while (it != mobs.end())
+ {
+ if (*it == mNick)
+ {
+ ++ it2;
+ if (it2 == mobs.end())
+ break;
+
+ mobs.splice(it, mobs, it2);
+ actorSpriteManager->setAttackMobs(mobs);
+ actorSpriteManager->rebuildAttackMobs();
+ break;
+ }
+ ++ it;
+ ++ it2;
+ }
+
+ if (socialWindow)
+ socialWindow->updateAttackFilter();
+ }
+ }
+ }
+ else if (link == "priority movedown")
+ {
+ if (player_node)
+ {
+ const int idx = actorSpriteManager
+ ->getPriorityAttackMobIndex(mNick);
+ const int size = actorSpriteManager->getPriorityAttackMobsSize();
+ if (idx + 1 < size)
+ {
+ std::list<std::string> mobs
+ = actorSpriteManager->getPriorityAttackMobs();
+ std::list<std::string>::iterator it = mobs.begin();
+ std::list<std::string>::iterator it2 = mobs.begin();
+ while (it != mobs.end())
+ {
+ if (*it == mNick)
+ {
+ ++ it2;
+ if (it2 == mobs.end())
+ break;
+
+ mobs.splice(it, mobs, it2);
+ actorSpriteManager->setPriorityAttackMobs(mobs);
+ actorSpriteManager->rebuildPriorityAttackMobs();
+ break;
+ }
+ ++ it;
+ ++ it2;
+ }
+
+ if (socialWindow)
+ socialWindow->updateAttackFilter();
+ }
+ }
+ }
+ else if (link == "attack remove")
+ {
+ if (actorSpriteManager)
+ {
+ if (mNick.empty())
+ {
+ if (actorSpriteManager->isInAttackList(mNick))
+ {
+ actorSpriteManager->removeAttackMob(mNick);
+ actorSpriteManager->addIgnoreAttackMob(mNick);
+ }
+ else
+ {
+ actorSpriteManager->removeAttackMob(mNick);
+ actorSpriteManager->addAttackMob(mNick);
+ }
+ }
+ else
+ {
+ actorSpriteManager->removeAttackMob(mNick);
+ }
+ if (socialWindow)
+ socialWindow->updateAttackFilter();
+ }
+ }
+ else if (link == "pickup remove")
+ {
+ if (actorSpriteManager)
+ {
+ if (mNick.empty())
+ {
+ if (actorSpriteManager->isInPickupList(mNick))
+ {
+ actorSpriteManager->removePickupItem(mNick);
+ actorSpriteManager->addIgnorePickupItem(mNick);
+ }
+ else
+ {
+ actorSpriteManager->removePickupItem(mNick);
+ actorSpriteManager->addPickupItem(mNick);
+ }
+ }
+ else
+ {
+ actorSpriteManager->removePickupItem(mNick);
+ }
+ if (socialWindow)
+ socialWindow->updatePickupFilter();
+ }
+ }
+ else if (link == "reset yellow")
+ {
+ if (player_node)
+ player_node->resetYellowBar();
+ }
+ else if (link == "bar to chat" && !mNick.empty())
+ {
+ if (chatWindow)
+ chatWindow->addInputText(mNick);
+ }
+ else if (link == "items" && being)
+ {
+ if (being == player_node)
+ {
+ if (equipmentWindow && !equipmentWindow->isWindowVisible())
+ equipmentWindow->setVisible(true);
+ }
+ else
+ {
+ if (beingEquipmentWindow)
+ {
+ beingEquipmentWindow->setBeing(being);
+ beingEquipmentWindow->setVisible(true);
+ }
+ }
+ }
+ else if (link == "undress item" && being && mItemId)
+ {
+ being->undressItemById(mItemId);
+ }
+ else if (link == "guild-pos" && !mNick.empty())
+ {
+ showChangePos(getX(), getY());
+ return;
+ }
+ else if (link == "clear outfit")
+ {
+ if (outfitWindow)
+ outfitWindow->clearCurrentOutfit();
+ }
+ else if (link == "clipboard copy")
+ {
+ if (mTextField)
+ mTextField->handleCopy();
+ }
+ else if (link == "clipboard paste")
+ {
+ if (mTextField)
+ mTextField->handlePaste();
+ }
+ else if (link == "open link" && !mNick.empty())
+ {
+ openBrowser(mNick);
+ }
+ else if (link == "clipboard link" && !mNick.empty())
+ {
+ sendBuffer(mNick);
+ }
+ else if (link == "goto" && !mNick.empty())
+ {
+ Net::getAdminHandler()->gotoName(mNick);
+ }
+ else if (link == "recall" && !mNick.empty())
+ {
+ Net::getAdminHandler()->recallName(mNick);
+ }
+ else if (link == "revive" && !mNick.empty())
+ {
+ Net::getAdminHandler()->reviveName(mNick);
+ }
+ else if (link == "ipcheck" && !mNick.empty())
+ {
+ Net::getAdminHandler()->ipcheckName(mNick);
+ }
+ else if (link == "gm" && !mNick.empty())
+ {
+ showGMPopup();
+ return;
+ }
+ else if (!link.compare(0, 10, "guild-pos-"))
+ {
+ if (player_node)
+ {
+ const int num = atoi(link.substr(10).c_str());
+ const Guild *const guild = player_node->getGuild();
+ if (guild)
+ {
+ Net::getGuildHandler()->changeMemberPostion(
+ guild->getMember(mNick), num);
+ }
+ }
+ }
+ else if (!link.compare(0, 7, "player_"))
+ {
+ if (actorSpriteManager)
+ {
+ mBeingId = atoi(link.substr(7).c_str());
+ being = actorSpriteManager->findBeing(mBeingId);
+ if (being)
+ {
+ showPopup(getX(), getY(), being);
+ return;
+ }
+ }
+ }
+ else if (!link.compare(0, 10, "flooritem_"))
+ {
+ if (actorSpriteManager)
+ {
+ const int id = atoi(link.substr(10).c_str());
+ if (id)
+ {
+ const FloorItem *const item = actorSpriteManager->findItem(id);
+ if (item)
+ {
+ mFloorItemId = item->getId();
+ showPopup(getX(), getY(), item);
+ return;
+ }
+ }
+ }
+ }
+ else if (!link.compare(0, 12, "hide button_"))
+ {
+ if (windowMenu)
+ windowMenu->showButton(link.substr(12), false);
+ }
+ else if (!link.compare(0, 12, "show button_"))
+ {
+ if (windowMenu)
+ windowMenu->showButton(link.substr(12), true);
+ }
+ else if (!link.compare(0, 9, "hide bar_"))
+ {
+ if (miniStatusWindow)
+ miniStatusWindow->showBar(link.substr(9), false);
+ }
+ else if (!link.compare(0, 9, "show bar_"))
+ {
+ if (miniStatusWindow)
+ miniStatusWindow->showBar(link.substr(9), true);
+ }
+ else if (!link.compare(0, 12, "show window_"))
+ {
+ const int id = atoi(link.substr(12).c_str());
+ if (id >= 0)
+ inputManager.executeAction(id);
+ }
+ // Unknown actions
+ else if (link != "cancel")
+ {
+ logger->log("PopupMenu: Warning, unknown action '%s'", link.c_str());
+ }
+
+ setVisible(false);
+
+ mBeingId = 0;
+ mFloorItemId = 0;
+ mItem = nullptr;
+ mItemId = 0;
+ mItemColor = 1;
+ mMapItem = nullptr;
+ mTab = nullptr;
+ mSpell = nullptr;
+ mWindow = nullptr;
+ mDialog = nullptr;
+ mButton = nullptr;
+ mNick.clear();
+ mTextField = nullptr;
+ mType = static_cast<int>(Being::UNKNOWN);
+ mX = 0;
+ mY = 0;
+}
+
+void PopupMenu::showPopup(Window *const parent, const int x, const int y,
+ Item *const item, const bool isInventory)
+{
+ if (!item)
+ return;
+
+ mItem = item;
+ mItemId = item->getId();
+ mItemColor = item->getColor();
+ mWindow = parent;
+ mX = x;
+ mY = y;
+ mNick.clear();
+ mBrowserBox->clearRows();
+
+ const int cnt = item->getQuantity();
+ const bool isProtected = PlayerInfo::isItemProtected(mItemId);
+
+ if (isInventory)
+ {
+ if (tradeWindow && tradeWindow->isWindowVisible() && !isProtected)
+ {
+ // TRANSLATORS: popup menu item
+ // TRANSLATORS: add item to trade
+ mBrowserBox->addRow("addtrade", _("Add to trade"));
+ if (cnt > 1)
+ {
+ if (cnt > 10)
+ {
+ // TRANSLATORS: popup menu item
+ // TRANSLATORS: add 10 item amount to trade
+ mBrowserBox->addRow("addtrade 10", _("Add to trade 10"));
+ }
+ // TRANSLATORS: popup menu item
+ // TRANSLATORS: add half item amount to trade
+ mBrowserBox->addRow("addtrade half", _("Add to trade half"));
+ // TRANSLATORS: popup menu item
+ // TRANSLATORS: add all amount except one item to trade
+ mBrowserBox->addRow("addtrade all-1", _("Add to trade all-1"));
+ // TRANSLATORS: popup menu item
+ // TRANSLATORS: add all amount item to trade
+ mBrowserBox->addRow("addtrade all", _("Add to trade all"));
+ }
+ mBrowserBox->addRow("##3---");
+ }
+ if (InventoryWindow::isStorageActive())
+ {
+ // TRANSLATORS: popup menu item
+ // TRANSLATORS: add item to storage
+ mBrowserBox->addRow("store", _("Store"));
+ if (cnt > 1)
+ {
+ if (cnt > 10)
+ {
+ // TRANSLATORS: popup menu item
+ // TRANSLATORS: add 10 item amount to storage
+ mBrowserBox->addRow("store 10", _("Store 10"));
+ }
+ // TRANSLATORS: popup menu item
+ // TRANSLATORS: add half item amount to storage
+ mBrowserBox->addRow("store half", _("Store half"));
+ // TRANSLATORS: popup menu item
+ // TRANSLATORS: add all except one item amount to storage
+ mBrowserBox->addRow("store all-1", _("Store all-1"));
+ // TRANSLATORS: popup menu item
+ // TRANSLATORS: add all item amount to storage
+ mBrowserBox->addRow("store all", _("Store all"));
+ }
+ mBrowserBox->addRow("##3---");
+ }
+
+ addUseDrop(item, isProtected);
+ }
+ // Assume in storage for now
+ else
+ {
+ // TRANSLATORS: popup menu item
+ // TRANSLATORS: get item from storage
+ mBrowserBox->addRow("retrieve", _("Retrieve"));
+ if (cnt > 1)
+ {
+ if (cnt > 10)
+ {
+ // TRANSLATORS: popup menu item
+ // TRANSLATORS: get 10 item amount from storage
+ mBrowserBox->addRow("retrieve 10", _("Retrieve 10"));
+ }
+ // TRANSLATORS: popup menu item
+ // TRANSLATORS: get half item amount from storage
+ mBrowserBox->addRow("retrieve half", _("Retrieve half"));
+ // TRANSLATORS: popup menu item
+ // TRANSLATORS: get all except one item amount from storage
+ mBrowserBox->addRow("retrieve all-1", _("Retrieve all-1"));
+ // TRANSLATORS: popup menu item
+ // TRANSLATORS: get all item amount from storage
+ mBrowserBox->addRow("retrieve all", _("Retrieve all"));
+ }
+ }
+ addProtection();
+ if (config.getBoolValue("enablePickupFilter"))
+ {
+ mNick = item->getName();
+ mBrowserBox->addRow("##3---");
+ addPickupFilter(mNick);
+ }
+ // TRANSLATORS: popup menu item
+ // TRANSLATORS: add item name to chat
+ mBrowserBox->addRow("chat", _("Add to chat"));
+ mBrowserBox->addRow("##3---");
+ // TRANSLATORS: popup menu item
+ // TRANSLATORS: close menu
+ mBrowserBox->addRow("cancel", _("Cancel"));
+
+ showPopup(x, y);
+}
+
+void PopupMenu::showItemPopup(const int x, const int y, const int itemId,
+ const unsigned char color)
+{
+ const Inventory *const inv = PlayerInfo::getInventory();
+ if (!inv)
+ return;
+
+ Item *const item = inv->findItem(itemId, color);
+ if (item)
+ {
+ showItemPopup(x, y, item);
+ }
+ else
+ {
+ mItem = nullptr;
+ mItemId = itemId;
+ mItemColor = color;
+ mX = x;
+ mY = y;
+ mBrowserBox->clearRows();
+
+ if (!PlayerInfo::isItemProtected(mItemId))
+ {
+ // TRANSLATORS: popup menu item
+ // TRANSLATORS: use item
+ mBrowserBox->addRow("use", _("Use"));
+ }
+ addProtection();
+ mBrowserBox->addRow("##3---");
+ // TRANSLATORS: popup menu item
+ // TRANSLATORS: close menu
+ mBrowserBox->addRow("cancel", _("Cancel"));
+
+ showPopup(x, y);
+ }
+}
+
+void PopupMenu::showItemPopup(const int x, const int y, Item *const item)
+{
+ mItem = item;
+ mX = x;
+ mY = y;
+ if (item)
+ {
+ mItemId = item->getId();
+ mItemColor = item->getColor();
+ }
+ else
+ {
+ mItemId = 0;
+ mItemColor = 1;
+ }
+ mNick.clear();
+ mBrowserBox->clearRows();
+
+ if (item)
+ {
+ const bool isProtected = PlayerInfo::isItemProtected(mItemId);
+ addUseDrop(item, isProtected);
+ if (InventoryWindow::isStorageActive())
+ {
+ // TRANSLATORS: popup menu item
+ // TRANSLATORS: add item to storage
+ mBrowserBox->addRow("store", _("Store"));
+ }
+ // TRANSLATORS: popup menu item
+ // TRANSLATORS: add item name to chat
+ mBrowserBox->addRow("chat", _("Add to chat"));
+
+ if (config.getBoolValue("enablePickupFilter"))
+ {
+ mNick = item->getName();
+
+ mBrowserBox->addRow("##3---");
+ addPickupFilter(mNick);
+ }
+ }
+ addProtection();
+ mBrowserBox->addRow("##3---");
+ // TRANSLATORS: popup menu item
+ // TRANSLATORS: close menu
+ mBrowserBox->addRow("cancel", _("Cancel"));
+
+ showPopup(x, y);
+}
+
+void PopupMenu::showDropPopup(const int x, const int y, Item *const item)
+{
+ mItem = item;
+ mX = x;
+ mY = y;
+ mNick.clear();
+ mBrowserBox->clearRows();
+
+ if (item)
+ {
+ mItemId = item->getId();
+ mItemColor = item->getColor();
+ const bool isProtected = PlayerInfo::isItemProtected(mItemId);
+ addUseDrop(item, isProtected);
+ if (InventoryWindow::isStorageActive())
+ {
+ // TRANSLATORS: popup menu item
+ // TRANSLATORS: add item to storage
+ mBrowserBox->addRow("store", _("Store"));
+ }
+ addProtection();
+ // TRANSLATORS: popup menu item
+ // TRANSLATORS: add item name to chat
+ mBrowserBox->addRow("chat", _("Add to chat"));
+ if (config.getBoolValue("enablePickupFilter"))
+ {
+ mNick = item->getName();
+ mBrowserBox->addRow("##3---");
+ addPickupFilter(mNick);
+ }
+ }
+ mBrowserBox->addRow("##3---");
+ // TRANSLATORS: popup menu item
+ mBrowserBox->addRow("clear drops", _("Clear drop window"));
+ mBrowserBox->addRow("##3---");
+ // TRANSLATORS: popup menu item
+ // TRANSLATORS: close menu
+ mBrowserBox->addRow("cancel", _("Cancel"));
+
+ showPopup(x, y);
+}
+
+void PopupMenu::showPopup(const int x, const int y, Button *const button)
+{
+ if (!button || !windowMenu)
+ return;
+
+ mButton = button;
+ mX = x;
+ mY = y;
+
+ mBrowserBox->clearRows();
+ std::vector<Button *> names = windowMenu->getButtons();
+ for (std::vector<Button *>::const_iterator it = names.begin(),
+ it_end = names.end(); it != it_end; ++ it)
+ {
+ const Button *const btn = dynamic_cast<Button*>(*it);
+ if (!btn || btn->getActionEventId() == "SET")
+ continue;
+
+ if (btn->isVisible())
+ {
+ mBrowserBox->addRow(strprintf("@@hide button_%s|%s %s (%s)@@",
+ // TRANSLATORS: popup menu item
+ btn->getActionEventId().c_str(), _("Hide"),
+ btn->getDescription().c_str(), btn->getCaption().c_str()));
+ }
+ else
+ {
+ mBrowserBox->addRow(strprintf("@@show button_%s|%s %s (%s)@@",
+ // TRANSLATORS: popup menu item
+ btn->getActionEventId().c_str(), _("Show"),
+ btn->getDescription().c_str(), btn->getCaption().c_str()));
+ }
+ }
+ mBrowserBox->addRow("##3---");
+ // TRANSLATORS: popup menu item
+ // TRANSLATORS: close menu
+ mBrowserBox->addRow("cancel", _("Cancel"));
+
+ showPopup(x, y);
+}
+
+void PopupMenu::showPopup(const int x, const int y, const ProgressBar *const b)
+{
+ if (!b || !miniStatusWindow)
+ return;
+
+ mNick = b->text();
+ mX = x;
+ mY = y;
+
+ mBrowserBox->clearRows();
+ std::vector <ProgressBar*> bars = miniStatusWindow->getBars();
+ ProgressBar *onlyBar = nullptr;
+ int cnt = 0;
+
+ // search for alone visible bar
+ for (std::vector <ProgressBar*>::const_iterator it = bars.begin(),
+ it_end = bars.end(); it != it_end; ++it)
+ {
+ ProgressBar *const bar = *it;
+ if (!bar)
+ continue;
+
+ if (bar->isVisible())
+ {
+ cnt ++;
+ onlyBar = bar;
+ }
+ }
+ if (cnt > 1)
+ onlyBar = nullptr;
+
+ for (std::vector <ProgressBar*>::const_iterator it = bars.begin(),
+ it_end = bars.end(); it != it_end; ++it)
+ {
+ ProgressBar *const bar = *it;
+ if (!bar || bar == onlyBar)
+ continue;
+
+ if (bar->isVisible())
+ {
+ mBrowserBox->addRow(strprintf("@@hide bar_%s|%s %s@@",
+ // TRANSLATORS: popup menu item
+ bar->getActionEventId().c_str(), _("Hide"),
+ bar->getId().c_str()));
+ }
+ else
+ {
+ mBrowserBox->addRow(strprintf("@@show bar_%s|%s %s@@",
+ // TRANSLATORS: popup menu item
+ bar->getActionEventId().c_str(), _("Show"),
+ bar->getId().c_str()));
+ }
+ }
+
+ mBrowserBox->addRow("##3---");
+ // TRANSLATORS: popup menu item
+ mBrowserBox->addRow("reset yellow", _("Reset yellow bar"));
+ mBrowserBox->addRow("##3---");
+ // TRANSLATORS: popup menu item
+ // TRANSLATORS: copy status to chat
+ mBrowserBox->addRow("bar to chat", _("Copy to chat"));
+ // TRANSLATORS: popup menu item
+ // TRANSLATORS: close menu
+ mBrowserBox->addRow("cancel", _("Cancel"));
+
+ showPopup(x, y);
+}
+
+void PopupMenu::showAttackMonsterPopup(const int x, const int y,
+ const std::string &name, const int type)
+{
+ if (!player_node || !actorSpriteManager)
+ return;
+
+ mNick = name;
+ mType = static_cast<int>(Being::MONSTER);
+ mX = x;
+ mY = y;
+
+ mBrowserBox->clearRows();
+
+ if (name.empty())
+ {
+ // TRANSLATORS: popup menu header
+ mBrowserBox->addRow(_("(default)"));
+ }
+ else
+ {
+ mBrowserBox->addRow(name);
+ }
+ switch (type)
+ {
+ case MapItem::ATTACK:
+ {
+ const int idx = actorSpriteManager->getAttackMobIndex(name);
+ const int size = actorSpriteManager->getAttackMobsSize();
+ if (idx > 0)
+ {
+ // TRANSLATORS: popup menu item
+ // TRANSLATORS: move attack target up
+ mBrowserBox->addRow("attack moveup", _("Move up"));
+ }
+ if (idx + 1 < size)
+ {
+ // TRANSLATORS: popup menu item
+ // TRANSLATORS: move attack target down
+ mBrowserBox->addRow("attack movedown", _("Move down"));
+ }
+ break;
+ }
+ case MapItem::PRIORITY:
+ {
+ const int idx = actorSpriteManager->
+ getPriorityAttackMobIndex(name);
+ const int size = actorSpriteManager->getPriorityAttackMobsSize();
+ if (idx > 0)
+ {
+ // TRANSLATORS: popup menu item
+ // TRANSLATORS: move attack target up
+ mBrowserBox->addRow("priority moveup", _("Move up"));
+ }
+ if (idx + 1 < size)
+ {
+ // TRANSLATORS: popup menu item
+ // TRANSLATORS: move attack target down
+ mBrowserBox->addRow("priority movedown", _("Move down"));
+ }
+ break;
+ }
+ case MapItem::IGNORE_:
+ break;
+ default:
+ break;
+ }
+
+ // TRANSLATORS: popup menu item
+ // TRANSLATORS: remove attack target
+ mBrowserBox->addRow("attack remove", _("Remove"));
+ mBrowserBox->addRow("##3---");
+ // TRANSLATORS: popup menu item
+ // TRANSLATORS: close menu
+ mBrowserBox->addRow("cancel", _("Cancel"));
+
+ showPopup(x, y);
+}
+
+void PopupMenu::showPickupItemPopup(const int x, const int y, std::string name)
+{
+ if (!player_node || !actorSpriteManager)
+ return;
+
+ mNick = name;
+ mType = static_cast<int>(Being::FLOOR_ITEM);
+ mX = x;
+ mY = y;
+
+ mBrowserBox->clearRows();
+
+ if (name.empty())
+ {
+ // TRANSLATORS: popup menu header
+ mBrowserBox->addRow(_("(default)"));
+ }
+ else
+ {
+ mBrowserBox->addRow(name);
+ }
+
+ // TRANSLATORS: popup menu item
+ // TRANSLATORS: remove item from pickup filter
+ mBrowserBox->addRow("pickup remove", _("Remove"));
+ mBrowserBox->addRow("##3---");
+ // TRANSLATORS: popup menu item
+ // TRANSLATORS: close menu
+ mBrowserBox->addRow("cancel", _("Cancel"));
+
+ showPopup(x, y);
+}
+
+void PopupMenu::showUndressPopup(const int x, const int y,
+ const Being *const being, Item *const item)
+{
+ if (!being || !item)
+ return;
+
+ mBeingId = being->getId();
+ mItem = item;
+ mItemId = item->getId();
+ mItemColor = item->getColor();
+ mX = x;
+ mY = y;
+
+ mBrowserBox->clearRows();
+
+ // TRANSLATORS: popup menu item
+ // TRANSLATORS: undress item from player
+ mBrowserBox->addRow("undress item", _("Undress"));
+ mBrowserBox->addRow("##3---");
+ // TRANSLATORS: popup menu item
+ // TRANSLATORS: close menu
+ mBrowserBox->addRow("cancel", _("Cancel"));
+
+ showPopup(x, y);
+}
+
+void PopupMenu::showTextFieldPopup(int x, int y, TextField *const input)
+{
+ mX = x;
+ mY = y;
+ mTextField = input;
+
+ mBrowserBox->clearRows();
+
+ // TRANSLATORS: popup menu item
+ // TRANSLATORS: copy text to clipboard
+ mBrowserBox->addRow("clipboard copy", _("Copy"));
+ // TRANSLATORS: popup menu item
+ // TRANSLATORS: paste text from clipboard
+ mBrowserBox->addRow("clipboard paste", _("Paste"));
+ mBrowserBox->addRow("##3---");
+ // TRANSLATORS: popup menu item
+ // TRANSLATORS: close menu
+ mBrowserBox->addRow("cancel", _("Cancel"));
+
+ showPopup(x, y);
+}
+
+void PopupMenu::showLinkPopup(const int x, const int y,
+ const std::string &link)
+{
+ mX = x;
+ mY = y;
+ mNick = link;
+
+ mBrowserBox->clearRows();
+
+ // TRANSLATORS: popup menu item
+ // TRANSLATORS: open link in browser
+ mBrowserBox->addRow("open link", _("Open link"));
+ // TRANSLATORS: popup menu item
+ // TRANSLATORS: copy link to clipboard
+ mBrowserBox->addRow("clipboard link", _("Copy to clipboard"));
+ mBrowserBox->addRow("##3---");
+ // TRANSLATORS: popup menu item
+ // TRANSLATORS: close menu
+ mBrowserBox->addRow("cancel", _("Cancel"));
+
+ showPopup(x, y);
+}
+
+void PopupMenu::showWindowsPopup(const int x, const int y)
+{
+ mX = x;
+ mY = y;
+
+ mBrowserBox->clearRows();
+ const std::vector<ButtonText*> &names = windowMenu->getButtonTexts();
+ // TRANSLATORS: popup menu header
+ mBrowserBox->addRow(_("Show window"));
+
+ FOR_EACH (std::vector<ButtonText*>::const_iterator, it, names)
+ {
+ const ButtonText *const btn = *it;
+ if (!btn)
+ continue;
+
+ mBrowserBox->addRow(strprintf("show window_%d", btn->key),
+ btn->text.c_str());
+ }
+ mBrowserBox->addRow("##3---");
+ // TRANSLATORS: popup menu item
+ // TRANSLATORS: close menu
+ mBrowserBox->addRow("cancel", _("Cancel"));
+
+ showPopup(x, y);
+}
+
+void PopupMenu::showNpcDialogPopup(const int npcId, const int x, const int y)
+{
+ mBeingId = npcId;
+ mX = x;
+ mY = y;
+ mBrowserBox->clearRows();
+ // TRANSLATORS: popup menu item
+ // TRANSLATORS: copy npc text to clipboard
+ mBrowserBox->addRow("npc clipboard", _("Copy to clipboard"));
+ mBrowserBox->addRow("##3---");
+ // TRANSLATORS: popup menu item
+ // TRANSLATORS: close menu
+ mBrowserBox->addRow("cancel", _("Cancel"));
+
+ showPopup(x, y);
+}
+
+void PopupMenu::showPopup(int x, int y)
+{
+ const int pad2 = 2 * mPadding;
+ const int bPad2 = 2 * mBrowserBox->getPadding();
+ mBrowserBox->setPosition(mPadding, mPadding);
+ mScrollArea->setPosition(mPadding, mPadding);
+ // add padding to initial size before draw browserbox
+ int height = mBrowserBox->getHeight();
+ if (height + pad2 >= mainGraphics->getHeight())
+ {
+ height = mainGraphics->getHeight() - bPad2 - pad2;
+ mBrowserBox->setWidth(mBrowserBox->getWidth() + bPad2 + 5);
+ mScrollArea->setWidth(mBrowserBox->getWidth() + pad2 + 10);
+ setContentSize(mBrowserBox->getWidth() + pad2 + 20,
+ height + pad2);
+ }
+ else
+ {
+ mBrowserBox->setWidth(mBrowserBox->getWidth() + bPad2);
+ mScrollArea->setWidth(mBrowserBox->getWidth() + pad2);
+ setContentSize(mBrowserBox->getWidth() + pad2,
+ height + pad2);
+ }
+ if (mainGraphics->mWidth < (x + getWidth() + 5))
+ x = mainGraphics->mWidth - getWidth();
+ if (mainGraphics->mHeight < (y + getHeight() + 5))
+ y = mainGraphics->mHeight - getHeight();
+ mScrollArea->setHeight(height);
+ setPosition(x, y);
+ setVisible(true);
+ requestMoveToTop();
+}
+
+void PopupMenu::addPlayerRelation(const std::string &name)
+{
+ switch (player_relations.getRelation(name))
+ {
+ case PlayerRelation::NEUTRAL:
+ // TRANSLATORS: popup menu item
+ // TRANSLATORS: add player to friends list
+ mBrowserBox->addRow("friend", _("Be friend"));
+ // TRANSLATORS: popup menu item
+ // TRANSLATORS: add player to disregarded list
+ mBrowserBox->addRow("disregard", _("Disregard"));
+ // TRANSLATORS: popup menu item
+ // TRANSLATORS: add player to ignore list
+ mBrowserBox->addRow("ignore", _("Ignore"));
+ // TRANSLATORS: popup menu item
+ // TRANSLATORS: add player to black list
+ mBrowserBox->addRow("blacklist", _("Black list"));
+ // TRANSLATORS: popup menu item
+ // TRANSLATORS: add player to enemy list
+ mBrowserBox->addRow("enemy", _("Set as enemy"));
+ // TRANSLATORS: popup menu item
+ // TRANSLATORS: add player to erased list
+ mBrowserBox->addRow("erase", _("Erase"));
+ break;
+
+ case PlayerRelation::FRIEND:
+ // TRANSLATORS: popup menu item
+ // TRANSLATORS: add player to disregarded list
+ mBrowserBox->addRow("disregard", _("Disregard"));
+ // TRANSLATORS: popup menu item
+ // TRANSLATORS: add player to ignore list
+ mBrowserBox->addRow("ignore", _("Ignore"));
+ // TRANSLATORS: popup menu item
+ // TRANSLATORS: add player to black list
+ mBrowserBox->addRow("blacklist", _("Black list"));
+ // TRANSLATORS: popup menu item
+ // TRANSLATORS: add player to enemy list
+ mBrowserBox->addRow("enemy", _("Set as enemy"));
+ // TRANSLATORS: popup menu item
+ // TRANSLATORS: add player to erased list
+ mBrowserBox->addRow("erase", _("Erase"));
+ break;
+
+ case PlayerRelation::BLACKLISTED:
+ // TRANSLATORS: popup menu item
+ // TRANSLATORS: remove player from ignore list
+ mBrowserBox->addRow("unignore", _("Unignore"));
+ // TRANSLATORS: popup menu item
+ // TRANSLATORS: add player to disregarded list
+ mBrowserBox->addRow("disregard", _("Disregard"));
+ // TRANSLATORS: popup menu item
+ // TRANSLATORS: add player to ignore list
+ mBrowserBox->addRow("ignore", _("Ignore"));
+ // TRANSLATORS: popup menu item
+ // TRANSLATORS: add player to enemy list
+ mBrowserBox->addRow("enemy", _("Set as enemy"));
+ // TRANSLATORS: popup menu item
+ // TRANSLATORS: add player to erased list
+ mBrowserBox->addRow("erase", _("Erase"));
+ break;
+
+ case PlayerRelation::DISREGARDED:
+ // TRANSLATORS: popup menu item
+ // TRANSLATORS: remove player from ignore list
+ mBrowserBox->addRow("unignore", _("Unignore"));
+ // TRANSLATORS: popup menu item
+ // TRANSLATORS: add player to completle ignore list
+ mBrowserBox->addRow("ignore", _("Completely ignore"));
+ // TRANSLATORS: popup menu item
+ // TRANSLATORS: add player to erased list
+ mBrowserBox->addRow("erase", _("Erase"));
+ break;
+
+ case PlayerRelation::IGNORED:
+ // TRANSLATORS: popup menu item
+ // TRANSLATORS: remove player from ignore list
+ mBrowserBox->addRow("unignore", _("Unignore"));
+ // TRANSLATORS: popup menu item
+ // TRANSLATORS: add player to erased list
+ mBrowserBox->addRow("erase", _("Erase"));
+ break;
+
+ case PlayerRelation::ENEMY2:
+ // TRANSLATORS: popup menu item
+ // TRANSLATORS: remove player from ignore list
+ mBrowserBox->addRow("unignore", _("Unignore"));
+ // TRANSLATORS: popup menu item
+ // TRANSLATORS: add player to disregarded list
+ mBrowserBox->addRow("disregard", _("Disregard"));
+ // TRANSLATORS: popup menu item
+ // TRANSLATORS: add player to ignore list
+ mBrowserBox->addRow("ignore", _("Ignore"));
+ // TRANSLATORS: popup menu item
+ // TRANSLATORS: add player to black list
+ mBrowserBox->addRow("blacklist", _("Black list"));
+ // TRANSLATORS: popup menu item
+ // TRANSLATORS: add player to erased list
+ mBrowserBox->addRow("erase", _("Erase"));
+ break;
+
+ case PlayerRelation::ERASED:
+ // TRANSLATORS: popup menu item
+ // TRANSLATORS: remove player from ignore list
+ mBrowserBox->addRow("unignore", _("Unignore"));
+ // TRANSLATORS: popup menu item
+ // TRANSLATORS: add player to disregarded list
+ mBrowserBox->addRow("disregard", _("Disregard"));
+ // TRANSLATORS: popup menu item
+ // TRANSLATORS: add player to ignore list
+ mBrowserBox->addRow("ignore", _("Completely ignore"));
+ break;
+
+ default:
+ break;
+ }
+}
+
+void PopupMenu::addFollow()
+{
+ // TRANSLATORS: popup menu item
+ mBrowserBox->addRow("follow", _("Follow"));
+ // TRANSLATORS: popup menu item
+ // TRANSLATORS: imitate player
+ mBrowserBox->addRow("imitation", _("Imitation"));
+}
+
+void PopupMenu::addBuySell(const Being *const being)
+{
+ if (player_relations.getDefault() & PlayerRelation::TRADE)
+ {
+ mBrowserBox->addRow("##3---");
+ if (being->isAdvanced())
+ {
+ if (being->isShopEnabled())
+ {
+ // TRANSLATORS: popup menu item
+ // TRANSLATORS: buy item
+ mBrowserBox->addRow("buy", _("Buy"));
+ // TRANSLATORS: popup menu item
+ // TRANSLATORS: sell item
+ mBrowserBox->addRow("sell", _("Sell"));
+ }
+ }
+ else
+ {
+ // TRANSLATORS: popup menu item
+ // TRANSLATORS: buy item
+ mBrowserBox->addRow("buy", _("Buy (?)"));
+ // TRANSLATORS: popup menu item
+ // TRANSLATORS: sell item
+ mBrowserBox->addRow("sell", _("Sell (?)"));
+ }
+ }
+}
+
+void PopupMenu::addBuySellDefault()
+{
+ if (player_relations.getDefault() & PlayerRelation::TRADE)
+ {
+ mBrowserBox->addRow("##3---");
+ // TRANSLATORS: popup menu item
+ // TRANSLATORS: buy item
+ mBrowserBox->addRow("buy", _("Buy (?)"));
+ // TRANSLATORS: popup menu item
+ // TRANSLATORS: sell item
+ mBrowserBox->addRow("sell", _("Sell (?)"));
+ }
+}
+
+void PopupMenu::addParty(const std::string &partyName)
+{
+ if (player_node->isInParty())
+ {
+ if (player_node->getParty())
+ {
+ if (player_node->getParty()->getName() != partyName)
+ {
+ // TRANSLATORS: popup menu item
+ // TRANSLATORS: invite player to party
+ mBrowserBox->addRow("party", _("Invite to party"));
+ }
+ else
+ {
+ // TRANSLATORS: popup menu item
+ // TRANSLATORS: kick player from party
+ mBrowserBox->addRow("kick party", _("Kick from party"));
+ }
+ mBrowserBox->addRow("##3---");
+ }
+ }
+}
+
+void PopupMenu::addPlayerMisc()
+{
+ // TRANSLATORS: popup menu item
+ mBrowserBox->addRow("items", _("Show Items"));
+ // TRANSLATORS: popup menu item
+ // TRANSLATORS: undress player
+ mBrowserBox->addRow("undress", _("Undress"));
+ // TRANSLATORS: popup menu item
+ // TRANSLATORS: add comment to player
+ mBrowserBox->addRow("addcomment", _("Add comment"));
+}
+
+void PopupMenu::addPickupFilter(const std::string &name)
+{
+ if (actorSpriteManager->isInPickupList(name)
+ || actorSpriteManager->isInIgnorePickupList(name))
+ {
+ mBrowserBox->addRow("remove pickup",
+ // TRANSLATORS: popup menu item
+ // TRANSLATORS: remove item from pickup list
+ _("Remove from pickup list"));
+ }
+ else
+ {
+ // TRANSLATORS: popup menu item
+ mBrowserBox->addRow("add pickup", _("Add to pickup list"));
+ mBrowserBox->addRow("add pickup ignore",
+ // TRANSLATORS: popup menu item
+ // TRANSLATORS: add item to pickup list
+ _("Add to ignore list"));
+ }
+}
+
+void PopupMenu::showPopup(const int x, const int y,
+ gcn::ListModel *const model)
+{
+ if (!model)
+ return;
+
+ mBrowserBox->clearRows();
+ for (int f = 0, sz = model->getNumberOfElements(); f < sz; f ++)
+ {
+ mBrowserBox->addRow(strprintf("dropdown_%d", f),
+ model->getElementAt(f).c_str());
+ }
+ // TRANSLATORS: popup menu item
+ // TRANSLATORS: close menu
+ mBrowserBox->addRow("cancel", _("Cancel"));
+ showPopup(x, y);
+}
+
+void PopupMenu::clear()
+{
+ if (mDialog)
+ {
+ mDialog->close();
+ mDialog = nullptr;
+ }
+ mItem = nullptr;
+ mMapItem = nullptr;
+ mTab = nullptr;
+ mSpell = nullptr;
+ mWindow = nullptr;
+ mButton = nullptr;
+ mTextField = nullptr;
+}
+
+void PopupMenu::addProtection()
+{
+ if (PlayerInfo::isItemProtected(mItemId))
+ {
+ mBrowserBox->addRow("##3---");
+ // TRANSLATORS: popup menu item
+ // TRANSLATORS: remove protection from item
+ mBrowserBox->addRow("unprotect item", _("Unprotect item"));
+ }
+ else
+ {
+ if (mItemId < SPELL_MIN_ID)
+ {
+ mBrowserBox->addRow("##3---");
+ // TRANSLATORS: popup menu item
+ // TRANSLATORS: add protection to item
+ mBrowserBox->addRow("protect item", _("Protect item"));
+ }
+ }
+}
+
+void PopupMenu::addUseDrop(const Item *const item, const bool isProtected)
+{
+ if (item->isEquipment())
+ {
+ if (item->isEquipped())
+ {
+ // TRANSLATORS: popup menu item
+ // TRANSLATORS: unequip item
+ mBrowserBox->addRow("use", _("Unequip"));
+ }
+ else
+ {
+ // TRANSLATORS: popup menu item
+ // TRANSLATORS: use item
+ mBrowserBox->addRow("use", _("Equip"));
+ }
+ }
+ else
+ {
+ if (!isProtected)
+ {
+ // TRANSLATORS: popup menu item
+ // TRANSLATORS: use item
+ mBrowserBox->addRow("use", _("Use"));
+ }
+ }
+
+ if (!isProtected)
+ {
+ mBrowserBox->addRow("##3---");
+ if (item->getQuantity() > 1)
+ {
+ // TRANSLATORS: popup menu item
+ // TRANSLATORS: drop item
+ mBrowserBox->addRow("drop", _("Drop..."));
+ // TRANSLATORS: popup menu item
+ // TRANSLATORS: drop all item amount
+ mBrowserBox->addRow("drop all", _("Drop all"));
+ }
+ else
+ {
+ // TRANSLATORS: popup menu item
+ // TRANSLATORS: drop item
+ mBrowserBox->addRow("drop", _("Drop"));
+ }
+ }
+
+ if (Net::getInventoryHandler()->canSplit(item))
+ {
+ // TRANSLATORS: popup menu item
+ // TRANSLATORS: split items
+ mBrowserBox->addRow("split", _("Split"));
+ }
+}
+
+void PopupMenu::addGmCommands()
+{
+ if (player_node->isGM())
+ {
+ // TRANSLATORS: popup menu item
+ // TRANSLATORS: gm commands
+ mBrowserBox->addRow("gm", _("GM..."));
+ }
+}
+
+void PopupMenu::showGMPopup()
+{
+ mBrowserBox->clearRows();
+ // TRANSLATORS: popup menu header
+ mBrowserBox->addRow(_("GM commands"));
+ if (player_node->isGM())
+ {
+ // TRANSLATORS: popup menu item
+ // TRANSLATORS: check player ip
+ mBrowserBox->addRow("ipcheck", _("Check ip"));
+ // TRANSLATORS: popup menu item
+ // TRANSLATORS: go to player position
+ mBrowserBox->addRow("goto", _("Goto"));
+ // TRANSLATORS: popup menu item
+ // TRANSLATORS: recall player to current position
+ mBrowserBox->addRow("recall", _("Recall"));
+ // TRANSLATORS: popup menu item
+ // TRANSLATORS: revive player
+ mBrowserBox->addRow("revive", _("Revive"));
+ if (mBeingId)
+ {
+ // TRANSLATORS: popup menu item
+ // TRANSLATORS: kick player
+ mBrowserBox->addRow("admin-kick", _("Kick"));
+ }
+ }
+
+ mBrowserBox->addRow("##3---");
+ // TRANSLATORS: popup menu item
+ // TRANSLATORS: close menu
+ mBrowserBox->addRow("cancel", _("Cancel"));
+
+ showPopup(getX(), getY());
+}
+
+RenameListener::RenameListener() :
+ gcn::ActionListener(),
+ mMapItemX(0),
+ mMapItemY(0),
+ mDialog(nullptr)
+{
+}
+
+void RenameListener::setMapItem(MapItem *const mapItem)
+{
+ if (mapItem)
+ {
+ mMapItemX = mapItem->getX();
+ mMapItemY = mapItem->getY();
+ }
+ else
+ {
+ mMapItemX = 0;
+ mMapItemY = 0;
+ }
+}
+
+void RenameListener::action(const gcn::ActionEvent &event)
+{
+ if (event.getId() == "ok" && viewport && mDialog)
+ {
+ Map *const map = viewport->getMap();
+ if (!map)
+ return;
+
+ SpecialLayer *const sl = map->getSpecialLayer();
+ MapItem *item = nullptr;
+ if (sl)
+ {
+ item = sl->getTile(mMapItemX, mMapItemY);
+ if (item)
+ item->setComment(mDialog->getText());
+ }
+ item = map->findPortalXY(mMapItemX, mMapItemY);
+ if (item)
+ item->setComment(mDialog->getText());
+
+ if (socialWindow)
+ socialWindow->updatePortalNames();
+ }
+ mDialog = nullptr;
+}
+
+PlayerListener::PlayerListener() :
+ ActionListener(),
+ mNick(),
+ mDialog(nullptr),
+ mType(static_cast<int>(Being::UNKNOWN))
+{
+}
+
+void PlayerListener::action(const gcn::ActionEvent &event)
+{
+ if (event.getId() == "ok" && !mNick.empty() && mDialog)
+ {
+ std::string comment = mDialog->getText();
+ Being *const being = actorSpriteManager->findBeingByName(
+ mNick, static_cast<ActorSprite::Type>(mType));
+ if (being)
+ being->setComment(comment);
+ Being::saveComment(mNick, comment, mType);
+ }
+ mDialog = nullptr;
+}