qTox  Version: nightly | Commit: bc751c8e1cac455f9690654fcfe0f560d2d7dfdd
genericchatform.cpp
Go to the documentation of this file.
1 /*
2  Copyright © 2014-2019 by The qTox Project Contributors
3 
4  This file is part of qTox, a Qt-based graphical interface for Tox.
5 
6  qTox is libre software: you can redistribute it and/or modify
7  it under the terms of the GNU General Public License as published by
8  the Free Software Foundation, either version 3 of the License, or
9  (at your option) any later version.
10 
11  qTox is distributed in the hope that it will be useful,
12  but WITHOUT ANY WARRANTY; without even the implied warranty of
13  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14  GNU General Public License for more details.
15 
16  You should have received a copy of the GNU General Public License
17  along with qTox. If not, see <http://www.gnu.org/licenses/>.
18 */
19 
20 #include "genericchatform.h"
21 
23 #include "src/chatlog/chatwidget.h"
26 #include "src/core/core.h"
27 #include "src/friendlist.h"
28 #include "src/grouplist.h"
29 #include "src/model/friend.h"
30 #include "src/model/group.h"
41 #include "src/widget/searchform.h"
42 #include "src/widget/style.h"
45 #include "src/widget/translator.h"
46 #include "src/widget/widget.h"
47 #include "src/widget/gui.h"
48 
49 #include <QClipboard>
50 #include <QFileDialog>
51 #include <QKeyEvent>
52 #include <QMessageBox>
53 #include <QRegularExpression>
54 #include <QStringBuilder>
55 #include <QtGlobal>
56 
57 #ifdef SPELL_CHECKING
58 #include <KF5/SonnetUi/sonnet/spellcheckdecorator.h>
59 #endif
60 
67 static const QSize FILE_FLYOUT_SIZE{24, 24};
68 static const short FOOT_BUTTONS_SPACING = 2;
69 static const short MESSAGE_EDIT_HEIGHT = 50;
70 static const short MAIN_FOOT_LAYOUT_SPACING = 5;
71 static const QString FONT_STYLE[]{"normal", "italic", "oblique"};
72 
79 static QString fontToCss(const QFont& font, const QString& name)
80 {
81  QString result{"%1{"
82  "font-family: \"%2\"; "
83  "font-size: %3px; "
84  "font-style: \"%4\"; "
85  "font-weight: normal;}"};
86  return result.arg(name).arg(font.family()).arg(font.pixelSize()).arg(FONT_STYLE[font.style()]);
87 }
88 
97 {
99  if (f) {
100  return f->getDisplayedName();
101  }
102 
103  for (Group* it : GroupList::getAllGroups()) {
104  QString res = it->resolveToxPk(pk);
105  if (!res.isEmpty()) {
106  return res;
107  }
108  }
109 
110  return pk.toString();
111 }
112 
113 namespace
114 {
115 const QString STYLE_PATH = QStringLiteral("chatForm/buttons.css");
116 }
117 
118 namespace
119 {
120 
121 template <class T, class Fun>
122 QPushButton* createButton(const QString& name, T* self, Fun onClickSlot)
123 {
124  QPushButton* btn = new QPushButton();
125  // Fix for incorrect layouts on OS X as per
126  // https://bugreports.qt-project.org/browse/QTBUG-14591
127  btn->setAttribute(Qt::WA_LayoutUsesWidgetRect);
128  btn->setObjectName(name);
129  btn->setProperty("state", "green");
130  btn->setStyleSheet(Style::getStylesheet(STYLE_PATH));
131  QObject::connect(btn, &QPushButton::clicked, self, onClickSlot);
132  return btn;
133 }
134 
135 } // namespace
136 
137 GenericChatForm::GenericChatForm(const Core& _core, const Contact* contact, IChatLog& chatLog,
138  IMessageDispatcher& messageDispatcher, QWidget* parent)
139  : QWidget(parent, Qt::Window)
140  , core{_core}
141  , audioInputFlag(false)
142  , audioOutputFlag(false)
143  , chatLog(chatLog)
144  , messageDispatcher(messageDispatcher)
145 {
146  curRow = 0;
147  headWidget = new ChatFormHeader();
148  searchForm = new SearchForm();
149  dateInfo = new QLabel(this);
150  chatWidget = new ChatWidget(chatLog, core, this);
151  searchForm->hide();
152  dateInfo->setAlignment(Qt::AlignHCenter);
153  dateInfo->setVisible(false);
154 
155  // settings
156  const Settings& s = Settings::getInstance();
159 
160  msgEdit = new ChatTextEdit();
161 #ifdef SPELL_CHECKING
162  if (s.getSpellCheckingEnabled()) {
163  decorator = new Sonnet::SpellCheckDecorator(msgEdit);
164  }
165 #endif
166 
167  sendButton = createButton("sendButton", this, &GenericChatForm::onSendTriggered);
168  emoteButton = createButton("emoteButton", this, &GenericChatForm::onEmoteButtonClicked);
169 
170  fileButton = createButton("fileButton", this, &GenericChatForm::onAttachClicked);
171  screenshotButton = createButton("screenshotButton", this, &GenericChatForm::onScreenshotClicked);
172 
173  // TODO: Make updateCallButtons (see ChatForm) abstract
174  // and call here to set tooltips.
175 
176  fileFlyout = new FlyoutOverlayWidget;
177  QHBoxLayout* fileLayout = new QHBoxLayout(fileFlyout);
178  fileLayout->addWidget(screenshotButton);
179  fileLayout->setContentsMargins(0, 0, 0, 0);
180  fileLayout->setSpacing(0);
181  fileLayout->setMargin(0);
182 
183  msgEdit->setFixedHeight(MESSAGE_EDIT_HEIGHT);
184  msgEdit->setFrameStyle(QFrame::NoFrame);
185 
186  bodySplitter = new QSplitter(Qt::Vertical, this);
187  QWidget* contentWidget = new QWidget(this);
188  bodySplitter->addWidget(contentWidget);
189 
190  QVBoxLayout* mainLayout = new QVBoxLayout();
191  mainLayout->addWidget(bodySplitter);
192  mainLayout->setMargin(0);
193 
194  setLayout(mainLayout);
195 
196  QVBoxLayout* footButtonsSmall = new QVBoxLayout();
197  footButtonsSmall->setSpacing(FOOT_BUTTONS_SPACING);
198  footButtonsSmall->addWidget(emoteButton);
199  footButtonsSmall->addWidget(fileButton);
200 
201  QHBoxLayout* mainFootLayout = new QHBoxLayout();
202  mainFootLayout->addWidget(msgEdit);
203  mainFootLayout->addLayout(footButtonsSmall);
204  mainFootLayout->addSpacing(MAIN_FOOT_LAYOUT_SPACING);
205  mainFootLayout->addWidget(sendButton);
206  mainFootLayout->setSpacing(0);
207 
208  contentLayout = new QVBoxLayout(contentWidget);
209  contentLayout->addWidget(searchForm);
210  contentLayout->addWidget(dateInfo);
211  contentLayout->addWidget(chatWidget);
212  contentLayout->addLayout(mainFootLayout);
213 
214  quoteAction = menu.addAction(QIcon(), QString(), this, SLOT(quoteSelectedText()),
215  QKeySequence(Qt::ALT + Qt::Key_Q));
216  addAction(quoteAction);
217  menu.addSeparator();
218 
219  goToCurrentDateAction = menu.addAction(QIcon(), QString(), this, SLOT(goToCurrentDate()),
220  QKeySequence(Qt::CTRL + Qt::Key_G));
221  addAction(goToCurrentDateAction);
222 
223  menu.addSeparator();
224 
225  searchAction = menu.addAction(QIcon(), QString(), this, SLOT(searchFormShow()),
226  QKeySequence(Qt::CTRL + Qt::Key_F));
227  addAction(searchAction);
228 
229  menu.addSeparator();
230 
231  menu.addActions(chatWidget->actions());
232  menu.addSeparator();
233 
234  clearAction = menu.addAction(QIcon::fromTheme("edit-clear"), QString(),
235  this, SLOT(clearChatArea()),
236  QKeySequence(Qt::CTRL + Qt::SHIFT + Qt::Key_L));
237  addAction(clearAction);
238 
239  copyLinkAction = menu.addAction(QIcon(), QString(), this, SLOT(copyLink()));
240  menu.addSeparator();
241 
242  loadHistoryAction = menu.addAction(QIcon(), QString(), this, SLOT(onLoadHistory()));
243  exportChatAction =
244  menu.addAction(QIcon::fromTheme("document-save"), QString(), this, SLOT(onExportChat()));
245 
246  connect(chatWidget, &ChatWidget::customContextMenuRequested, this,
249 
250  connect(searchForm, &SearchForm::searchInBegin, chatWidget, &ChatWidget::startSearch);
251  connect(searchForm, &SearchForm::searchUp, chatWidget, &ChatWidget::onSearchUp);
252  connect(searchForm, &SearchForm::searchDown, chatWidget, &ChatWidget::onSearchDown);
253  connect(searchForm, &SearchForm::visibleChanged, chatWidget, &ChatWidget::removeSearchPhrase);
254  connect(chatWidget, &ChatWidget::messageNotFoundShow, searchForm, &SearchForm::showMessageNotFound);
255 
257 
259 
260  reloadTheme();
261 
262  fileFlyout->setFixedSize(FILE_FLYOUT_SIZE);
263  fileFlyout->setParent(this);
264  fileButton->installEventFilter(this);
265  fileFlyout->installEventFilter(this);
266 
267  retranslateUi();
269 
270  // update header on name/title change
271  connect(contact, &Contact::displayedNameChanged, this, &GenericChatForm::setName);
272 
273 }
274 
276 {
278  delete searchForm;
279 }
280 
282 {
283  QPoint pos = fileButton->mapTo(bodySplitter, QPoint());
284  QSize size = fileFlyout->size();
285  fileFlyout->move(pos.x() - size.width(), pos.y());
286 }
287 
289 {
290  if (!fileFlyout->isShown() && !fileFlyout->isBeingShown()) {
292  }
293 
295 }
296 
298 {
301 }
302 
304 {
306  return QDateTime();
307 
308  const auto shouldUseTimestamp = [this] (ChatLogIdx idx) {
310  return true;
311  }
312 
313  const auto& message = chatLog.at(idx).getContentAsSystemMessage();
314  switch (message.messageType) {
319  return true;
328  return false;
329  }
330 
331  qWarning("Unexpected system message type %d", static_cast<int>(message.messageType));
332  return false;
333  };
334 
335  ChatLogIdx idx = chatLog.getNextIdx();
336  while (idx > chatLog.getFirstIdx()) {
337  idx = idx - 1;
338  if (shouldUseTimestamp(idx)) {
339  return chatLog.at(idx).getTimestamp();
340  }
341  }
342 
343  return QDateTime();
344 }
345 
347 {
348  const Settings& s = Settings::getInstance();
349  setStyleSheet(Style::getStylesheet("genericChatForm/genericChatForm.css"));
350  msgEdit->setStyleSheet(Style::getStylesheet("msgEdit/msgEdit.css")
351  + fontToCss(s.getChatMessageFont(), "QTextEdit"));
352 
353  emoteButton->setStyleSheet(Style::getStylesheet(STYLE_PATH));
354  fileButton->setStyleSheet(Style::getStylesheet(STYLE_PATH));
355  screenshotButton->setStyleSheet(Style::getStylesheet(STYLE_PATH));
356  sendButton->setStyleSheet(Style::getStylesheet(STYLE_PATH));
357 }
358 
359 void GenericChatForm::setName(const QString& newName)
360 {
361  headWidget->setName(newName);
362 }
363 
365 {
366  contentLayout->mainHead->layout()->addWidget(headWidget);
367  headWidget->show();
368 
369 #if QT_VERSION < QT_VERSION_CHECK(5, 12, 4) && QT_VERSION > QT_VERSION_CHECK(5, 11, 0)
370  // HACK: switching order happens to avoid a Qt bug causing segfault, present between these versions.
371  // this could cause flickering if our form is shown before added to the layout
372  // https://github.com/qTox/qTox/issues/5570
373  QWidget::show();
374  contentLayout->mainContent->layout()->addWidget(this);
375 #else
376  contentLayout->mainContent->layout()->addWidget(this);
377  QWidget::show();
378 #endif
379 }
380 
381 void GenericChatForm::showEvent(QShowEvent*)
382 {
383  msgEdit->setFocus();
385 }
386 
387 bool GenericChatForm::event(QEvent* e)
388 {
389  // If the user accidentally starts typing outside of the msgEdit, focus it automatically
390  if (e->type() == QEvent::KeyPress) {
391  QKeyEvent* ke = static_cast<QKeyEvent*>(e);
392  if ((ke->modifiers() == Qt::NoModifier || ke->modifiers() == Qt::ShiftModifier)
393  && !ke->text().isEmpty()) {
394  if (searchForm->isHidden()) {
395  msgEdit->sendKeyEvent(ke);
396  msgEdit->setFocus();
397  } else {
398  searchForm->insertEditor(ke->text());
400  }
401  }
402  }
403  return QWidget::event(e);
404 }
405 
407 {
408  QWidget* sender = static_cast<QWidget*>(QObject::sender());
409  pos = sender->mapToGlobal(pos);
410 
411  // If we right-clicked on a link, give the option to copy it
412  bool clickedOnLink = false;
413  Text* clickedText = qobject_cast<Text*>(chatWidget->getContentFromGlobalPos(pos));
414  if (clickedText) {
415  QPointF scenePos = chatWidget->mapToScene(chatWidget->mapFromGlobal(pos));
416  QString linkTarget = clickedText->getLinkAt(scenePos);
417  if (!linkTarget.isEmpty()) {
418  clickedOnLink = true;
419  copyLinkAction->setData(linkTarget);
420  }
421  }
422  copyLinkAction->setVisible(clickedOnLink);
423 
424  menu.exec(pos);
425 }
426 
428 {
429  auto msg = msgEdit->toPlainText();
430 
431  bool isAction = msg.startsWith(ChatForm::ACTION_PREFIX, Qt::CaseInsensitive);
432  if (isAction) {
433  msg.remove(0, ChatForm::ACTION_PREFIX.length());
434  }
435 
436  if (msg.isEmpty()) {
437  return;
438  }
439 
440  msgEdit->setLastMessage(msg);
441  msgEdit->clear();
442 
443  messageDispatcher.sendMessage(isAction, msg);
444 }
445 
446 
448 {
449  // don't show the smiley selection widget if there are no smileys available
450  if (SmileyPack::getInstance().getEmoticons().empty())
451  return;
452 
453  EmoticonsWidget widget;
454  connect(&widget, SIGNAL(insertEmoticon(QString)), this, SLOT(onEmoteInsertRequested(QString)));
455  widget.installEventFilter(this);
456 
457  QWidget* sender = qobject_cast<QWidget*>(QObject::sender());
458  if (sender) {
459  QPoint pos =
460  -QPoint(widget.sizeHint().width() / 2, widget.sizeHint().height()) - QPoint(0, 10);
461  widget.exec(sender->mapToGlobal(pos));
462  }
463 }
464 
466 {
467  // insert the emoticon
468  QWidget* sender = qobject_cast<QWidget*>(QObject::sender());
469  if (sender)
470  msgEdit->insertPlainText(str);
471 
472  msgEdit->setFocus(); // refocus so that we can continue typing
473 }
474 
476 {
478 }
479 
481 {
482  msgEdit->setFocus();
483 }
484 
486 {
487  // chat log
488  chatWidget->fontChanged(font);
490  // message editor
491  msgEdit->setStyleSheet(Style::getStylesheet("msgEdit/msgEdit.css")
492  + fontToCss(font, "QTextEdit"));
493 }
494 
496 {
497  chatWidget->setColorizedNames(enable);
498 }
499 
500 void GenericChatForm::addSystemInfoMessage(const QDateTime& datetime, SystemMessageType messageType,
501  SystemMessage::Args messageArgs)
502 {
503  SystemMessage systemMessage;
504  systemMessage.messageType = messageType;
505  systemMessage.timestamp = datetime;
506  systemMessage.args = std::move(messageArgs);
507  chatLog.addSystemMessage(systemMessage);
508 }
509 
510 QDateTime GenericChatForm::getTime(const ChatLine::Ptr &chatLine) const
511 {
512  if (chatLine) {
513  Timestamp* const timestamp = qobject_cast<Timestamp*>(chatLine->getContent(2));
514 
515  if (timestamp) {
516  return timestamp->getTime();
517  } else {
518  return QDateTime();
519  }
520  }
521 
522  return QDateTime();
523 }
524 
525 
527 {
528  clearChatArea(/* confirm = */ true, /* inform = */ true);
529 }
530 
531 void GenericChatForm::clearChatArea(bool confirm, bool inform)
532 {
533  if (confirm) {
534  QMessageBox::StandardButton mboxResult =
535  QMessageBox::question(this, tr("Confirmation"),
536  tr("Are you sure that you want to clear all displayed messages?"),
537  QMessageBox::Yes | QMessageBox::No, QMessageBox::No);
538  if (mboxResult == QMessageBox::No) {
539  return;
540  }
541  }
542 
543  chatWidget->clear();
544 
545  if (inform)
546  addSystemInfoMessage(QDateTime::currentDateTime(), SystemMessageType::cleared, {});
547 }
548 
550 {
552 }
553 
554 void GenericChatForm::hideEvent(QHideEvent* event)
555 {
556  hideFileMenu();
557  QWidget::hideEvent(event);
558 }
559 
560 void GenericChatForm::resizeEvent(QResizeEvent* event)
561 {
563  QWidget::resizeEvent(event);
564 }
565 
566 bool GenericChatForm::eventFilter(QObject* object, QEvent* event)
567 {
568  EmoticonsWidget* ev = qobject_cast<EmoticonsWidget*>(object);
569  if (ev && event->type() == QEvent::KeyPress) {
570  QKeyEvent* key = static_cast<QKeyEvent*>(event);
571  msgEdit->sendKeyEvent(key);
572  msgEdit->setFocus();
573  return false;
574  }
575 
576  if (object != this->fileButton && object != this->fileFlyout)
577  return false;
578 
579  if (!qobject_cast<QWidget*>(object)->isEnabled())
580  return false;
581 
582  switch (event->type()) {
583  case QEvent::Enter:
584  showFileMenu();
585  break;
586 
587  case QEvent::Leave: {
588  QPoint flyPos = fileFlyout->mapToGlobal(QPoint());
589  QSize flySize = fileFlyout->size();
590 
591  QPoint filePos = fileButton->mapToGlobal(QPoint());
592  QSize fileSize = fileButton->size();
593 
594  QRect region = QRect(flyPos, flySize).united(QRect(filePos, fileSize));
595 
596  if (!region.contains(QCursor::pos()))
597  hideFileMenu();
598 
599  break;
600  }
601 
602  case QEvent::MouseButtonPress:
603  hideFileMenu();
604  break;
605 
606  default:
607  break;
608  }
609 
610  return false;
611 }
612 
614 {
615  QString selectedText = chatWidget->getSelectedText();
616 
617  if (selectedText.isEmpty())
618  return;
619 
620  // forming pretty quote text
621  // 1. insert "> " to the begining of quote;
622  // 2. replace all possible line terminators with "\n> ";
623  // 3. append new line to the end of quote.
624  QString quote = selectedText;
625 
626  quote.insert(0, "> ");
627  quote.replace(QRegExp(QString("\r\n|[\r\n\u2028\u2029]")), QString("\n> "));
628  quote.append("\n");
629 
630  msgEdit->append(quote);
631 }
632 
637 {
638  QString linkText = copyLinkAction->data().toString();
639  QApplication::clipboard()->setText(linkText);
640 }
641 
643 {
644  if (searchForm->isHidden()) {
645  searchForm->show();
647  }
648 }
649 
651 {
653  if (dlg.exec()) {
654  chatWidget->jumpToDate(dlg.getFromDate().date());
655  }
656 }
657 
659 {
660  QString path = QFileDialog::getSaveFileName(Q_NULLPTR, tr("Save chat log"));
661  if (path.isEmpty()) {
662  return;
663  }
664 
665  QFile file(path);
666  if (!file.open(QIODevice::WriteOnly | QIODevice::Text)) {
667  return;
668  }
669 
670  QString buffer;
671  for (auto i = chatLog.getFirstIdx(); i < chatLog.getNextIdx(); ++i) {
672  const auto& item = chatLog.at(i);
673  if (item.getContentType() != ChatLogItem::ContentType::message) {
674  continue;
675  }
676 
677  QString timestamp = item.getTimestamp().time().toString("hh:mm:ss");
678  QString datestamp = item.getTimestamp().date().toString("yyyy-MM-dd");
679  QString author = item.getDisplayName();
680 
681  buffer = buffer
682  % QString{datestamp % '\t' % timestamp % '\t' % author % '\t'
683  % item.getContentAsMessage().message.content % '\n'};
684  }
685  file.write(buffer.toUtf8());
686  file.close();
687 }
688 
690 {
692 }
693 
695 {
696  // If the dateInfo is visible we need to pretend the top line is the one
697  // covered by the date to prevent oscillations
698  const auto effectiveTopLine = (dateInfo->isVisible() && prevLine)
699  ? prevLine : topLine;
700 
701  const auto date = getTime(effectiveTopLine);
702 
703  if (date.isValid() && date.date() != QDate::currentDate()) {
704  const auto dateText = QStringLiteral("<b>%1<\b>").arg(date.toString(Settings::getInstance().getDateFormat()));
705  dateInfo->setText(dateText);
706  dateInfo->setVisible(true);
707  } else {
708  dateInfo->setVisible(false);
709  }
710 }
711 
713 {
714  sendButton->setToolTip(tr("Send message"));
715  emoteButton->setToolTip(tr("Smileys"));
716  fileButton->setToolTip(tr("Send file(s)"));
717  screenshotButton->setToolTip(tr("Send a screenshot"));
718  clearAction->setText(tr("Clear displayed messages"));
719  quoteAction->setText(tr("Quote selected text"));
720  copyLinkAction->setText(tr("Copy link address"));
721  searchAction->setText(tr("Search in text"));
722  goToCurrentDateAction->setText(tr("Go to current date"));
723  loadHistoryAction->setText(tr("Load chat history..."));
724  exportChatAction->setText(tr("Export to file"));
725 }
Settings::emojiFontPointSizeChanged
void emojiFontPointSizeChanged(int size)
Settings
Definition: settings.h:51
loadhistorydialog.h
GenericChatForm::quoteSelectedText
void quoteSelectedText()
Definition: genericchatform.cpp:613
SystemMessageType::cleared
@ cleared
GenericChatForm::fileFlyout
FlyoutOverlayWidget * fileFlyout
Definition: genericchatform.h:163
style.h
GenericChatForm::showFileMenu
void showFileMenu()
Definition: genericchatform.cpp:288
ChatLogItem::getTimestamp
QDateTime getTimestamp() const
Definition: chatlogitem.cpp:112
SearchForm::insertEditor
void insertEditor(const QString &text)
Definition: searchform.cpp:119
GenericChatForm::onScreenshotClicked
virtual void onScreenshotClicked()=0
friend.h
GenericChatForm::bodySplitter
QSplitter * bodySplitter
Definition: genericchatform.h:152
flyoutoverlaywidget.h
ChatWidget::getContentFromGlobalPos
ChatLineContent * getContentFromGlobalPos(QPoint pos) const
Finds the chat line object at a position on screen.
Definition: chatwidget.cpp:702
ChatWidget::startSearch
void startSearch(const QString &phrase, const ParameterSearch &parameter)
Definition: chatwidget.cpp:803
GenericChatForm::goToCurrentDateAction
QAction * goToCurrentDateAction
Definition: genericchatform.h:140
friendlist.h
Timestamp
Definition: timestamp.h:28
settings.h
chatwidget.h
GenericChatForm::exportChatAction
QAction * exportChatAction
Definition: genericchatform.h:142
GenericChatForm::setName
void setName(const QString &newName)
Definition: genericchatform.cpp:359
GenericChatForm::dateInfo
QLabel * dateInfo
Definition: genericchatform.h:157
SystemMessageType
SystemMessageType
Definition: systemmessage.h:28
GenericChatForm::clearChatArea
void clearChatArea()
Definition: genericchatform.cpp:526
contentdialogmanager.h
EmoticonsWidget
Definition: emoticonswidget.h:31
SystemMessage::timestamp
QDateTime timestamp
Definition: systemmessage.h:51
IChatLog::addSystemMessage
virtual void addSystemMessage(const SystemMessage &message)=0
Inserts a system message at the end of the chat.
GenericChatForm::focusInput
void focusInput()
Definition: genericchatform.cpp:480
group.h
SystemMessageType::unexpectedCallEnd
@ unexpectedCallEnd
Settings::getChatMessageFont
const QFont & getChatMessageFont() const
Definition: settings.cpp:1420
ChatLogItem::ContentType::message
@ message
FlyoutOverlayWidget::animateHide
void animateHide()
Definition: flyoutoverlaywidget.cpp:99
HistMessageContentType::file
@ file
contentdialog.h
SearchForm::searchInBegin
void searchInBegin(const QString &phrase, const ParameterSearch &parameter)
GenericChatForm::headWidget
ChatFormHeader * headWidget
Definition: genericchatform.h:154
GenericChatForm::resolveToxPk
static QString resolveToxPk(const ToxPk &pk)
Searches for name (possibly alias) of someone with specified public key among all of your friends or ...
Definition: genericchatform.cpp:96
IMessageDispatcher::sendMessage
virtual std::pair< DispatchedMessageId, DispatchedMessageId > sendMessage(bool isAction, const QString &content)=0
Sends message to associated chat.
SystemMessage::args
Args args
Definition: systemmessage.h:52
Translator::unregister
static void unregister(void *owner)
Unregisters all handlers of an owner.
Definition: translator.cpp:103
EmoticonsWidget::sizeHint
QSize sizeHint() const override
Definition: emoticonswidget.cpp:147
GenericChatForm::setColorizedNames
void setColorizedNames(bool enable)
Definition: genericchatform.cpp:495
GenericChatForm::chatLog
IChatLog & chatLog
Definition: genericchatform.h:166
ChatWidget
Definition: chatwidget.h:41
GenericChatForm::emoteButton
QPushButton * emoteButton
Definition: genericchatform.h:147
FlyoutOverlayWidget::animateShow
void animateShow()
Definition: flyoutoverlaywidget.cpp:88
ChatWidget::removeSearchPhrase
void removeSearchPhrase()
Definition: chatwidget.cpp:1505
GenericChatForm::onLoadHistory
void onLoadHistory()
Definition: genericchatform.cpp:650
SystemMessageType::messageSendFailed
@ messageSendFailed
SystemMessage
Definition: systemmessage.h:47
GenericChatForm::searchAction
QAction * searchAction
Definition: genericchatform.h:139
SystemMessage::Args
std::array< QString, 4 > Args
Definition: systemmessage.h:49
Settings::getSpellCheckingEnabled
bool getSpellCheckingEnabled() const
Definition: settings.cpp:1041
SystemMessageType::callEnd
@ callEnd
IMessageDispatcher
Definition: imessagedispatcher.h:34
FlyoutOverlayWidget::isBeingShown
bool isBeingShown() const
Definition: flyoutoverlaywidget.cpp:83
GenericChatForm::clearAction
QAction * clearAction
Definition: genericchatform.h:136
IChatLog::at
virtual const ChatLogItem & at(ChatLogIdx idx) const =0
Returns reference to item at idx.
GenericChatForm::getLatestTime
QDateTime getLatestTime() const
Definition: genericchatform.cpp:303
Settings::getDateFormat
const QString & getDateFormat() const
Definition: settings.cpp:1494
GenericChatForm::onAttachClicked
virtual void onAttachClicked()=0
ChatLogItem::getContentType
ContentType getContentType() const
Definition: chatlogitem.cpp:70
SearchForm::searchDown
void searchDown(const QString &phrase, const ParameterSearch &parameter)
ChatTextEdit::sendKeyEvent
void sendKeyEvent(QKeyEvent *event)
Definition: chattextedit.cpp:87
IChatLog::getFirstIdx
virtual ChatLogIdx getFirstIdx() const =0
The underlying chat log instance may not want to start at 0.
IChatLog
Definition: ichatlog.h:83
GenericChatForm::onEmoteButtonClicked
void onEmoteButtonClicked()
Definition: genericchatform.cpp:447
FriendList::findFriend
static Friend * findFriend(const ToxPk &friendPk)
Definition: friendlist.cpp:47
ChatWidget::messageNotFoundShow
void messageNotFoundShow(SearchDirection direction)
GenericChatForm::~GenericChatForm
~GenericChatForm() override
Definition: genericchatform.cpp:275
SearchForm::showMessageNotFound
void showMessageNotFound(SearchDirection direction)
Definition: searchform.cpp:289
GUI::getInstance
static GUI & getInstance()
Returns the singleton instance.
Definition: gui.cpp:56
SystemMessageType::fileSendFailed
@ fileSendFailed
chatform.h
ChatWidget::jumpToIdx
void jumpToIdx(ChatLogIdx idx)
Definition: chatwidget.cpp:1515
GenericChatForm::event
bool event(QEvent *) final
Definition: genericchatform.cpp:387
GenericChatForm::screenshotButton
QPushButton * screenshotButton
Definition: genericchatform.h:149
GenericChatForm::showEvent
void showEvent(QShowEvent *) override
Definition: genericchatform.cpp:381
Settings::chatMessageFontChanged
void chatMessageFontChanged(const QFont &font)
ChatWidget::fontChanged
void fontChanged(const QFont &font)
Definition: chatwidget.cpp:782
SystemMessageType::titleChanged
@ titleChanged
smileypack.h
HistMessageContentType::message
@ message
grouplist.h
SmileyPack::getInstance
static SmileyPack & getInstance()
Returns the singleton instance.
Definition: smileypack.cpp:147
filetransferwidget.h
ToxPk
This class represents a Tox Public Key, which is a part of Tox ID.
Definition: toxpk.h:26
GenericChatForm::onSelectAllClicked
void onSelectAllClicked()
Definition: genericchatform.cpp:549
ChatWidget::firstVisibleLineChanged
void firstVisibleLineChanged(const ChatLine::Ptr &prevLine, const ChatLine::Ptr &firstLine)
Contact
Definition: contact.h:26
Friend
Definition: friend.h:31
GenericChatForm::onSendTriggered
void onSendTriggered()
Definition: genericchatform.cpp:427
widget.h
SearchForm::searchUp
void searchUp(const QString &phrase, const ParameterSearch &parameter)
GenericChatForm::quoteAction
QAction * quoteAction
Definition: genericchatform.h:137
SystemMessageType::peerNameChanged
@ peerNameChanged
Text
Definition: text.h:29
GenericChatForm::contentLayout
QVBoxLayout * contentLayout
Definition: genericchatform.h:146
maskablepixmapwidget.h
SystemMessageType::outgoingCall
@ outgoingCall
GenericChatForm::hideEvent
void hideEvent(QHideEvent *event) override
Definition: genericchatform.cpp:554
GUI::themeReload
void themeReload()
SearchForm::visibleChanged
void visibleChanged()
chattextedit.h
GenericChatForm::searchForm
SearchForm * searchForm
Definition: genericchatform.h:156
SystemMessageType::userJoinedGroup
@ userJoinedGroup
GenericChatForm::reloadTheme
virtual void reloadTheme()
Definition: genericchatform.cpp:346
chatlinecontentproxy.h
SystemMessage::messageType
SystemMessageType messageType
Definition: systemmessage.h:50
ChatWidget::selectAll
void selectAll()
Definition: chatwidget.cpp:767
GenericChatForm::loadHistoryAction
QAction * loadHistoryAction
Definition: genericchatform.h:141
SystemMessageType::peerStateChange
@ peerStateChange
Translator::registerHandler
static void registerHandler(const std::function< void()> &, void *owner)
Register a function to be called when the UI needs to be retranslated.
Definition: translator.cpp:93
ChatWidget::getSelectedText
QString getSelectedText() const
Definition: chatwidget.cpp:659
Friend::getDisplayedName
QString getDisplayedName() const override
Friend::getDisplayedName Gets the name that should be displayed for a user.
Definition: friend.cpp:112
Contact::displayedNameChanged
void displayedNameChanged(const QString &newName)
GenericChatForm::show
virtual void show(ContentLayout *contentLayout)
Definition: genericchatform.cpp:364
GenericChatForm::goToCurrentDate
void goToCurrentDate()
Definition: genericchatform.cpp:689
Settings::getInstance
static Settings & getInstance()
Returns the singleton instance.
Definition: settings.cpp:88
GenericChatForm::onChatContextMenuRequested
void onChatContextMenuRequested(QPoint pos)
Definition: genericchatform.cpp:406
Group
Definition: group.h:34
ChatWidget::onSearchDown
void onSearchDown(const QString &phrase, const ParameterSearch &parameter)
Definition: chatwidget.cpp:849
ChatLogIdx
NamedType< size_t, struct ChatLogIdxTag, Orderable, UnderlyingAddable, UnitlessDifferencable, Incrementable > ChatLogIdx
Definition: ichatlog.h:38
ChatTextEdit
Definition: chattextedit.h:24
ChatWidget::setColorizedNames
void setColorizedNames(bool enable)
Definition: chatwidget.h:65
emoticonswidget.h
ChatTextEdit::setLastMessage
void setLastMessage(QString lm)
Definition: chattextedit.cpp:77
contentlayout.h
GenericChatForm::GenericChatForm
GenericChatForm(const Core &_core, const Contact *contact, IChatLog &chatLog, IMessageDispatcher &messageDispatcher, QWidget *parent=nullptr)
Definition: genericchatform.cpp:137
Style::getStylesheet
static const QString getStylesheet(const QString &filename, const QFont &baseFont=QFont())
Definition: style.cpp:165
ChatFormHeader::showCallConfirm
void showCallConfirm()
Definition: chatformheader.cpp:226
GenericChatForm::msgEdit
ChatTextEdit * msgEdit
Definition: genericchatform.h:159
SearchForm::setFocusEditor
void setFocusEditor()
Definition: searchform.cpp:114
IChatLog::getNextIdx
virtual ChatLogIdx getNextIdx() const =0
GenericChatForm::sendButton
QPushButton * sendButton
Definition: genericchatform.h:150
GenericChatForm::onExportChat
void onExportChat()
Definition: genericchatform.cpp:658
ChatWidget::onSearchUp
void onSearchUp(const QString &phrase, const ParameterSearch &parameter)
Definition: chatwidget.cpp:843
LoadHistoryDialog
Definition: loadhistorydialog.h:31
core.h
GenericChatForm::updateShowDateInfo
void updateShowDateInfo(const ChatLine::Ptr &prevLine, const ChatLine::Ptr &topLine)
Definition: genericchatform.cpp:694
GenericChatForm::hideFileMenu
void hideFileMenu()
Definition: genericchatform.cpp:297
ContentLayout
Definition: contentlayout.h:25
GenericChatForm::menu
QMenu menu
Definition: genericchatform.h:144
GroupList::getAllGroups
static QList< Group * > getAllGroups()
Definition: grouplist.cpp:64
ContactId::toString
QString toString() const
Converts the ContactId to a uppercase hex string.
Definition: contactid.cpp:78
LoadHistoryDialog::getFromDate
QDateTime getFromDate()
Definition: loadhistorydialog.cpp:53
GenericChatForm::resizeEvent
void resizeEvent(QResizeEvent *event) final
Definition: genericchatform.cpp:560
FlyoutOverlayWidget
Definition: flyoutoverlaywidget.h:27
ChatLogItem::ContentType::systemMessage
@ systemMessage
GenericChatForm::adjustFileMenuPosition
void adjustFileMenuPosition()
Definition: genericchatform.cpp:281
ChatLogItem::getContentAsSystemMessage
SystemMessage & getContentAsSystemMessage()
Definition: chatlogitem.cpp:99
ChatForm::ACTION_PREFIX
static const QString ACTION_PREFIX
Definition: chatform.h:58
gui.h
GenericChatForm::onChatMessageFontChanged
void onChatMessageFontChanged(const QFont &font)
Definition: genericchatform.cpp:485
ChatWidget::forceRelayout
void forceRelayout()
Definition: chatwidget.cpp:894
GenericChatForm::getTime
QDateTime getTime(const ChatLine::Ptr &chatLine) const
Definition: genericchatform.cpp:510
GenericChatForm::copyLinkAction
QAction * copyLinkAction
Definition: genericchatform.h:138
GenericChatForm::searchFormShow
void searchFormShow()
Definition: genericchatform.cpp:642
Text::getLinkAt
QString getLinkAt(QPointF scenePos) const
Extracts the target of a link from the text at a given coordinate.
Definition: text.cpp:308
ChatFormHeader
Definition: chatformheader.h:38
SearchForm
Definition: searchform.h:31
GenericChatForm::retranslateUi
void retranslateUi()
Definition: genericchatform.cpp:712
GenericChatForm::fileButton
QPushButton * fileButton
Definition: genericchatform.h:148
translator.h
genericchatform.h
SystemMessageType::userLeftGroup
@ userLeftGroup
ChatWidget::copySelectedText
void copySelectedText(bool toSelectionBuffer=false) const
Definition: chatwidget.cpp:728
GenericChatForm::chatWidget
ChatWidget * chatWidget
Definition: genericchatform.h:158
timestamp.h
Timestamp::getTime
QDateTime getTime()
Definition: timestamp.cpp:28
ChatWidget::jumpToDate
void jumpToDate(QDate date)
Definition: chatwidget.cpp:1510
FlyoutOverlayWidget::isShown
bool isShown() const
Definition: flyoutoverlaywidget.cpp:73
GenericChatForm::messageDispatcher
IMessageDispatcher & messageDispatcher
Definition: genericchatform.h:167
chatformheader.h
ChatLine::Ptr
std::shared_ptr< ChatLine > Ptr
Definition: chatline.h:68
GenericChatForm::addSystemInfoMessage
void addSystemInfoMessage(const QDateTime &datetime, SystemMessageType messageType, SystemMessage::Args messageArgs)
Definition: genericchatform.cpp:500
ChatWidget::clear
void clear()
Definition: chatwidget.cpp:707
GenericChatForm::onEmoteInsertRequested
void onEmoteInsertRequested(QString str)
Definition: genericchatform.cpp:465
Core
Definition: core.h:59
ChatTextEdit::enterPressed
void enterPressed()
GenericChatForm::copyLink
void copyLink()
Callback of GenericChatForm::copyLinkAction.
Definition: genericchatform.cpp:636
GenericChatForm::onCopyLogClicked
void onCopyLogClicked()
Definition: genericchatform.cpp:475
searchform.h
GenericChatForm::eventFilter
bool eventFilter(QObject *object, QEvent *event) final
Definition: genericchatform.cpp:566
ChatFormHeader::setName
void setName(const QString &newName)
Definition: chatformheader.cpp:175
SystemMessageType::incomingCall
@ incomingCall