00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022 #include "chat.h"
00023
00024 #include "gui/itemlinkhandler.h"
00025 #include "gui/recorder.h"
00026 #include "gui/sdlinput.h"
00027
00028 #include "gui/widgets/chattab.h"
00029 #include "gui/widgets/scrollarea.h"
00030 #include "gui/widgets/tabbedarea.h"
00031 #include "gui/widgets/textfield.h"
00032 #include "gui/widgets/whispertab.h"
00033
00034 #include "beingmanager.h"
00035 #include "configuration.h"
00036 #include "localplayer.h"
00037
00038 #include "net/chathandler.h"
00039 #include "net/net.h"
00040
00041 #include "utils/dtor.h"
00042 #include "utils/stringutils.h"
00043 #include "utils/strprintf.h"
00044
00045 #include <guichan/focushandler.hpp>
00046 #include <guichan/focuslistener.hpp>
00047
00051 class ChatInput : public TextField, public gcn::FocusListener
00052 {
00053 public:
00054 ChatInput()
00055 {
00056 setVisible(false);
00057 addFocusListener(this);
00058 }
00059
00064 void focusLost(const gcn::Event &event)
00065 {
00066 setVisible(false);
00067 }
00068 };
00069
00070
00071 ChatWindow::ChatWindow():
00072 Window(_("Chat")),
00073 mTmpVisible(false),
00074 mCurrentTab(NULL)
00075 {
00076 setWindowName("Chat");
00077
00078 setResizable(true);
00079 setDefaultVisible(true);
00080 setSaveVisible(true);
00081 setDefaultSize(600, 123, ImageRect::LOWER_LEFT);
00082 setMinWidth(150);
00083 setMinHeight(90);
00084
00085 mItemLinkHandler = new ItemLinkHandler;
00086
00087 mChatInput = new ChatInput;
00088 mChatInput->setActionEventId("chatinput");
00089 mChatInput->addActionListener(this);
00090
00091 mChatTabs = new TabbedArea;
00092
00093 add(mChatTabs);
00094 add(mChatInput);
00095
00096 loadWindowState();
00097
00098
00099 mChatInput->addKeyListener(this);
00100 mCurHist = mHistory.end();
00101
00102 mReturnToggles = config.getValue("ReturnToggles", "0") == "1";
00103
00104 #ifdef EATHENA_SUPPORT
00105
00106
00107 if (config.getValue(player_node->getName() + "GMassert", 0)) {
00108 std::string cmd = "@assert";
00109 chatInput(cmd);
00110 }
00111 #endif
00112 mRecorder = new Recorder(this);
00113 }
00114
00115 ChatWindow::~ChatWindow()
00116 {
00117 config.setValue("ReturnToggles", mReturnToggles);
00118 delete mRecorder;
00119 delete_all(mWhispers);
00120 delete mItemLinkHandler;
00121 }
00122
00123 void ChatWindow::resetToDefaultSize()
00124 {
00125 mRecorder->resetToDefaultSize();
00126 Window::resetToDefaultSize();
00127 }
00128
00129 void ChatWindow::adjustTabSize()
00130 {
00131 const gcn::Rectangle area = getChildrenArea();
00132
00133 mChatInput->setPosition(mChatInput->getFrameSize(),
00134 area.height - mChatInput->getHeight() -
00135 mChatInput->getFrameSize());
00136 mChatInput->setWidth(area.width - 2 * mChatInput->getFrameSize());
00137
00138 mChatTabs->setWidth(area.width - 2 * mChatTabs->getFrameSize());
00139 mChatTabs->setHeight(area.height - 2 * mChatTabs->getFrameSize() -
00140 (mChatInput->getHeight() + mChatInput->getFrameSize() * 2));
00141
00142 ChatTab *tab = getFocused();
00143 if (tab) {
00144 gcn::Widget *content = tab->mScrollArea;
00145 content->setSize(mChatTabs->getWidth() - 2 * content->getFrameSize(),
00146 mChatTabs->getContainerHeight() - 2 * content->getFrameSize());
00147 content->logic();
00148 }
00149 }
00150
00151 void ChatWindow::widgetResized(const gcn::Event &event)
00152 {
00153 Window::widgetResized(event);
00154
00155 adjustTabSize();
00156 }
00157
00158 void ChatWindow::logic()
00159 {
00160 Window::logic();
00161
00162 Tab *tab = getFocused();
00163 if (tab != mCurrentTab) {
00164 mCurrentTab = tab;
00165 adjustTabSize();
00166 }
00167 }
00168
00169 ChatTab *ChatWindow::getFocused() const
00170 {
00171 return dynamic_cast<ChatTab*>(mChatTabs->getSelectedTab());
00172 }
00173
00174 void ChatWindow::clearTab(ChatTab *tab)
00175 {
00176 if (tab)
00177 tab->clearText();
00178 }
00179
00180 void ChatWindow::clearTab()
00181 {
00182 clearTab(getFocused());
00183 }
00184
00185 void ChatWindow::prevTab()
00186 {
00187 int tab = mChatTabs->getSelectedTabIndex();
00188
00189 if (tab == 0)
00190 tab = mChatTabs->getNumberOfTabs();
00191 tab--;
00192
00193 mChatTabs->setSelectedTab(tab);
00194 }
00195
00196 void ChatWindow::nextTab()
00197 {
00198 int tab = mChatTabs->getSelectedTabIndex();
00199
00200 tab++;
00201 if (tab == mChatTabs->getNumberOfTabs())
00202 tab = 0;
00203
00204 mChatTabs->setSelectedTab(tab);
00205 }
00206
00207 void ChatWindow::action(const gcn::ActionEvent &event)
00208 {
00209 if (event.getId() == "chatinput")
00210 {
00211 std::string message = mChatInput->getText();
00212
00213 if (!message.empty())
00214 {
00215
00216 if (mHistory.empty() || message != mHistory.back())
00217 {
00218 mHistory.push_back(message);
00219 }
00220
00221 mCurHist = mHistory.end();
00222
00223
00224 chatInput(message);
00225
00226
00227 mChatInput->setText("");
00228 }
00229
00230 if (message.empty() || !mReturnToggles)
00231 {
00232
00233 mFocusHandler->focusNone();
00234
00235
00236
00237 if (mTmpVisible)
00238 setVisible(false);
00239 }
00240 }
00241 }
00242
00243 bool ChatWindow::requestChatFocus()
00244 {
00245
00246 if (!isVisible())
00247 {
00248 setVisible(true);
00249
00250
00251
00252
00253
00254
00255 mTmpVisible = true;
00256 }
00257
00258
00259 if (mChatInput->isVisible() && mChatInput->isFocused())
00260 return false;
00261
00262
00263 mChatInput->setVisible(true);
00264 mChatInput->requestFocus();
00265 return true;
00266 }
00267
00268 bool ChatWindow::isInputFocused()
00269 {
00270 return mChatInput->isFocused();
00271 }
00272
00273 void ChatWindow::removeTab(ChatTab *tab)
00274 {
00275
00276 if (tab == localChatTab)
00277 return;
00278
00279 mChatTabs->removeTab(tab);
00280 }
00281
00282 void ChatWindow::addTab(ChatTab *tab)
00283 {
00284
00285
00286
00287 mChatTabs->addTab(tab, tab->mScrollArea);
00288
00289
00290 if (tab == localChatTab)
00291 adjustTabSize();
00292
00293
00294 logic();
00295 }
00296
00297 void ChatWindow::removeWhisper(std::string nick)
00298 {
00299 mWhispers.erase(nick);
00300 }
00301
00302 void ChatWindow::chatInput(std::string &msg)
00303 {
00304 ChatTab *tab = getFocused();
00305 tab->chatInput(msg);
00306 }
00307
00308 void ChatWindow::doPresent()
00309 {
00310 const Beings &beings = beingManager->getAll();
00311 std::string response = "";
00312
00313 for (Beings::const_iterator bi = beings.begin(), be = beings.end();
00314 bi != be; ++bi)
00315 {
00316 if ((*bi)->getType() == Being::PLAYER)
00317 {
00318 if (!response.empty())
00319 {
00320 response += ", ";
00321 }
00322 response += (*bi)->getName();
00323 }
00324 }
00325
00326 if (mRecorder->isRecording())
00327 {
00328
00329 time_t t;
00330 time(&t);
00331
00332
00333 std::stringstream timeStr;
00334 timeStr << "[" << ((((t / 60) / 60) % 24 < 10) ? "0" : "")
00335 << (int) (((t / 60) / 60) % 24)
00336 << ":" << (((t / 60) % 60 < 10) ? "0" : "")
00337 << (int) ((t / 60) % 60)
00338 << "] ";
00339
00340
00341 mRecorder->record(timeStr.str() + _("Present: ") + response + ".");
00342 getFocused()->chatLog(_("Attendance written to record log."),
00343 BY_SERVER, true);
00344 }
00345 else
00346 {
00347 getFocused()->chatLog(_("Present: ") + response, BY_SERVER);
00348 }
00349 }
00350
00351 void ChatWindow::scroll(int amount)
00352 {
00353 if (!isVisible())
00354 return;
00355
00356 ChatTab *tab = getFocused();
00357 if (tab) tab->scroll(amount);
00358 }
00359
00360 void ChatWindow::keyPressed(gcn::KeyEvent &event)
00361 {
00362 if (event.getKey().getValue() == Key::DOWN &&
00363 mCurHist != mHistory.end())
00364 {
00365
00366 HistoryIterator prevHist = mCurHist++;
00367
00368 if (mCurHist != mHistory.end())
00369 {
00370 mChatInput->setText(*mCurHist);
00371 mChatInput->setCaretPosition(mChatInput->getText().length());
00372 }
00373 else
00374 {
00375 mCurHist = prevHist;
00376 }
00377 }
00378 else if (event.getKey().getValue() == Key::UP &&
00379 mCurHist != mHistory.begin() && mHistory.size() > 0)
00380 {
00381
00382 mCurHist--;
00383 mChatInput->setText(*mCurHist);
00384 mChatInput->setCaretPosition(mChatInput->getText().length());
00385 }
00386 }
00387
00388 void ChatWindow::addInputText(std::string input_str)
00389 {
00390 mChatInput->setText(mChatInput->getText() + input_str + " ");
00391 requestChatFocus();
00392 }
00393
00394 void ChatWindow::addItemText(const std::string &item)
00395 {
00396 std::ostringstream text;
00397 text << "[" << item << "] ";
00398 addInputText(text.str());
00399 }
00400
00401 void ChatWindow::setVisible(bool isVisible)
00402 {
00403 Window::setVisible(isVisible);
00404
00405
00406
00407
00408
00409 mTmpVisible = false;
00410 }
00411
00412 void ChatWindow::setRecordingFile(const std::string &msg)
00413 {
00414 mRecorder->setRecordingFile(msg);
00415 }
00416
00417 void ChatWindow::whisper(const std::string &nick, std::string mes, bool own)
00418 {
00419 if (mes.empty())
00420 return;
00421
00422 std::string playerName = player_node->getName();
00423 std::string tempNick = nick;
00424
00425 toLower(playerName);
00426 toLower(tempNick);
00427
00428 if (tempNick.compare(playerName) == 0)
00429 return;
00430
00431 ChatTab *tab = mWhispers[tempNick];
00432
00433 if (!tab && config.getValue("whispertab", false))
00434 {
00435 tab = addWhisperTab(nick);
00436 }
00437
00438 if (tab)
00439 {
00440 if (own)
00441 tab->chatInput(mes);
00442 else
00443 tab->chatLog(nick, mes);
00444 }
00445 else
00446 {
00447 if (own)
00448 {
00449 Net::getChatHandler()->privateMessage(nick, mes);
00450
00451 localChatTab->chatLog(strprintf(_("Whispering to %s: %s"),
00452 nick.c_str(), mes.c_str()), BY_PLAYER);
00453 }
00454 else
00455 localChatTab->chatLog(nick + " : " + mes, ACT_WHISPER, false);
00456 }
00457 }
00458
00459 ChatTab *ChatWindow::addWhisperTab(const std::string &nick, bool switchTo)
00460 {
00461 std::string playerName = player_node->getName();
00462 std::string tempNick = nick;
00463
00464 toLower(playerName);
00465 toLower(tempNick);
00466
00467 if (mWhispers[tempNick] || tempNick.compare(playerName) == 0)
00468 return NULL;
00469
00470 ChatTab *ret = mWhispers[tempNick] = new WhisperTab(nick);
00471
00472 mChatTabs->setSelectedTab(ret);
00473
00474 return ret;
00475 }