qTox  Version: nightly | Commit: bc751c8e1cac455f9690654fcfe0f560d2d7dfdd
chatform.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 "chatform.h"
22 #include "src/chatlog/chatwidget.h"
26 #include "src/core/core.h"
27 #include "src/core/coreav.h"
28 #include "src/core/corefile.h"
29 #include "src/model/friend.h"
30 #include "src/model/status.h"
31 #include "src/nexus.h"
36 #include "src/video/netcamview.h"
42 #include "src/widget/searchform.h"
43 #include "src/widget/style.h"
48 #include "src/widget/translator.h"
49 #include "src/widget/widget.h"
50 
51 #include <QApplication>
52 #include <QClipboard>
53 #include <QFileDialog>
54 #include <QFileInfo>
55 #include <QMessageBox>
56 #include <QMimeData>
57 #include <QPushButton>
58 #include <QScrollBar>
59 #include <QSplitter>
60 #include <QStringBuilder>
61 
62 #include <cassert>
63 
73 static constexpr int CHAT_WIDGET_MIN_HEIGHT = 50;
74 static constexpr int SCREENSHOT_GRABBER_OPENING_DELAY = 500;
75 static constexpr int TYPING_NOTIFICATION_DURATION = 3000;
76 
77 const QString ChatForm::ACTION_PREFIX = QStringLiteral("/me ");
78 
79 namespace {
80 QString secondsToDHMS(quint32 duration)
81 {
82  QString res;
83  QString cD = ChatForm::tr("Call duration: ");
84  quint32 seconds = duration % 60;
85  duration /= 60;
86  quint32 minutes = duration % 60;
87  duration /= 60;
88  quint32 hours = duration % 24;
89  quint32 days = duration / 24;
90 
91  // I assume no one will ever have call longer than a month
92  if (days) {
93  return cD + res.asprintf("%dd%02dh %02dm %02ds", days, hours, minutes, seconds);
94  }
95 
96  if (hours) {
97  return cD + res.asprintf("%02dh %02dm %02ds", hours, minutes, seconds);
98  }
99 
100  if (minutes) {
101  return cD + res.asprintf("%02dm %02ds", minutes, seconds);
102  }
103 
104  return cD + res.asprintf("%02ds", seconds);
105 }
106 } // namespace
107 
108 ChatForm::ChatForm(Profile& profile, Friend* chatFriend, IChatLog& chatLog, IMessageDispatcher& messageDispatcher)
109  : GenericChatForm(profile.getCore(), chatFriend, chatLog, messageDispatcher)
110  , core{profile.getCore()}
111  , f(chatFriend)
112  , isTyping{false}
113  , lastCallIsVideo{false}
114 {
115  setName(f->getDisplayedName());
116 
117  headWidget->setAvatar(QPixmap(":/img/contact_dark.svg"));
118 
119  statusMessageLabel = new CroppingLabel();
120  statusMessageLabel->setObjectName("statusLabel");
121  statusMessageLabel->setFont(Style::getFont(Style::Medium));
122  statusMessageLabel->setMinimumHeight(Style::getFont(Style::Medium).pixelSize());
123  statusMessageLabel->setTextFormat(Qt::PlainText);
124  statusMessageLabel->setContextMenuPolicy(Qt::CustomContextMenu);
125 
126  typingTimer.setSingleShot(true);
127 
128  callDurationTimer = nullptr;
129 
130  chatWidget->setMinimumHeight(CHAT_WIDGET_MIN_HEIGHT);
131 
132  callDuration = new QLabel();
133  headWidget->addWidget(statusMessageLabel);
134  headWidget->addStretch();
135  headWidget->addWidget(callDuration, 1, Qt::AlignCenter);
136  callDuration->hide();
137 
138  imagePreview = new ImagePreviewButton(this);
139  imagePreview->setFixedSize(100, 100);
140  imagePreview->setFlat(true);
141  imagePreview->setStyleSheet("QPushButton { border: 0px }");
142  imagePreview->hide();
143 
144  auto cancelIcon = QIcon(Style::getImagePath("rejectCall/rejectCall.svg"));
145  QPushButton* cancelButton = new QPushButton(imagePreview);
146  cancelButton->setFixedSize(20, 20);
147  cancelButton->move(QPoint(80, 0));
148  cancelButton->setIcon(cancelIcon);
149  cancelButton->setFlat(true);
150 
151  connect(cancelButton, &QPushButton::pressed, this, &ChatForm::cancelImagePreview);
152 
153  contentLayout->insertWidget(3, imagePreview);
154 
155  copyStatusAction = statusMessageMenu.addAction(QString(), this, SLOT(onCopyStatusMessage()));
156 
157  const CoreFile* coreFile = core.getCoreFile();
158  connect(&profile, &Profile::friendAvatarChanged, this, &ChatForm::onAvatarChanged);
162  connect(coreFile, &CoreFile::fileNameChanged, this, &ChatForm::onFileNameChanged);
163 
164  connect(chatFriend, &Friend::statusChanged, this, &ChatForm::onFriendStatusChanged);
165 
166  const CoreAV* av = core.getAv();
167  connect(av, &CoreAV::avInvite, this, &ChatForm::onAvInvite);
168  connect(av, &CoreAV::avStart, this, &ChatForm::onAvStart);
169  connect(av, &CoreAV::avEnd, this, &ChatForm::onAvEnd);
170 
171  connect(headWidget, &ChatFormHeader::callTriggered, this, &ChatForm::onCallTriggered);
173  connect(headWidget, &ChatFormHeader::micMuteToggle, this, &ChatForm::onMicMuteToggle);
174  connect(headWidget, &ChatFormHeader::volMuteToggle, this, &ChatForm::onVolMuteToggle);
175  connect(sendButton, &QPushButton::pressed, this, &ChatForm::callUpdateFriendActivity);
176  connect(sendButton, &QPushButton::pressed, this, &ChatForm::sendImageFromPreview);
178  connect(msgEdit, &ChatTextEdit::textChanged, this, &ChatForm::onTextEditChanged);
179  connect(msgEdit, &ChatTextEdit::pasteImage, this, &ChatForm::previewImage);
182  connect(statusMessageLabel, &CroppingLabel::customContextMenuRequested, this,
183  [&](const QPoint& pos) {
184  if (!statusMessageLabel->text().isEmpty()) {
185  QWidget* sender = static_cast<QWidget*>(this->sender());
186  statusMessageMenu.exec(sender->mapToGlobal(pos));
187  }
188  });
189 
190  connect(&typingTimer, &QTimer::timeout, this, [&] {
191  core.sendTyping(f->getId(), false);
192  isTyping = false;
193  });
194 
195  // reflect name changes in the header
196  connect(headWidget, &ChatFormHeader::nameChanged, this,
197  [=](const QString& newName) { f->setAlias(newName); });
198  connect(headWidget, &ChatFormHeader::callAccepted, this,
199  [this] { onAnswerCallTriggered(lastCallIsVideo); });
201 
202  connect(bodySplitter, &QSplitter::splitterMoved, this, &ChatForm::onSplitterMoved);
203 
205 
206  updateCallButtons();
207 
208  setAcceptDrops(true);
209  retranslateUi();
210  Translator::registerHandler(std::bind(&ChatForm::retranslateUi, this), this);
211 }
212 
214 {
216 }
217 
218 void ChatForm::setStatusMessage(const QString& newMessage)
219 {
220  statusMessageLabel->setText(newMessage);
221  // for long messsages
222  statusMessageLabel->setToolTip(Qt::convertFromPlainText(newMessage, Qt::WhiteSpaceNormal));
223 }
224 
226 {
227  emit updateFriendActivity(*f);
228 }
229 
231 {
232  if (file.friendId != f->getId()) {
233  return;
234  }
235  emit updateFriendActivity(*f);
236 }
237 
238 void ChatForm::onFileNameChanged(const ToxPk& friendPk)
239 {
240  if (friendPk != f->getPublicKey()) {
241  return;
242  }
243 
244  QMessageBox::warning(this, tr("Filename contained illegal characters"),
245  tr("Illegal characters have been changed to _ \n"
246  "so you can save the file on Windows."));
247 }
248 
250 {
251  headWidget->updateExtensionSupport(extensions);
252 }
253 
255 {
256  if (!Settings::getInstance().getTypingNotification()) {
257  if (isTyping) {
258  isTyping = false;
259  core.sendTyping(f->getId(), false);
260  }
261 
262  return;
263  }
264  bool isTypingNow = !msgEdit->toPlainText().isEmpty();
265  if (isTyping != isTypingNow) {
266  core.sendTyping(f->getId(), isTypingNow);
267  if (isTypingNow) {
268  typingTimer.start(TYPING_NOTIFICATION_DURATION);
269  }
270 
271  isTyping = isTypingNow;
272  }
273 }
274 
276 {
277  QStringList paths = QFileDialog::getOpenFileNames(Q_NULLPTR, tr("Send a file"),
278  QDir::homePath(), nullptr, nullptr);
279 
280  if (paths.isEmpty()) {
281  return;
282  }
283 
284  for (QString path : paths) {
285  QFile file(path);
286  QString fileName = QFileInfo(path).fileName();
287  if (!file.exists() || !file.open(QIODevice::ReadOnly)) {
288  QMessageBox::warning(this, tr("Unable to open"),
289  tr("qTox wasn't able to open %1").arg(fileName));
290  continue;
291  }
292 
293  file.close();
294  if (file.isSequential()) {
295  QMessageBox::critical(this, tr("Bad idea"),
296  tr("You're trying to send a sequential file, "
297  "which is not going to work!"));
298  continue;
299  }
300 
301  qint64 filesize = file.size();
302  core.getCoreFile()->sendFile(f->getId(), fileName, path, filesize);
303  }
304 }
305 
306 void ChatForm::onAvInvite(uint32_t friendId, bool video)
307 {
308  if (friendId != f->getId()) {
309  return;
310  }
311 
312  QString displayedName = f->getDisplayedName();
313 
314  SystemMessage systemMessage;
316  systemMessage.args = {displayedName};
317  chatLog.addSystemMessage(systemMessage);
318 
320  // AutoAcceptCall is set for this friend
321  if (Settings::getInstance().getAutoAcceptCall(f->getPublicKey()).testFlag(testedFlag)) {
322  uint32_t friendId = f->getId();
323  qDebug() << "automatic call answer";
324  CoreAV* coreav = core.getAv();
325  QMetaObject::invokeMethod(coreav, "answerCall", Qt::QueuedConnection,
326  Q_ARG(uint32_t, friendId), Q_ARG(bool, video));
327  onAvStart(friendId, video);
328  } else {
331  lastCallIsVideo = video;
332  emit incomingNotification(friendId);
333  }
334 }
335 
336 void ChatForm::onAvStart(uint32_t friendId, bool video)
337 {
338  if (friendId != f->getId()) {
339  return;
340  }
341 
342  if (video) {
343  showNetcam();
344  } else {
345  hideNetcam();
346  }
347 
348  emit stopNotification();
350  startCounter();
351 }
352 
353 void ChatForm::onAvEnd(uint32_t friendId, bool error)
354 {
355  if (friendId != f->getId()) {
356  return;
357  }
358 
360  // Fixes an OS X bug with ending a call while in full screen
361  if (netcam && netcam->isFullScreen()) {
362  netcam->showNormal();
363  }
364 
365  emit stopNotification();
366  emit endCallNotification();
368  stopCounter(error);
369  hideNetcam();
370 }
371 
373 {
375  addSystemInfoMessage(QDateTime::currentDateTime(), SystemMessageType::outgoingCall,
376  {f->getDisplayedName()});
377  emit outgoingNotification();
378  emit updateFriendActivity(*f);
379 }
380 
382 {
384  uint32_t friendId = f->getId();
385  emit stopNotification();
386  emit acceptCall(friendId);
387 
389  CoreAV* av = core.getAv();
390  if (!av->answerCall(friendId, video)) {
392  stopCounter();
393  hideNetcam();
394  return;
395  }
396 
397  onAvStart(friendId, av->isCallVideoEnabled(f));
398 }
399 
401 {
403  emit rejectCall(f->getId());
404 }
405 
407 {
408  CoreAV* av = core.getAv();
409  uint32_t friendId = f->getId();
410  if (av->isCallStarted(f)) {
411  av->cancelCall(friendId);
412  } else if (av->startCall(friendId, false)) {
413  showOutgoingCall(false);
414  }
415 }
416 
418 {
419  CoreAV* av = core.getAv();
420  uint32_t friendId = f->getId();
421  if (av->isCallStarted(f)) {
422  // TODO: We want to activate video on the active call.
423  if (av->isCallVideoEnabled(f)) {
424  av->cancelCall(friendId);
425  }
426  } else if (av->startCall(friendId, true)) {
427  showOutgoingCall(true);
428  }
429 }
430 
432 {
433  CoreAV* av = core.getAv();
434  const bool audio = av->isCallActive(f);
435  const bool video = av->isCallVideoEnabled(f);
436  const bool online = Status::isOnline(f->getStatus());
437  headWidget->updateCallButtons(online, audio, video);
440 }
441 
443 {
444  CoreAV* av = core.getAv();
445  av->toggleMuteCallInput(f);
447 }
448 
450 {
451  CoreAV* av = core.getAv();
452  av->toggleMuteCallOutput(f);
454 }
455 
457 {
458  // Disable call buttons if friend is offline
459  assert(friendPk == f->getPublicKey());
460 
461  if (!Status::isOnline(f->getStatus())) {
462  // Hide the "is typing" message when a friend goes offline
463  setFriendTyping(false);
464  }
465 
467 
468  if (Settings::getInstance().getStatusChangeNotificationEnabled()) {
469  QString fStatus = Status::getTitle(status);
470  addSystemInfoMessage(QDateTime::currentDateTime(), SystemMessageType::peerStateChange,
471  {f->getDisplayedName(), fStatus});
472  }
473 }
474 
475 void ChatForm::onFriendTypingChanged(quint32 friendId, bool isTyping)
476 {
477  if (friendId == f->getId()) {
479  }
480 }
481 
482 void ChatForm::onFriendNameChanged(const QString& name)
483 {
484  if (sender() == f) {
485  setName(name);
486  }
487 }
488 
489 void ChatForm::onStatusMessage(const QString& message)
490 {
491  if (sender() == f) {
493  }
494 }
495 
496 void ChatForm::onAvatarChanged(const ToxPk& friendPk, const QPixmap& pic)
497 {
498  if (friendPk != f->getPublicKey()) {
499  return;
500  }
501 
502  headWidget->setAvatar(pic);
503 }
504 
505 std::unique_ptr<NetCamView> ChatForm::createNetcam()
506 {
507  qDebug() << "creating netcam";
508  uint32_t friendId = f->getId();
509  std::unique_ptr<NetCamView> view = std::unique_ptr<NetCamView>(new NetCamView(f->getPublicKey(), this));
510  CoreAV* av = core.getAv();
511  VideoSource* source = av->getVideoSourceFromCall(friendId);
512  view->show(source, f->getDisplayedName());
513  connect(view.get(), &NetCamView::videoCallEnd, this, &ChatForm::onVideoCallTriggered);
514  connect(view.get(), &NetCamView::volMuteToggle, this, &ChatForm::onVolMuteToggle);
515  connect(view.get(), &NetCamView::micMuteToggle, this, &ChatForm::onMicMuteToggle);
516  return view;
517 }
518 
519 void ChatForm::dragEnterEvent(QDragEnterEvent* ev)
520 {
521  if (ev->mimeData()->hasUrls()) {
522  ev->acceptProposedAction();
523  }
524 }
525 
526 void ChatForm::dropEvent(QDropEvent* ev)
527 {
528  if (!ev->mimeData()->hasUrls()) {
529  return;
530  }
531 
532  for (const QUrl& url : ev->mimeData()->urls()) {
533  QFileInfo info(url.path());
534  QFile file(info.absoluteFilePath());
535 
536  QString urlString = url.toString();
537  if (url.isValid() && !url.isLocalFile()
538  && urlString.length() < static_cast<int>(tox_max_message_length())) {
539  messageDispatcher.sendMessage(false, urlString);
540 
541  continue;
542  }
543 
544  QString fileName = info.fileName();
545  if (!file.exists() || !file.open(QIODevice::ReadOnly)) {
546  info.setFile(url.toLocalFile());
547  file.setFileName(info.absoluteFilePath());
548  if (!file.exists() || !file.open(QIODevice::ReadOnly)) {
549  QMessageBox::warning(this, tr("Unable to open"),
550  tr("qTox wasn't able to open %1").arg(fileName));
551  continue;
552  }
553  }
554 
555  file.close();
556  if (file.isSequential()) {
557  QMessageBox::critical(nullptr, tr("Bad idea"),
558  tr("You're trying to send a sequential file, "
559  "which is not going to work!"));
560  continue;
561  }
562 
563  if (info.exists()) {
564  core.getCoreFile()->sendFile(f->getId(), fileName, info.absoluteFilePath(), info.size());
565  }
566  }
567 }
568 
570 {
571  GenericChatForm::clearChatArea(/* confirm = */ false, /* inform = */ true);
572 }
573 
575 {
576  doScreenshot();
577  // Give the window manager a moment to open the fullscreen grabber window
578  QTimer::singleShot(SCREENSHOT_GRABBER_OPENING_DELAY, this, SLOT(hideFileMenu()));
579 }
580 
582 {
583  // note: grabber is self-managed and will destroy itself when done
584  ScreenshotGrabber* grabber = new ScreenshotGrabber;
586  grabber->showGrabber();
587 }
588 
589 void ChatForm::previewImage(const QPixmap& pixmap)
590 {
591  imagePreviewSource = pixmap;
593  imagePreview->show();
594 }
595 
597 {
598  imagePreviewSource = QPixmap();
599  imagePreview->hide();
600 }
601 
603 {
604  if (!imagePreview->isVisible()) {
605  return;
606  }
607 
608  QDir(Settings::getInstance().getPaths().getAppDataDirPath()).mkpath("images");
609 
610  // use ~ISO 8601 for screenshot timestamp, considering FS limitations
611  // https://en.wikipedia.org/wiki/ISO_8601
612  // Windows has to be supported, thus filename can't have `:` in it :/
613  // Format should be: `qTox_Screenshot_yyyy-MM-dd HH-mm-ss.zzz.png`
614  QString filepath = QString("%1images%2qTox_Image_%3.png")
615  .arg(Settings::getInstance().getPaths().getAppDataDirPath())
616  .arg(QDir::separator())
617  .arg(QDateTime::currentDateTime().toString("yyyy-MM-dd HH-mm-ss.zzz"));
618  QFile file(filepath);
619 
620  if (file.open(QFile::ReadWrite)) {
621  imagePreviewSource.save(&file, "PNG");
622  qint64 filesize = file.size();
623  imagePreview->hide();
624  imagePreviewSource = QPixmap();
625  file.close();
626  QFileInfo fi(file);
627  CoreFile* coreFile = core.getCoreFile();
628  coreFile->sendFile(f->getId(), fi.fileName(), fi.filePath(), filesize);
629  } else {
630  QMessageBox::warning(this,
631  tr("Failed to open temporary file", "Temporary file for screenshot"),
632  tr("qTox wasn't able to save the screenshot"));
633  }
634 }
635 
637 {
638  // make sure to copy not truncated text directly from the friend
639  QString text = f->getStatusMessage();
640  QClipboard* clipboard = QApplication::clipboard();
641  if (clipboard) {
642  clipboard->setText(text, QClipboard::Clipboard);
643  }
644 }
645 
647 {
648  const CoreAV* av = core.getAv();
649  bool active = av->isCallActive(f);
650  bool inputMuted = av->isCallInputMuted(f);
651  headWidget->updateMuteMicButton(active, inputMuted);
652  if (netcam) {
653  netcam->updateMuteMicButton(inputMuted);
654  }
655 }
656 
658 {
659  const CoreAV* av = core.getAv();
660  bool active = av->isCallActive(f);
661  bool outputMuted = av->isCallOutputMuted(f);
662  headWidget->updateMuteVolButton(active, outputMuted);
663  if (netcam) {
664  netcam->updateMuteVolButton(outputMuted);
665  }
666 }
667 
669 {
670  if (callDurationTimer) {
671  return;
672  }
673  callDurationTimer = new QTimer();
674  connect(callDurationTimer, &QTimer::timeout, this, &ChatForm::onUpdateTime);
675  callDurationTimer->start(1000);
676  timeElapsed.start();
677  callDuration->show();
678 }
679 
680 void ChatForm::stopCounter(bool error)
681 {
682  if (!callDurationTimer) {
683  return;
684  }
685  QString dhms = secondsToDHMS(timeElapsed.elapsed() / 1000);
686  QString name = f->getDisplayedName();
688  // TODO: add notification once notifications are implemented
689 
690  addSystemInfoMessage(QDateTime::currentDateTime(), messageType, {name, dhms});
691  callDurationTimer->stop();
692  callDuration->setText("");
693  callDuration->hide();
694 
695  delete callDurationTimer;
696  callDurationTimer = nullptr;
697 }
698 
700 {
701  callDuration->setText(secondsToDHMS(timeElapsed.elapsed() / 1000));
702 }
703 
704 void ChatForm::setFriendTyping(bool isTyping)
705 {
707  QString name = f->getDisplayedName();
709 }
710 
711 void ChatForm::show(ContentLayout* contentLayout)
712 {
714 }
715 
717 {
719 }
720 
721 void ChatForm::showEvent(QShowEvent* event)
722 {
724 }
725 
726 void ChatForm::hideEvent(QHideEvent* event)
727 {
729 }
730 
732 {
733  copyStatusAction->setText(tr("Copy"));
734 
737 
738  if (netcam) {
739  netcam->setShowMessages(chatWidget->isVisible());
740  }
741 }
742 
744 {
745  if (!netcam) {
746  netcam = createNetcam();
747  }
748 
749  connect(netcam.get(), &NetCamView::showMessageClicked, this,
751 
752  bodySplitter->insertWidget(0, netcam.get());
753  bodySplitter->setCollapsible(0, false);
754 
755  QSize minSize = netcam->getSurfaceMinSize();
757  if (current) {
758  current->onVideoShow(minSize);
759  }
760 }
761 
763 {
764  if (!netcam) {
765  return;
766  }
767 
769  if (current) {
770  current->onVideoHide();
771  }
772 
773  netcam->close();
774  netcam->hide();
775  netcam.reset();
776 }
777 
779 {
780  if (netcam) {
781  netcam->setShowMessages(bodySplitter->sizes()[1] == 0);
782  }
783 }
784 
786 {
787  if (netcam) {
788  if (bodySplitter->sizes()[1] == 0) {
789  bodySplitter->setSizes({1, 1});
790  }
791  else {
792  bodySplitter->setSizes({1, 0});
793  }
794 
795  onSplitterMoved(0, 0);
796  }
797 }
Style::getFont
static QFont getFont(Font font)
Definition: style.cpp:214
ChatForm::setStatusMessage
void setStatusMessage(const QString &newMessage)
Definition: chatform.cpp:218
ChatForm::onSplitterMoved
void onSplitterMoved(int pos, int index)
Definition: chatform.cpp:778
profile.h
ChatFormHeader::videoCallTriggered
void videoCallTriggered()
loadhistorydialog.h
ChatForm::showEvent
void showEvent(QShowEvent *event) final
Definition: chatform.cpp:721
Status::Status
Status
Definition: status.h:28
style.h
ScreenshotGrabber
Definition: screenshotgrabber.h:36
CoreAV::avInvite
void avInvite(uint32_t friendId, bool video)
Sent when a friend calls us.
history.h
ChatWidget::setTypingNotificationName
void setTypingNotificationName(const QString &displayName)
Definition: chatwidget.cpp:745
ChatForm::stopCounter
void stopCounter(bool error=false)
Definition: chatform.cpp:680
ImagePreviewButton
Definition: imagepreviewwidget.h:26
GenericChatForm
Parent class for all chatforms. It's provide the minimum required UI elements and methods to work wit...
Definition: genericchatform.h:67
friend.h
GenericChatForm::bodySplitter
QSplitter * bodySplitter
Definition: genericchatform.h:152
ChatForm::updateCallButtons
void updateCallButtons()
Definition: chatform.cpp:431
ChatFormHeader::updateExtensionSupport
void updateExtensionSupport(ExtensionSet extensions)
Definition: chatformheader.cpp:237
ChatForm::onTextEditChanged
void onTextEditChanged()
Definition: chatform.cpp:254
ContentDialog::onVideoShow
void onVideoShow(QSize size)
Definition: contentdialog.cpp:351
settings.h
VideoSource
An abstract source of video frames.
Definition: videosource.h:29
ContentDialog::onVideoHide
void onVideoHide()
Definition: contentdialog.cpp:363
ChatForm::core
Core & core
Definition: chatform.h:127
netcamview.h
chatwidget.h
ChatFormHeader::removeCallConfirm
void removeCallConfirm()
Definition: chatformheader.cpp:232
NetCamView::videoCallEnd
void videoCallEnd()
GenericChatForm::setName
void setName(const QString &newName)
Definition: genericchatform.cpp:359
ChatForm::statusMessageLabel
CroppingLabel * statusMessageLabel
Definition: chatform.h:129
ChatForm::onMicMuteToggle
void onMicMuteToggle()
Definition: chatform.cpp:442
GenericChatForm::clearChatArea
void clearChatArea()
Definition: genericchatform.cpp:526
contentdialogmanager.h
CoreAV::isCallVideoEnabled
bool isCallVideoEnabled(const Friend *f) const
Definition: coreav.cpp:242
CroppingLabel
Definition: croppinglabel.h:26
Profile
Handles all qTox internal paths.
Definition: profile.h:42
ChatFormHeader::showOutgoingCall
void showOutgoingCall(bool video)
Definition: chatformheader.cpp:211
IChatLog::addSystemMessage
virtual void addSystemMessage(const SystemMessage &message)=0
Inserts a system message at the end of the chat.
ChatFormHeader::volMuteToggle
void volMuteToggle()
ChatForm::onVideoCallTriggered
void onVideoCallTriggered()
Definition: chatform.cpp:417
CoreAV::avStart
void avStart(uint32_t friendId, bool video)
Sent when a call we initiated has started.
ChatForm::incomingNotification
void incomingNotification(uint32_t friendId)
SystemMessageType::unexpectedCallEnd
@ unexpectedCallEnd
IFriendSettings::AutoAcceptCall::Video
@ Video
HistMessageContentType::file
@ file
CroppingLabel::setText
void setText(const QString &text)
Definition: croppinglabel.cpp:81
GenericChatForm::headWidget
ChatFormHeader * headWidget
Definition: genericchatform.h:154
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
ChatForm::timeElapsed
QElapsedTimer timeElapsed
Definition: chatform.h:134
GenericChatForm::chatLog
IChatLog & chatLog
Definition: genericchatform.h:166
ChatForm::reloadTheme
void reloadTheme() final
Definition: chatform.cpp:716
CoreAV::isCallOutputMuted
bool isCallOutputMuted(const Friend *f) const
Returns the calls output (speaker) mute state.
Definition: coreav.cpp:688
callconfirmwidget.h
screenshotgrabber.h
ChatForm::onExtensionSupportChanged
void onExtensionSupportChanged(ExtensionSet extensions)
Definition: chatform.cpp:249
ChatForm::createNetcam
std::unique_ptr< NetCamView > createNetcam()
Definition: chatform.cpp:505
CoreAV::isCallActive
bool isCallActive(const Friend *f) const
Checks the call status for a Tox friend.
Definition: coreav.cpp:217
ChatFormHeader::micMuteToggle
void micMuteToggle()
CoreAV::answerCall
bool answerCall(uint32_t friendNum, bool video)
Definition: coreav.cpp:249
ChatForm::onScreenshotClicked
void onScreenshotClicked() override
Definition: chatform.cpp:574
SystemMessage
Definition: systemmessage.h:47
ChatFormHeader::updateMuteMicButton
void updateMuteMicButton(bool active, bool inputMuted)
Definition: chatformheader.cpp:269
ContentDialogManager::getInstance
static ContentDialogManager * getInstance()
Definition: contentdialogmanager.cpp:174
SystemMessageType::callEnd
@ callEnd
ChatFormHeader::updateMuteVolButton
void updateMuteVolButton(bool active, bool outputMuted)
Definition: chatformheader.cpp:281
ChatForm::dragEnterEvent
void dragEnterEvent(QDragEnterEvent *ev) final
Definition: chatform.cpp:519
ChatForm::onAvatarChanged
void onAvatarChanged(const ToxPk &friendPk, const QPixmap &pic)
Definition: chatform.cpp:496
IMessageDispatcher
Definition: imessagedispatcher.h:34
Style::getImagePath
static const QString getImagePath(const QString &filename)
Definition: style.cpp:182
ContentDialogManager::current
ContentDialog * current()
Definition: contentdialogmanager.cpp:46
ChatForm::imagePreviewSource
QPixmap imagePreviewSource
Definition: chatform.h:136
Core::getCoreFile
CoreFile * getCoreFile() const
Definition: core.cpp:718
ChatFormHeader::callRejected
void callRejected()
ChatForm::onAnswerCallTriggered
void onAnswerCallTriggered(bool video)
Definition: chatform.cpp:381
ChatForm::previewImage
void previewImage(const QPixmap &pixmap)
Definition: chatform.cpp:589
CoreAV::cancelCall
bool cancelCall(uint32_t friendNum)
Definition: coreav.cpp:299
NetCamView::micMuteToggle
void micMuteToggle()
IChatLog
Definition: ichatlog.h:83
ChatForm::sendImageFromPreview
void sendImageFromPreview()
Definition: chatform.cpp:602
CoreAV::getVideoSourceFromCall
VideoSource * getVideoSourceFromCall(int callNumber) const
Get a call's video source.
Definition: coreav.cpp:527
Core::getAv
const CoreAV * getAv() const
Definition: core.cpp:703
Profile::getCore
Core & getCore() const
Definition: profile.cpp:428
ChatForm::retranslateUi
void retranslateUi()
Definition: chatform.cpp:731
croppinglabel.h
coreav.h
ChatForm::onAvInvite
void onAvInvite(uint32_t friendId, bool video)
Definition: chatform.cpp:306
ChatForm::clearChatArea
void clearChatArea()
Definition: chatform.cpp:569
CoreAV::startCall
bool startCall(uint32_t friendNum, bool video)
Definition: coreav.cpp:272
ChatForm::netcam
std::unique_ptr< NetCamView > netcam
Definition: chatform.h:140
chatform.h
GenericChatForm::event
bool event(QEvent *) final
Definition: genericchatform.cpp:387
Friend::getStatus
Status::Status getStatus() const
Definition: friend.cpp:190
GenericChatForm::showEvent
void showEvent(QShowEvent *) override
Definition: genericchatform.cpp:381
offlinemsgengine.h
ContentDialog
Definition: contentdialog.h:49
ChatForm::showNetcam
void showNetcam()
Definition: chatform.cpp:743
ChatForm::updateMuteMicButton
void updateMuteMicButton()
Definition: chatform.cpp:646
ChatForm::showOutgoingCall
void showOutgoingCall(bool video)
Definition: chatform.cpp:372
ChatFormHeader::setAvatar
void setAvatar(const QPixmap &img)
Definition: chatformheader.cpp:293
HistMessageContentType::message
@ message
ChatFormHeader::callAccepted
void callAccepted()
ChatForm::doScreenshot
void doScreenshot()
Definition: chatform.cpp:581
filetransferwidget.h
ChatFormHeader::updateCallButtons
void updateCallButtons(bool online, bool audio, bool video=false)
Definition: chatformheader.cpp:242
ChatForm::endCallNotification
void endCallNotification()
ToxPk
This class represents a Tox Public Key, which is a part of Tox ID.
Definition: toxpk.h:26
ChatForm::updateMuteVolButton
void updateMuteVolButton()
Definition: chatform.cpp:657
Friend
Definition: friend.h:31
CoreAV::toggleMuteCallInput
void toggleMuteCallInput(const Friend *f)
Toggles the mute state of the call's input (microphone).
Definition: coreav.cpp:429
CoreFile::fileReceiveRequested
void fileReceiveRequested(ToxFile file)
widget.h
Profile::friendAvatarChanged
void friendAvatarChanged(const ToxPk &friendPk, const QPixmap &pixmap)
imagepreviewwidget.h
ChatForm::rejectCall
void rejectCall(uint32_t friendId)
ChatForm::onCopyStatusMessage
void onCopyStatusMessage()
Definition: chatform.cpp:636
ChatForm::cancelImagePreview
void cancelImagePreview()
Definition: chatform.cpp:596
text.h
ChatForm::onAvStart
void onAvStart(uint32_t friendId, bool video)
Definition: chatform.cpp:336
GenericChatForm::contentLayout
QVBoxLayout * contentLayout
Definition: genericchatform.h:146
CoreFile::fileNameChanged
void fileNameChanged(const ToxPk &friendPk)
maskablepixmapwidget.h
ChatForm::onCallTriggered
void onCallTriggered()
Definition: chatform.cpp:406
ChatForm::hideEvent
void hideEvent(QHideEvent *event) final
Definition: chatform.cpp:726
SystemMessageType::outgoingCall
@ outgoingCall
GenericChatForm::hideEvent
void hideEvent(QHideEvent *event) override
Definition: genericchatform.cpp:554
ChatForm::onFileNameChanged
void onFileNameChanged(const ToxPk &friendPk)
Definition: chatform.cpp:238
chattextedit.h
GenericChatForm::reloadTheme
virtual void reloadTheme()
Definition: genericchatform.cpp:346
ChatForm::onAvEnd
void onAvEnd(uint32_t friendId, bool error)
Definition: chatform.cpp:353
chatlinecontentproxy.h
SystemMessage::messageType
SystemMessageType messageType
Definition: systemmessage.h:50
SystemMessageType::peerStateChange
@ peerStateChange
ChatForm::outgoingNotification
void outgoingNotification()
CoreFile::sendFile
void sendFile(uint32_t friendId, QString filename, QString filePath, long long filesize)
Definition: corefile.cpp:144
ChatFormHeader::createCallConfirm
void createCallConfirm(bool video)
Definition: chatformheader.cpp:218
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
NetCamView
Definition: netcamview.h:38
ScreenshotGrabber::screenshotTaken
void screenshotTaken(const QPixmap &pixmap)
ScreenshotGrabber::showGrabber
void showGrabber()
Definition: screenshotgrabber.cpp:78
ChatForm::acceptCall
void acceptCall(uint32_t friendId)
Friend::getDisplayedName
QString getDisplayedName() const override
Friend::getDisplayedName Gets the name that should be displayed for a user.
Definition: friend.cpp:112
Friend::extensionSupportChanged
void extensionSupportChanged(ExtensionSet extensions)
ChatForm::isTyping
bool isTyping
Definition: chatform.h:138
ImagePreviewButton::setIconFromPixmap
void setIconFromPixmap(const QPixmap &image)
Definition: imagepreviewwidget.cpp:124
ChatForm::callDuration
QLabel * callDuration
Definition: chatform.h:131
GenericChatForm::show
virtual void show(ContentLayout *contentLayout)
Definition: genericchatform.cpp:364
ChatForm::callUpdateFriendActivity
void callUpdateFriendActivity()
Definition: chatform.cpp:225
Settings::getInstance
static Settings & getInstance()
Returns the singleton instance.
Definition: settings.cpp:88
ChatForm::~ChatForm
~ChatForm() override
Definition: chatform.cpp:213
Status::getTitle
QString getTitle(Status status)
Definition: status.cpp:31
ChatForm::copyStatusAction
QAction * copyStatusAction
Definition: chatform.h:135
ChatForm::imagePreview
ImagePreviewButton * imagePreview
Definition: chatform.h:137
CoreAV::isCallStarted
bool isCallStarted(const Friend *f) const
Checks the call status for a Tox friend.
Definition: coreav.cpp:195
CoreAV::isCallInputMuted
bool isCallInputMuted(const Friend *f) const
Returns the calls input (microphone) mute state.
Definition: coreav.cpp:671
ChatForm::show
void show(ContentLayout *contentLayout) final
Definition: chatform.cpp:711
ChatForm::dropEvent
void dropEvent(QDropEvent *ev) final
Definition: chatform.cpp:526
ChatForm::typingTimer
QTimer typingTimer
Definition: chatform.h:133
ChatForm::ChatForm
ChatForm(Profile &profile, Friend *chatFriend, IChatLog &chatLog, IMessageDispatcher &messageDispatcher)
Definition: chatform.cpp:108
ExtensionSet
std::bitset< ExtensionType::max > ExtensionSet
Definition: extension.h:32
corefile.h
IFriendSettings::AutoAcceptCall::Audio
@ Audio
ChatForm::onAttachClicked
void onAttachClicked() override
Definition: chatform.cpp:275
ChatForm::updateFriendActivity
void updateFriendActivity(Friend &frnd)
ChatForm::setFriendTyping
void setFriendTyping(bool isTyping)
Definition: chatform.cpp:704
Friend::getPublicKey
const ToxPk & getPublicKey() const
Definition: friend.cpp:131
ChatForm::onVolMuteToggle
void onVolMuteToggle()
Definition: chatform.cpp:449
ChatForm::updateFriendActivityForFile
void updateFriendActivityForFile(const ToxFile &file)
Definition: chatform.cpp:230
ChatForm::lastCallIsVideo
bool lastCallIsVideo
Definition: chatform.h:139
ChatForm::stopNotification
void stopNotification()
ChatFormHeader::showCallConfirm
void showCallConfirm()
Definition: chatformheader.cpp:226
GenericChatForm::msgEdit
ChatTextEdit * msgEdit
Definition: genericchatform.h:159
ChatFormHeader::callTriggered
void callTriggered()
CoreFile::fileSendStarted
void fileSendStarted(ToxFile file)
Friend::getStatusMessage
QString getStatusMessage() const
Definition: friend.cpp:101
ChatTextEdit::pasteImage
void pasteImage(const QPixmap &pixmap)
Core::friendTypingChanged
void friendTypingChanged(uint32_t friendId, bool isTyping)
ChatForm::f
Friend * f
Definition: chatform.h:128
core.h
GenericChatForm::hideFileMenu
void hideFileMenu()
Definition: genericchatform.cpp:297
ContentLayout
Definition: contentlayout.h:25
ChatForm::onFriendTypingChanged
void onFriendTypingChanged(quint32 friendId, bool isTyping)
Definition: chatform.cpp:475
chatmessage.h
ChatForm::onFriendStatusChanged
void onFriendStatusChanged(const ToxPk &friendPk, Status::Status status)
Definition: chatform.cpp:456
NetCamView::showMessageClicked
void showMessageClicked()
Friend::statusChanged
void statusChanged(const ToxPk &friendId, Status::Status status)
ChatForm::ACTION_PREFIX
static const QString ACTION_PREFIX
Definition: chatform.h:58
ChatForm::onUpdateTime
void onUpdateTime()
Definition: chatform.cpp:699
CoreAV::toggleMuteCallOutput
void toggleMuteCallOutput(const Friend *f)
Toggles the mute state of the call's output (speaker).
Definition: coreav.cpp:444
ChatTextEdit::escapePressed
void escapePressed()
ChatFormHeader::nameChanged
void nameChanged(const QString &name)
Friend::getId
uint32_t getId() const override
Definition: friend.cpp:136
Status::isOnline
bool isOnline(Status status)
Definition: status.cpp:83
translator.h
ChatForm::callDurationTimer
QTimer * callDurationTimer
Definition: chatform.h:132
NetCamView::volMuteToggle
void volMuteToggle()
ToxFile
Definition: toxfile.h:32
GenericChatForm::chatWidget
ChatWidget * chatWidget
Definition: genericchatform.h:158
ChatForm::onRejectCallTriggered
void onRejectCallTriggered()
Definition: chatform.cpp:400
ChatForm::onStatusMessage
void onStatusMessage(const QString &message)
Definition: chatform.cpp:489
Style::Medium
@ Medium
Definition: style.h:59
CoreFile
Manages the file transfer service of toxcore.
Definition: corefile.h:46
nexus.h
GenericChatForm::messageDispatcher
IMessageDispatcher & messageDispatcher
Definition: genericchatform.h:167
ChatForm::startCounter
void startCounter()
Definition: chatform.cpp:668
chatformheader.h
CoreAV
Definition: coreav.h:47
ChatForm::onFriendNameChanged
void onFriendNameChanged(const QString &name)
Definition: chatform.cpp:482
ChatForm::hideNetcam
void hideNetcam()
Definition: chatform.cpp:762
status.h
GenericChatForm::addSystemInfoMessage
void addSystemInfoMessage(const QDateTime &datetime, SystemMessageType messageType, SystemMessage::Args messageArgs)
Definition: genericchatform.cpp:500
ChatWidget::setTypingNotificationVisible
void setTypingNotificationVisible(bool visible)
Definition: chatwidget.cpp:737
CoreAV::avEnd
void avEnd(uint32_t friendId, bool error=false)
Sent when a call was ended by the peer.
ChatTextEdit::enterPressed
void enterPressed()
Core::sendTyping
void sendTyping(uint32_t friendId, bool typing)
Definition: core.cpp:1120
ChatForm::onShowMessagesClicked
void onShowMessagesClicked()
Definition: chatform.cpp:785
searchform.h
SystemMessageType::incomingCall
@ incomingCall