From 4371c8c1ffcf24e8d5a7cf2ec126be239cab3d76 Mon Sep 17 00:00:00 2001 From: David Athay Date: Fri, 18 Apr 2008 15:23:49 +0000 Subject: Fixed numerous crashes with chat and guild windows using new tabbed area. --- ChangeLog | 9 ++++++ src/CMakeLists.txt | 2 ++ src/Makefile.am | 4 +++ src/gui/chat.cpp | 64 +++++++++++++++++++++++++----------------- src/gui/chat.h | 26 ++++++++--------- src/gui/gui.cpp | 20 ++++++------- src/gui/guildwindow.cpp | 17 ++++------- src/gui/widgets/tabbedarea.cpp | 55 ++++++++++++++++++++++++++++++++++++ src/gui/widgets/tabbedarea.h | 7 ++++- src/net/chathandler.cpp | 14 +++++++-- src/net/guildhandler.cpp | 9 ++++-- tmw.cbp | 4 +++ 12 files changed, 163 insertions(+), 68 deletions(-) diff --git a/ChangeLog b/ChangeLog index eff8c85b..a9a924b8 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,12 @@ +2008-04-18 David Athay + + * src/gui/chat.h, src/gui/widgets/tabbedarea.h, + src/gui/widgets/tabbedarea.cpp, src/gui/chat.cpp, + src/gui/guildwindow.cpp, src/gui/gui.cpp, src/CMakeLists.txt, + src/net/guildhandler.cpp, src/net/chathandler.cpp, src/Makefile.am, + tmw.cbp: Fixed numerous crashes with chat and guild windows using new + tabbed area. + 2008-04-17 David Athay * src/player.cpp, src/player.h, src/net/partyhandler.h, diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index e6a6653f..dcc1ba08 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -248,6 +248,8 @@ SET(SRCS net/chatserver/guild.h net/chatserver/internal.cpp net/chatserver/internal.h + net/chatserver/party.cpp + net/chatserver/party.h net/gameserver/gameserver.cpp net/gameserver/gameserver.h net/gameserver/internal.cpp diff --git a/src/Makefile.am b/src/Makefile.am index 3cfa64ea..e4682fa8 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -200,6 +200,10 @@ tmw_SOURCES = gui/widgets/dropdown.cpp \ net/chatserver/chatserver.h \ net/chatserver/internal.cpp \ net/chatserver/internal.h \ + net/chatserver/guild.cpp \ + net/chatserver/guild.h \ + net/chatserver/party.cpp \ + net/chatserver/party.h \ net/gameserver/gameserver.cpp \ net/gameserver/gameserver.h \ net/gameserver/internal.cpp \ diff --git a/src/gui/chat.cpp b/src/gui/chat.cpp index a0e7f036..d490853c 100644 --- a/src/gui/chat.cpp +++ b/src/gui/chat.cpp @@ -74,15 +74,11 @@ ChatWindow::ChatWindow(): mChatTabs = new TabbedArea(); mChatTabs->addTab("General", scrollArea); - mChatTabs->setWidth(getWidth()); - mChatTabs->setHeight(getHeight()); + mChatTabs->setPosition(mChatTabs->getFrameSize(), mChatTabs->getFrameSize()); mChannelOutput["General"] = textOutput; mChannelScroll["General"] = scrollArea; - mTextOutput = textOutput; - mScrollArea = scrollArea; - add(mChatTabs); add(mChatInput); @@ -93,6 +89,7 @@ ChatWindow::ChatWindow(): ChatWindow::~ChatWindow() { + delete mChatInput; delete mChatTabs; } @@ -102,26 +99,33 @@ ChatWindow::logic() // todo: only do this when the size changes (updateWidgets?) const gcn::Rectangle area = getChildrenArea(); + std::string channelName = mChatTabs->getSelectedTab()->getCaption(); + ScrollArea *scroll = mChannelScroll[channelName]; + mChatInput->setPosition(mChatInput->getFrameSize(), area.height - mChatInput->getHeight() - mChatInput->getFrameSize()); mChatInput->setWidth(area.width - 2 * mChatInput->getFrameSize()); - mScrollArea->setWidth(area.width - 2 * mScrollArea->getFrameSize()); - mScrollArea->setHeight(area.height - 2 * mScrollArea->getFrameSize() - + mChatTabs->setWidth(area.width - 2 * mChatTabs->getFrameSize()); + mChatTabs->setHeight(area.height - 2 * mChatTabs->getFrameSize()); + + scroll->setWidth(area.width - 2 * scroll->getFrameSize()); + scroll->setHeight(area.height - 2 * scroll->getFrameSize() - mChatInput->getHeight() - 26); + Window::logic(); } void -ChatWindow::chatLog(std::string line, int own, std::string channelName) +ChatWindow::chatLog(std::string line, int own, const std::string &channelName) { CHATLOG tmp; tmp.own = own; tmp.nick = ""; - mTextOutput = mChannelOutput[channelName]; - mScrollArea = mChannelScroll[channelName]; + BrowserBox *output = mChannelOutput[channelName]; + ScrollArea *scroll = mChannelScroll[channelName]; // Fix the owner of welcome message. if (line.substr(0, 7) == "Welcome") @@ -146,7 +150,7 @@ ChatWindow::chatLog(std::string line, int own, std::string channelName) break; case BY_PLAYER: tmp.nick += ": "; - lineColor = "##2"; // Equiv. to BrowserBox::GREEN + lineColor = "##5"; // Equiv. to BrowserBox::YELLOW break; case BY_OTHER: tmp.nick += ": "; @@ -180,14 +184,14 @@ ChatWindow::chatLog(std::string line, int own, std::string channelName) // 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 (mScrollArea->getVerticalScrollAmount() == mScrollArea->getVerticalMaxScroll()) + if (scroll->getVerticalScrollAmount() == scroll->getVerticalMaxScroll()) { - mTextOutput->addRow(line); - mScrollArea->setVerticalScrollAmount(mScrollArea->getVerticalMaxScroll()); + output->addRow(line); + scroll->setVerticalScrollAmount(scroll->getVerticalMaxScroll()); } else { - mTextOutput->addRow(line); + output->addRow(line); } } @@ -332,6 +336,7 @@ void ChatWindow::chatSend(std::string const &nick, std::string const &msg, } else if (command == "register") { + // TODO: Parse the announcement and password chatLog("Requesting to register channel " + arg, BY_SERVER); Net::ChatServer::registerChannel(arg, "", ""); } @@ -447,9 +452,9 @@ ChatWindow::const_msg(CHATSKILL act) #endif void -ChatWindow::addChannel(short channelId, std::string channelName) +ChatWindow::addChannel(short channelId, const std::string &channelName) { - Channel* channel = new Channel(channelId); + Channel *channel = new Channel(channelId); channel->setName(channelName); channelManager->addChannel(channel); } @@ -457,7 +462,18 @@ ChatWindow::addChannel(short channelId, std::string channelName) void ChatWindow::removeChannel(short channelId) { - Channel* channel = channelManager->findById(channelId); + removeChannel(channelManager->findById(channelId)); +} + +void +ChatWindow::removeChannel(const std::string &channelName) +{ + removeChannel(channelManager->findByName(channelName)); +} + +void +ChatWindow::removeChannel(Channel *channel) +{ if(channel) { gcn::Tab *tab = mChatTabs->getTab(channel->getName()); @@ -467,13 +483,13 @@ ChatWindow::removeChannel(short channelId) mChannelOutput.erase(channel->getName()); mChannelScroll.erase(channel->getName()); channelManager->removeChannel(channel); - mTextOutput = mChannelOutput["General"]; - mScrollArea = mChannelScroll["General"]; + + logic(); } } void -ChatWindow::createNewChannelTab(std::string channelName) +ChatWindow::createNewChannelTab(const std::string &channelName) { // Create new channel BrowserBox *textOutput = new BrowserBox(BrowserBox::AUTO_WRAP); @@ -488,8 +504,6 @@ ChatWindow::createNewChannelTab(std::string channelName) mChatTabs->addTab(channelName, scrollArea); mChannelOutput[channelName] = textOutput; mChannelScroll[channelName] = scrollArea; - mScrollArea = scrollArea; - mTextOutput = textOutput; // Ask for channel users Net::ChatServer::getUserList(channelName); @@ -499,13 +513,13 @@ ChatWindow::createNewChannelTab(std::string channelName) } void -ChatWindow::enterChannel(std::string channel, std::string password) +ChatWindow::enterChannel(const std::string &channel, const std::string &password) { Net::ChatServer::enterChannel(channel, password); } void -ChatWindow::sendToChannel(short channelId, std::string user, std::string msg) +ChatWindow::sendToChannel(short channelId, const std::string &user, const std::string &msg) { Channel *channel = channelManager->findById(channelId); if (channel) diff --git a/src/gui/chat.h b/src/gui/chat.h index d605def0..ab8c3985 100644 --- a/src/gui/chat.h +++ b/src/gui/chat.h @@ -37,9 +37,8 @@ class BrowserBox; class ScrollArea; -//class TabbedContainer; -//class GCContainer; class TabbedArea; +class Channel; enum { @@ -131,7 +130,7 @@ class ChatWindow : public Window, public gcn::ActionListener, * @param line Text message. * @parem own Type of message (usually the owner-type). */ - void chatLog(std::string line, int own, std::string channelName = "General"); + void chatLog(std::string line, int own, const std::string &channelName = "General"); #if 0 /* @@ -184,23 +183,27 @@ class ChatWindow : public Window, public gcn::ActionListener, /** Called to add the channel to the channel manager */ void - addChannel(short channel, std::string channelName); + addChannel(short channel, const std::string &channelName); /** Called to remove the channel from the channel manager */ void - removeChannel(short channel); + removeChannel(short channelId); + void + removeChannel(const std::string &channelName); + void + removeChannel(Channel *channel); /** Called to create a new channel tab */ void - createNewChannelTab(std::string channelName); + createNewChannelTab(const std::string &channelName); /** Called to join channel */ void - enterChannel(std::string channel, std::string password = "None"); + enterChannel(const std::string &channel, const std::string &password = "None"); /** Called to output text to a specific channel */ void - sendToChannel(short channel, std::string user, std::string msg); + sendToChannel(short channel, const std::string &user, const std::string &msg); /** Called when key is pressed */ void @@ -233,18 +236,13 @@ class ChatWindow : public Window, public gcn::ActionListener, #if 0 /** Constructs failed messages for actions */ - std::string const_msg(CHATSKILL); - std::map mTabs; - TabbedContainer *mContainer; /**< Tabbed container for tabbing between channels */ - GCContainer *mTab; /**< Tabs */ + std::string const_msg(CHATSKILL);*/ #endif TabbedArea *mChatTabs; /** < Chat Tabbed area for holding each channel */ gcn::TextField *mChatInput; /**< Input box for typing chat messages */ std::map mChannelOutput; /**< Map each TextOutput to a tab */ std::map mChannelScroll; /**< Map each ScrollArea to a tab */ - BrowserBox *mTextOutput; /**< Text box for displaying chat history */ - ScrollArea *mScrollArea; /**< Scroll area around text output */ typedef std::list History; typedef History::iterator HistoryIterator; diff --git a/src/gui/gui.cpp b/src/gui/gui.cpp index 2ef7aba3..db0d1905 100644 --- a/src/gui/gui.cpp +++ b/src/gui/gui.cpp @@ -107,24 +107,20 @@ Gui::Gui(Graphics *graphics): Window::setWindowContainer(guiTop); setTop(guiTop); + ResourceManager *resman = ResourceManager::getInstance(); + // Set global font - try { - mGuiFont = new TrueTypeFont("data/fonts/dejavusans.ttf", 11); - } - catch (gcn::Exception e) + std::string path = resman->getPath("fonts/dejavusans.ttf"); + if (path != "") { - logger->error(std::string("Unable to load dejavusans.ttf: ") + e.getMessage()); + mGuiFont = new TrueTypeFont(path.c_str(), 11); } // Set speech font - try - { - // FIXME: use another font? - speechFont = new TrueTypeFont("data/fonts/dejavusans.ttf", 11); - } - catch (gcn::Exception e) + path = resman->getPath("fonts/dejavusans.ttf"); + if (path != "") { - logger->error(std::string("Unable to load dejavusans.ttf: ") + e.getMessage()); + speechFont = new TrueTypeFont(path.c_str(), 11); } gcn::Widget::setGlobalFont(mGuiFont); diff --git a/src/gui/guildwindow.cpp b/src/gui/guildwindow.cpp index 2a4de773..e982487c 100644 --- a/src/gui/guildwindow.cpp +++ b/src/gui/guildwindow.cpp @@ -86,7 +86,7 @@ void GuildWindow::update() { updateTab(); - if (mGuildButton[2]->isEnabled()&& mGuildTabs->getNumberOfTabs() <= 0) + if (mGuildButton[2]->isEnabled() && mGuildTabs->getNumberOfTabs() <= 0) { mGuildButton[2]->setEnabled(false); mGuildButton[1]->setEnabled(false); @@ -107,14 +107,6 @@ void GuildWindow::action(const gcn::ActionEvent &event) // Stats Part if (eventId == "CREATE_GUILD") { - if (mGuildTabs->getNumberOfTabs() > 1) - { - // This is just to limit the number of guild tabs that are created - // TODO: Either limit this server side, or fix the interface issue - chatWindow->chatLog("Current maximum number of guilds ownable is 2", BY_SERVER); - return; - } - // Set focus so that guild name to be created can be typed. mFocus = true; guildDialog = new TextDialog("Guild Name", "Choose your guild's name", this); @@ -123,7 +115,7 @@ void GuildWindow::action(const gcn::ActionEvent &event) } else if (eventId == "INVITE_USER") { - // TODO - Process Invite User button clicked + // TODO - Give feedback on whether the invite succeeded mFocus = true; inviteDialog = new TextDialog("Member Invite", "Who would you like to invite?", this); inviteDialog->setOKButtonActionId("INVITE_USER_OK"); @@ -261,7 +253,10 @@ void GuildWindow::removeTab(int guildId) if (guild) { gcn::Tab *tab = mGuildTabs->getTab(guild->getName()); - mGuildTabs->removeTab(tab); + if (tab) + { + mGuildTabs->removeTab(tab); + } updateTab(); } mGuildTabs->logic(); diff --git a/src/gui/widgets/tabbedarea.cpp b/src/gui/widgets/tabbedarea.cpp index 9087babc..5402bb10 100644 --- a/src/gui/widgets/tabbedarea.cpp +++ b/src/gui/widgets/tabbedarea.cpp @@ -87,3 +87,58 @@ gcn::Widget* TabbedArea::getWidget(const std::string &name) return NULL; } + +void TabbedArea::removeTab(gcn::Tab *tab) +{ + int tabIndexToBeSelected = 0; + + if (tab == mSelectedTab) + { + int index = getSelectedTabIndex(); + + if (index == (int)mTabs.size() - 1 + && mTabs.size() == 1) + { + tabIndexToBeSelected = -1; + } + else + { + tabIndexToBeSelected = index - 1; + } + } + + std::vector >::iterator iter; + for (iter = mTabs.begin(); iter != mTabs.end(); iter++) + { + if (iter->first == tab) + { + mTabContainer->remove(tab); + mTabs.erase(iter); + break; + } + } + + std::vector::iterator iter2; + for (iter2 = mTabsToDelete.begin(); iter2 != mTabsToDelete.end(); iter2++) + { + if (*iter2 == tab) + { + mTabsToDelete.erase(iter2); + delete tab; + break; + } + } + + if (tabIndexToBeSelected == -1) + { + mSelectedTab = NULL; + mWidgetContainer->clear(); + } + else + { + setSelectedTab(tabIndexToBeSelected); + } + + adjustSize(); + adjustTabPositions(); +} diff --git a/src/gui/widgets/tabbedarea.h b/src/gui/widgets/tabbedarea.h index 3f58acde..bc623427 100644 --- a/src/gui/widgets/tabbedarea.h +++ b/src/gui/widgets/tabbedarea.h @@ -57,9 +57,14 @@ class TabbedArea : public gcn::TabbedArea gcn::Tab* getTab(const std::string &name); /** - * Return selected tab's widget + * Returns the widget with the tab that has specified caption */ gcn::Widget* getWidget(const std::string &name); + + /** + * Overload the remove tab function as its broken in guichan 0.8 + */ + void removeTab(gcn::Tab *tab); }; #endif diff --git a/src/net/chathandler.cpp b/src/net/chathandler.cpp index d8a228ea..d3dcd2b1 100644 --- a/src/net/chathandler.cpp +++ b/src/net/chathandler.cpp @@ -70,7 +70,7 @@ void ChatHandler::handleMessage(MessageIn &msg) short channelId; std::string userNick; std::string channelName; - //Sint16 chatMsgLength; + short error = -1; switch (msg.getId()) { @@ -88,7 +88,8 @@ void ChatHandler::handleMessage(MessageIn &msg) } break; case CPMSG_REGISTER_CHANNEL_RESPONSE: - if(msg.readInt8() == ERRMSG_OK) + error = msg.readInt8(); + if(error == ERRMSG_OK) { channelId = msg.readInt16(); std::string channelName = msg.readString(); @@ -98,7 +99,14 @@ void ChatHandler::handleMessage(MessageIn &msg) } else { - chatWindow->chatLog("Error registering channel", BY_SERVER); + if (error == ERRMSG_INVALID_ARGUMENT) + { + chatWindow->chatLog("Error registering channel - Invalid Channel Name given", BY_SERVER); + } + else + { + chatWindow->chatLog("Error registering channel", BY_SERVER); + } } break; case CPMSG_ENTER_CHANNEL_RESPONSE: diff --git a/src/net/guildhandler.cpp b/src/net/guildhandler.cpp index c178df18..05fa0953 100644 --- a/src/net/guildhandler.cpp +++ b/src/net/guildhandler.cpp @@ -168,8 +168,13 @@ void GuildHandler::handleMessage(MessageIn &msg) // Must remove tab first, as it wont find the guild // name after its removed from the player int guildId = msg.readInt16(); - guildWindow->removeTab(guildId); - player_node->removeGuild(guildId); + Guild *guild = player_node->getGuild(guildId); + if (guild) + { + chatWindow->removeChannel(guild->getName()); + guildWindow->removeTab(guildId); + player_node->removeGuild(guildId); + } } } break; } diff --git a/tmw.cbp b/tmw.cbp index d30bb0e2..cb5d6f33 100644 --- a/tmw.cbp +++ b/tmw.cbp @@ -513,6 +513,8 @@ + +