ManaPlus
chatwindow.cpp
Go to the documentation of this file.
1 /*
2  * The ManaPlus Client
3  * Copyright (C) 2004-2009 The Mana World Development Team
4  * Copyright (C) 2009-2010 The Mana Developers
5  * Copyright (C) 2011-2018 The ManaPlus Developers
6  *
7  * This file is part of The ManaPlus Client.
8  *
9  * This program is free software; you can redistribute it and/or modify
10  * it under the terms of the GNU General Public License as published by
11  * the Free Software Foundation; either version 2 of the License, or
12  * any later version.
13  *
14  * This program is distributed in the hope that it will be useful,
15  * but WITHOUT ANY WARRANTY; without even the implied warranty of
16  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17  * GNU General Public License for more details.
18  *
19  * You should have received a copy of the GNU General Public License
20  * along with this program. If not, see <http://www.gnu.org/licenses/>.
21  */
22 
23 #include "gui/windows/chatwindow.h"
24 
25 #include "actormanager.h"
26 #include "game.h"
27 #include "guild.h"
28 #include "party.h"
29 #include "settings.h"
30 #include "spellmanager.h"
31 
32 #include "being/localplayer.h"
33 #include "being/playerinfo.h"
34 #include "being/playerrelations.h"
35 
36 #include "const/gui/chat.h"
37 
38 #include "fs/virtfs/tools.h"
39 
40 #include "input/inputmanager.h"
41 
42 #include "gui/focushandler.h"
43 #include "gui/gui.h"
44 #include "gui/skin.h"
45 #include "gui/viewport.h"
46 
48 
49 #include "gui/popups/popupmenu.h"
50 
53 
54 #include "gui/widgets/button.h"
55 #include "gui/widgets/chatinput.h"
57 #include "gui/widgets/dropdown.h"
59 #include "gui/widgets/scrollarea.h"
60 #include "gui/widgets/tabbedarea.h"
61 
68 
70 
71 #include "resources/db/textdb.h"
72 
73 #include "net/chathandler.h"
74 #include "net/net.h"
75 
76 #include "utils/copynpaste.h"
77 #include "utils/delete2.h"
78 #include "utils/foreach.h"
79 
81 
82 #include <sys/stat.h>
83 
84 #include <fstream>
85 #include <sstream>
86 
87 #include "debug.h"
88 
90 
91 static const char *const ACTION_COLOR_PICKER = "color picker";
92 
93 ChatWindow::ChatWindow(const std::string &name) :
94  // TRANSLATORS: chat window name
95  Window(_("Chat"), Modal_false, nullptr, "chat.xml"),
97  KeyListener(),
99  mItemLinkHandler(new ItemLinkHandler),
100  mChatTabs(CREATEWIDGETR(TabbedArea, this)),
101  mChatInput(new ChatInput(this)),
102  mRainbowColor(0U),
103  mWhispers(),
104  mChannels(),
105  mHistory(),
106  mCurHist(),
107  mCommands(),
108  mCustomWords(),
109  mTradeFilter(),
110  mColorListModel(new ColorListModel),
111  mColorPicker(new DropDown(this, mColorListModel,
112  false, Modal_false, nullptr, std::string())),
113  mChatButton(new Button(this, ":)", "openemote", BUTTON_SKIN, this)),
114  mAwayLog(),
115  mHighlights(),
116  mGlobalsFilter(),
117  mChatColor(config.getIntValue("chatColor")),
118  mEmoteButtonSpacing(mSkin != nullptr ?
119  mSkin->getOption("emoteButtonSpacing", 2) : 2),
120  mEmoteButtonY(mSkin != nullptr ?
121  mSkin->getOption("emoteButtonY", -2) : -2),
122  mChatHistoryIndex(0),
123  mReturnToggles(config.getBoolValue("ReturnToggles")),
124  mGMLoaded(false),
125  mHaveMouse(false),
126  mAutoHide(config.getBoolValue("autohideChat")),
127  mShowBattleEvents(config.getBoolValue("showBattleEvents")),
128  mShowAllLang(serverConfig.getValue("showAllLang", 0) != 0),
129  mEnableTradeFilter(config.getBoolValue("enableTradeFilter")),
130  mTmpVisible(false)
131 {
132  setWindowName(name);
133 
134  if (setupWindow != nullptr)
136 
137  setShowTitle(false);
138  setResizable(true);
139  setDefaultVisible(true);
140  setSaveVisible(true);
141  setStickyButtonLock(true);
142 
143  int w = 600;
144 #ifdef ANDROID
145  if (mainGraphics->getWidth() < 710)
146  w = mainGraphics->getWidth() - 110;
147  if (w < 100)
148  w = 100;
149  if (mainGraphics->getHeight() < 480)
150  setDefaultSize(w, 90, ImagePosition::UPPER_LEFT, -110, -35);
151  else
152  setDefaultSize(w, 123, ImagePosition::UPPER_LEFT, -110, -35);
153 #else // ANDROID
154 
155  if (mainGraphics->getWidth() < 600)
156  w = mainGraphics->getWidth() - 10;
157  if (w < 100)
158  w = 100;
160 #endif // ANDROID
161 
162  setMinWidth(150);
163  setMinHeight(90);
164 
166 
167  if (emoteWindow != nullptr)
168  emoteWindow->addListeners(this);
169 
171 
174  mChatTabs->setResizeHeight(false);
175 
176  mChatInput->setActionEventId("chatinput");
179 
183 
185 
186  loadWindowState();
187 
189  - 2 * mPadding - 8 - 16, mPadding);
190 
191  // Add key listener to chat input to be able to respond to up/down
192  mChatInput->addKeyListener(this);
193  mCurHist = mHistory.end();
195  "showChatColorsList"), Visible));
197 
198  fillCommands();
199  if ((localPlayer != nullptr) && localPlayer->isGM())
200  loadGMCommands();
201  initTradeFilter();
202  loadCustomList();
203  parseHighlights();
205 
206  config.addListener("autohideChat", this);
207  config.addListener("showBattleEvents", this);
208  config.addListener("globalsFilter", this);
209  config.addListener("enableTradeFilter", this);
210 
211  enableVisibleSound(true);
212 }
213 
215 {
216  config.removeListeners(this);
218  saveState();
219  config.setValue("ReturnToggles", mReturnToggles);
225 }
226 
228 {
230  add(mChatTabs);
231  add(mChatInput);
232  add(mColorPicker);
233  add(mChatButton);
235 }
236 
237 void ChatWindow::loadCommandsFile(const std::string &name)
238 {
239  StringVect list;
240  VirtFs::loadTextFile(name, list);
241  StringVectCIter it = list.begin();
242  const StringVectCIter it_end = list.end();
243 
244  while (it != it_end)
245  {
246  const std::string str = *it;
247  if (!str.empty())
248  mCommands.push_back(str);
249  ++ it;
250  }
251 }
252 
254 {
255  loadCommandsFile("chatcommands.txt");
257 }
258 
260 {
261  if (mGMLoaded)
262  return;
263 
264  loadCommandsFile("gmcommands.txt");
265  mGMLoaded = true;
266 }
267 
269 {
272  else
274 }
275 
277 {
278  const Rect area = getChildrenArea();
279 
280  const int aw = area.width;
281  const int ah = area.height;
282  const int frame = mChatInput->getFrameSize();
283  const int inputHeight = mChatInput->getHeight();
284  const bool showEmotes = config.getBoolValue("showEmotesButton");
285  int maxHeight = inputHeight;
286  if (showEmotes)
287  {
288  const int buttonHeight = mChatButton->getHeight();
289  if (buttonHeight > maxHeight)
290  maxHeight = buttonHeight;
291  }
292  const int frame2 = 2 * frame;
293  const int awFrame2 = aw - frame2;
294  int y = ah - maxHeight - frame;
295  mChatInput->setPosition(frame, y);
296  mChatTabs->setWidth(awFrame2);
297  const int height = ah - frame2 - (maxHeight + frame2);
298  if (mChatInput->mVisible == Visible_true ||
299  !config.getBoolValue("hideChatInput"))
300  {
301  mChatTabs->setHeight(height);
302  }
303  else
304  {
305  mChatTabs->setHeight(height + maxHeight);
306  }
308 
309  if (showEmotes)
310  {
311  const int chatButtonSize = mChatButton->getWidth();
312  int w = awFrame2 - chatButtonSize;
313  const int x = aw - frame - chatButtonSize;
314  w -= mEmoteButtonSpacing;
315  y += mEmoteButtonY;
316  mChatInput->setWidth(w);
318  mChatButton->setPosition(x, y);
319  }
320  else
321  {
322  mChatInput->setWidth(awFrame2);
324  }
325 
326  const ChatTab *const tab = getFocused();
327  if (tab != nullptr)
328  {
329  Widget *const content = tab->mScrollArea;
330  if (content != nullptr)
331  {
332  const int contentFrame2 = 2 * content->getFrameSize();
333  content->setSize(mChatTabs->getWidth() - contentFrame2,
334  mChatTabs->getContainerHeight() - contentFrame2);
335  content->logic();
336  }
337  }
338 
340  - 2 * mPadding - 8 - 16, mPadding);
341 
343 }
344 
346 {
347  Window::widgetResized(event);
348 
349  adjustTabSize();
350 }
351 
353 {
354  return static_cast<ChatTab*>(mChatTabs->getSelectedTab());
355 }
356 
358 {
359  if (tab != nullptr)
360  tab->clearText();
361 }
362 
364 {
365  clearTab(getFocused());
366 }
367 
369 {
370  if (mChatTabs == nullptr)
371  return;
372 
373  int tab = mChatTabs->getSelectedTabIndex();
374 
375  if (tab <= 0)
376  tab = mChatTabs->getNumberOfTabs();
377  tab--;
378 
380 }
381 
383 {
384  if (mChatTabs == nullptr)
385  return;
386 
387  int tab = mChatTabs->getSelectedTabIndex();
388 
389  tab++;
390  if (tab == mChatTabs->getNumberOfTabs())
391  tab = 0;
392 
394 }
395 
397 {
398  if (mChatTabs == nullptr)
399  return;
400 
401  int sz = mChatTabs->getNumberOfTabs();
402  for (int f = 0; f < sz; f ++)
403  {
404  ChatTab *const tab = dynamic_cast<ChatTab*>(
406  if ((tab != nullptr) && tab->getType() == type)
407  {
409  break;
410  }
411  }
412 }
413 
415 {
416  if (mChatTabs == nullptr)
417  return;
418 
419  ChatTab *const tab = dynamic_cast<ChatTab*>(mChatTabs->getTabByIndex(
421  if (tab == nullptr)
422  return;
423  const ChatTabTypeT &type = tab->getType();
424  if (type == ChatTabType::WHISPER || type == ChatTabType::CHANNEL)
425  tab->handleCommand("close", "");
426 }
427 
429 {
430  if (mChatTabs != nullptr)
432 }
433 
434 void ChatWindow::action(const ActionEvent &event)
435 {
436  const std::string &eventId = event.getId();
437  if (eventId == "chatinput")
438  {
439  std::string message = mChatInput->getText();
440 
441  if (!message.empty())
442  {
443  // If message different from previous, put it in the history
444  if (mHistory.empty() || message != mHistory.back())
445  mHistory.push_back(message);
446 
447  // Reset history iterator
448  mCurHist = mHistory.end();
449 
450  // Send the message to the server
451  chatInput(addColors(message));
452 
453  // Clear the text from the chat input
454  mChatInput->setText("");
455  }
456 
457  if (message.empty() || !mReturnToggles)
458  {
459  // Remove focus and hide input
461  if (mFocusHandler != nullptr)
463 
464  // If the chatWindow is shown up because you want to send a message
465  // It should hide now
466  if (mTmpVisible)
468  }
469  }
470  else if (eventId == "emote")
471  {
472  if (emoteWindow != nullptr)
473  {
474  const std::string str = emoteWindow->getSelectedEmote();
475  if (!str.empty())
476  {
477  addInputText(str, false);
479  }
480  }
481  }
482  else if (eventId == "openemote")
483  {
484  if (emoteWindow != nullptr)
485  {
487  emoteWindow->hide();
488  else
489  emoteWindow->show();
490  }
491  }
492  else if (eventId == "color")
493  {
494  if (emoteWindow != nullptr)
495  {
496  const std::string str = emoteWindow->getSelectedColor();
497  if (!str.empty())
498  {
499  addInputText(str, false);
501  }
502  }
503  }
504  else if (eventId == "font")
505  {
506  if (emoteWindow != nullptr)
507  {
508  const std::string str = emoteWindow->getSelectedFont();
509  if (!str.empty())
510  {
511  addInputText(str, false);
513  }
514  }
515  }
516  else if (eventId == "text")
517  {
518  if ((emoteWindow != nullptr) && (reverseDictionary != nullptr))
519  {
520  const int idx = emoteWindow->getSelectedTextIndex();
521  if (idx >= 0)
522  {
523  const std::string str = TextDb::getByIndex(idx);
524  const std::string enStr = reverseDictionary->getStr(str);
525  addInputText(enStr, false);
526  }
528  }
529  }
530  else if (eventId == ACTION_COLOR_PICKER)
531  {
532  if (mColorPicker != nullptr)
533  {
535  config.setValue("chatColor", mChatColor);
536  }
537  }
538 
539  if (mColorPicker != nullptr)
540  {
541  const Visible vis = fromBool(config.getBoolValue(
542  "showChatColorsList"), Visible);
543  if (mColorPicker->mVisible != vis)
544  mColorPicker->setVisible(vis);
545  }
546 }
547 
549 {
550  // Make sure chatWindow is visible
551  if (!isWindowVisible())
552  {
554 
555  /*
556  * This is used to hide chatWindow after sending the message. There is
557  * a trick here, because setVisible will set mTmpVisible to false, you
558  * have to put this sentence *after* setVisible, not before it
559  */
560  mTmpVisible = true;
561  }
562 
563  // Don't do anything else if the input is already visible and has focus
565  return false;
566 
567  // Give focus to the chat input
569  unHideWindow();
571  return true;
572 }
573 
575 {
576  return mChatInput->isFocused();
577 }
578 
580 {
581  mChatTabs->removeTab(tab);
582 }
583 
584 void ChatWindow::addTab(ChatTab *const tab)
585 {
586  if (tab == nullptr)
587  return;
588 
589  mChatTabs->addTab(tab, tab->mScrollArea);
590  logic();
591 }
592 
593 void ChatWindow::removeWhisper(const std::string &nick)
594 {
595  std::string tempNick = nick;
596  toLower(tempNick);
597  mWhispers.erase(tempNick);
598 }
599 
600 void ChatWindow::removeChannel(const std::string &name)
601 {
602  std::string tempName = name;
603  toLower(tempName);
604  mChannels.erase(tempName);
605  chatHandler->partChannel(name);
606 }
607 
609 {
610  std::list<ChatTab*> tabs;
611 
612  FOR_EACH (TabMap::iterator, iter, mWhispers)
613  tabs.push_back(iter->second);
614 
615  for (std::list<ChatTab*>::iterator it = tabs.begin();
616  it != tabs.end(); ++it)
617  {
618  delete *it;
619  }
620 
621  mWhispers.clear();
622 }
623 
625 {
626  std::list<ChatTab*> tabs;
627 
628  FOR_EACH (ChannelMap::iterator, iter, mChannels)
629  tabs.push_back(iter->second);
630 
631  for (std::list<ChatTab*>::iterator it = tabs.begin();
632  it != tabs.end(); ++it)
633  {
634  delete *it;
635  }
636 
637  mChannels.clear();
638 }
639 
641 {
642  for (TabMap::iterator iter = mWhispers.begin();
643  iter != mWhispers.end();
644  ++ iter)
645  {
646  WhisperTab *const tab = iter->second;
647  if (tab != nullptr)
648  {
651  {
654  }
655  tab->handleCommand("close", "");
656  }
657  }
658 }
659 
660 void ChatWindow::chatInput(const std::string &message) const
661 {
662  ChatTab *tab = nullptr;
663  std::string msg = message;
664  trim(msg);
665 
666  if (config.getBoolValue("allowCommandsInChatTabs")
667  && msg.length() > 1
668  && ((msg.at(0) == '#' && msg.at(1) != '#') || msg.at(0) == '@')
669  && (localChatTab != nullptr))
670  {
671  tab = localChatTab;
672  }
673  else
674  {
675  tab = getFocused();
676  if (tab == nullptr)
677  tab = localChatTab;
678  }
679  if (tab != nullptr)
680  tab->chatInput(msg);
681  Game *const game = Game::instance();
682  if (game != nullptr)
683  game->setValidSpeed();
684 }
685 
686 void ChatWindow::localChatInput(const std::string &msg) const
687 {
688  if (localChatTab != nullptr)
689  localChatTab->chatInput(msg);
690  else
691  chatInput(msg);
692 }
693 
695 {
696  if (actorManager == nullptr)
697  return;
698 
699  const ActorSprites &actors = actorManager->getAll();
700  std::string response;
701  int playercount = 0;
702 
703  FOR_EACH (ActorSpritesIterator, it, actors)
704  {
705  if ((*it)->getType() == ActorType::Player)
706  {
707  if (!response.empty())
708  response.append(", ");
709  response.append(static_cast<Being*>(*it)->getName());
710  playercount ++;
711  }
712  }
713 
714  ChatTab *const tab = getFocused();
715  if (tab != nullptr)
716  {
717  const std::string log = strprintf(
718  // TRANSLATORS: chat message
719  _("Present: %s; %d players are present."),
720  response.c_str(), playercount);
721  tab->chatLog(log,
725  }
726 }
727 
728 void ChatWindow::scroll(const int amount) const
729 {
730  if (!isWindowVisible())
731  return;
732 
733  ChatTab *const tab = getFocused();
734  if (tab != nullptr)
735  tab->scroll(amount);
736 }
737 
739 {
740  if (event.isConsumed())
741  return;
742 
743  if (event.getButton() == MouseButton::RIGHT)
744  {
745  if (popupMenu != nullptr)
746  {
747  ChatTab *const cTab = dynamic_cast<ChatTab*>(
749  if (cTab != nullptr)
750  {
751  event.consume();
753  {
756  std::string(), cTab);
757  }
758  else
759  {
761  viewport->mMouseY,
762  cTab);
763  }
764  }
765  }
766  }
767 
768  Window::mousePressed(event);
769 
770  if (event.isConsumed())
771  return;
772 
773  if (event.getButton() == MouseButton::LEFT)
774  {
775  const int clicks = event.getClickCount();
776  if (clicks == 2)
777  {
778  toggleChatFocus();
779  if (gui != nullptr)
780  gui->resetClickCount();
781  }
782  else if (clicks == 1)
783  {
784  const ChatTab *const tab = getFocused();
785  if (tab != nullptr)
786  mMoved = !isResizeAllowed(event);
787  }
788  }
789 
790  mDragOffsetX = event.getX();
791  mDragOffsetY = event.getY();
792 }
793 
795 {
796  Window::mouseDragged(event);
797 
798  if (event.isConsumed())
799  return;
800 
801  if (canMove() && isMovable() && mMoved)
802  {
803  int newX = std::max(0, getX() + event.getX() - mDragOffsetX);
804  int newY = std::max(0, getY() + event.getY() - mDragOffsetY);
805  newX = std::min(mainGraphics->mWidth - getWidth(), newX);
806  newY = std::min(mainGraphics->mHeight - getHeight(), newY);
807  setPosition(newX, newY);
808  }
809 }
810 
811 #define ifKey(key, str) \
812  else if (actionId == (key)) \
813  { \
814  temp = str; \
815  }
816 
818 {
819  const InputActionT actionId = event.getActionId();
820  std::string temp;
821  if (actionId == InputAction::GUI_DOWN)
822  {
823  if (mCurHist != mHistory.end())
824  {
825  // Move forward through the history
826  const HistoryIterator prevHist = mCurHist++;
828 
829  if (mCurHist != mHistory.end())
830  {
833  mChatInput->getText().length()));
834  }
835  else
836  {
837  mChatInput->setText("");
838  mCurHist = prevHist;
839  }
840  }
841  else if (!mChatInput->getText().empty())
842  {
843  if (addCurrentToHistory())
844  mCurHist = mHistory.end();
845  mChatInput->setText("");
846  }
847  }
848  else if (actionId == InputAction::GUI_UP &&
849  mCurHist != mHistory.begin() &&
850  !mHistory.empty())
851  {
852  // Move backward through the history
853  --mCurHist;
857  mChatInput->getText().length()));
858  }
859  else if (actionId == InputAction::GUI_INSERT &&
860  !mChatInput->getText().empty())
861  {
862  const std::string str = mChatInput->getText();
863  // Add the current message to the history and clear the text
864  if (mHistory.empty() || str != mHistory.back())
865  mHistory.push_back(str);
866  mCurHist = mHistory.end();
867  mChatInput->setText(std::string());
868  }
869  else if (actionId == InputAction::GUI_TAB &&
870  !mChatInput->getText().empty())
871  {
872  autoComplete();
873  return;
874  }
875  else if (actionId == InputAction::GUI_CANCEL &&
877  {
879  }
880  else if (actionId == InputAction::CHAT_PREV_HISTORY &&
882  {
883  const ChatTab *const tab = getFocused();
884  if ((tab != nullptr) && tab->hasRows())
885  {
886  if (mChatHistoryIndex == 0u)
887  {
889  tab->getRows().size());
890 
891  mChatInput->setText("");
893  return;
894  }
895 
897 
898  unsigned int f = 0;
899  const std::list<std::string> &rows = tab->getRows();
900  for (std::list<std::string>::const_iterator it = rows.begin(),
901  it_end = rows.end(); it != it_end; ++ it, f ++)
902  {
903  if (f == mChatHistoryIndex)
904  mChatInput->setText(*it);
905  }
907  mChatInput->getText().length()));
908  }
909  }
910  else if (actionId == InputAction::CHAT_NEXT_HISTORY &&
912  {
913  const ChatTab *const tab = getFocused();
914  if ((tab != nullptr) && tab->hasRows())
915  {
916  const std::list<std::string> &rows = tab->getRows();
917  const size_t &tabSize = rows.size();
918  if (CAST_SIZE(mChatHistoryIndex) + 1 < tabSize)
919  {
921  }
922  else if (CAST_SIZE(mChatHistoryIndex) < tabSize)
923  {
925  mChatInput->setText("");
927  return;
928  }
929  else
930  {
931  mChatHistoryIndex = 0;
932  }
933 
934  unsigned int f = 0;
935  for (std::list<std::string>::const_iterator
936  it = rows.begin(), it_end = rows.end();
937  it != it_end; ++it, f++)
938  {
939  if (f == mChatHistoryIndex)
940  mChatInput->setText(*it);
941  }
943  mChatInput->getText().length()));
944  }
945  }
946  else if (actionId == InputAction::GUI_F1)
947  {
948  if (emoteWindow != nullptr)
949  {
951  emoteWindow->hide();
952  else
953  emoteWindow->show();
954  }
955  }
956  ifKey(InputAction::GUI_F2, "\u2318")
957  ifKey(InputAction::GUI_F3, "\u263A")
958  ifKey(InputAction::GUI_F4, "\u2665")
959  ifKey(InputAction::GUI_F5, "\u266A")
960  ifKey(InputAction::GUI_F6, "\u266B")
961  ifKey(InputAction::GUI_F7, "\u26A0")
962  ifKey(InputAction::GUI_F8, "\u2622")
963  ifKey(InputAction::GUI_F9, "\u262E")
964  ifKey(InputAction::GUI_F10, "\u2605")
965  ifKey(InputAction::GUI_F11, "\u2618")
966  ifKey(InputAction::GUI_F12, "\u2592")
967 
969  {
970  if (actionId == InputAction::GUI_B)
971  {
972  std::string inputText = mChatInput->getTextBeforeCaret();
973  toLower(inputText);
974  const size_t idx = inputText.rfind("##b");
975  if (idx == std::string::npos
976  || mChatInput->getTextBeforeCaret().substr(idx, 3) == "##b")
977  {
978  temp = "##B";
979  }
980  else
981  {
982  temp = "##b";
983  }
984  }
985  }
986 
987  if (!temp.empty())
988  addInputText(temp, false);
989 }
990 
991 #undef ifKey
992 
994 {
995  const std::string &str = mChatInput->getText();
996  if (str.empty())
997  return false;
999  {
1000  if (*it == str)
1001  return false;
1002  }
1003  mHistory.push_back(str);
1004  return true;
1005 }
1006 
1008  const int64_t oldVal,
1009  const int64_t newVal)
1010 {
1011  if (!mShowBattleEvents)
1012  return;
1013  PRAGMA45(GCC diagnostic push)
1014  PRAGMA45(GCC diagnostic ignored "-Wswitch-enum")
1015  switch (id)
1016  {
1018  {
1019  if (oldVal > newVal)
1020  break;
1021  const int64_t change = newVal - oldVal;
1022  if (change != 0)
1023  {
1024  battleChatLog(std::string("+").append(toString(
1025  CAST_U64(change))).append(" xp"),
1029  }
1030  break;
1031  }
1033  battleChatLog(std::string(
1034  "Level: ").append(toString(CAST_S32(
1035  newVal))),
1039  break;
1041  {
1042  if (!config.getBoolValue("showJobExp"))
1043  return;
1044  if (oldVal > newVal ||
1047  {
1048  return;
1049  }
1050  const int64_t change = newVal - oldVal;
1051  if (change != 0)
1052  {
1053  battleChatLog(std::string("+").append(toString(CAST_U64(
1054  change))).append(" job"),
1058  }
1059  break;
1060  }
1061  default:
1062  break;
1063  };
1064  PRAGMA45(GCC diagnostic pop)
1065 }
1066 
1067 void ChatWindow::addInputText(const std::string &text,
1068  const bool space)
1069 {
1070  const int caretPos = mChatInput->getCaretPosition();
1071  const std::string &inputText = mChatInput->getText();
1072 
1073  std::ostringstream ss;
1074  ss << inputText.substr(0, caretPos) << text;
1075  if (space)
1076  ss << " ";
1077 
1078  ss << inputText.substr(caretPos);
1079  mChatInput->setText(ss.str());
1080  mChatInput->setCaretPosition(caretPos + CAST_S32(
1081  text.length()) + CAST_S32(space));
1082  requestChatFocus();
1083 }
1084 
1085 void ChatWindow::addItemText(const std::string &item)
1086 {
1087  std::ostringstream text;
1088  text << "[" << item << "]";
1089  addInputText(text.str(),
1090  true);
1091 }
1092 
1094 {
1095  Window::setVisible(visible);
1096 
1097  /*
1098  * For whatever reason, if setVisible is called, the mTmpVisible effect
1099  * should be disabled.
1100  */
1101  mTmpVisible = false;
1102 }
1103 
1104 void ChatWindow::addWhisper(const std::string &restrict nick,
1105  const std::string &restrict mes,
1106  const ChatMsgTypeT own)
1107 {
1108  if (mes.empty() || (localPlayer == nullptr))
1109  return;
1110 
1111  std::string playerName = localPlayer->getName();
1112  std::string tempNick = nick;
1113 
1114  toLower(playerName);
1115  toLower(tempNick);
1116 
1117  if (tempNick == playerName)
1118  return;
1119 
1120  WhisperTab *tab = nullptr;
1121  const TabMap::const_iterator i = mWhispers.find(tempNick);
1122 
1123  if (i != mWhispers.end())
1124  {
1125  tab = i->second;
1126  }
1127  else if (config.getBoolValue("whispertab"))
1128  {
1129  tab = addWhisperTab(nick, nick, false);
1130  if (tab != nullptr)
1131  saveState();
1132  }
1133 
1134  if (tab != nullptr)
1135  {
1136  if (own == ChatMsgType::BY_PLAYER)
1137  {
1138  tab->chatInput(mes);
1139  }
1140  else if (own == ChatMsgType::BY_SERVER)
1141  {
1142  tab->chatLog(mes,
1146  }
1147  else
1148  {
1149  if (tab->getRemoveNames())
1150  {
1151  std::string msg = mes;
1152  const size_t idx = mes.find(':');
1153  if (idx != std::string::npos && idx > 0)
1154  {
1155  std::string nick2 = msg.substr(0, idx);
1156  msg = msg.substr(idx + 1);
1157  nick2 = removeColors(nick2);
1158  nick2 = trim(nick2);
1159  if (config.getBoolValue("removeColors"))
1160  msg = removeColors(msg);
1161  msg = trim(msg);
1162  tab->chatLog(nick2, msg);
1163  }
1164  else
1165  {
1166  if (config.getBoolValue("removeColors"))
1167  msg = removeColors(msg);
1168  tab->chatLog(msg,
1172  }
1173  }
1174  else
1175  {
1176  tab->chatLog(nick, mes);
1177  }
1178  localPlayer->afkRespond(tab, nick);
1179  }
1180  }
1181  else if (localChatTab != nullptr)
1182  {
1183  if (own == ChatMsgType::BY_PLAYER)
1184  {
1185  chatHandler->privateMessage(nick, mes);
1186 
1187  // TRANSLATORS: chat message
1188  localChatTab->chatLog(strprintf(_("Whispering to %s: %s"),
1189  nick.c_str(), mes.c_str()),
1193  }
1194  else
1195  {
1196  localChatTab->chatLog(std::string(nick).append(
1197  " : ").append(mes),
1201  if (localPlayer != nullptr)
1202  localPlayer->afkRespond(nullptr, nick);
1203  }
1204  }
1205 }
1206 
1207 WhisperTab *ChatWindow::addWhisperTab(const std::string &caption,
1208  const std::string &nick,
1209  const bool switchTo)
1210 {
1211  if (localPlayer == nullptr)
1212  return nullptr;
1213 
1214  std::string playerName = localPlayer->getName();
1215  std::string tempNick = nick;
1216 
1217  toLower(playerName);
1218  toLower(tempNick);
1219 
1220  const TabMap::const_iterator i = mWhispers.find(tempNick);
1221  WhisperTab *ret = nullptr;
1222 
1223  if (tempNick == playerName)
1224  return nullptr;
1225 
1226  if (i != mWhispers.end())
1227  {
1228  ret = i->second;
1229  }
1230  else
1231  {
1232  ret = new WhisperTab(this, caption, nick);
1233  if ((gui != nullptr) && !playerRelations.isGoodName(nick))
1234  ret->setLabelFont(gui->getSecureFont());
1235  mWhispers[tempNick] = ret;
1236  if (config.getBoolValue("showChatHistory"))
1237  ret->loadFromLogFile(nick);
1238  }
1239 
1240  if (switchTo)
1241  mChatTabs->setSelectedTab(ret);
1242 
1243  return ret;
1244 }
1245 
1246 WhisperTab *ChatWindow::getWhisperTab(const std::string &nick) const
1247 {
1248  if (localPlayer == nullptr)
1249  return nullptr;
1250 
1251  std::string playerName = localPlayer->getName();
1252  std::string tempNick = nick;
1253 
1254  toLower(playerName);
1255  toLower(tempNick);
1256 
1257  const TabMap::const_iterator i = mWhispers.find(tempNick);
1258  WhisperTab *ret = nullptr;
1259 
1260  if (tempNick == playerName)
1261  return nullptr;
1262 
1263  if (i != mWhispers.end())
1264  ret = i->second;
1265 
1266  return ret;
1267 }
1268 
1270  const bool switchTo)
1271 {
1272  ChatTab *ret = nullptr;
1273  if (name == TRADE_CHANNEL)
1274  {
1275  if (tradeChatTab == nullptr)
1276  {
1277  tradeChatTab = new TradeTab(chatWindow);
1280  }
1281  ret = tradeChatTab;
1282  }
1283  else if (name == GM_CHANNEL)
1284  {
1285  if (gmChatTab == nullptr)
1286  {
1287  gmChatTab = new GmTab(chatWindow);
1289  }
1290  ret = gmChatTab;
1291  }
1292  if (switchTo)
1293  mChatTabs->setSelectedTab(ret);
1294 
1295  return ret;
1296 }
1297 
1298 ChatTab *ChatWindow::addChannelTab(const std::string &name,
1299  const bool switchTo)
1300 {
1301  std::string tempName = name;
1302  toLower(tempName);
1303 
1304  ChatTab *const tab = addSpecialChannelTab(name, switchTo);
1305  if (tab != nullptr)
1306  return tab;
1307 
1308  const ChannelMap::const_iterator i = mChannels.find(tempName);
1309  ChannelTab *ret = nullptr;
1310 
1311  if (i != mChannels.end())
1312  {
1313  ret = i->second;
1314  }
1315  else
1316  {
1317  ret = new ChannelTab(this, name);
1318  mChannels[tempName] = ret;
1319  ret->setAllowHighlight(false);
1320  if (config.getBoolValue("showChatHistory"))
1321  ret->loadFromLogFile(name);
1322  }
1323 
1324  if (switchTo)
1325  mChatTabs->setSelectedTab(ret);
1326 
1327  return ret;
1328 }
1329 
1330 ChatTab *ChatWindow::addChatTab(const std::string &name,
1331  const bool switchTo,
1332  const bool join)
1333 {
1335  name.size() > 1 &&
1336  name[0] == '#')
1337  {
1338  ChatTab *const tab = addChannelTab(name, switchTo);
1339  if ((tab != nullptr) && join)
1340  chatHandler->joinChannel(name);
1341  return tab;
1342  }
1343  return addWhisperTab(name, name, switchTo);
1344 }
1345 
1347 {
1348  FOR_EACH (ChannelMap::const_iterator, iter, mChannels)
1349  {
1350  ChatTab *const tab = iter->second;
1351  if (tab == nullptr)
1352  return;
1354  }
1355  if (langChatTab != nullptr)
1357 }
1358 
1359 #define changeColor(fun) \
1360  { \
1361  msg = removeColors(msg); \
1362  int skip = 0; \
1363  const size_t sz = msg.length(); \
1364  for (size_t f = 0; f < sz; f ++) \
1365  { \
1366  if (skip > 0) \
1367  { \
1368  newMsg += msg.at(f); \
1369  skip --; \
1370  continue; \
1371  } \
1372  const unsigned char ch = CAST_U8(msg.at(f)); \
1373  if (f + 2 < sz && msg.substr(f, 2) == "%%") \
1374  { \
1375  newMsg += msg.at(f); \
1376  skip = 2; \
1377  } \
1378  else if (ch > 0xc0 || ch < 0x80) \
1379  { \
1380  newMsg += "##" + toString(fun) + msg.at(f); \
1381  if (mRainbowColor > 9U) \
1382  mRainbowColor = 0U; \
1383  } \
1384  else \
1385  { \
1386  newMsg += msg.at(f); \
1387  } \
1388  } \
1389  }
1390 
1391 std::string ChatWindow::addColors(std::string &msg)
1392 {
1393  // default color or chat command
1394  if (mChatColor == 0 || msg.length() == 0 || msg.at(0) == '#'
1395  || msg.at(0) == '/' || msg.at(0) == '@' || msg.at(0) == '!')
1396  {
1397  return msg;
1398  }
1399 
1400  std::string newMsg;
1401  const int cMap[] = {1, 4, 5, 2, 3, 6, 7, 9, 0, 8};
1402 
1403  // rainbow
1404  switch (mChatColor)
1405  {
1406  case 11:
1408  return newMsg;
1409  case 12:
1410  changeColor(cMap[mRainbowColor++])
1411  return newMsg;
1412  case 13:
1413  changeColor(cMap[9-mRainbowColor++])
1414  return newMsg;
1415  default:
1416  break;
1417  }
1418 
1419  // simple colors
1420  return std::string("##").append(toString(mChatColor - 1)).append(msg);
1421 }
1422 
1423 #undef changeColor
1424 
1426 {
1427  const int caretPos = mChatInput->getCaretPosition();
1428  int startName = 0;
1429  const std::string &inputText = mChatInput->getText();
1430  std::string name = inputText.substr(0, caretPos);
1431 
1432  for (int f = caretPos - 1; f > -1; f --)
1433  {
1434  if (isWordSeparator(inputText[f]))
1435  {
1436  startName = f + 1;
1437  name = inputText.substr(f + 1, caretPos - f);
1438  break;
1439  }
1440  }
1441 
1442  if (caretPos - 1 + 1 == startName)
1443  return;
1444 
1445  const ChatTab *const cTab = static_cast<ChatTab*>(
1447  StringVect nameList;
1448 
1449  if (cTab != nullptr)
1450  cTab->getAutoCompleteList(nameList);
1451  std::string newName = autoComplete(nameList, name);
1452  if (!newName.empty() && (startName == 0))
1453  secureChatCommand(newName);
1454 
1455  if ((cTab != nullptr) && newName.empty())
1456  {
1457  cTab->getAutoCompleteCommands(nameList);
1458  newName = autoComplete(nameList, name);
1459  }
1460 
1461  if (newName.empty() && (actorManager != nullptr))
1462  {
1464  newName = autoComplete(nameList, name);
1465  if (!newName.empty() && (startName == 0))
1466  secureChatCommand(newName);
1467  }
1468  if (newName.empty())
1469  newName = autoCompleteHistory(name);
1470  if (newName.empty() && (spellManager != nullptr))
1471  newName = spellManager->autoComplete(name);
1472  if (newName.empty())
1473  newName = autoComplete(name, &mCommands);
1474  if (newName.empty() && (actorManager != nullptr))
1475  {
1476  actorManager->getMobNames(nameList);
1477  newName = autoComplete(nameList, name);
1478  }
1479  if (newName.empty())
1480  newName = autoComplete(name, &mCustomWords);
1481  if (newName.empty())
1482  {
1483  whoIsOnline->getPlayerNames(nameList);
1484  newName = autoComplete(nameList, name);
1485  }
1486 
1487  if (!newName.empty())
1488  {
1489  mChatInput->setText(inputText.substr(0, startName).append(newName)
1490  .append(inputText.substr(caretPos,
1491  inputText.length() - caretPos)));
1492 
1493  const int len = caretPos - CAST_S32(name.length())
1494  + CAST_S32(newName.length());
1495 
1496  if (startName > 0)
1497  mChatInput->setCaretPosition(len + 1);
1498  else
1500  }
1501 }
1502 
1503 std::string ChatWindow::autoComplete(const StringVect &names,
1504  std::string partName)
1505 {
1506  StringVectCIter i = names.begin();
1507  const StringVectCIter i_end = names.end();
1508  toLower(partName);
1509  std::string newName;
1510 
1511  while (i != i_end)
1512  {
1513  if (!i->empty())
1514  {
1515  std::string name = *i;
1516  toLower(name);
1517 
1518  const size_t pos = name.find(partName, 0);
1519  if (pos == 0)
1520  {
1521  if (!newName.empty())
1522  newName = findSameSubstringI(*i, newName);
1523  else
1524  newName = *i;
1525  }
1526  }
1527  ++i;
1528  }
1529 
1530  return newName;
1531 }
1532 
1533 std::string ChatWindow::autoComplete(const std::string &partName,
1534  const History *const words) const
1535 {
1536  if (words == nullptr)
1537  return "";
1538 
1539  ChatCommands::const_iterator i = words->begin();
1540  const ChatCommands::const_iterator i_end = words->end();
1541  StringVect nameList;
1542 
1543  while (i != i_end)
1544  {
1545  const std::string line = *i;
1546  if (line.find(partName, 0) == 0)
1547  nameList.push_back(line);
1548  ++i;
1549  }
1550  return autoComplete(nameList, partName);
1551 }
1552 
1553 /*
1554 void ChatWindow::moveTabLeft(ChatTab *tab)
1555 {
1556  mChatTabs->moveLeft(tab);
1557 }
1558 
1559 void ChatWindow::moveTabRight(ChatTab *tab)
1560 {
1561  mChatTabs->moveRight(tab);
1562 }
1563 */
1564 
1565 std::string ChatWindow::autoCompleteHistory(const std::string &partName) const
1566 {
1567  History::const_iterator i = mHistory.begin();
1568  const History::const_iterator i_end = mHistory.end();
1569  StringVect nameList;
1570 
1571  while (i != i_end)
1572  {
1573  std::string line = *i;
1574  unsigned int f = 0;
1575  while (f < line.length() && !isWordSeparator(line.at(f)))
1576  f++;
1577 
1578  line = line.substr(0, f);
1579  if (!line.empty())
1580  nameList.push_back(line);
1581 
1582  ++i;
1583  }
1584  return autoComplete(nameList, partName);
1585 }
1586 
1587 bool ChatWindow::resortChatLog(std::string line,
1588  ChatMsgTypeT own,
1589  const std::string &channel,
1590  const IgnoreRecord ignoreRecord,
1591  const TryRemoveColors tryRemoveColors)
1592 {
1593  if (own == ChatMsgType::BY_UNKNOWN)
1594  {
1595  const size_t pos = line.find(" : ");
1596  if (pos != std::string::npos)
1597  {
1598  if (line.length() <= pos + 3)
1599  own = ChatMsgType::BY_SERVER;
1600  else if (line.substr(0, pos) == localPlayer->getName())
1601  own = ChatMsgType::BY_PLAYER;
1602  else
1603  own = ChatMsgType::BY_OTHER;
1604  }
1605  else
1606  {
1607  own = ChatMsgType::BY_SERVER;
1608  }
1609  }
1610 
1611  std::string prefix;
1612  if (!channel.empty())
1613  {
1614  prefix = std::string("##3").append(channel).append("##0");
1615  }
1616  else if (mEnableTradeFilter &&
1617  (tradeChatTab != nullptr) &&
1618  findI(line, mTradeFilter) != std::string::npos)
1619  {
1620  // TRANSLATORS: prefix for moved message to trade tab.
1621  tradeChatTab->chatLog(std::string("##S") + _("Moved: ") + line,
1622  own,
1623  ignoreRecord,
1624  tryRemoveColors);
1625  if (own == ChatMsgType::BY_PLAYER)
1626  {
1627  own = ChatMsgType::BY_SERVER;
1628  // TRANSLATORS: moved message to trade tab warning.
1629  line = _("Your message was moved to trade tab");
1630  }
1631  else
1632  {
1633  return false;
1634  }
1635  }
1636 
1637  size_t idx2 = line.find(": ");
1638  if (idx2 != std::string::npos)
1639  {
1640  std::string tmpNick = line.substr(0, idx2);
1641  if (tmpNick.find('#') != std::string::npos ||
1642  tmpNick.find(':') != std::string::npos ||
1643  tmpNick.find('%') != std::string::npos ||
1644  tmpNick.find('@') != std::string::npos ||
1645  tmpNick.size() < 5 ||
1646  tmpNick[0] == '@' ||
1647  tmpNick[0] == '/' ||
1648  tmpNick[0] == '!'
1649  )
1650  {
1651  replaceAll(tmpNick, "#", "_");
1652  replaceAll(tmpNick, "%", "_");
1653  // TRANSLATORS: error message
1654  line = _("Broken nick detected: ") + line;
1655  own = ChatMsgType::BY_SERVER;
1656  }
1657  const size_t idx = line.find(": \302\202");
1658  if (idx == idx2)
1659  {
1660  if (line.find(": \302\202\302") != std::string::npos)
1661  {
1662  if (line.find(": \302\202\302e") != std::string::npos)
1663  {
1664  // Do nothing. Before was local pet emote
1665  }
1666  else if (line.find(": \302\202\302m") != std::string::npos)
1667  {
1668  // Do nothing. Before was local pet move
1669  }
1670  else if (line.find(": \302\202\302d") != std::string::npos)
1671  {
1672  // Do nothing. Before was local pet direction
1673  }
1674  else if (line.find(": \302\202\302a") != std::string::npos)
1675  {
1676  // Do nothing. Before was local pet ai enable/disable
1677  }
1678  // ignore other special message formats.
1679  return false;
1680  }
1681 
1682  // pet talk message detected
1683  if (line.find(": \302\202\303 ") != std::string::npos)
1684  {
1685  // Do nothing. Before was local pet talk
1686  return false;
1687  }
1688  if (line.find(": \302\202\304") != std::string::npos)
1689  {
1690  replaceAll(line, ": \302\202\304", ": ");
1691  }
1692 
1693  if (tradeChatTab != nullptr)
1694  {
1695  line = line.erase(idx + 2, 2);
1696  tradeChatTab->chatLog(prefix + line,
1697  own,
1698  ignoreRecord,
1699  tryRemoveColors);
1700  }
1701  else if (localChatTab != nullptr)
1702  {
1703  line = line.erase(idx + 2, 2);
1704  localChatTab->chatLog(prefix + line,
1705  own,
1706  ignoreRecord,
1707  tryRemoveColors);
1708  }
1709  return false;
1710  }
1711  }
1712 
1713  if (!channel.empty())
1714  {
1715  if (langChatTab != nullptr)
1716  {
1718  {
1719  langChatTab->chatLog(line,
1720  own,
1721  ignoreRecord,
1722  tryRemoveColors);
1723  }
1724  else if (mShowAllLang)
1725  {
1726  langChatTab->chatLog(prefix + line,
1727  own,
1728  ignoreRecord,
1729  tryRemoveColors);
1730  }
1731  }
1733  {
1734  channelChatLog(channel, line, own, ignoreRecord, tryRemoveColors);
1735  return false;
1736  }
1737  else if (mShowAllLang)
1738  {
1739  localChatTab->chatLog(prefix + line,
1740  own,
1741  ignoreRecord,
1742  tryRemoveColors);
1743  }
1744  }
1745  else if (localChatTab != nullptr)
1746  {
1747  localChatTab->chatLog(line, own, ignoreRecord, tryRemoveColors);
1748  }
1749  return true;
1750 }
1751 
1752 void ChatWindow::battleChatLog(const std::string &line, ChatMsgTypeT own,
1753  const IgnoreRecord ignoreRecord,
1754  const TryRemoveColors tryRemoveColors)
1755 {
1756  if (own == ChatMsgType::BY_UNKNOWN)
1757  own = ChatMsgType::BY_SERVER;
1758  if (battleChatTab != nullptr)
1759  battleChatTab->chatLog(line, own, ignoreRecord, tryRemoveColors);
1760  else if (debugChatTab != nullptr)
1761  debugChatTab->chatLog(line, own, ignoreRecord, tryRemoveColors);
1762 }
1763 
1764 void ChatWindow::channelChatLog(const std::string &channel,
1765  const std::string &line,
1766  ChatMsgTypeT own,
1767  const IgnoreRecord ignoreRecord,
1768  const TryRemoveColors tryRemoveColors)
1769 {
1770  std::string tempChannel = channel;
1771  toLower(tempChannel);
1772 
1773  ChatTab *tab = nullptr;
1774  const ChannelMap::const_iterator i = mChannels.find(tempChannel);
1775 
1776  if (i != mChannels.end())
1777  {
1778  tab = i->second;
1779  }
1780  else
1781  {
1782  tab = addChannelTab(channel, false);
1783  if (tab != nullptr)
1784  saveState();
1785  }
1786 
1787  if (tab != nullptr)
1788  tab->chatLog(line, own, ignoreRecord, tryRemoveColors);
1789 }
1790 
1792 {
1793  const std::string tradeListName = settings.serverConfigDir
1794  + "/tradefilter.txt";
1795 
1796  std::ifstream tradeFile;
1797  struct stat statbuf;
1798 
1799  if (stat(tradeListName.c_str(), &statbuf) == 0 &&
1800  S_ISREG(statbuf.st_mode))
1801  {
1802  tradeFile.open(tradeListName.c_str(), std::ios::in);
1803  if (tradeFile.is_open())
1804  {
1805  char line[100];
1806  while (tradeFile.getline(line, 100))
1807  {
1808  const std::string str = line;
1809  if (!str.empty())
1810  mTradeFilter.push_back(str);
1811  }
1812  }
1813  tradeFile.close();
1814  }
1815 }
1816 
1817 void ChatWindow::updateOnline(const std::set<std::string> &onlinePlayers) const
1818 {
1819  const Party *party = nullptr;
1820  const Guild *guild = nullptr;
1821  if (localPlayer != nullptr)
1822  {
1823  party = localPlayer->getParty();
1824  guild = localPlayer->getGuild();
1825  }
1826  FOR_EACH (TabMap::const_iterator, iter, mWhispers)
1827  {
1828  if (iter->second == nullptr)
1829  return;
1830 
1831  WhisperTab *const tab = static_cast<WhisperTab*>(iter->second);
1832  if (tab == nullptr)
1833  continue;
1834 
1835  if (onlinePlayers.find(tab->getNick()) != onlinePlayers.end())
1836  {
1837  tab->setWhisperTabColors();
1838  }
1839  else
1840  {
1841  const std::string &nick = tab->getNick();
1842  if (actorManager != nullptr)
1843  {
1844  const Being *const being = actorManager->findBeingByName(
1845  nick, ActorType::Player);
1846  if (being != nullptr)
1847  {
1848  tab->setWhisperTabColors();
1849  continue;
1850  }
1851  }
1852  if (party != nullptr)
1853  {
1854  const PartyMember *const pm = party->getMember(nick);
1855  if ((pm != nullptr) && pm->getOnline())
1856  {
1857  tab->setWhisperTabColors();
1858  continue;
1859  }
1860  }
1861  if (guild != nullptr)
1862  {
1863  const GuildMember *const gm = guild->getMember(nick);
1864  if ((gm != nullptr) && gm->getOnline())
1865  {
1866  tab->setWhisperTabColors();
1867  continue;
1868  }
1869  }
1871  }
1872  }
1873 }
1874 
1876 {
1877  int num = 0;
1878  while (num < 50)
1879  {
1880  const std::string nick = serverConfig.getValue(
1881  "chatWhisper" + toString(num), "");
1882 
1883  if (nick.empty())
1884  break;
1885 
1886  const int flags = serverConfig.getValue(
1887  "chatWhisperFlags" + toString(num), 1);
1888 
1889  ChatTab *const tab = addChatTab(nick, false, false);
1890  if (tab != nullptr)
1891  {
1892  tab->setAllowHighlight((flags & 1) != 0);
1893  tab->setRemoveNames(((flags & 2) / 2) != 0);
1894  tab->setNoAway(((flags & 4) / 4) != 0);
1895  }
1896  num ++;
1897  }
1898 }
1899 
1901 {
1902  int num = 0;
1903  for (ChannelMap::const_iterator iter = mChannels.begin(),
1904  iter_end = mChannels.end(); iter != iter_end && num < 50; ++iter)
1905  {
1906  if (iter->second == nullptr)
1907  return;
1908  if (!saveTab(num, iter->second))
1909  continue;
1910  num ++;
1911  }
1912 
1913  for (TabMap::const_iterator iter = mWhispers.begin(),
1914  iter_end = mWhispers.end(); iter != iter_end && num < 50; ++iter)
1915  {
1916  if (iter->second == nullptr)
1917  return;
1918  if (!saveTab(num, iter->second))
1919  continue;
1920  num ++;
1921  }
1922 
1923  while (num < 50)
1924  {
1925  serverConfig.deleteKey("chatWhisper" + toString(num));
1926  serverConfig.deleteKey("chatWhisperFlags" + toString(num));
1927  num ++;
1928  }
1929 }
1930 
1931 bool ChatWindow::saveTab(const int num,
1932  const ChatTab *const tab) const
1933 {
1934  if (tab == nullptr)
1935  return false;
1936 
1937  serverConfig.setValue("chatWhisper" + toString(num),
1938  tab->getChannelName());
1939 
1940  serverConfig.setValue("chatWhisperFlags" + toString(num),
1941  CAST_S32(tab->getAllowHighlight())
1942  + (2 * CAST_S32(tab->getRemoveNames()))
1943  + (4 * CAST_S32(tab->getNoAway())));
1944 
1945  return true;
1946 }
1947 
1948 std::string ChatWindow::doReplace(const std::string &msg)
1949 {
1950  std::string str = msg;
1951  replaceSpecialChars(str);
1952  return str;
1953 }
1954 
1956 {
1957  std::ifstream listFile;
1958  struct stat statbuf;
1959 
1960  std::string listName = settings.serverConfigDir
1961  + "/customwords.txt";
1962 
1963  if ((stat(listName.c_str(), &statbuf) == 0) && S_ISREG(statbuf.st_mode))
1964  {
1965  listFile.open(listName.c_str(), std::ios::in);
1966  if (listFile.is_open())
1967  {
1968  char line[101];
1969  while (listFile.getline(line, 100))
1970  {
1971  std::string str = line;
1972  if (!str.empty())
1973  mCustomWords.push_back(str);
1974  }
1975  }
1976  listFile.close();
1977  }
1978 }
1979 
1980 void ChatWindow::addToAwayLog(const std::string &line)
1981 {
1982  if (!settings.awayMode)
1983  return;
1984 
1985  if (mAwayLog.size() > 20)
1986  mAwayLog.pop_front();
1987 
1988  if (findI(line, mHighlights) != std::string::npos)
1989  mAwayLog.push_back("##aaway:" + line);
1990 }
1991 
1993 {
1994  if (localChatTab == nullptr)
1995  return;
1996 
1997  std::list<std::string>::const_iterator i = mAwayLog.begin();
1998  const std::list<std::string>::const_iterator i_end = mAwayLog.end();
1999 
2000  while (i != i_end)
2001  {
2002  std::string str = *i;
2003  localChatTab->addNewRow(str);
2004  ++i;
2005  }
2006 }
2007 
2009 {
2010  mHighlights.clear();
2011  if (localPlayer == nullptr)
2012  return;
2013 
2015  "highlightWords"), ',');
2016 
2017  mHighlights.push_back(localPlayer->getName());
2018 }
2019 
2021 {
2022  mGlobalsFilter.clear();
2023  if (localPlayer == nullptr)
2024  return;
2025 
2027  "globalsFilter"), ',');
2028 
2029  mHighlights.push_back(localPlayer->getName());
2030 }
2031 
2032 bool ChatWindow::findHighlight(const std::string &str)
2033 {
2034  return findI(str, mHighlights) != std::string::npos;
2035 }
2036 
2037 void ChatWindow::copyToClipboard(const int x, const int y) const
2038 {
2039  const ChatTab *const tab = getFocused();
2040  if (tab == nullptr)
2041  return;
2042 
2043  const BrowserBox *const text = tab->mTextOutput;
2044  if (text == nullptr)
2045  return;
2046 
2047  std::string str = text->getTextAtPos(x, y);
2048  sendBuffer(str);
2049 }
2050 
2051 void ChatWindow::optionChanged(const std::string &name)
2052 {
2053  if (name == "autohideChat")
2054  mAutoHide = config.getBoolValue("autohideChat");
2055  else if (name == "showBattleEvents")
2056  mShowBattleEvents = config.getBoolValue("showBattleEvents");
2057  else if (name == "globalsFilter")
2059  else if (name == "enableTradeFilter")
2060  mEnableTradeFilter = config.getBoolValue("enableTradeFilter");
2061 }
2062 
2064 {
2065  mHaveMouse = true;
2066  Window::mouseMoved(event);
2067 }
2068 
2070 {
2071  mHaveMouse = true;
2072  Window::mouseEntered(event);
2073 }
2074 
2076 {
2077  updateVisibility();
2078  Window::mouseExited(event);
2079 }
2080 
2081 void ChatWindow::draw(Graphics *const graphics)
2082 {
2083  BLOCK_START("ChatWindow::draw")
2084  if (!mAutoHide || mHaveMouse)
2085  {
2086  GLDEBUG_START("ChatWindow::draw");
2087  Window::draw(graphics);
2088  GLDEBUG_END();
2089  }
2090  BLOCK_END("ChatWindow::draw")
2091 }
2092 
2093 void ChatWindow::safeDraw(Graphics *const graphics)
2094 {
2095  BLOCK_START("ChatWindow::draw")
2096  if (!mAutoHide || mHaveMouse)
2097  {
2098  GLDEBUG_START("ChatWindow::draw");
2099  Window::safeDraw(graphics);
2100  GLDEBUG_END();
2101  }
2102  BLOCK_END("ChatWindow::draw")
2103 }
2104 
2106 {
2107  if (gui == nullptr)
2108  return;
2109 
2110  int mouseX = 0;
2111  int mouseY = 0;
2112  int x = 0;
2113  int y = 0;
2114  Gui::getMouseState(mouseX, mouseY);
2115  getAbsolutePosition(x, y);
2116  if (mChatInput->isVisible())
2117  {
2118  mHaveMouse = true;
2119  }
2120  else
2121  {
2122  mHaveMouse = mouseX >= x && mouseX <= x + getWidth()
2123  && mouseY >= y && mouseY <= y + getHeight();
2124  }
2125 }
2126 
2128 {
2129  mHaveMouse = true;
2130 }
2131 
2132 #ifdef USE_PROFILER
2134 {
2135  BLOCK_START("ChatWindow::logicChildren")
2137  BLOCK_END("ChatWindow::logicChildren")
2138 }
2139 #endif // USE_PROFILER
2140 
2141 void ChatWindow::addGlobalMessage(const std::string &line)
2142 {
2143  if (debugChatTab != nullptr &&
2144  findI(line, mGlobalsFilter) != std::string::npos)
2145  {
2146  debugChatTab->chatLog(line,
2150  }
2151  else
2152  {
2153  localChatTab->chatLog(line,
2157  }
2158 }
2159 
2160 bool ChatWindow::isTabPresent(const ChatTab *const tab) const
2161 {
2162  return mChatTabs->isTabPresent(tab);
2163 }
2164 
2165 void ChatWindow::debugMessage(const std::string &msg)
2166 {
2167  if (debugChatTab != nullptr)
2168  {
2169  debugChatTab->chatLog(msg,
2173  }
2174 }
2175 
2177 {
2178  if ((gmChatTab == nullptr) &&
2179  config.getBoolValue("enableGmTab") &&
2180  localPlayer->getGroupId() >= paths.getIntValue("gmTabMinimalLevel"))
2181  {
2183  }
2184 }
2185 
2187 {
2190  else
2191  requestChatFocus();
2192 }
2193 
2194 void ChatWindow::joinRoom(const bool isJoin)
2195 {
2196  Tab *const tab = mChatTabs->getTabByIndex(0);
2197  if (tab != nullptr)
2198  {
2199  std::string name;
2200  if (isJoin)
2201  {
2202  name = PlayerInfo::getRoomName();
2203  }
2204  else
2205  {
2206  // TRANSLATORS: chat tab name
2207  name = _("General");
2208  }
2209  tab->setCaption(name);
2210  }
2211 }
2212 
2214 {
2217 }
void setSize(const int width, const int height)
Definition: widget.cpp:366
#define CAST_U32
Definition: cast.h:30
void removeChannel(const std::string &nick)
Definition: chatwindow.cpp:600
void scheduleDelete()
void clearText()
void setHeight(int height)
Definition: tabbedarea.cpp:754
ChatWindow * chatWindow
Definition: chatwindow.cpp:89
bool sendBuffer(const std::string &text)
Definition: copynpaste.cpp:517
#define FOR_EACH(type, iter, array)
Definition: foreach.h:24
void setDefaultSize()
Definition: window.cpp:1193
int getContainerHeight() const
Definition: tabbedarea.h:163
std::string getStringValue(const std::string &key) const
#define _(s)
Definition: gettext.h:34
int width
Definition: rect.h:218
static void removeListener(const DebugMessageListener *const listener)
void showChatPopup(const int x, const int y, ChatTab *const tab)
Definition: popupmenu.cpp:912
unsigned int mRainbowColor
Definition: chatwindow.h:352
void mouseExited(MouseEvent &event)
void setDefaultVisible(const bool save)
Definition: window.h:287
int getWidth() const
Definition: widget.h:220
void localChatInput(const std::string &msg) const
Definition: chatwindow.cpp:686
void addNewRow(std::string &line)
Definition: chattab.cpp:525
ScrollArea * mScrollArea
Definition: chattab.h:207
void setVisible(Visible visible)
void showGMTab()
void clearColor()
bool getOnline() const
Definition: avatar.h:80
int mDragOffsetY
Definition: window.h:641
void setWidth(const int width)
Definition: widget.cpp:132
StringVect::const_iterator StringVectCIter
Definition: stringvector.h:30
virtual void getAutoCompleteList(StringVect &names) const
Definition: chattab.h:198
Definition: party.h:61
void addTab(ChatTab *const tab)
Definition: chatwindow.cpp:584
friend class WhisperTab
Definition: chatwindow.h:312
void unprotectFocus()
Definition: chatinput.h:93
int mPadding
Definition: window.h:617
void splitToStringVector(StringVect &tokens, const std::string &text, const char separator)
ChatTab * localChatTab
Definition: chattab.cpp:61
Gui * gui
Definition: gui.cpp:110
bool handleCommand(const std::string &type, const std::string &args)
Definition: whispertab.cpp:92
void setCaption(const std::string &caption)
Definition: tab.cpp:457
const bool Visible_true
Definition: visible.h:29
Definition: tab.h:84
std::string autoCompleteHistory(const std::string &partName) const
void setValidSpeed()
Definition: game.cpp:1269
void displayAwayLog() const
void loadGMCommands()
Definition: chatwindow.cpp:259
RelationT getRelation(const std::string &name) const
void updateVisibility()
void loadWindowState()
Definition: window.cpp:1082
PRAGMA45(GCC diagnostic push) PRAGMA45(GCC diagnostic ignored "-Wunused-result") int TestLauncher
LangTab * langChatTab
Definition: langtab.cpp:27
void scroll(const int amount)
Definition: chattab.cpp:418
int getY() const
Definition: widget.h:287
ChatTab * addChannelTab(const std::string &name, const bool switchTo)
SpellManager * spellManager
void clearText()
Definition: chattab.cpp:427
void addActionListener(ActionListener *const actionListener)
Definition: widget.cpp:251
int mEmoteButtonSpacing
Definition: chatwindow.h:388
StringVect mGlobalsFilter
Definition: chatwindow.h:386
Rect getChildrenArea()
Definition: window.cpp:1468
void setVisible(Visible visible)
Definition: widget.cpp:224
void removeTab(Tab *const tab)
Definition: tabbedarea.cpp:322
void removeTab(ChatTab *const tab)
Definition: chatwindow.cpp:579
const Guild * getGuild(const std::string &guildName) const
Definition: being.cpp:1257
void doPresent() const
Definition: chatwindow.cpp:694
bool isTabPresent(const ChatTab *const tab) const
Button * mChatButton
Definition: chatwindow.h:383
DropDown * mColorPicker
Definition: chatwindow.h:382
void secureChatCommand(std::string &str)
MouseButtonT getButton() const
Definition: mouseevent.h:115
Definition: rect.h:72
virtual void getAutoCompleteCommands(StringVect &names) const
Definition: chattab.h:201
#define CAST_U64
Definition: cast.h:32
TradeTab * tradeChatTab
Definition: tradetab.cpp:35
void getMobNames(StringVect &names) const
void setMinWidth(const int width)
Definition: window.cpp:586
Definition: window.h:98
int mWidth
Definition: graphics.h:483
void postConnection()
#define BLOCK_START(name)
Definition: perfomance.h:78
Definition: button.h:96
History mCustomWords
Definition: chatwindow.h:377
void setShowTitle(bool flag)
Definition: window.h:234
Configuration config
void removeWhisper(const std::string &nick)
Definition: chatwindow.cpp:593
void getPlayerNames(StringVect &names)
void unHideWindow()
void loadCustomList()
std::string & replaceAll(std::string &context, const std::string &from, const std::string &to)
void optionChanged(const std::string &name)
const std::string & getChannelName() const
Definition: chattab.h:182
#define GLDEBUG_START(text)
Definition: opengldebug.h:34
void mouseMoved(MouseEvent &event)
Definition: window.cpp:962
void setCaretPosition(unsigned int position)
Definition: textfield.cpp:751
void autoComplete()
bool isInputFocused() const
Definition: chatwindow.cpp:574
WhoIsOnline * whoIsOnline
Definition: whoisonline.cpp:78
#define BLOCK_END(name)
Definition: perfomance.h:79
const bool TryRemoveColors_true
void chatLog(std::string line, ChatMsgTypeT own, const IgnoreRecord ignoreRecord, const TryRemoveColors tryRemoveColors)
Definition: chattab.cpp:110
FocusHandler * mFocusHandler
Definition: widget.h:1115
Party * getParty() const
Definition: being.h:329
bool msg(InputEvent &event)
Definition: chat.cpp:38
int getIntValue(const std::string &key) const
bool mMoved
Definition: window.h:646
std::string removeColors(std::string msg)
virtual bool handleCommand(const std::string &type, const std::string &args)
Definition: chattab.h:127
void chatInput(const std::string &msg)
Definition: chattab.cpp:381
void setActionEventId(const std::string &actionEventId)
Definition: widget.h:595
int mMouseX
Definition: viewport.h:153
std::vector< std::string > StringVect
Definition: stringvector.h:28
#define delete2(var)
Definition: delete2.h:24
Configuration serverConfig
void mouseDragged(MouseEvent &event)
Definition: chatwindow.cpp:794
const bool NpcNames_true
Definition: npcnames.h:29
void fillCommands()
Definition: chatwindow.cpp:253
uint32_t party
bool mShowBattleEvents
Definition: chatwindow.h:396
int getWidth() const
Definition: graphics.cpp:642
WhisperTab * getWhisperTab(const std::string &nick) const
std::string getTextAtPos(const int x, const int y) const
Definition: browserbox.cpp:869
void adjustTabSize()
Definition: chatwindow.cpp:276
#define ifKey(key, str)
Definition: chatwindow.cpp:811
int getNumberOfTabs() const
Definition: tabbedarea.cpp:168
void setRightMargin(const int n)
Definition: tabbedarea.h:204
void addListener(const std::string &key, ConfigListener *const listener)
std::list< std::string > History
Definition: chatwindow.h:315
void enableScrollButtons(const bool enable)
Definition: tabbedarea.cpp:149
int mDragOffsetX
Definition: window.h:634
GuildMember * getMember(const BeingId id) const
Definition: guild.cpp:139
bool isActionActive(const InputActionT index) const
virtual bool isFocused() const
Definition: widget.cpp:183
bool isMovable() const
Definition: window.h:575
void setText(const std::string &text)
Definition: textfield.cpp:802
void registerWindowForReset(Window *const window)
void adjustSize()
Definition: button.cpp:798
bool isWordSeparator(const signed char chr) A_CONST
Definition: stringutils.h:141
unsigned int getFrameSize() const
Definition: widget.h:183
StringVect mTradeFilter
Definition: chatwindow.h:379
ChatWindow(const std::string &name)
Definition: chatwindow.cpp:93
void setSelectedTab(Tab *const tab)
Definition: tabbedarea.cpp:406
friend class ChannelTab
Definition: chatwindow.h:310
void loadFromLogFile(const std::string &name)
Definition: chattab.cpp:509
void addListeners(ActionListener *const listener)
BattleTab * battleChatTab
Definition: battletab.cpp:31
void parseGlobalsFilter()
void chatInput(const std::string &msg) const
Definition: chatwindow.cpp:660
bool isGoodName(Being *const being) const
Visible mVisible
Definition: widget.h:962
bool mShowAllLang
Definition: chatrecv.cpp:50
#define new
Definition: debug_new.h:147
Tab * getTabByIndex(const int index) const
Definition: tabbedarea.cpp:713
Settings settings
Definition: settings.cpp:31
void clearFont()
const std::string findSameSubstringI(const std::string &s1, const std::string &s2)
void keyPressed(KeyEvent &event)
Definition: chatwindow.cpp:817
bool hasRows() const
Definition: chattab.h:152
void widgetResized(const Event &event)
Definition: window.cpp:650
TabbedArea * mChatTabs
Definition: chatwindow.h:343
int getTitlePadding() const
Definition: window.h:601
std::string getRoomName()
Definition: playerinfo.cpp:629
bool getBoolValue(const std::string &key) const
void updateTabsMargin()
Definition: chatwindow.cpp:268
void loadCommandsFile(const std::string &name)
Definition: chatwindow.cpp:237
virtual void privateMessage(const std::string &recipient, const std::string &text) const =0
bool mReturnToggles
Definition: chatwindow.h:391
#define changeColor(fun)
#define CAST_S32
Definition: cast.h:29
virtual void requestFocus()
Definition: widget.cpp:203
std::string getTextBeforeCaret() const
Definition: textfield.h:206
const std::string BUTTON_SKIN
Definition: button.h:88
void afkRespond(ChatTab *const tab, const std::string &nick)
std::string strprintf(const char *const format,...)
Definition: stringutils.cpp:99
ChatTab * addSpecialChannelTab(const std::string &name, const bool switchTo)
PoDict * reverseDictionary
Definition: podict.cpp:29
void toggleChatFocus()
void loadState()
StringVect mHighlights
Definition: chatwindow.h:385
void setWhisperTabColors()
Definition: whispertab.cpp:122
void clearEmote()
const bool Visible_false
Definition: visible.h:29
const std::string GM_CHANNEL
Definition: chat.h:29
void saveState() const
EmoteWindow * emoteWindow
Definition: emotewindow.cpp:48
#define fromBool(val, name)
Definition: booldefines.h:48
void draw(Graphics *const graphics)
const std::string & getNick() const
Definition: whispertab.h:36
std::string serverConfigDir
Definition: settings.h:115
bool requestChatFocus()
Definition: chatwindow.cpp:548
Definition: game.h:62
void draw(Graphics *const graphics)
Definition: window.cpp:310
unsigned int getCaretPosition() const
Definition: textfield.h:233
bool canMove() const
Definition: window.cpp:972
int getSelectedTabIndex() const
Definition: tabbedarea.cpp:448
void postInit()
Definition: chatwindow.cpp:227
void setWidth(int width)
Definition: tabbedarea.cpp:747
virtual void logic()
Definition: widget.h:192
LocalPlayer * localPlayer
PopupMenu * popupMenu
Definition: popupmenu.cpp:102
void replaceSpecialChars(std::string &text)
virtual void logicChildren()
std::string autoComplete(const std::string &partName) const
int getHeight() const
Definition: graphics.cpp:647
virtual void add(Widget *const widget)
std::string trim(std::string const &str)
const bool IgnoreRecord_false
Definition: ignorerecord.h:29
void resetClickCount()
Definition: gui.cpp:978
bool mAutoHide
Definition: chatwindow.h:395
std::string toLower(std::string const &s)
InputAction ::T InputActionT
Definition: inputaction.h:715
PartyMember * getMember(const BeingId id) const
Definition: party.cpp:98
ActorSprites::iterator ActorSpritesIterator
Definition: actormanager.h:59
#define nullptr
Definition: localconsts.h:44
Graphics * mainGraphics
Definition: graphics.cpp:108
int mEmoteButtonY
Definition: chatwindow.h:389
std::list< std::string > mAwayLog
Definition: chatwindow.h:384
bool isWindowVisible() const
Definition: window.h:483
ChatTabTypeT getType() const
Definition: chattab.h:144
bool getRemoveNames() const
Definition: chattab.h:163
std::string getSelectedEmote() const
void widgetResized(const Event &event)
Definition: chatwindow.cpp:345
void initTradeFilter()
std::string addColors(std::string &msg)
BrowserBox * mTextOutput
Definition: chattab.h:206
History::iterator HistoryIterator
Definition: chatwindow.h:370
void setPosition(const int x, const int y)
Definition: widget.cpp:160
int height
Definition: rect.h:223
void addKeyListener(KeyListener *const keyListener)
Definition: widget.cpp:271
int getGroupId() const
Definition: being.h:1090
int mHeight
Definition: graphics.h:484
virtual void getAbsolutePosition(int &x, int &y) const
Definition: widget.cpp:311
static std::string doReplace(const std::string &msg)
static uint8_t getMouseState(int &x, int &y)
Definition: gui.cpp:1169
WhisperTab * addWhisperTab(const std::string &caption, const std::string &nick, const bool switchTo)
Definition: gmtab.h:29
bool isConsumed() const
const std::string & getName() const
Definition: being.h:231
void enableVisibleSound(bool b)
Definition: window.h:480
void setMinHeight(const int height)
Definition: window.cpp:599
std::string getSelectedFont() const
void attributeChanged(const AttributesT id, const int64_t oldVal, const int64_t newVal)
virtual void scheduleDelete()
Definition: window.cpp:826
ChatTab * addChatTab(const std::string &name, const bool switchTo, const bool join)
int mMouseY
Definition: viewport.h:154
ChannelMap mChannels
Definition: chatwindow.h:368
bool addCurrentToHistory()
Definition: chatwindow.cpp:993
void debugMessage(const std::string &msg)
int getY() const
Definition: mouseevent.h:137
void defaultTab()
Definition: chatwindow.cpp:428
bool saveTab(const int num, const ChatTab *const tab) const
ChatTabType ::T ChatTabTypeT
Definition: chattabtype.h:48
void setSaveVisible(const bool save)
Definition: window.h:299
ServerTypeT getNetworkType()
Definition: net.cpp:182
void prevTab()
Definition: chatwindow.cpp:368
void setSelectedTabByIndex(const size_t index)
Definition: tabbedarea.cpp:314
Configuration paths
void setLabelFont(Font *const font)
Definition: tab.cpp:413
int getX() const
Definition: widget.h:268
void addGlobalMessage(const std::string &line)
void copyToClipboard(const int x, const int y) const
ChatTab * debugChatTab
Definition: chattab.cpp:62
void mouseEntered(MouseEvent &event)
std::string toString(T const &value)
converts any type to a string
Definition: catch.hpp:1774
std::string getValue(const std::string &key, const std::string &deflt) const
void setFollowDownScroll(const bool n)
Definition: tabbedarea.h:210
void action(const ActionEvent &event)
Definition: chatwindow.cpp:434
virtual void setVisible(Visible visible)
Definition: window.cpp:773
void adjustSize()
Definition: tabbedarea.cpp:567
bool isVisible() const
Definition: widget.h:377
bool Visible
Definition: visible.h:29
Font * getSecureFont() const
Definition: gui.h:171
void joinRoom(const bool isJoin)
void addChatCommands(std::list< std::string > &arr)
GmTab * gmChatTab
Definition: gmtab.cpp:33
Definition: widget.h:97
Net::ChatHandler * chatHandler
Definition: net.cpp:82
HistoryIterator mCurHist
Definition: chatwindow.h:372
void parseHighlights()
ChatTab * getFocused() const
Definition: chatwindow.cpp:352
void mouseMoved(MouseEvent &event)
void setRemoveNames(const bool n)
Definition: chattab.h:166
void setAllowSpecialActions(const bool b)
Definition: textfield.h:203
void removeListeners(ConfigListener *const listener)
void removeAllChannels()
Definition: chatwindow.cpp:624
History mCommands
Definition: chatwindow.h:376
bool getNoAway() const
Definition: chattab.h:169
Definition: event.h:77
std::string getByIndex(const int index)
Definition: textdb.cpp:96
void mouseDragged(MouseEvent &event)
Definition: window.cpp:977
bool isResizeAllowed(const MouseEvent &event) const
Definition: window.cpp:1340
void mouseEntered(MouseEvent &event)
Definition: window.cpp:914
bool gm(InputEvent &event)
Definition: commands.cpp:74
Tab * getSelectedTab() const
Definition: tabbedarea.h:174
void closeTab() const
Definition: chatwindow.cpp:414
ItemLinkHandler * mItemLinkHandler
Definition: chatwindow.h:340
void mousePressed(MouseEvent &event)
Definition: window.cpp:831
Attributes ::T AttributesT
Definition: attributes.h:117
bool getAllowHighlight() const
Definition: chattab.h:157
bool awayMode
Definition: settings.h:155
void setAllowCommands(const bool b)
void deleteKey(const std::string &key)
int getHeight() const
Definition: widget.h:239
void mouseExited(MouseEvent &event)
Definition: window.cpp:919
const ActorSprites & getAll() const A_CONST
bool mHaveMouse
Definition: chatwindow.h:394
void removeAllWhispers()
Definition: chatwindow.cpp:608
static void battleChatLog(const std::string &line, ChatMsgTypeT own, const IgnoreRecord ignoreRecord, const TryRemoveColors tryRemoveColors)
static Game * instance()
Definition: game.h:81
#define restrict
Definition: localconsts.h:156
History mHistory
Definition: chatwindow.h:371
void addItemText(const std::string &item)
virtual void partChannel(const std::string &channel) const =0
bool mEnableTradeFilter
Definition: chatwindow.h:398
Being * findBeingByName(const std::string &name, const ActorTypeT type) const
void setResizable(const bool resize)
Definition: window.cpp:622
bool mTmpVisible
Definition: chatwindow.h:399
bool loadTextFile(const std::string &fileName, StringVect &lines)
Definition: tools.cpp:136
void setStickyButtonLock(const bool sticky)
Definition: window.cpp:767
#define CAST_SIZE
Definition: cast.h:33
int getSelectedTextIndex() const
int getX() const
Definition: mouseevent.h:126
SetupWindow * setupWindow
Definition: setupwindow.cpp:63
#define CHECKLISTENERS
Definition: localconsts.h:268
InputManager inputManager
ColorListModel * mColorListModel
Definition: chatwindow.h:381
void scroll(const int amount) const
Definition: chatwindow.cpp:728
void addToAwayLog(const std::string &line)
#define CREATEWIDGETR(type,...)
Definition: createwidget.h:35
int mChatColor
Definition: chatwindow.h:387
void setTitleBarHeight(unsigned int height)
Definition: window.h:512
ChatMsgType ::T ChatMsgTypeT
Definition: chatmsgtype.h:40
void mousePressed(MouseEvent &event)
Definition: chatwindow.cpp:738
const std::string TRADE_CHANNEL
Definition: chat.h:30
bool mShowAllLang
Definition: chatwindow.h:397
bool mGMLoaded
Definition: chatwindow.h:393
bool executeChatCommand(const std::string &cmd, const std::string &args, ChatTab *const tab)
void clearTab() const
Definition: chatwindow.cpp:363
bool isTabPresent(const Tab *const tab) const
Definition: tabbedarea.cpp:299
int32_t getAttribute(const AttributesT id)
Definition: playerinfo.cpp:100
const std::string getStr(const std::string &str)
Definition: podict.cpp:44
uint32_t guild
Definition: being.h:93
void setWhisperTabOfflineColors()
Definition: whispertab.cpp:127
PlayerRelationsManager playerRelations
void processVisible(const Visible n)
Definition: chatinput.h:74
Definition: guild.h:68
void setSelected(int selected)
Definition: dropdown.cpp:514
bool findHighlight(const std::string &str)
void setValue(const std::string &key, const std::string &value)
void setNoAway(const bool n)
Definition: chattab.h:172
void ignoreAllWhispers()
Definition: chatwindow.cpp:640
ChatInput * mChatInput
Definition: chatwindow.h:346
size_t findI(std::string str, std::string subStr)
unsigned int mChatHistoryIndex
Definition: chatwindow.h:390
void setAllowHighlight(const bool n)
Definition: chattab.h:160
const std::string & getText() const
Definition: textfield.h:223
const std::list< std::string > & getRows() const
Definition: chattab.h:149
int getPadding() const
Definition: window.h:503
void addWhisper(const std::string &nick, const std::string &mes, const ChatMsgTypeT own)
void getPlayerNames(StringVect &names, const NpcNames npcNames) const
void setRelation(const std::string &name, const RelationT relation)
#define GLDEBUG_END()
Definition: opengldebug.h:35
int getSelected() const
Definition: dropdown.cpp:509
bool resortChatLog(std::string line, ChatMsgTypeT own, const std::string &channel, const IgnoreRecord ignoreRecord, const TryRemoveColors tryRemoveColors)
bool isGM() const
Definition: being.h:658
static const char *const ACTION_COLOR_PICKER
Definition: chatwindow.cpp:91
void addInputText(const std::string &text, const bool space)
void postInit()
Definition: window.cpp:248
ActorManager * actorManager
Viewport * viewport
Definition: viewport.cpp:35
virtual void joinChannel(const std::string &channel) const =0
void safeDraw(Graphics *const graphics)
Definition: window.cpp:422
void safeDraw(Graphics *const graphics)
void addTab(Tab *const tab, Widget *const widget)
Definition: tabbedarea.cpp:237
std::string getSelectedColor() const
void updateOnline(const std::set< std::string > &onlinePlayers) const
void setResizeHeight(bool b)
Definition: tabbedarea.h:231
void setWindowName(const std::string &name)
Definition: window.h:354
TabMap mWhispers
Definition: chatwindow.h:367
void nextTab()
Definition: chatwindow.cpp:382
void channelChatLog(const std::string &channel, const std::string &line, ChatMsgTypeT own, const IgnoreRecord ignoreRecord, const TryRemoveColors tryRemoveColors)
std::set< ActorSprite * > ActorSprites
Definition: actormanager.h:56
void selectTabByType(const ChatTabTypeT &type)
Definition: chatwindow.cpp:396