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