|
|
|
|
@ -17,63 +17,65 @@
@@ -17,63 +17,65 @@
|
|
|
|
|
along with qTox. If not, see <http://www.gnu.org/licenses/>.
|
|
|
|
|
*/ |
|
|
|
|
|
|
|
|
|
#include <QDebug> |
|
|
|
|
#include "chatform.h" |
|
|
|
|
|
|
|
|
|
#include <QApplication> |
|
|
|
|
#include <QBitmap> |
|
|
|
|
#include <QBoxLayout> |
|
|
|
|
#include <QScrollBar> |
|
|
|
|
#include <QClipboard> |
|
|
|
|
#include <QDebug> |
|
|
|
|
#include <QDragEnterEvent> |
|
|
|
|
#include <QFileDialog> |
|
|
|
|
#include <QFileInfo> |
|
|
|
|
#include <QMessageBox> |
|
|
|
|
#include <QPushButton> |
|
|
|
|
#include <QMimeData> |
|
|
|
|
#include <QFileInfo> |
|
|
|
|
#include <QDragEnterEvent> |
|
|
|
|
#include <QBitmap> |
|
|
|
|
#include <QPushButton> |
|
|
|
|
#include <QScreen> |
|
|
|
|
#include <QTemporaryFile> |
|
|
|
|
#include <QApplication> |
|
|
|
|
#include <QGuiApplication> |
|
|
|
|
#include <QStyle> |
|
|
|
|
#include <QScrollBar> |
|
|
|
|
#include <QSplitter> |
|
|
|
|
#include <QClipboard> |
|
|
|
|
#include <QStyle> |
|
|
|
|
#include <QTemporaryFile> |
|
|
|
|
|
|
|
|
|
#include <cassert> |
|
|
|
|
#include "chatform.h" |
|
|
|
|
#include "audio/audio.h" |
|
|
|
|
#include "core/core.h" |
|
|
|
|
#include "core/coreav.h" |
|
|
|
|
#include "friend.h" |
|
|
|
|
#include "widget/style.h" |
|
|
|
|
#include "persistence/settings.h" |
|
|
|
|
#include "core/cstring.h" |
|
|
|
|
#include "widget/tool/callconfirmwidget.h" |
|
|
|
|
#include "widget/friendwidget.h" |
|
|
|
|
#include "widget/form/loadhistorydialog.h" |
|
|
|
|
#include "widget/tool/chattextedit.h" |
|
|
|
|
#include "widget/widget.h" |
|
|
|
|
#include "widget/maskablepixmapwidget.h" |
|
|
|
|
#include "widget/tool/croppinglabel.h" |
|
|
|
|
#include "chatlog/chatmessage.h" |
|
|
|
|
#include "chatlog/content/filetransferwidget.h" |
|
|
|
|
#include "chatlog/chatlinecontentproxy.h" |
|
|
|
|
#include "chatlog/content/text.h" |
|
|
|
|
#include "chatlog/chatlog.h" |
|
|
|
|
#include "video/netcamview.h" |
|
|
|
|
#include "persistence/offlinemsgengine.h" |
|
|
|
|
#include "widget/tool/screenshotgrabber.h" |
|
|
|
|
#include "widget/tool/flyoutoverlaywidget.h" |
|
|
|
|
#include "widget/translator.h" |
|
|
|
|
#include "video/videosource.h" |
|
|
|
|
#include "video/camerasource.h" |
|
|
|
|
#include "nexus.h" |
|
|
|
|
#include "persistence/profile.h" |
|
|
|
|
|
|
|
|
|
#include"audio/audio.h" |
|
|
|
|
#include"chatlog/chatlinecontentproxy.h" |
|
|
|
|
#include"chatlog/chatlog.h" |
|
|
|
|
#include"chatlog/chatmessage.h" |
|
|
|
|
#include"chatlog/content/filetransferwidget.h" |
|
|
|
|
#include"chatlog/content/text.h" |
|
|
|
|
#include"core/core.h" |
|
|
|
|
#include"core/coreav.h" |
|
|
|
|
#include"core/cstring.h" |
|
|
|
|
#include"friend.h" |
|
|
|
|
#include"nexus.h" |
|
|
|
|
#include"nexus.h" |
|
|
|
|
#include"persistence/offlinemsgengine.h" |
|
|
|
|
#include"persistence/profile.h" |
|
|
|
|
#include"persistence/settings.h" |
|
|
|
|
#include"video/camerasource.h" |
|
|
|
|
#include"video/netcamview.h" |
|
|
|
|
#include"video/videosource.h" |
|
|
|
|
#include"widget/form/loadhistorydialog.h" |
|
|
|
|
#include"widget/friendwidget.h" |
|
|
|
|
#include"widget/maskablepixmapwidget.h" |
|
|
|
|
#include"widget/style.h" |
|
|
|
|
#include"widget/tool/callconfirmwidget.h" |
|
|
|
|
#include"widget/tool/chattextedit.h" |
|
|
|
|
#include"widget/tool/croppinglabel.h" |
|
|
|
|
#include"widget/tool/flyoutoverlaywidget.h" |
|
|
|
|
#include"widget/tool/screenshotgrabber.h" |
|
|
|
|
#include"widget/translator.h" |
|
|
|
|
#include"widget/widget.h" |
|
|
|
|
|
|
|
|
|
const QString ChatForm::ACTION_PREFIX = QStringLiteral("/me "); |
|
|
|
|
|
|
|
|
|
ChatForm::ChatForm(Friend* chatFriend) |
|
|
|
|
: f(chatFriend) |
|
|
|
|
, callDuration(new QLabel(this)) |
|
|
|
|
, isTyping(false) |
|
|
|
|
{ |
|
|
|
|
Core* core = Core::getInstance(); |
|
|
|
|
coreav = core->getAv(); |
|
|
|
|
|
|
|
|
|
nameLabel->setText(f->getDisplayedName()); |
|
|
|
|
|
|
|
|
|
avatar->setPixmap(QPixmap(":/img/contact_dark.svg")); |
|
|
|
|
@ -91,9 +93,9 @@ ChatForm::ChatForm(Friend* chatFriend)
@@ -91,9 +93,9 @@ ChatForm::ChatForm(Friend* chatFriend)
|
|
|
|
|
typingTimer.setSingleShot(true); |
|
|
|
|
|
|
|
|
|
callDurationTimer = nullptr; |
|
|
|
|
disableCallButtonsTimer = nullptr; |
|
|
|
|
|
|
|
|
|
chatWidget->setTypingNotification(ChatMessage::createTypingNotification()); |
|
|
|
|
chatWidget->setMinimumHeight(50); |
|
|
|
|
|
|
|
|
|
headTextLayout->addWidget(statusMessageLabel); |
|
|
|
|
headTextLayout->addStretch(); |
|
|
|
|
@ -101,44 +103,72 @@ ChatForm::ChatForm(Friend* chatFriend)
@@ -101,44 +103,72 @@ ChatForm::ChatForm(Friend* chatFriend)
|
|
|
|
|
headTextLayout->addWidget(callDuration, 1, Qt::AlignCenter); |
|
|
|
|
callDuration->hide(); |
|
|
|
|
|
|
|
|
|
chatWidget->setMinimumHeight(50); |
|
|
|
|
connect(this, &GenericChatForm::messageInserted, this, &ChatForm::onMessageInserted); |
|
|
|
|
|
|
|
|
|
loadHistoryAction = menu.addAction(QString(), this, SLOT(onLoadHistory())); |
|
|
|
|
copyStatusAction = statusMessageMenu.addAction(QString(), this, SLOT(onCopyStatusMessage())); |
|
|
|
|
|
|
|
|
|
connect(core, &Core::fileSendStarted, this, &ChatForm::startFileSend); |
|
|
|
|
connect(sendButton, &QPushButton::clicked, this, &ChatForm::onSendTriggered); |
|
|
|
|
connect(fileButton, &QPushButton::clicked, this, &ChatForm::onAttachClicked); |
|
|
|
|
connect(screenshotButton, &QPushButton::clicked, this, &ChatForm::onScreenshotClicked); |
|
|
|
|
connect(callButton, &QPushButton::clicked, this, &ChatForm::onCallTriggered); |
|
|
|
|
connect(videoButton, &QPushButton::clicked, this, &ChatForm::onVideoCallTriggered); |
|
|
|
|
connect(msgEdit, &ChatTextEdit::enterPressed, this, &ChatForm::onSendTriggered); |
|
|
|
|
connect(msgEdit, &ChatTextEdit::textChanged, this, &ChatForm::onTextEditChanged); |
|
|
|
|
connect(core, &Core::fileSendFailed, this, &ChatForm::onFileSendFailed); |
|
|
|
|
connect(core, &Core::friendStatusChanged, this, &ChatForm::onFriendStatusChanged); |
|
|
|
|
connect(this, &ChatForm::chatAreaCleared, getOfflineMsgEngine(), &OfflineMsgEngine::removeAllReceipts); |
|
|
|
|
connect(statusMessageLabel, &CroppingLabel::customContextMenuRequested, this, [&](const QPoint& pos) |
|
|
|
|
{ |
|
|
|
|
const Core* core = Core::getInstance(); |
|
|
|
|
connect(core, &Core::fileReceiveRequested, |
|
|
|
|
this, &ChatForm::onFileRecvRequest); |
|
|
|
|
connect(core, &Core::friendAvatarChanged, |
|
|
|
|
this, &ChatForm::onAvatarChange); |
|
|
|
|
connect(core, &Core::friendAvatarRemoved, |
|
|
|
|
this, &ChatForm::onAvatarRemoved); |
|
|
|
|
connect(core, &Core::fileSendStarted, |
|
|
|
|
this, &ChatForm::startFileSend); |
|
|
|
|
connect(core, &Core::fileSendFailed, |
|
|
|
|
this, &ChatForm::onFileSendFailed); |
|
|
|
|
connect(core, &Core::receiptRecieved, |
|
|
|
|
this, &ChatForm::onReceiptReceived); |
|
|
|
|
connect(core, &Core::friendMessageReceived, |
|
|
|
|
this, &ChatForm::onFriendMessageReceived); |
|
|
|
|
connect(core, &Core::friendTypingChanged, |
|
|
|
|
this, &ChatForm::onFriendTypingChanged); |
|
|
|
|
|
|
|
|
|
const CoreAV* av = core->getAv(); |
|
|
|
|
connect(av, &CoreAV::avInvite, this, &ChatForm::onAvInvite); |
|
|
|
|
connect(av, &CoreAV::avStart, this, &ChatForm::onAvStart); |
|
|
|
|
connect(av, &CoreAV::avEnd, this, &ChatForm::onAvEnd); |
|
|
|
|
|
|
|
|
|
connect(sendButton, &QPushButton::clicked, |
|
|
|
|
this, &ChatForm::onSendTriggered); |
|
|
|
|
connect(fileButton, &QPushButton::clicked, |
|
|
|
|
this, &ChatForm::onAttachClicked); |
|
|
|
|
connect(screenshotButton, &QPushButton::clicked, |
|
|
|
|
this, &ChatForm::onScreenshotClicked); |
|
|
|
|
connect(callButton, &QAbstractButton::clicked, |
|
|
|
|
this, &ChatForm::onCallTriggered); |
|
|
|
|
connect(videoButton, &QAbstractButton::clicked, |
|
|
|
|
this, &ChatForm::onVideoCallTriggered); |
|
|
|
|
connect(micButton, &QAbstractButton::clicked, |
|
|
|
|
this, &ChatForm::onMicMuteToggle); |
|
|
|
|
connect(volButton, &QAbstractButton::clicked, |
|
|
|
|
this, &ChatForm::onVolMuteToggle); |
|
|
|
|
|
|
|
|
|
connect(msgEdit, &ChatTextEdit::enterPressed, |
|
|
|
|
this, &ChatForm::onSendTriggered); |
|
|
|
|
connect(msgEdit, &ChatTextEdit::textChanged, |
|
|
|
|
this, &ChatForm::onTextEditChanged); |
|
|
|
|
connect(statusMessageLabel, &CroppingLabel::customContextMenuRequested, |
|
|
|
|
this, [&](const QPoint& pos) { |
|
|
|
|
if (!statusMessageLabel->text().isEmpty()) |
|
|
|
|
{ |
|
|
|
|
QWidget* sender = static_cast<QWidget*>(this->sender()); |
|
|
|
|
|
|
|
|
|
statusMessageMenu.exec(sender->mapToGlobal(pos)); |
|
|
|
|
} |
|
|
|
|
} ); |
|
|
|
|
connect(&typingTimer, &QTimer::timeout, this, [=]{ |
|
|
|
|
}); |
|
|
|
|
|
|
|
|
|
connect(&typingTimer, &QTimer::timeout, this, [=] { |
|
|
|
|
Core::getInstance()->sendTyping(f->getFriendID(), false); |
|
|
|
|
isTyping = false; |
|
|
|
|
} ); |
|
|
|
|
connect(nameLabel, &CroppingLabel::editFinished, this, [=](const QString& newName) |
|
|
|
|
{ |
|
|
|
|
}); |
|
|
|
|
|
|
|
|
|
connect(nameLabel, &CroppingLabel::editFinished, |
|
|
|
|
this, [=](const QString& newName) { |
|
|
|
|
nameLabel->setText(newName); |
|
|
|
|
emit aliasChanged(newName); |
|
|
|
|
} ); |
|
|
|
|
}); |
|
|
|
|
|
|
|
|
|
setAcceptDrops(true); |
|
|
|
|
disableCallButtons(); |
|
|
|
|
retranslateUi(); |
|
|
|
|
Translator::registerHandler(std::bind(&ChatForm::retranslateUi, this), this); |
|
|
|
|
} |
|
|
|
|
@ -147,14 +177,13 @@ ChatForm::~ChatForm()
@@ -147,14 +177,13 @@ ChatForm::~ChatForm()
|
|
|
|
|
{ |
|
|
|
|
Translator::unregister(this); |
|
|
|
|
delete netcam; |
|
|
|
|
delete callConfirm; |
|
|
|
|
delete offlineEngine; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
void ChatForm::setStatusMessage(QString newMessage) |
|
|
|
|
{ |
|
|
|
|
statusMessageLabel->setText(newMessage); |
|
|
|
|
statusMessageLabel->setToolTip(Qt::convertFromPlainText(newMessage, Qt::WhiteSpaceNormal)); // for overlength messsages
|
|
|
|
|
// for long messsages
|
|
|
|
|
statusMessageLabel->setToolTip(Qt::convertFromPlainText(newMessage, Qt::WhiteSpaceNormal)); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
void ChatForm::onSendTriggered() |
|
|
|
|
@ -197,6 +226,7 @@ void ChatForm::onAttachClicked()
@@ -197,6 +226,7 @@ void ChatForm::onAttachClicked()
|
|
|
|
|
if (paths.isEmpty()) |
|
|
|
|
return; |
|
|
|
|
|
|
|
|
|
Core* core = Core::getInstance(); |
|
|
|
|
for (QString path : paths) |
|
|
|
|
{ |
|
|
|
|
QFile file(path); |
|
|
|
|
@ -207,11 +237,13 @@ void ChatForm::onAttachClicked()
@@ -207,11 +237,13 @@ void ChatForm::onAttachClicked()
|
|
|
|
|
tr("qTox wasn't able to open %1").arg(QFileInfo(path).fileName())); |
|
|
|
|
continue; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
if (file.isSequential()) |
|
|
|
|
{ |
|
|
|
|
QMessageBox::critical(this, |
|
|
|
|
tr("Bad idea"), |
|
|
|
|
tr("You're trying to send a special (sequential) file, that's not going to work!")); |
|
|
|
|
tr("You're trying to send a sequential file," |
|
|
|
|
" which is not going to work!")); |
|
|
|
|
file.close(); |
|
|
|
|
continue; |
|
|
|
|
} |
|
|
|
|
@ -219,7 +251,8 @@ void ChatForm::onAttachClicked()
@@ -219,7 +251,8 @@ void ChatForm::onAttachClicked()
|
|
|
|
|
file.close(); |
|
|
|
|
QFileInfo fi(path); |
|
|
|
|
|
|
|
|
|
emit sendFile(f->getFriendID(), fi.fileName(), path, filesize); |
|
|
|
|
core->sendFile(f->getFriendID(), fi.fileName(), path, |
|
|
|
|
filesize); |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
@ -277,13 +310,12 @@ void ChatForm::onFileRecvRequest(ToxFile file)
@@ -277,13 +310,12 @@ void ChatForm::onFileRecvRequest(ToxFile file)
|
|
|
|
|
Widget::getInstance()->updateFriendActivity(f); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
void ChatForm::onAvInvite(uint32_t FriendId, bool video) |
|
|
|
|
void ChatForm::onAvInvite(uint32_t friendId, bool video) |
|
|
|
|
{ |
|
|
|
|
if (FriendId != f->getFriendID()) |
|
|
|
|
if (friendId != f->getFriendID()) |
|
|
|
|
return; |
|
|
|
|
|
|
|
|
|
qDebug() << "onAvInvite"; |
|
|
|
|
disableCallButtons(); |
|
|
|
|
callConfirm = new CallConfirmWidget(video ? videoButton : callButton, *f); |
|
|
|
|
insertChatMessage(ChatMessage::createChatInfoMessage(tr("%1 calling").arg(f->getDisplayedName()), |
|
|
|
|
ChatMessage::INFO, |
|
|
|
|
QDateTime::currentDateTime())); |
|
|
|
|
@ -293,35 +325,25 @@ void ChatForm::onAvInvite(uint32_t FriendId, bool video)
@@ -293,35 +325,25 @@ void ChatForm::onAvInvite(uint32_t FriendId, bool video)
|
|
|
|
|
{ |
|
|
|
|
uint32_t friendId = f->getFriendID(); |
|
|
|
|
qDebug() << "automatic call answer"; |
|
|
|
|
CoreAV* coreav = Core::getInstance()->getAv(); |
|
|
|
|
QMetaObject::invokeMethod(coreav, "answerCall", Qt::QueuedConnection, Q_ARG(uint32_t, friendId)); |
|
|
|
|
onAvStart(friendId,video); |
|
|
|
|
} |
|
|
|
|
else |
|
|
|
|
{ |
|
|
|
|
if (video) |
|
|
|
|
{ |
|
|
|
|
callConfirm = new CallConfirmWidget(videoButton, *f); |
|
|
|
|
videoButton->setObjectName("yellow"); |
|
|
|
|
videoButton->setToolTip(tr("Accept video call")); |
|
|
|
|
videoButton->style()->polish(videoButton); |
|
|
|
|
connect(videoButton, &QPushButton::clicked, this, &ChatForm::onAnswerCallTriggered); |
|
|
|
|
} |
|
|
|
|
else |
|
|
|
|
{ |
|
|
|
|
callConfirm = new CallConfirmWidget(callButton, *f); |
|
|
|
|
callButton->setObjectName("yellow"); |
|
|
|
|
callButton->setToolTip(tr("Accept audio call")); |
|
|
|
|
callButton->style()->polish(callButton); |
|
|
|
|
connect(callButton, &QPushButton::clicked, this, &ChatForm::onAnswerCallTriggered); |
|
|
|
|
} |
|
|
|
|
callConfirm->show(); |
|
|
|
|
|
|
|
|
|
if (f->getFriendWidget()->chatFormIsSet(false)) |
|
|
|
|
callConfirm->show(); |
|
|
|
|
connect(callConfirm.data(), &CallConfirmWidget::accepted, |
|
|
|
|
this, &ChatForm::onAnswerCallTriggered); |
|
|
|
|
connect(callConfirm.data(), &CallConfirmWidget::rejected, |
|
|
|
|
this, &ChatForm::onRejectCallTriggered); |
|
|
|
|
|
|
|
|
|
connect(callConfirm, &CallConfirmWidget::accepted, this, &ChatForm::onAnswerCallTriggered); |
|
|
|
|
connect(callConfirm, &CallConfirmWidget::rejected, this, &ChatForm::onRejectCallTriggered); |
|
|
|
|
insertChatMessage(ChatMessage::createChatInfoMessage( |
|
|
|
|
tr("%1 calling").arg(f->getDisplayedName()), |
|
|
|
|
ChatMessage::INFO, |
|
|
|
|
QDateTime::currentDateTime())); |
|
|
|
|
|
|
|
|
|
Widget::getInstance()->newFriendMessageAlert(FriendId, false); |
|
|
|
|
Widget::getInstance()->newFriendMessageAlert(friendId, false); |
|
|
|
|
Audio& audio = Audio::getInstance(); |
|
|
|
|
audio.startLoop(); |
|
|
|
|
audio.playMono16Sound(Audio::getSound(Audio::Sound::IncomingCall)); |
|
|
|
|
@ -333,44 +355,12 @@ void ChatForm::onAvStart(uint32_t FriendId, bool video)
@@ -333,44 +355,12 @@ void ChatForm::onAvStart(uint32_t FriendId, bool video)
|
|
|
|
|
if (FriendId != f->getFriendID()) |
|
|
|
|
return; |
|
|
|
|
|
|
|
|
|
qDebug() << "onAvStart"; |
|
|
|
|
|
|
|
|
|
audioInputFlag = true; |
|
|
|
|
audioOutputFlag = true; |
|
|
|
|
disableCallButtons(); |
|
|
|
|
|
|
|
|
|
if (video) |
|
|
|
|
{ |
|
|
|
|
videoButton->setObjectName("red"); |
|
|
|
|
videoButton->setToolTip(tr("End video call")); |
|
|
|
|
videoButton->style()->polish(videoButton); |
|
|
|
|
connect(videoButton, SIGNAL(clicked()), |
|
|
|
|
this, SLOT(onHangupCallTriggered())); |
|
|
|
|
|
|
|
|
|
showNetcam(); |
|
|
|
|
} |
|
|
|
|
else |
|
|
|
|
{ |
|
|
|
|
callButton->setObjectName("red"); |
|
|
|
|
callButton->setToolTip(tr("End audio call")); |
|
|
|
|
callButton->style()->polish(callButton); |
|
|
|
|
connect(callButton, SIGNAL(clicked()), |
|
|
|
|
this, SLOT(onHangupCallTriggered())); |
|
|
|
|
hideNetcam(); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
micButton->setObjectName("green"); |
|
|
|
|
micButton->style()->polish(micButton); |
|
|
|
|
micButton->setToolTip(tr("Mute microphone")); |
|
|
|
|
volButton->setObjectName("green"); |
|
|
|
|
volButton->style()->polish(volButton); |
|
|
|
|
volButton->setToolTip(tr("Mute call")); |
|
|
|
|
|
|
|
|
|
connect(micButton, SIGNAL(clicked()), |
|
|
|
|
this, SLOT(onMicMuteToggle())); |
|
|
|
|
connect(volButton, SIGNAL(clicked()), |
|
|
|
|
this, SLOT(onVolMuteToggle())); |
|
|
|
|
|
|
|
|
|
updateCallButtons(); |
|
|
|
|
startCounter(); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
@ -379,39 +369,32 @@ void ChatForm::onAvEnd(uint32_t FriendId)
@@ -379,39 +369,32 @@ void ChatForm::onAvEnd(uint32_t FriendId)
|
|
|
|
|
if (FriendId != f->getFriendID()) |
|
|
|
|
return; |
|
|
|
|
|
|
|
|
|
qDebug() << "onAvEnd"; |
|
|
|
|
|
|
|
|
|
delete callConfirm; |
|
|
|
|
callConfirm = nullptr; |
|
|
|
|
|
|
|
|
|
//Fixes an OS X bug with ending a call while in full screen
|
|
|
|
|
if (netcam && netcam->isFullScreen()) |
|
|
|
|
netcam->showNormal(); |
|
|
|
|
|
|
|
|
|
Audio::getInstance().stopLoop(); |
|
|
|
|
|
|
|
|
|
enableCallButtons(); |
|
|
|
|
updateCallButtons(); |
|
|
|
|
stopCounter(); |
|
|
|
|
hideNetcam(); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
void ChatForm::showOutgoingCall(bool video) |
|
|
|
|
{ |
|
|
|
|
audioInputFlag = true; |
|
|
|
|
audioOutputFlag = true; |
|
|
|
|
|
|
|
|
|
disableCallButtons(); |
|
|
|
|
if (video) |
|
|
|
|
{ |
|
|
|
|
videoButton->setObjectName("yellow"); |
|
|
|
|
videoButton->style()->polish(videoButton); |
|
|
|
|
videoButton->setStyleSheet(Style::getStylesheet(QStringLiteral(":/ui/videoButton/videoButton.css"))); |
|
|
|
|
videoButton->setToolTip(tr("Cancel video call")); |
|
|
|
|
connect(videoButton, &QPushButton::clicked, |
|
|
|
|
this, &ChatForm::onCancelCallTriggered); |
|
|
|
|
} |
|
|
|
|
else |
|
|
|
|
{ |
|
|
|
|
callButton->setObjectName("yellow"); |
|
|
|
|
callButton->style()->polish(callButton); |
|
|
|
|
callButton->setStyleSheet(Style::getStylesheet(QStringLiteral(":/ui/callButton/callButton.css"))); |
|
|
|
|
callButton->setToolTip(tr("Cancel audio call")); |
|
|
|
|
connect(callButton, &QPushButton::clicked, |
|
|
|
|
this, &ChatForm::onCancelCallTriggered); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
addSystemInfoMessage(tr("Calling %1").arg(f->getDisplayedName()), |
|
|
|
|
@ -423,240 +406,202 @@ void ChatForm::showOutgoingCall(bool video)
@@ -423,240 +406,202 @@ void ChatForm::showOutgoingCall(bool video)
|
|
|
|
|
|
|
|
|
|
void ChatForm::onAnswerCallTriggered() |
|
|
|
|
{ |
|
|
|
|
qDebug() << "onAnswerCallTriggered"; |
|
|
|
|
|
|
|
|
|
if (callConfirm) |
|
|
|
|
{ |
|
|
|
|
delete callConfirm; |
|
|
|
|
callConfirm = nullptr; |
|
|
|
|
} |
|
|
|
|
delete callConfirm; |
|
|
|
|
|
|
|
|
|
Audio::getInstance().stopLoop(); |
|
|
|
|
|
|
|
|
|
disableCallButtons(); |
|
|
|
|
updateCallButtons(); |
|
|
|
|
|
|
|
|
|
if (!coreav->answerCall(f->getFriendID())) |
|
|
|
|
CoreAV* av = Core::getInstance()->getAv(); |
|
|
|
|
if (!av->answerCall(f->getFriendID())) |
|
|
|
|
{ |
|
|
|
|
enableCallButtons(); |
|
|
|
|
updateCallButtons(); |
|
|
|
|
stopCounter(); |
|
|
|
|
hideNetcam(); |
|
|
|
|
return; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
onAvStart(f->getFriendID(), coreav->isCallActive(f)); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
void ChatForm::onHangupCallTriggered() |
|
|
|
|
{ |
|
|
|
|
qDebug() << "onHangupCallTriggered"; |
|
|
|
|
|
|
|
|
|
//Fixes an OS X bug with ending a call while in full screen
|
|
|
|
|
if (netcam && netcam->isFullScreen()) |
|
|
|
|
netcam->showNormal(); |
|
|
|
|
|
|
|
|
|
audioInputFlag = false; |
|
|
|
|
audioOutputFlag = false; |
|
|
|
|
coreav->cancelCall(f->getFriendID()); |
|
|
|
|
|
|
|
|
|
stopCounter(); |
|
|
|
|
enableCallButtons(); |
|
|
|
|
hideNetcam(); |
|
|
|
|
onAvStart(f->getFriendID(), av->isCallVideoEnabled(f)); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
void ChatForm::onRejectCallTriggered() |
|
|
|
|
{ |
|
|
|
|
qDebug() << "onRejectCallTriggered"; |
|
|
|
|
|
|
|
|
|
if (callConfirm) |
|
|
|
|
{ |
|
|
|
|
delete callConfirm; |
|
|
|
|
callConfirm = nullptr; |
|
|
|
|
} |
|
|
|
|
delete callConfirm; |
|
|
|
|
|
|
|
|
|
Audio::getInstance().stopLoop(); |
|
|
|
|
|
|
|
|
|
audioInputFlag = false; |
|
|
|
|
audioOutputFlag = false; |
|
|
|
|
coreav->cancelCall(f->getFriendID()); |
|
|
|
|
|
|
|
|
|
enableCallButtons(); |
|
|
|
|
stopCounter(); |
|
|
|
|
CoreAV* av = Core::getInstance()->getAv(); |
|
|
|
|
av->cancelCall(f->getFriendID()); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
void ChatForm::onCallTriggered() |
|
|
|
|
{ |
|
|
|
|
qDebug() << "onCallTriggered"; |
|
|
|
|
|
|
|
|
|
disableCallButtons(); |
|
|
|
|
if (coreav->startCall(f->getFriendID(), false)) |
|
|
|
|
CoreAV* av = Core::getInstance()->getAv(); |
|
|
|
|
if (av->isCallActive(f)) |
|
|
|
|
{ |
|
|
|
|
av->cancelCall(f->getFriendID()); |
|
|
|
|
} |
|
|
|
|
else if (av->startCall(f->getFriendID(), false)) |
|
|
|
|
{ |
|
|
|
|
showOutgoingCall(false); |
|
|
|
|
else |
|
|
|
|
enableCallButtons(); |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
void ChatForm::onVideoCallTriggered() |
|
|
|
|
{ |
|
|
|
|
qDebug() << "onVideoCallTriggered"; |
|
|
|
|
|
|
|
|
|
disableCallButtons(); |
|
|
|
|
if (coreav->startCall(f->getFriendID(), true)) |
|
|
|
|
CoreAV* av = Core::getInstance()->getAv(); |
|
|
|
|
if (av->isCallActive(f)) |
|
|
|
|
{ |
|
|
|
|
// TODO: We want to activate video on the active call.
|
|
|
|
|
if (av->isCallVideoEnabled(f)) |
|
|
|
|
av->cancelCall(f->getFriendID()); |
|
|
|
|
} |
|
|
|
|
else if (av->startCall(f->getFriendID(), true)) |
|
|
|
|
{ |
|
|
|
|
showOutgoingCall(true); |
|
|
|
|
else |
|
|
|
|
enableCallButtons(); |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
void ChatForm::onCancelCallTriggered() |
|
|
|
|
void ChatForm::updateCallButtons() |
|
|
|
|
{ |
|
|
|
|
qDebug() << "onCancelCallTriggered"; |
|
|
|
|
CoreAV* av = Core::getInstance()->getAv(); |
|
|
|
|
if (av->isCallActive(f)) |
|
|
|
|
{ |
|
|
|
|
callButton->setObjectName("red"); |
|
|
|
|
callButton->setToolTip(tr("End audio call")); |
|
|
|
|
|
|
|
|
|
if (!coreav->cancelCall(f->getFriendID())) |
|
|
|
|
qWarning() << "Failed to cancel a call! Assuming we're not in call"; |
|
|
|
|
if (av->isCallVideoEnabled(f)) |
|
|
|
|
{ |
|
|
|
|
videoButton->setObjectName("red"); |
|
|
|
|
videoButton->setToolTip(tr("End video call")); |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
else |
|
|
|
|
{ |
|
|
|
|
const Status fs = f->getStatus(); |
|
|
|
|
callButton->setEnabled(fs != Status::Offline); |
|
|
|
|
videoButton->setEnabled(fs != Status::Offline); |
|
|
|
|
|
|
|
|
|
enableCallButtons(); |
|
|
|
|
stopCounter(); |
|
|
|
|
hideNetcam(); |
|
|
|
|
if (callButton->isEnabled()) |
|
|
|
|
{ |
|
|
|
|
callButton->setObjectName("green"); |
|
|
|
|
callButton->setToolTip(tr("Start audio call")); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
if (videoButton->isEnabled()) |
|
|
|
|
{ |
|
|
|
|
videoButton->setObjectName("green"); |
|
|
|
|
videoButton->setToolTip(tr("Start video call")); |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
callButton->setStyleSheet(Style::getStylesheet(QStringLiteral(":/ui/callButton/callButton.css"))); |
|
|
|
|
videoButton->setStyleSheet(Style::getStylesheet(QStringLiteral(":/ui/videoButton/videoButton.css"))); |
|
|
|
|
|
|
|
|
|
updateMuteMicButton(); |
|
|
|
|
updateMuteVolButton(); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
void ChatForm::enableCallButtons() |
|
|
|
|
void ChatForm::onMicMuteToggle() |
|
|
|
|
{ |
|
|
|
|
qDebug() << "enableCallButtons"; |
|
|
|
|
CoreAV* av = Core::getInstance()->getAv(); |
|
|
|
|
|
|
|
|
|
audioInputFlag = false; |
|
|
|
|
audioOutputFlag = false; |
|
|
|
|
av->toggleMuteCallInput(f); |
|
|
|
|
updateMuteMicButton(); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
disableCallButtons(); |
|
|
|
|
void ChatForm::onVolMuteToggle() |
|
|
|
|
{ |
|
|
|
|
CoreAV* av = Core::getInstance()->getAv(); |
|
|
|
|
|
|
|
|
|
if (disableCallButtonsTimer == nullptr) |
|
|
|
|
{ |
|
|
|
|
disableCallButtonsTimer = new QTimer(); |
|
|
|
|
connect(disableCallButtonsTimer, SIGNAL(timeout()), |
|
|
|
|
this, SLOT(onEnableCallButtons())); |
|
|
|
|
disableCallButtonsTimer->start(1500); // 1.5sec
|
|
|
|
|
qDebug() << "timer started!!"; |
|
|
|
|
} |
|
|
|
|
av->toggleMuteCallOutput(f); |
|
|
|
|
updateMuteVolButton(); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
void ChatForm::disableCallButtons() |
|
|
|
|
void ChatForm::onFileSendFailed(uint32_t friendId, const QString &fname) |
|
|
|
|
{ |
|
|
|
|
// Prevents race enable / disable / onEnable, when it should be disabled
|
|
|
|
|
if (disableCallButtonsTimer) |
|
|
|
|
{ |
|
|
|
|
disableCallButtonsTimer->stop(); |
|
|
|
|
delete disableCallButtonsTimer; |
|
|
|
|
disableCallButtonsTimer = nullptr; |
|
|
|
|
} |
|
|
|
|
if (friendId != f->getFriendID()) |
|
|
|
|
return; |
|
|
|
|
|
|
|
|
|
micButton->setObjectName("grey"); |
|
|
|
|
micButton->style()->polish(micButton); |
|
|
|
|
micButton->setToolTip(""); |
|
|
|
|
micButton->disconnect(); |
|
|
|
|
volButton->setObjectName("grey"); |
|
|
|
|
volButton->style()->polish(volButton); |
|
|
|
|
volButton->setToolTip(""); |
|
|
|
|
volButton->disconnect(); |
|
|
|
|
|
|
|
|
|
callButton->setObjectName("grey"); |
|
|
|
|
callButton->style()->polish(callButton); |
|
|
|
|
callButton->setToolTip(""); |
|
|
|
|
callButton->disconnect(); |
|
|
|
|
videoButton->setObjectName("grey"); |
|
|
|
|
videoButton->style()->polish(videoButton); |
|
|
|
|
videoButton->setToolTip(""); |
|
|
|
|
videoButton->disconnect(); |
|
|
|
|
addSystemInfoMessage(tr("Failed to send file \"%1\"").arg(fname), ChatMessage::ERROR, QDateTime::currentDateTime()); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
void ChatForm::onEnableCallButtons() |
|
|
|
|
void ChatForm::onFriendStatusChanged(uint32_t friendId, Status status) |
|
|
|
|
{ |
|
|
|
|
audioInputFlag = false; |
|
|
|
|
audioOutputFlag = false; |
|
|
|
|
|
|
|
|
|
callButton->setObjectName("green"); |
|
|
|
|
callButton->style()->polish(callButton); |
|
|
|
|
callButton->setToolTip(tr("Start audio call")); |
|
|
|
|
videoButton->setObjectName("green"); |
|
|
|
|
videoButton->style()->polish(videoButton); |
|
|
|
|
videoButton->setToolTip(tr("Start video call")); |
|
|
|
|
|
|
|
|
|
connect(callButton, SIGNAL(clicked()), |
|
|
|
|
this, SLOT(onCallTriggered())); |
|
|
|
|
connect(videoButton, SIGNAL(clicked()), |
|
|
|
|
this, SLOT(onVideoCallTriggered())); |
|
|
|
|
|
|
|
|
|
if (disableCallButtonsTimer != nullptr) |
|
|
|
|
// Disable call buttons if friend is offline
|
|
|
|
|
if(friendId != f->getFriendID()) |
|
|
|
|
return; |
|
|
|
|
|
|
|
|
|
if (status == Status::Offline) |
|
|
|
|
{ |
|
|
|
|
disableCallButtonsTimer->stop(); |
|
|
|
|
delete disableCallButtonsTimer; |
|
|
|
|
disableCallButtonsTimer = nullptr; |
|
|
|
|
// Hide the "is typing" message when a friend goes offline
|
|
|
|
|
setFriendTyping(false); |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
void ChatForm::onMicMuteToggle() |
|
|
|
|
{ |
|
|
|
|
if (audioInputFlag) |
|
|
|
|
else |
|
|
|
|
{ |
|
|
|
|
coreav->toggleMuteCallInput(f); |
|
|
|
|
if (micButton->objectName() == "red") |
|
|
|
|
{ |
|
|
|
|
micButton->setObjectName("green"); |
|
|
|
|
micButton->setToolTip(tr("Mute microphone")); |
|
|
|
|
} |
|
|
|
|
else |
|
|
|
|
{ |
|
|
|
|
micButton->setObjectName("red"); |
|
|
|
|
micButton->setToolTip(tr("Unmute microphone")); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
Style::repolish(micButton); |
|
|
|
|
QTimer::singleShot(250, this, SLOT(onDeliverOfflineMessages())); |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
void ChatForm::onVolMuteToggle() |
|
|
|
|
{ |
|
|
|
|
if (audioOutputFlag) |
|
|
|
|
updateCallButtons(); |
|
|
|
|
|
|
|
|
|
if (Settings::getInstance().getStatusChangeNotificationEnabled()) |
|
|
|
|
{ |
|
|
|
|
coreav->toggleMuteCallOutput(f); |
|
|
|
|
if (volButton->objectName() == "red") |
|
|
|
|
QString fStatus = ""; |
|
|
|
|
switch (status) |
|
|
|
|
{ |
|
|
|
|
volButton->setObjectName("green"); |
|
|
|
|
volButton->setToolTip(tr("Mute call")); |
|
|
|
|
} |
|
|
|
|
else |
|
|
|
|
{ |
|
|
|
|
volButton->setObjectName("red"); |
|
|
|
|
volButton->setToolTip(tr("Unmute call")); |
|
|
|
|
case Status::Away: |
|
|
|
|
fStatus = tr("away", "contact status"); break; |
|
|
|
|
case Status::Busy: |
|
|
|
|
fStatus = tr("busy", "contact status"); break; |
|
|
|
|
case Status::Offline: |
|
|
|
|
fStatus = tr("offline", "contact status"); break; |
|
|
|
|
case Status::Online: |
|
|
|
|
fStatus = tr("online", "contact status"); break; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
Style::repolish(volButton); |
|
|
|
|
addSystemInfoMessage(tr("%1 is now %2", "e.g. \"Dubslow is now online\"") |
|
|
|
|
.arg(f->getDisplayedName()).arg(fStatus), |
|
|
|
|
ChatMessage::INFO, QDateTime::currentDateTime()); |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
void ChatForm::onFileSendFailed(uint32_t FriendId, const QString &fname) |
|
|
|
|
void ChatForm::onFriendTypingChanged(quint32 friendId, bool isTyping) |
|
|
|
|
{ |
|
|
|
|
if (FriendId != f->getFriendID()) |
|
|
|
|
return; |
|
|
|
|
if (friendId == f->getFriendID()) |
|
|
|
|
setFriendTyping(isTyping); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
addSystemInfoMessage(tr("Failed to send file \"%1\"").arg(fname), ChatMessage::ERROR, QDateTime::currentDateTime()); |
|
|
|
|
void ChatForm::onFriendNameChanged(const QString& name) |
|
|
|
|
{ |
|
|
|
|
if (sender() == f) |
|
|
|
|
setName(name); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
void ChatForm::onFriendStatusChanged(uint32_t friendId, Status status) |
|
|
|
|
void ChatForm::onFriendMessageReceived(quint32 friendId, const QString& message, |
|
|
|
|
bool isAction) |
|
|
|
|
{ |
|
|
|
|
// Disable call buttons if friend is offline
|
|
|
|
|
if(friendId != f->getFriendID()) |
|
|
|
|
if (friendId != f->getFriendID()) |
|
|
|
|
return; |
|
|
|
|
|
|
|
|
|
Status old = oldStatus.value(friendId, Status::Offline); |
|
|
|
|
QDateTime timestamp = QDateTime::currentDateTime(); |
|
|
|
|
addMessage(f->getToxId(), message, isAction, timestamp, true); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
if (old != Status::Offline && status == Status::Offline) |
|
|
|
|
disableCallButtons(); |
|
|
|
|
else if (old == Status::Offline && status != Status::Offline) |
|
|
|
|
enableCallButtons(); |
|
|
|
|
void ChatForm::onStatusMessage(const QString& message) |
|
|
|
|
{ |
|
|
|
|
if (sender() == f) |
|
|
|
|
setStatusMessage(message); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
oldStatus[friendId] = status; |
|
|
|
|
void ChatForm::onReceiptReceived(quint32 friendId, int receipt) |
|
|
|
|
{ |
|
|
|
|
if (friendId == f->getFriendID()) |
|
|
|
|
f->getChatForm()->getOfflineMsgEngine()->dischargeReceipt(receipt); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
void ChatForm::onAvatarChange(uint32_t FriendId, const QPixmap &pic) |
|
|
|
|
void ChatForm::onAvatarChange(uint32_t friendId, const QPixmap &pic) |
|
|
|
|
{ |
|
|
|
|
if (FriendId != f->getFriendID()) |
|
|
|
|
if (friendId != f->getFriendID()) |
|
|
|
|
return; |
|
|
|
|
|
|
|
|
|
avatar->setPixmap(pic); |
|
|
|
|
@ -680,6 +625,7 @@ void ChatForm::dropEvent(QDropEvent *ev)
@@ -680,6 +625,7 @@ void ChatForm::dropEvent(QDropEvent *ev)
|
|
|
|
|
{ |
|
|
|
|
if (ev->mimeData()->hasUrls()) |
|
|
|
|
{ |
|
|
|
|
Core* core = Core::getInstance(); |
|
|
|
|
for (QUrl url : ev->mimeData()->urls()) |
|
|
|
|
{ |
|
|
|
|
QFileInfo info(url.path()); |
|
|
|
|
@ -690,26 +636,34 @@ void ChatForm::dropEvent(QDropEvent *ev)
@@ -690,26 +636,34 @@ void ChatForm::dropEvent(QDropEvent *ev)
|
|
|
|
|
SendMessageStr(url.toString()); |
|
|
|
|
continue; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
if (!file.exists() || !file.open(QIODevice::ReadOnly)) |
|
|
|
|
{ |
|
|
|
|
info.setFile(url.toLocalFile()); |
|
|
|
|
file.setFileName(info.absoluteFilePath()); |
|
|
|
|
if (!file.exists() || !file.open(QIODevice::ReadOnly)) |
|
|
|
|
{ |
|
|
|
|
QMessageBox::warning(this, tr("Unable to open"), tr("qTox wasn't able to open %1").arg(info.fileName())); |
|
|
|
|
QMessageBox::warning(this, tr("Unable to open"), |
|
|
|
|
tr("qTox wasn't able to open %1") |
|
|
|
|
.arg(info.fileName())); |
|
|
|
|
continue; |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
if (file.isSequential()) |
|
|
|
|
{ |
|
|
|
|
QMessageBox::critical(0, tr("Bad idea"), tr("You're trying to send a special (sequential) file, that's not going to work!")); |
|
|
|
|
QMessageBox::critical(0, tr("Bad idea"), |
|
|
|
|
tr("You're trying to send a sequential" |
|
|
|
|
" file, which is not going to work!")); |
|
|
|
|
file.close(); |
|
|
|
|
continue; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
file.close(); |
|
|
|
|
|
|
|
|
|
if (info.exists()) |
|
|
|
|
Core::getInstance()->sendFile(f->getFriendID(), info.fileName(), info.absoluteFilePath(), info.size()); |
|
|
|
|
core->sendFile(f->getFriendID(), info.fileName(), |
|
|
|
|
info.absoluteFilePath(), info.size()); |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
@ -722,6 +676,23 @@ void ChatForm::onAvatarRemoved(uint32_t FriendId)
@@ -722,6 +676,23 @@ void ChatForm::onAvatarRemoved(uint32_t FriendId)
|
|
|
|
|
avatar->setPixmap(QPixmap(":/img/contact_dark.svg")); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
void ChatForm::clearChatArea(bool notInForm) |
|
|
|
|
{ |
|
|
|
|
GenericChatForm::clearChatArea(notInForm); |
|
|
|
|
f->getChatForm()->getOfflineMsgEngine()->removeAllReceipts(); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
void ChatForm::onDeliverOfflineMessages() |
|
|
|
|
{ |
|
|
|
|
f->getChatForm()->getOfflineMsgEngine()->deliverOfflineMsgs(); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
void ChatForm::onLoadChatHistory() |
|
|
|
|
{ |
|
|
|
|
if (sender() == f) |
|
|
|
|
loadHistory(QDateTime::currentDateTime().addDays(-7), true); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
// TODO: Split on smaller methods (style)
|
|
|
|
|
void ChatForm::loadHistory(QDateTime since, bool processUndelivered) |
|
|
|
|
{ |
|
|
|
|
@ -870,7 +841,8 @@ void ChatForm::onScreenshotTaken(const QPixmap &pixmap) {
@@ -870,7 +841,8 @@ void ChatForm::onScreenshotTaken(const QPixmap &pixmap) {
|
|
|
|
|
file.close(); |
|
|
|
|
QFileInfo fi(file); |
|
|
|
|
|
|
|
|
|
emit sendFile(f->getFriendID(), fi.fileName(), fi.filePath(), filesize); |
|
|
|
|
Core::getInstance()->sendFile(f->getFriendID(), fi.fileName(), |
|
|
|
|
fi.filePath(), filesize); |
|
|
|
|
} |
|
|
|
|
else |
|
|
|
|
{ |
|
|
|
|
@ -894,8 +866,10 @@ void ChatForm::onLoadHistory()
@@ -894,8 +866,10 @@ void ChatForm::onLoadHistory()
|
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
void ChatForm::onMessageInserted() |
|
|
|
|
void ChatForm::insertChatMessage(ChatMessage::Ptr msg) |
|
|
|
|
{ |
|
|
|
|
GenericChatForm::insertChatMessage(msg); |
|
|
|
|
|
|
|
|
|
if (netcam && bodySplitter->sizes()[1] == 0) |
|
|
|
|
netcam->setShowMessages(true, true); |
|
|
|
|
} |
|
|
|
|
@ -911,12 +885,59 @@ void ChatForm::onCopyStatusMessage()
@@ -911,12 +885,59 @@ void ChatForm::onCopyStatusMessage()
|
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
void ChatForm::updateMuteMicButton() |
|
|
|
|
{ |
|
|
|
|
const CoreAV* av = Core::getInstance()->getAv(); |
|
|
|
|
|
|
|
|
|
micButton->setEnabled(av->isCallActive(f)); |
|
|
|
|
|
|
|
|
|
if (micButton->isEnabled()) |
|
|
|
|
{ |
|
|
|
|
if (av->isCallInputMuted(f)) |
|
|
|
|
{ |
|
|
|
|
micButton->setObjectName("red"); |
|
|
|
|
micButton->setToolTip(tr("Unmute microphone")); |
|
|
|
|
} |
|
|
|
|
else |
|
|
|
|
{ |
|
|
|
|
micButton->setObjectName("green"); |
|
|
|
|
micButton->setToolTip(tr("Mute microphone")); |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
micButton->setStyleSheet(Style::getStylesheet(QStringLiteral(":/ui/micButton/micButton.css"))); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
void ChatForm::updateMuteVolButton() |
|
|
|
|
{ |
|
|
|
|
const CoreAV* av = Core::getInstance()->getAv(); |
|
|
|
|
|
|
|
|
|
volButton->setEnabled(av->isCallActive(f)); |
|
|
|
|
|
|
|
|
|
if (videoButton->isEnabled()) |
|
|
|
|
{ |
|
|
|
|
if (av->isCallOutputMuted(f)) |
|
|
|
|
{ |
|
|
|
|
volButton->setObjectName("red"); |
|
|
|
|
volButton->setToolTip(tr("Unmute call")); |
|
|
|
|
} |
|
|
|
|
else |
|
|
|
|
{ |
|
|
|
|
volButton->setObjectName("green"); |
|
|
|
|
volButton->setToolTip(tr("Mute call")); |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
volButton->setStyleSheet(Style::getStylesheet(QStringLiteral(":/ui/volButton/volButton.css"))); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
void ChatForm::startCounter() |
|
|
|
|
{ |
|
|
|
|
if (!callDurationTimer) |
|
|
|
|
{ |
|
|
|
|
callDurationTimer = new QTimer(); |
|
|
|
|
connect(callDurationTimer, SIGNAL(timeout()), this, SLOT(onUpdateTime())); |
|
|
|
|
connect(callDurationTimer, &QTimer::timeout, |
|
|
|
|
this, &ChatForm::onUpdateTime); |
|
|
|
|
callDurationTimer->start(1000); |
|
|
|
|
timeElapsed.start(); |
|
|
|
|
callDuration->show(); |
|
|
|
|
@ -1062,15 +1083,8 @@ void ChatForm::retranslateUi()
@@ -1062,15 +1083,8 @@ void ChatForm::retranslateUi()
|
|
|
|
|
loadHistoryAction->setText(tr("Load chat history...")); |
|
|
|
|
copyStatusAction->setText(tr("Copy")); |
|
|
|
|
|
|
|
|
|
if (volObjectName == QStringLiteral("green")) |
|
|
|
|
volButton->setToolTip(tr("Mute call")); |
|
|
|
|
else if (volObjectName == QStringLiteral("red")) |
|
|
|
|
volButton->setToolTip(tr("Unmute call")); |
|
|
|
|
|
|
|
|
|
if (micObjectName == QStringLiteral("green")) |
|
|
|
|
micButton->setToolTip(tr("Mute microphone")); |
|
|
|
|
else if (micObjectName == QStringLiteral("red")) |
|
|
|
|
micButton->setToolTip(tr("Unmute microphone")); |
|
|
|
|
updateMuteMicButton(); |
|
|
|
|
updateMuteVolButton(); |
|
|
|
|
|
|
|
|
|
if (netcam) |
|
|
|
|
netcam->setShowMessages(chatWidget->isVisible()); |
|
|
|
|
|