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