summaryrefslogtreecommitdiff
path: root/src/gui/chat.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/gui/chat.cpp')
-rw-r--r--src/gui/chat.cpp416
1 files changed, 56 insertions, 360 deletions
diff --git a/src/gui/chat.cpp b/src/gui/chat.cpp
index 597eddfd..5c15580d 100644
--- a/src/gui/chat.cpp
+++ b/src/gui/chat.cpp
@@ -21,42 +21,19 @@
#include <guichan/focushandler.hpp>
-#include "browserbox.h"
#include "chat.h"
#include "chatinput.h"
#include "itemlinkhandler.h"
#include "recorder.h"
#include "scrollarea.h"
#include "sdlinput.h"
-#include "windowcontainer.h"
-#include "widgets/layout.h"
-#include "widgets/tab.h"
#include "widgets/tabbedarea.h"
#include "../beingmanager.h"
-#include "../commandhandler.h"
-#include "../channelmanager.h"
-#include "../channel.h"
#include "../configuration.h"
-#include "../game.h"
#include "../localplayer.h"
-#ifdef TMWSERV_SUPPORT
-#include "../net/tmwserv/chatserver/chatserver.h"
-#include "../net/tmwserv/gameserver/player.h"
-#else
-#include "../party.h"
-#include "../net/messageout.h"
-#include "../net/ea/protocol.h"
-#endif
-
-#include "../resources/iteminfo.h"
-#include "../resources/itemdb.h"
-
-#include "../utils/dtor.h"
-#include "../utils/gettext.h"
-#include "../utils/strprintf.h"
#include "../utils/stringutils.h"
#ifdef TMWSERV_SUPPORT
@@ -82,14 +59,9 @@ ChatWindow::ChatWindow(Network * network):
mChatInput->addActionListener(this);
mChatTabs = new TabbedArea();
- createNewChannelTab("General");
-
- place(0, 0, mChatTabs, 5, 5).setPadding(0);
- place(0, 5, mChatInput, 5).setPadding(1);
- Layout &layout = getLayout();
- layout.setRowHeight(0, Layout::AUTO_SET);
- layout.setMargin(2);
+ add(mChatTabs);
+ add(mChatInput);
loadWindowState();
@@ -102,7 +74,6 @@ ChatWindow::ChatWindow(Network * network):
std::string partyPrefix = config.getValue("PartyPrefix", "$");
mPartyPrefix = (partyPrefix.empty() ? '$' : partyPrefix.at(0));
mReturnToggles = config.getValue("ReturnToggles", "0") == "1";
- mRecorder = new Recorder(this);
// If the player had @assert on in the last session, ask the server to
// run the @assert command for the player again. Convenience for GMs.
@@ -111,6 +82,7 @@ ChatWindow::ChatWindow(Network * network):
chatSend(cmd);
}
#endif
+ mRecorder = new Recorder(this);
}
ChatWindow::~ChatWindow()
@@ -121,7 +93,6 @@ ChatWindow::~ChatWindow()
config.setValue("PartyPrefix", partyPrefix);
config.setValue("ReturnToggles", mReturnToggles ? "1" : "0");
delete mRecorder;
- delete mParty;
#endif
delete mItemLinkHandler;
}
@@ -132,10 +103,8 @@ void ChatWindow::resetToDefaultSize()
Window::resetToDefaultSize();
}
-void ChatWindow::widgetResized(const gcn::Event &event)
+void ChatWindow::adjustTabSize()
{
- Window::widgetResized(event);
-
const gcn::Rectangle area = getChildrenArea();
mChatInput->setPosition(mChatInput->getFrameSize(),
@@ -144,34 +113,28 @@ void ChatWindow::widgetResized(const gcn::Event &event)
mChatInput->setWidth(area.width - 2 * mChatInput->getFrameSize());
mChatTabs->setWidth(area.width - 2 * mChatTabs->getFrameSize());
- mChatTabs->setHeight(area.height - 2 * mChatTabs->getFrameSize());
-
- const std::string &channelName = getFocused();
- ChannelMap::const_iterator chan = mChannels.find(channelName);
- if (chan != mChannels.end()) {
- ScrollArea *scroll = chan->second.scroll;
- scroll->setWidth(area.width - 2 * scroll->getFrameSize());
- scroll->setHeight(area.height - 2 * scroll->getFrameSize() -
- mChatInput->getHeight() - 5);
- scroll->logic();
+ mChatTabs->setHeight(area.height - 2 * mChatTabs->getFrameSize() -
+ (mChatInput->getHeight() + mChatInput->getFrameSize() * 2));
+
+ ChatTab *tab = getFocused();
+ if (tab) {
+ gcn::Widget *content = tab->mScrollArea;
+ content->setSize(mChatTabs->getWidth() - 2 * content->getFrameSize(),
+ mChatTabs->getContainerHeight() - 2 * content->getFrameSize());
+ content->logic();
}
}
-void ChatWindow::logic()
+void ChatWindow::widgetResized(const gcn::Event &event)
{
- Window::logic();
+ Window::widgetResized(event);
- const gcn::Rectangle area = getChildrenArea();
+ adjustTabSize();
+}
- const std::string &channelName = getFocused();
- ChannelMap::const_iterator chan = mChannels.find(channelName);
- if (chan != mChannels.end()) {
- ScrollArea *scroll = chan->second.scroll;
- scroll->setWidth(area.width - 2 * scroll->getFrameSize());
- scroll->setHeight(area.height - 2 * scroll->getFrameSize() -
- mChatInput->getHeight() - 5);
- scroll->logic();
- }
+void ChatWindow::logic()
+{
+ Window::logic();
}
void ChatWindow::chatLog(std::string line, int own, std::string channelName,
@@ -183,199 +146,29 @@ void ChatWindow::chatLog(std::string line, int own, std::string channelName,
#else
channelName = "General";
#endif
+ ChatTab *tab = findTab(channelName);
- ChannelMap::const_iterator chan = mChannels.find(channelName);
- if (chan == mChannels.end())
- return;
-
- BrowserBox * const output = chan->second.browser;
- ScrollArea * const scroll = chan->second.scroll;
-
- // Trim whitespace
- trim(line);
-
- if (line.empty())
- return;
-
- CHATLOG tmp;
- tmp.own = own;
- tmp.nick = "";
- tmp.text = line;
-
- std::string::size_type pos = line.find(" : ");
- if (pos != std::string::npos)
- {
- tmp.nick = line.substr(0, pos);
- tmp.text = line.substr(pos + 3);
- }
- else
- {
- // Fix the owner of welcome message.
- if (line.substr(0, 7) == "Welcome")
- {
- own = BY_SERVER;
- }
- }
-
- // *implements actions in a backwards compatible way*
- if (own == BY_PLAYER &&
- tmp.text.at(0) == '*' &&
- tmp.text.at(tmp.text.length()-1) == '*')
- {
- tmp.text[0] = ' ';
- tmp.text.erase(tmp.text.length() - 1);
- own = ACT_IS;
- }
-
- std::string lineColor = "##C";
- switch (own)
- {
- case BY_GM:
- if (tmp.nick.empty())
- {
- tmp.nick = std::string(_("Global announcement:"));
- tmp.nick += " ";
- lineColor = "##G";
- }
- else
- {
- tmp.nick = strprintf(_("Global announcement from %s:"),
- tmp.nick.c_str());
- tmp.nick += " ";
- lineColor = "##1"; // Equiv. to BrowserBox::RED
- }
- break;
- case BY_PLAYER:
- tmp.nick += CAT_NORMAL;
- lineColor = "##Y";
- break;
- case BY_OTHER:
- tmp.nick += CAT_NORMAL;
- lineColor = "##C";
- break;
- case BY_SERVER:
- tmp.nick = _("Server:");
- tmp.nick += " ";
- tmp.text = line;
- lineColor = "##S";
- break;
- case BY_CHANNEL:
- tmp.nick = "";
- // TODO: Use a predefined color
- lineColor = "##2"; // Equiv. to BrowserBox::GREEN
- break;
-#ifdef EATHENA_SUPPORT
- case BY_PARTY:
- tmp.nick += CAT_NORMAL;
- lineColor = "##P";
- break;
-#endif
- case ACT_WHISPER:
- tmp.nick = strprintf(_("%s whispers:"), tmp.nick.c_str());
- tmp.nick += " ";
- lineColor = "##W";
- break;
- case ACT_IS:
- tmp.nick += CAT_IS;
- lineColor = "##I";
- break;
- case BY_LOGGER:
- tmp.nick = "";
- tmp.text = line;
- lineColor = "##L";
- break;
- }
-
- if (tmp.nick == ": ")
- {
- tmp.nick = "";
- lineColor = "##S";
- }
-
-#ifdef EATHENA_SUPPORT
- if (tmp.nick.empty() && tmp.text.substr(0, 17) == "Visible GM status")
- {
- player_node->setGM();
- }
-#endif
-
- // Get the current system time
- time_t t;
- time(&t);
-
- // Format the time string properly
- std::stringstream timeStr;
- timeStr << "[" << ((((t / 60) / 60) % 24 < 10) ? "0" : "")
- << (int) (((t / 60) / 60) % 24)
- << ":" << (((t / 60) % 60 < 10) ? "0" : "")
- << (int) ((t / 60) % 60)
- << "] ";
-
- // Check for item link
- std::string::size_type start = tmp.text.find('[');
- while (start != std::string::npos && tmp.text[start+1] != '@')
- {
- std::string::size_type end = tmp.text.find(']', start);
- if (start+1 != end && end != std::string::npos)
- {
- // Catch multiple embeds and ignore them
- // so it doesn't crash the client.
- while ((tmp.text.find('[', start + 1) != std::string::npos) &&
- (tmp.text.find('[', start + 1) < end))
- {
- start = tmp.text.find('[', start + 1);
- }
-
- std::string temp = tmp.text.substr(start+1, end - start - 1);
-
- trim(temp);
-
- for (unsigned int i = 0; i < temp.size(); i++)
- {
- temp[i] = (char) tolower(temp[i]);
- }
-
- const ItemInfo itemInfo = ItemDB::get(temp);
- if (itemInfo.getName() != _("Unknown item"))
- {
- tmp.text.insert(end, "@@");
- tmp.text.insert(start+1, "|");
- tmp.text.insert(start+1, toString(itemInfo.getId()));
- tmp.text.insert(start+1, "@@");
- }
- }
- start = tmp.text.find('[', start + 1);
- }
-
- line = lineColor + timeStr.str() + tmp.nick + tmp.text;
-
- // We look if the Vertical Scroll Bar is set at the max before
- // adding a row, otherwise the max will always be a row higher
- // at comparison.
- if (scroll->getVerticalScrollAmount() >= scroll->getVerticalMaxScroll())
- {
- output->addRow(line);
- scroll->setVerticalScrollAmount(scroll->getVerticalMaxScroll());
- }
- else
- {
- output->addRow(line);
- }
+ tab->chatLog(line, own, ignoreRecord);
+}
- scroll->logic();
- mRecorder->record(line.substr(3));
+ChatTab* ChatWindow::getFocused() const
+{
+ return dynamic_cast<ChatTab*>(mChatTabs->getSelectedTab());
}
-const std::string &ChatWindow::getFocused() const
+void ChatWindow::clearTab(ChatTab* tab)
{
- return mChatTabs->getSelectedTab()->getCaption();
+ if (tab) tab->clearText();
}
void ChatWindow::clearTab(const std::string &tab)
{
- ChannelMap::const_iterator chan = mChannels.find(tab);
- if (chan != mChannels.end())
- chan->second.browser->clearRows();
+ clearTab(findTab(tab));
+}
+
+void ChatWindow::clearTab()
+{
+ clearTab(getFocused());
}
void ChatWindow::action(const gcn::ActionEvent &event)
@@ -444,130 +237,43 @@ bool ChatWindow::isInputFocused()
return mChatInput->isFocused();
}
-void ChatWindow::removeChannel(short channelId)
+ChatTab* ChatWindow::findTab(const std::string &tabName)
{
- removeChannel(channelManager->findById(channelId));
+ return mTabs[tabName];
}
-void ChatWindow::removeChannel(const std::string &channelName)
+void ChatWindow::removeTab(ChatTab *tab)
{
- removeChannel(channelManager->findByName(channelName));
+ mTabs.erase(tab->getCaption());
+ mChatTabs->removeTab(tab);
}
-void ChatWindow::removeChannel(Channel *channel)
+void ChatWindow::removeTab(const std::string &tabName)
{
- if (channel)
- {
- Tab *tab = mChatTabs->getTab(channel->getName());
- if (!tab)
- return;
- clearTab(channel->getName());
- mChatTabs->removeTab(tab);
- mChannels.erase(channel->getName());
- channelManager->removeChannel(channel);
-
- logic();
- }
+ ChatTab *tab = findTab(tabName);
+ if (tab) removeTab(tab);
}
-void ChatWindow::createNewChannelTab(const std::string &channelName)
+void ChatWindow::addTab(ChatTab *tab)
{
- // Create new channel
- BrowserBox *textOutput = new BrowserBox(BrowserBox::AUTO_WRAP);
- textOutput->setOpaque(false);
- textOutput->disableLinksAndUserColors();
- textOutput->setMaxRow((int) config.getValue("ChatLogLength", 0));
- ScrollArea *scrollArea = new ScrollArea(textOutput);
- scrollArea->setPosition(scrollArea->getFrameSize(), scrollArea->getFrameSize());
- scrollArea->setScrollPolicy(gcn::ScrollArea::SHOW_NEVER, gcn::ScrollArea::SHOW_ALWAYS);
- scrollArea->setOpaque(false);
- scrollArea->setWidth(getChildrenArea().width - 2 * scrollArea->getFrameSize());
- scrollArea->setHeight(getChildrenArea().height - 2 * scrollArea->getFrameSize() -
- mChatInput->getHeight() - 5);
- scrollArea->logic();
- textOutput->setWidth(scrollArea->getChildrenArea().width);
- textOutput->setHeight(scrollArea->getChildrenArea().height);
-
- // Add channel to the tabbed area
- mChatTabs->addTab(channelName, scrollArea);
- mChannels.insert(
- std::make_pair(channelName, ChatArea(textOutput, scrollArea)));
+ // Make sure we don't end up with duplicates in the gui
+ removeTab(tab->getCaption());
+
+ mTabs[tab->getCaption()] = tab;
+
+ mChatTabs->addTab(tab, tab->mScrollArea);
+
+ if (mTabs.size() == 1)
+ adjustTabSize();
// Update UI
logic();
}
-void ChatWindow::sendToChannel(short channelId,
- const std::string &user,
- const std::string &msg)
-{
- Channel *channel = channelManager->findById(channelId);
- if (channel)
- {
- std::string channelName = channel->getName();
- chatLog(user + ": " + msg, user == player_node->getName() ? BY_PLAYER : BY_OTHER, channelName);
- mChatTabs->getTab(channelName)->setHighlighted(true);
- }
-}
-
void ChatWindow::chatSend(std::string &msg)
{
- trim(msg);
-
- if (msg.empty()) return;
-
-#ifdef EATHENA_SUPPORT
- // Send party message
- if (msg.at(0) == mPartyPrefix)
- {
- msg.erase(0, 1);
- std::size_t length = msg.length() + 1;
-
- if (length == 0)
- {
- chatLog(_("Trying to send a blank party message."), BY_SERVER);
- return;
- }
- MessageOut outMsg(mNetwork);
-
- outMsg.writeInt16(CMSG_PARTY_MESSAGE);
- outMsg.writeInt16(length + 4);
- outMsg.writeString(msg, length);
- return;
- }
-#endif
-
- // Prepare ordinary message
- if (msg[0] != '/')
- {
-#ifdef TMWSERV_SUPPORT
- if (getFocused() == "General")
- {
- Net::GameServer::Player::say(msg);
- }
- else
- {
- Channel *channel = channelManager->findByName(getFocused());
- if (channel)
- {
- Net::ChatServer::chat(channel->getId(), msg);
- }
- }
-#else
- msg = player_node->getName() + " : " + msg;
-
- MessageOut outMsg(mNetwork);
- outMsg.writeInt16(CMSG_CHAT_MESSAGE);
- // Added + 1 in order to let eAthena parse admin commands correctly
- outMsg.writeInt16(msg.length() + 4 + 1);
- outMsg.writeString(msg, msg.length() + 1);
- return;
-#endif
- }
- else
- {
- commandHandler->handleCommand(std::string(msg, 1));
- }
+ ChatTab *tab = getFocused();
+ tab->chatSend(msg);
}
void ChatWindow::doPresent()
@@ -617,18 +323,8 @@ void ChatWindow::scroll(int amount)
if (!isVisible())
return;
- ChannelMap::const_iterator chan = mChannels.find(getFocused());
- if (chan == mChannels.end())
- return;
-
- BrowserBox *browser = chan->second.browser;
- ScrollArea *scroll = chan->second.scroll;
-
- int range = scroll->getHeight() / 8 * amount;
- gcn::Rectangle scr;
- scr.y = scroll->getVerticalScrollAmount() + range;
- scr.height = abs(range);
- browser->showPart(scr);
+ ChatTab *tab = getFocused();
+ if (tab) tab->scroll(amount);
}
void ChatWindow::keyPressed(gcn::KeyEvent &event)