mirror of
https://github.com/qTox/qTox.git
synced 2024-03-22 14:00:36 +08:00
fix: Status reflection for friend calls
This commit is contained in:
parent
7b60a5dd36
commit
917812daaa
@ -175,7 +175,9 @@ bool CoreAV::anyActiveCalls() const
|
|||||||
*/
|
*/
|
||||||
bool CoreAV::isCallActive(const Friend* f) const
|
bool CoreAV::isCallActive(const Friend* f) const
|
||||||
{
|
{
|
||||||
return f && calls.contains(f->getFriendID());
|
return f && calls.contains(f->getFriendID())
|
||||||
|
? !(calls[f->getFriendID()].inactive)
|
||||||
|
: false;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -17,63 +17,65 @@
|
|||||||
along with qTox. If not, see <http://www.gnu.org/licenses/>.
|
along with qTox. If not, see <http://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <QDebug>
|
#include "chatform.h"
|
||||||
#include <QBoxLayout>
|
|
||||||
#include <QScrollBar>
|
|
||||||
#include <QFileDialog>
|
|
||||||
#include <QMessageBox>
|
|
||||||
#include <QPushButton>
|
|
||||||
#include <QMimeData>
|
|
||||||
#include <QFileInfo>
|
|
||||||
#include <QDragEnterEvent>
|
|
||||||
#include <QBitmap>
|
|
||||||
#include <QScreen>
|
|
||||||
#include <QTemporaryFile>
|
|
||||||
#include <QApplication>
|
#include <QApplication>
|
||||||
#include <QGuiApplication>
|
#include <QBitmap>
|
||||||
#include <QStyle>
|
#include <QBoxLayout>
|
||||||
#include <QSplitter>
|
|
||||||
#include <QClipboard>
|
#include <QClipboard>
|
||||||
|
#include <QDebug>
|
||||||
|
#include <QDragEnterEvent>
|
||||||
|
#include <QFileDialog>
|
||||||
|
#include <QFileInfo>
|
||||||
|
#include <QMessageBox>
|
||||||
|
#include <QMimeData>
|
||||||
|
#include <QPushButton>
|
||||||
|
#include <QScreen>
|
||||||
|
#include <QScrollBar>
|
||||||
|
#include <QSplitter>
|
||||||
|
#include <QStyle>
|
||||||
|
#include <QTemporaryFile>
|
||||||
|
|
||||||
#include <cassert>
|
#include <cassert>
|
||||||
#include "chatform.h"
|
#include "chatform.h"
|
||||||
#include "audio/audio.h"
|
|
||||||
#include "core/core.h"
|
#include"audio/audio.h"
|
||||||
#include "core/coreav.h"
|
#include"chatlog/chatlinecontentproxy.h"
|
||||||
#include "friend.h"
|
#include"chatlog/chatlog.h"
|
||||||
#include "widget/style.h"
|
#include"chatlog/chatmessage.h"
|
||||||
#include "persistence/settings.h"
|
#include"chatlog/content/filetransferwidget.h"
|
||||||
#include "core/cstring.h"
|
#include"chatlog/content/text.h"
|
||||||
#include "widget/tool/callconfirmwidget.h"
|
#include"core/core.h"
|
||||||
#include "widget/friendwidget.h"
|
#include"core/coreav.h"
|
||||||
#include "widget/form/loadhistorydialog.h"
|
#include"core/cstring.h"
|
||||||
#include "widget/tool/chattextedit.h"
|
#include"friend.h"
|
||||||
#include "widget/widget.h"
|
#include"nexus.h"
|
||||||
#include "widget/maskablepixmapwidget.h"
|
#include"nexus.h"
|
||||||
#include "widget/tool/croppinglabel.h"
|
#include"persistence/offlinemsgengine.h"
|
||||||
#include "chatlog/chatmessage.h"
|
#include"persistence/profile.h"
|
||||||
#include "chatlog/content/filetransferwidget.h"
|
#include"persistence/settings.h"
|
||||||
#include "chatlog/chatlinecontentproxy.h"
|
#include"video/camerasource.h"
|
||||||
#include "chatlog/content/text.h"
|
#include"video/netcamview.h"
|
||||||
#include "chatlog/chatlog.h"
|
#include"video/videosource.h"
|
||||||
#include "video/netcamview.h"
|
#include"widget/form/loadhistorydialog.h"
|
||||||
#include "persistence/offlinemsgengine.h"
|
#include"widget/friendwidget.h"
|
||||||
#include "widget/tool/screenshotgrabber.h"
|
#include"widget/maskablepixmapwidget.h"
|
||||||
#include "widget/tool/flyoutoverlaywidget.h"
|
#include"widget/style.h"
|
||||||
#include "widget/translator.h"
|
#include"widget/tool/callconfirmwidget.h"
|
||||||
#include "video/videosource.h"
|
#include"widget/tool/chattextedit.h"
|
||||||
#include "video/camerasource.h"
|
#include"widget/tool/croppinglabel.h"
|
||||||
#include "nexus.h"
|
#include"widget/tool/flyoutoverlaywidget.h"
|
||||||
#include "persistence/profile.h"
|
#include"widget/tool/screenshotgrabber.h"
|
||||||
|
#include"widget/translator.h"
|
||||||
|
#include"widget/widget.h"
|
||||||
|
|
||||||
const QString ChatForm::ACTION_PREFIX = QStringLiteral("/me ");
|
const QString ChatForm::ACTION_PREFIX = QStringLiteral("/me ");
|
||||||
|
|
||||||
ChatForm::ChatForm(Friend* chatFriend)
|
ChatForm::ChatForm(Friend* chatFriend)
|
||||||
: f(chatFriend)
|
: f(chatFriend)
|
||||||
|
, callDuration(new QLabel(this))
|
||||||
, isTyping(false)
|
, isTyping(false)
|
||||||
{
|
{
|
||||||
Core* core = Core::getInstance();
|
|
||||||
coreav = core->getAv();
|
|
||||||
|
|
||||||
nameLabel->setText(f->getDisplayedName());
|
nameLabel->setText(f->getDisplayedName());
|
||||||
|
|
||||||
avatar->setPixmap(QPixmap(":/img/contact_dark.svg"));
|
avatar->setPixmap(QPixmap(":/img/contact_dark.svg"));
|
||||||
@ -91,9 +93,9 @@ ChatForm::ChatForm(Friend* chatFriend)
|
|||||||
typingTimer.setSingleShot(true);
|
typingTimer.setSingleShot(true);
|
||||||
|
|
||||||
callDurationTimer = nullptr;
|
callDurationTimer = nullptr;
|
||||||
disableCallButtonsTimer = nullptr;
|
|
||||||
|
|
||||||
chatWidget->setTypingNotification(ChatMessage::createTypingNotification());
|
chatWidget->setTypingNotification(ChatMessage::createTypingNotification());
|
||||||
|
chatWidget->setMinimumHeight(50);
|
||||||
|
|
||||||
headTextLayout->addWidget(statusMessageLabel);
|
headTextLayout->addWidget(statusMessageLabel);
|
||||||
headTextLayout->addStretch();
|
headTextLayout->addStretch();
|
||||||
@ -101,44 +103,72 @@ ChatForm::ChatForm(Friend* chatFriend)
|
|||||||
headTextLayout->addWidget(callDuration, 1, Qt::AlignCenter);
|
headTextLayout->addWidget(callDuration, 1, Qt::AlignCenter);
|
||||||
callDuration->hide();
|
callDuration->hide();
|
||||||
|
|
||||||
chatWidget->setMinimumHeight(50);
|
|
||||||
connect(this, &GenericChatForm::messageInserted, this, &ChatForm::onMessageInserted);
|
|
||||||
|
|
||||||
loadHistoryAction = menu.addAction(QString(), this, SLOT(onLoadHistory()));
|
loadHistoryAction = menu.addAction(QString(), this, SLOT(onLoadHistory()));
|
||||||
copyStatusAction = statusMessageMenu.addAction(QString(), this, SLOT(onCopyStatusMessage()));
|
copyStatusAction = statusMessageMenu.addAction(QString(), this, SLOT(onCopyStatusMessage()));
|
||||||
|
|
||||||
connect(core, &Core::fileSendStarted, this, &ChatForm::startFileSend);
|
const Core* core = Core::getInstance();
|
||||||
connect(sendButton, &QPushButton::clicked, this, &ChatForm::onSendTriggered);
|
connect(core, &Core::fileReceiveRequested,
|
||||||
connect(fileButton, &QPushButton::clicked, this, &ChatForm::onAttachClicked);
|
this, &ChatForm::onFileRecvRequest);
|
||||||
connect(screenshotButton, &QPushButton::clicked, this, &ChatForm::onScreenshotClicked);
|
connect(core, &Core::friendAvatarChanged,
|
||||||
connect(callButton, &QPushButton::clicked, this, &ChatForm::onCallTriggered);
|
this, &ChatForm::onAvatarChange);
|
||||||
connect(videoButton, &QPushButton::clicked, this, &ChatForm::onVideoCallTriggered);
|
connect(core, &Core::friendAvatarRemoved,
|
||||||
connect(msgEdit, &ChatTextEdit::enterPressed, this, &ChatForm::onSendTriggered);
|
this, &ChatForm::onAvatarRemoved);
|
||||||
connect(msgEdit, &ChatTextEdit::textChanged, this, &ChatForm::onTextEditChanged);
|
connect(core, &Core::fileSendStarted,
|
||||||
connect(core, &Core::fileSendFailed, this, &ChatForm::onFileSendFailed);
|
this, &ChatForm::startFileSend);
|
||||||
connect(core, &Core::friendStatusChanged, this, &ChatForm::onFriendStatusChanged);
|
connect(core, &Core::fileSendFailed,
|
||||||
connect(this, &ChatForm::chatAreaCleared, getOfflineMsgEngine(), &OfflineMsgEngine::removeAllReceipts);
|
this, &ChatForm::onFileSendFailed);
|
||||||
connect(statusMessageLabel, &CroppingLabel::customContextMenuRequested, this, [&](const QPoint& pos)
|
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())
|
if (!statusMessageLabel->text().isEmpty())
|
||||||
{
|
{
|
||||||
QWidget* sender = static_cast<QWidget*>(this->sender());
|
QWidget* sender = static_cast<QWidget*>(this->sender());
|
||||||
|
|
||||||
statusMessageMenu.exec(sender->mapToGlobal(pos));
|
statusMessageMenu.exec(sender->mapToGlobal(pos));
|
||||||
}
|
}
|
||||||
} );
|
});
|
||||||
connect(&typingTimer, &QTimer::timeout, this, [=]{
|
|
||||||
|
connect(&typingTimer, &QTimer::timeout, this, [=] {
|
||||||
Core::getInstance()->sendTyping(f->getFriendID(), false);
|
Core::getInstance()->sendTyping(f->getFriendID(), false);
|
||||||
isTyping = false;
|
isTyping = false;
|
||||||
} );
|
});
|
||||||
connect(nameLabel, &CroppingLabel::editFinished, this, [=](const QString& newName)
|
|
||||||
{
|
connect(nameLabel, &CroppingLabel::editFinished,
|
||||||
|
this, [=](const QString& newName) {
|
||||||
nameLabel->setText(newName);
|
nameLabel->setText(newName);
|
||||||
emit aliasChanged(newName);
|
emit aliasChanged(newName);
|
||||||
} );
|
});
|
||||||
|
|
||||||
setAcceptDrops(true);
|
setAcceptDrops(true);
|
||||||
disableCallButtons();
|
|
||||||
retranslateUi();
|
retranslateUi();
|
||||||
Translator::registerHandler(std::bind(&ChatForm::retranslateUi, this), this);
|
Translator::registerHandler(std::bind(&ChatForm::retranslateUi, this), this);
|
||||||
}
|
}
|
||||||
@ -147,14 +177,13 @@ ChatForm::~ChatForm()
|
|||||||
{
|
{
|
||||||
Translator::unregister(this);
|
Translator::unregister(this);
|
||||||
delete netcam;
|
delete netcam;
|
||||||
delete callConfirm;
|
|
||||||
delete offlineEngine;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void ChatForm::setStatusMessage(QString newMessage)
|
void ChatForm::setStatusMessage(QString newMessage)
|
||||||
{
|
{
|
||||||
statusMessageLabel->setText(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()
|
void ChatForm::onSendTriggered()
|
||||||
@ -197,6 +226,7 @@ void ChatForm::onAttachClicked()
|
|||||||
if (paths.isEmpty())
|
if (paths.isEmpty())
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
Core* core = Core::getInstance();
|
||||||
for (QString path : paths)
|
for (QString path : paths)
|
||||||
{
|
{
|
||||||
QFile file(path);
|
QFile file(path);
|
||||||
@ -207,11 +237,13 @@ void ChatForm::onAttachClicked()
|
|||||||
tr("qTox wasn't able to open %1").arg(QFileInfo(path).fileName()));
|
tr("qTox wasn't able to open %1").arg(QFileInfo(path).fileName()));
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (file.isSequential())
|
if (file.isSequential())
|
||||||
{
|
{
|
||||||
QMessageBox::critical(this,
|
QMessageBox::critical(this,
|
||||||
tr("Bad idea"),
|
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();
|
file.close();
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
@ -219,7 +251,8 @@ void ChatForm::onAttachClicked()
|
|||||||
file.close();
|
file.close();
|
||||||
QFileInfo fi(path);
|
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)
|
|||||||
Widget::getInstance()->updateFriendActivity(f);
|
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;
|
return;
|
||||||
|
|
||||||
qDebug() << "onAvInvite";
|
callConfirm = new CallConfirmWidget(video ? videoButton : callButton, *f);
|
||||||
disableCallButtons();
|
|
||||||
insertChatMessage(ChatMessage::createChatInfoMessage(tr("%1 calling").arg(f->getDisplayedName()),
|
insertChatMessage(ChatMessage::createChatInfoMessage(tr("%1 calling").arg(f->getDisplayedName()),
|
||||||
ChatMessage::INFO,
|
ChatMessage::INFO,
|
||||||
QDateTime::currentDateTime()));
|
QDateTime::currentDateTime()));
|
||||||
@ -293,35 +325,25 @@ void ChatForm::onAvInvite(uint32_t FriendId, bool video)
|
|||||||
{
|
{
|
||||||
uint32_t friendId = f->getFriendID();
|
uint32_t friendId = f->getFriendID();
|
||||||
qDebug() << "automatic call answer";
|
qDebug() << "automatic call answer";
|
||||||
|
CoreAV* coreav = Core::getInstance()->getAv();
|
||||||
QMetaObject::invokeMethod(coreav, "answerCall", Qt::QueuedConnection, Q_ARG(uint32_t, friendId));
|
QMetaObject::invokeMethod(coreav, "answerCall", Qt::QueuedConnection, Q_ARG(uint32_t, friendId));
|
||||||
onAvStart(friendId,video);
|
onAvStart(friendId,video);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if (video)
|
callConfirm->show();
|
||||||
{
|
|
||||||
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);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (f->getFriendWidget()->chatFormIsSet(false))
|
connect(callConfirm.data(), &CallConfirmWidget::accepted,
|
||||||
callConfirm->show();
|
this, &ChatForm::onAnswerCallTriggered);
|
||||||
|
connect(callConfirm.data(), &CallConfirmWidget::rejected,
|
||||||
|
this, &ChatForm::onRejectCallTriggered);
|
||||||
|
|
||||||
connect(callConfirm, &CallConfirmWidget::accepted, this, &ChatForm::onAnswerCallTriggered);
|
insertChatMessage(ChatMessage::createChatInfoMessage(
|
||||||
connect(callConfirm, &CallConfirmWidget::rejected, this, &ChatForm::onRejectCallTriggered);
|
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& audio = Audio::getInstance();
|
||||||
audio.startLoop();
|
audio.startLoop();
|
||||||
audio.playMono16Sound(Audio::getSound(Audio::Sound::IncomingCall));
|
audio.playMono16Sound(Audio::getSound(Audio::Sound::IncomingCall));
|
||||||
@ -333,44 +355,12 @@ void ChatForm::onAvStart(uint32_t FriendId, bool video)
|
|||||||
if (FriendId != f->getFriendID())
|
if (FriendId != f->getFriendID())
|
||||||
return;
|
return;
|
||||||
|
|
||||||
qDebug() << "onAvStart";
|
|
||||||
|
|
||||||
audioInputFlag = true;
|
|
||||||
audioOutputFlag = true;
|
|
||||||
disableCallButtons();
|
|
||||||
|
|
||||||
if (video)
|
if (video)
|
||||||
{
|
|
||||||
videoButton->setObjectName("red");
|
|
||||||
videoButton->setToolTip(tr("End video call"));
|
|
||||||
videoButton->style()->polish(videoButton);
|
|
||||||
connect(videoButton, SIGNAL(clicked()),
|
|
||||||
this, SLOT(onHangupCallTriggered()));
|
|
||||||
|
|
||||||
showNetcam();
|
showNetcam();
|
||||||
}
|
|
||||||
else
|
else
|
||||||
{
|
|
||||||
callButton->setObjectName("red");
|
|
||||||
callButton->setToolTip(tr("End audio call"));
|
|
||||||
callButton->style()->polish(callButton);
|
|
||||||
connect(callButton, SIGNAL(clicked()),
|
|
||||||
this, SLOT(onHangupCallTriggered()));
|
|
||||||
hideNetcam();
|
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();
|
startCounter();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -379,39 +369,32 @@ void ChatForm::onAvEnd(uint32_t FriendId)
|
|||||||
if (FriendId != f->getFriendID())
|
if (FriendId != f->getFriendID())
|
||||||
return;
|
return;
|
||||||
|
|
||||||
qDebug() << "onAvEnd";
|
|
||||||
|
|
||||||
delete callConfirm;
|
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();
|
Audio::getInstance().stopLoop();
|
||||||
|
|
||||||
enableCallButtons();
|
updateCallButtons();
|
||||||
stopCounter();
|
stopCounter();
|
||||||
hideNetcam();
|
hideNetcam();
|
||||||
}
|
}
|
||||||
|
|
||||||
void ChatForm::showOutgoingCall(bool video)
|
void ChatForm::showOutgoingCall(bool video)
|
||||||
{
|
{
|
||||||
audioInputFlag = true;
|
|
||||||
audioOutputFlag = true;
|
|
||||||
|
|
||||||
disableCallButtons();
|
|
||||||
if (video)
|
if (video)
|
||||||
{
|
{
|
||||||
videoButton->setObjectName("yellow");
|
videoButton->setObjectName("yellow");
|
||||||
videoButton->style()->polish(videoButton);
|
videoButton->setStyleSheet(Style::getStylesheet(QStringLiteral(":/ui/videoButton/videoButton.css")));
|
||||||
videoButton->setToolTip(tr("Cancel video call"));
|
videoButton->setToolTip(tr("Cancel video call"));
|
||||||
connect(videoButton, &QPushButton::clicked,
|
|
||||||
this, &ChatForm::onCancelCallTriggered);
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
callButton->setObjectName("yellow");
|
callButton->setObjectName("yellow");
|
||||||
callButton->style()->polish(callButton);
|
callButton->setStyleSheet(Style::getStylesheet(QStringLiteral(":/ui/callButton/callButton.css")));
|
||||||
callButton->setToolTip(tr("Cancel audio call"));
|
callButton->setToolTip(tr("Cancel audio call"));
|
||||||
connect(callButton, &QPushButton::clicked,
|
|
||||||
this, &ChatForm::onCancelCallTriggered);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
addSystemInfoMessage(tr("Calling %1").arg(f->getDisplayedName()),
|
addSystemInfoMessage(tr("Calling %1").arg(f->getDisplayedName()),
|
||||||
@ -423,216 +406,121 @@ void ChatForm::showOutgoingCall(bool video)
|
|||||||
|
|
||||||
void ChatForm::onAnswerCallTriggered()
|
void ChatForm::onAnswerCallTriggered()
|
||||||
{
|
{
|
||||||
qDebug() << "onAnswerCallTriggered";
|
delete callConfirm;
|
||||||
|
|
||||||
if (callConfirm)
|
|
||||||
{
|
|
||||||
delete callConfirm;
|
|
||||||
callConfirm = nullptr;
|
|
||||||
}
|
|
||||||
|
|
||||||
Audio::getInstance().stopLoop();
|
Audio::getInstance().stopLoop();
|
||||||
|
|
||||||
disableCallButtons();
|
updateCallButtons();
|
||||||
|
|
||||||
if (!coreav->answerCall(f->getFriendID()))
|
CoreAV* av = Core::getInstance()->getAv();
|
||||||
|
if (!av->answerCall(f->getFriendID()))
|
||||||
{
|
{
|
||||||
enableCallButtons();
|
updateCallButtons();
|
||||||
stopCounter();
|
stopCounter();
|
||||||
hideNetcam();
|
hideNetcam();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
onAvStart(f->getFriendID(), coreav->isCallActive(f));
|
onAvStart(f->getFriendID(), av->isCallVideoEnabled(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();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void ChatForm::onRejectCallTriggered()
|
void ChatForm::onRejectCallTriggered()
|
||||||
{
|
{
|
||||||
qDebug() << "onRejectCallTriggered";
|
delete callConfirm;
|
||||||
|
|
||||||
if (callConfirm)
|
|
||||||
{
|
|
||||||
delete callConfirm;
|
|
||||||
callConfirm = nullptr;
|
|
||||||
}
|
|
||||||
|
|
||||||
Audio::getInstance().stopLoop();
|
Audio::getInstance().stopLoop();
|
||||||
|
|
||||||
audioInputFlag = false;
|
CoreAV* av = Core::getInstance()->getAv();
|
||||||
audioOutputFlag = false;
|
av->cancelCall(f->getFriendID());
|
||||||
coreav->cancelCall(f->getFriendID());
|
|
||||||
|
|
||||||
enableCallButtons();
|
|
||||||
stopCounter();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void ChatForm::onCallTriggered()
|
void ChatForm::onCallTriggered()
|
||||||
{
|
{
|
||||||
qDebug() << "onCallTriggered";
|
CoreAV* av = Core::getInstance()->getAv();
|
||||||
|
if (av->isCallActive(f))
|
||||||
disableCallButtons();
|
{
|
||||||
if (coreav->startCall(f->getFriendID(), false))
|
av->cancelCall(f->getFriendID());
|
||||||
|
}
|
||||||
|
else if (av->startCall(f->getFriendID(), false))
|
||||||
|
{
|
||||||
showOutgoingCall(false);
|
showOutgoingCall(false);
|
||||||
else
|
}
|
||||||
enableCallButtons();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void ChatForm::onVideoCallTriggered()
|
void ChatForm::onVideoCallTriggered()
|
||||||
{
|
{
|
||||||
qDebug() << "onVideoCallTriggered";
|
CoreAV* av = Core::getInstance()->getAv();
|
||||||
|
if (av->isCallActive(f))
|
||||||
disableCallButtons();
|
{
|
||||||
if (coreav->startCall(f->getFriendID(), true))
|
// 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);
|
showOutgoingCall(true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void ChatForm::updateCallButtons()
|
||||||
|
{
|
||||||
|
CoreAV* av = Core::getInstance()->getAv();
|
||||||
|
if (av->isCallActive(f))
|
||||||
|
{
|
||||||
|
callButton->setObjectName("red");
|
||||||
|
callButton->setToolTip(tr("End audio call"));
|
||||||
|
|
||||||
|
if (av->isCallVideoEnabled(f))
|
||||||
|
{
|
||||||
|
videoButton->setObjectName("red");
|
||||||
|
videoButton->setToolTip(tr("End video call"));
|
||||||
|
}
|
||||||
|
}
|
||||||
else
|
else
|
||||||
enableCallButtons();
|
|
||||||
}
|
|
||||||
|
|
||||||
void ChatForm::onCancelCallTriggered()
|
|
||||||
{
|
|
||||||
qDebug() << "onCancelCallTriggered";
|
|
||||||
|
|
||||||
if (!coreav->cancelCall(f->getFriendID()))
|
|
||||||
qWarning() << "Failed to cancel a call! Assuming we're not in call";
|
|
||||||
|
|
||||||
enableCallButtons();
|
|
||||||
stopCounter();
|
|
||||||
hideNetcam();
|
|
||||||
}
|
|
||||||
|
|
||||||
void ChatForm::enableCallButtons()
|
|
||||||
{
|
|
||||||
qDebug() << "enableCallButtons";
|
|
||||||
|
|
||||||
audioInputFlag = false;
|
|
||||||
audioOutputFlag = false;
|
|
||||||
|
|
||||||
disableCallButtons();
|
|
||||||
|
|
||||||
if (disableCallButtonsTimer == nullptr)
|
|
||||||
{
|
{
|
||||||
disableCallButtonsTimer = new QTimer();
|
const Status fs = f->getStatus();
|
||||||
connect(disableCallButtonsTimer, SIGNAL(timeout()),
|
callButton->setEnabled(fs != Status::Offline);
|
||||||
this, SLOT(onEnableCallButtons()));
|
videoButton->setEnabled(fs != Status::Offline);
|
||||||
disableCallButtonsTimer->start(1500); // 1.5sec
|
|
||||||
qDebug() << "timer started!!";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void ChatForm::disableCallButtons()
|
if (callButton->isEnabled())
|
||||||
{
|
{
|
||||||
// Prevents race enable / disable / onEnable, when it should be disabled
|
callButton->setObjectName("green");
|
||||||
if (disableCallButtonsTimer)
|
callButton->setToolTip(tr("Start audio call"));
|
||||||
{
|
}
|
||||||
disableCallButtonsTimer->stop();
|
|
||||||
delete disableCallButtonsTimer;
|
if (videoButton->isEnabled())
|
||||||
disableCallButtonsTimer = nullptr;
|
{
|
||||||
|
videoButton->setObjectName("green");
|
||||||
|
videoButton->setToolTip(tr("Start video call"));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
micButton->setObjectName("grey");
|
callButton->setStyleSheet(Style::getStylesheet(QStringLiteral(":/ui/callButton/callButton.css")));
|
||||||
micButton->style()->polish(micButton);
|
videoButton->setStyleSheet(Style::getStylesheet(QStringLiteral(":/ui/videoButton/videoButton.css")));
|
||||||
micButton->setToolTip("");
|
|
||||||
micButton->disconnect();
|
|
||||||
volButton->setObjectName("grey");
|
|
||||||
volButton->style()->polish(volButton);
|
|
||||||
volButton->setToolTip("");
|
|
||||||
volButton->disconnect();
|
|
||||||
|
|
||||||
callButton->setObjectName("grey");
|
updateMuteMicButton();
|
||||||
callButton->style()->polish(callButton);
|
updateMuteVolButton();
|
||||||
callButton->setToolTip("");
|
|
||||||
callButton->disconnect();
|
|
||||||
videoButton->setObjectName("grey");
|
|
||||||
videoButton->style()->polish(videoButton);
|
|
||||||
videoButton->setToolTip("");
|
|
||||||
videoButton->disconnect();
|
|
||||||
}
|
|
||||||
|
|
||||||
void ChatForm::onEnableCallButtons()
|
|
||||||
{
|
|
||||||
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)
|
|
||||||
{
|
|
||||||
disableCallButtonsTimer->stop();
|
|
||||||
delete disableCallButtonsTimer;
|
|
||||||
disableCallButtonsTimer = nullptr;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void ChatForm::onMicMuteToggle()
|
void ChatForm::onMicMuteToggle()
|
||||||
{
|
{
|
||||||
if (audioInputFlag)
|
CoreAV* av = Core::getInstance()->getAv();
|
||||||
{
|
|
||||||
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);
|
av->toggleMuteCallInput(f);
|
||||||
}
|
updateMuteMicButton();
|
||||||
}
|
}
|
||||||
|
|
||||||
void ChatForm::onVolMuteToggle()
|
void ChatForm::onVolMuteToggle()
|
||||||
{
|
{
|
||||||
if (audioOutputFlag)
|
CoreAV* av = Core::getInstance()->getAv();
|
||||||
{
|
|
||||||
coreav->toggleMuteCallOutput(f);
|
|
||||||
if (volButton->objectName() == "red")
|
|
||||||
{
|
|
||||||
volButton->setObjectName("green");
|
|
||||||
volButton->setToolTip(tr("Mute call"));
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
volButton->setObjectName("red");
|
|
||||||
volButton->setToolTip(tr("Unmute call"));
|
|
||||||
}
|
|
||||||
|
|
||||||
Style::repolish(volButton);
|
av->toggleMuteCallOutput(f);
|
||||||
}
|
updateMuteVolButton();
|
||||||
}
|
}
|
||||||
|
|
||||||
void ChatForm::onFileSendFailed(uint32_t FriendId, const QString &fname)
|
void ChatForm::onFileSendFailed(uint32_t friendId, const QString &fname)
|
||||||
{
|
{
|
||||||
if (FriendId != f->getFriendID())
|
if (friendId != f->getFriendID())
|
||||||
return;
|
return;
|
||||||
|
|
||||||
addSystemInfoMessage(tr("Failed to send file \"%1\"").arg(fname), ChatMessage::ERROR, QDateTime::currentDateTime());
|
addSystemInfoMessage(tr("Failed to send file \"%1\"").arg(fname), ChatMessage::ERROR, QDateTime::currentDateTime());
|
||||||
@ -644,19 +532,76 @@ void ChatForm::onFriendStatusChanged(uint32_t friendId, Status status)
|
|||||||
if(friendId != f->getFriendID())
|
if(friendId != f->getFriendID())
|
||||||
return;
|
return;
|
||||||
|
|
||||||
Status old = oldStatus.value(friendId, Status::Offline);
|
if (status == Status::Offline)
|
||||||
|
{
|
||||||
|
// Hide the "is typing" message when a friend goes offline
|
||||||
|
setFriendTyping(false);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
QTimer::singleShot(250, this, SLOT(onDeliverOfflineMessages()));
|
||||||
|
}
|
||||||
|
|
||||||
if (old != Status::Offline && status == Status::Offline)
|
updateCallButtons();
|
||||||
disableCallButtons();
|
|
||||||
else if (old == Status::Offline && status != Status::Offline)
|
|
||||||
enableCallButtons();
|
|
||||||
|
|
||||||
oldStatus[friendId] = status;
|
if (Settings::getInstance().getStatusChangeNotificationEnabled())
|
||||||
|
{
|
||||||
|
QString fStatus = "";
|
||||||
|
switch (status)
|
||||||
|
{
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
|
||||||
|
addSystemInfoMessage(tr("%1 is now %2", "e.g. \"Dubslow is now online\"")
|
||||||
|
.arg(f->getDisplayedName()).arg(fStatus),
|
||||||
|
ChatMessage::INFO, QDateTime::currentDateTime());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void ChatForm::onAvatarChange(uint32_t FriendId, const QPixmap &pic)
|
void ChatForm::onFriendTypingChanged(quint32 friendId, bool isTyping)
|
||||||
{
|
{
|
||||||
if (FriendId != f->getFriendID())
|
if (friendId == f->getFriendID())
|
||||||
|
setFriendTyping(isTyping);
|
||||||
|
}
|
||||||
|
|
||||||
|
void ChatForm::onFriendNameChanged(const QString& name)
|
||||||
|
{
|
||||||
|
if (sender() == f)
|
||||||
|
setName(name);
|
||||||
|
}
|
||||||
|
|
||||||
|
void ChatForm::onFriendMessageReceived(quint32 friendId, const QString& message,
|
||||||
|
bool isAction)
|
||||||
|
{
|
||||||
|
if (friendId != f->getFriendID())
|
||||||
|
return;
|
||||||
|
|
||||||
|
QDateTime timestamp = QDateTime::currentDateTime();
|
||||||
|
addMessage(f->getToxId(), message, isAction, timestamp, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
void ChatForm::onStatusMessage(const QString& message)
|
||||||
|
{
|
||||||
|
if (sender() == f)
|
||||||
|
setStatusMessage(message);
|
||||||
|
}
|
||||||
|
|
||||||
|
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)
|
||||||
|
{
|
||||||
|
if (friendId != f->getFriendID())
|
||||||
return;
|
return;
|
||||||
|
|
||||||
avatar->setPixmap(pic);
|
avatar->setPixmap(pic);
|
||||||
@ -680,6 +625,7 @@ void ChatForm::dropEvent(QDropEvent *ev)
|
|||||||
{
|
{
|
||||||
if (ev->mimeData()->hasUrls())
|
if (ev->mimeData()->hasUrls())
|
||||||
{
|
{
|
||||||
|
Core* core = Core::getInstance();
|
||||||
for (QUrl url : ev->mimeData()->urls())
|
for (QUrl url : ev->mimeData()->urls())
|
||||||
{
|
{
|
||||||
QFileInfo info(url.path());
|
QFileInfo info(url.path());
|
||||||
@ -690,26 +636,34 @@ void ChatForm::dropEvent(QDropEvent *ev)
|
|||||||
SendMessageStr(url.toString());
|
SendMessageStr(url.toString());
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!file.exists() || !file.open(QIODevice::ReadOnly))
|
if (!file.exists() || !file.open(QIODevice::ReadOnly))
|
||||||
{
|
{
|
||||||
info.setFile(url.toLocalFile());
|
info.setFile(url.toLocalFile());
|
||||||
file.setFileName(info.absoluteFilePath());
|
file.setFileName(info.absoluteFilePath());
|
||||||
if (!file.exists() || !file.open(QIODevice::ReadOnly))
|
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;
|
continue;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (file.isSequential())
|
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();
|
file.close();
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
file.close();
|
file.close();
|
||||||
|
|
||||||
if (info.exists())
|
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)
|
|||||||
avatar->setPixmap(QPixmap(":/img/contact_dark.svg"));
|
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)
|
// TODO: Split on smaller methods (style)
|
||||||
void ChatForm::loadHistory(QDateTime since, bool processUndelivered)
|
void ChatForm::loadHistory(QDateTime since, bool processUndelivered)
|
||||||
{
|
{
|
||||||
@ -870,7 +841,8 @@ void ChatForm::onScreenshotTaken(const QPixmap &pixmap) {
|
|||||||
file.close();
|
file.close();
|
||||||
QFileInfo fi(file);
|
QFileInfo fi(file);
|
||||||
|
|
||||||
emit sendFile(f->getFriendID(), fi.fileName(), fi.filePath(), filesize);
|
Core::getInstance()->sendFile(f->getFriendID(), fi.fileName(),
|
||||||
|
fi.filePath(), filesize);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@ -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)
|
if (netcam && bodySplitter->sizes()[1] == 0)
|
||||||
netcam->setShowMessages(true, true);
|
netcam->setShowMessages(true, true);
|
||||||
}
|
}
|
||||||
@ -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()
|
void ChatForm::startCounter()
|
||||||
{
|
{
|
||||||
if (!callDurationTimer)
|
if (!callDurationTimer)
|
||||||
{
|
{
|
||||||
callDurationTimer = new QTimer();
|
callDurationTimer = new QTimer();
|
||||||
connect(callDurationTimer, SIGNAL(timeout()), this, SLOT(onUpdateTime()));
|
connect(callDurationTimer, &QTimer::timeout,
|
||||||
|
this, &ChatForm::onUpdateTime);
|
||||||
callDurationTimer->start(1000);
|
callDurationTimer->start(1000);
|
||||||
timeElapsed.start();
|
timeElapsed.start();
|
||||||
callDuration->show();
|
callDuration->show();
|
||||||
@ -1062,15 +1083,8 @@ void ChatForm::retranslateUi()
|
|||||||
loadHistoryAction->setText(tr("Load chat history..."));
|
loadHistoryAction->setText(tr("Load chat history..."));
|
||||||
copyStatusAction->setText(tr("Copy"));
|
copyStatusAction->setText(tr("Copy"));
|
||||||
|
|
||||||
if (volObjectName == QStringLiteral("green"))
|
updateMuteMicButton();
|
||||||
volButton->setToolTip(tr("Mute call"));
|
updateMuteVolButton();
|
||||||
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"));
|
|
||||||
|
|
||||||
if (netcam)
|
if (netcam)
|
||||||
netcam->setShowMessages(chatWidget->isVisible());
|
netcam->setShowMessages(chatWidget->isVisible());
|
||||||
|
@ -56,77 +56,81 @@ public:
|
|||||||
static const QString ACTION_PREFIX;
|
static const QString ACTION_PREFIX;
|
||||||
|
|
||||||
signals:
|
signals:
|
||||||
void sendFile(uint32_t friendId, QString, QString, long long);
|
|
||||||
void aliasChanged(const QString& alias);
|
void aliasChanged(const QString& alias);
|
||||||
|
|
||||||
public slots:
|
public slots:
|
||||||
void startFileSend(ToxFile file);
|
void startFileSend(ToxFile file);
|
||||||
void onFileRecvRequest(ToxFile file);
|
void onFileRecvRequest(ToxFile file);
|
||||||
void onAvInvite(uint32_t FriendId, bool video);
|
void onAvInvite(uint32_t friendId, bool video);
|
||||||
void onAvStart(uint32_t FriendId, bool video);
|
void onAvStart(uint32_t friendId, bool video);
|
||||||
void onAvEnd(uint32_t FriendId);
|
void onAvEnd(uint32_t friendId);
|
||||||
void onAvatarChange(uint32_t FriendId, const QPixmap& pic);
|
void onAvatarChange(uint32_t friendId, const QPixmap& pic);
|
||||||
void onAvatarRemoved(uint32_t FriendId);
|
void onAvatarRemoved(uint32_t friendId);
|
||||||
|
|
||||||
private slots:
|
private slots:
|
||||||
|
void clearChatArea(bool notInForm) override final;
|
||||||
|
|
||||||
|
void onDeliverOfflineMessages();
|
||||||
|
void onLoadChatHistory();
|
||||||
void onSendTriggered();
|
void onSendTriggered();
|
||||||
void onTextEditChanged();
|
void onTextEditChanged();
|
||||||
void onAttachClicked();
|
void onAttachClicked();
|
||||||
void onCallTriggered();
|
void onCallTriggered();
|
||||||
void onVideoCallTriggered();
|
void onVideoCallTriggered();
|
||||||
void onAnswerCallTriggered();
|
void onAnswerCallTriggered();
|
||||||
void onHangupCallTriggered();
|
|
||||||
void onCancelCallTriggered();
|
|
||||||
void onRejectCallTriggered();
|
void onRejectCallTriggered();
|
||||||
void onMicMuteToggle();
|
void onMicMuteToggle();
|
||||||
void onVolMuteToggle();
|
void onVolMuteToggle();
|
||||||
void onFileSendFailed(uint32_t FriendId, const QString &fname);
|
|
||||||
void onFriendStatusChanged(uint32_t friendId, Status status);
|
void onFileSendFailed(uint32_t friendId, const QString &fname);
|
||||||
|
void onFriendStatusChanged(quint32 friendId, Status status);
|
||||||
|
void onFriendTypingChanged(quint32 friendId, bool isTyping);
|
||||||
|
void onFriendNameChanged(const QString& name);
|
||||||
|
void onFriendMessageReceived(quint32 friendId, const QString& message,
|
||||||
|
bool isAction);
|
||||||
|
void onStatusMessage(const QString& message);
|
||||||
|
void onReceiptReceived(quint32 friendId, int receipt);
|
||||||
void onLoadHistory();
|
void onLoadHistory();
|
||||||
void onUpdateTime();
|
void onUpdateTime();
|
||||||
void onEnableCallButtons();
|
|
||||||
void onScreenshotClicked();
|
void onScreenshotClicked();
|
||||||
void onScreenshotTaken(const QPixmap &pixmap);
|
void onScreenshotTaken(const QPixmap &pixmap);
|
||||||
void doScreenshot();
|
void doScreenshot();
|
||||||
void onMessageInserted();
|
|
||||||
void onCopyStatusMessage();
|
void onCopyStatusMessage();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
void updateMuteMicButton();
|
||||||
|
void updateMuteVolButton();
|
||||||
void retranslateUi();
|
void retranslateUi();
|
||||||
void showOutgoingCall(bool video);
|
void showOutgoingCall(bool video);
|
||||||
void startCounter();
|
void startCounter();
|
||||||
void stopCounter();
|
void stopCounter();
|
||||||
QString secondsToDHMS(quint32 duration);
|
QString secondsToDHMS(quint32 duration);
|
||||||
void enableCallButtons();
|
void updateCallButtons();
|
||||||
void disableCallButtons();
|
|
||||||
void SendMessageStr(QString msg);
|
void SendMessageStr(QString msg);
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
virtual GenericNetCamView* createNetcam() final override;
|
GenericNetCamView* createNetcam() final override;
|
||||||
// drag & drop
|
void insertChatMessage(ChatMessage::Ptr msg) final override;
|
||||||
virtual void dragEnterEvent(QDragEnterEvent* ev) final override;
|
void dragEnterEvent(QDragEnterEvent* ev) final override;
|
||||||
virtual void dropEvent(QDropEvent* ev) final override;
|
void dropEvent(QDropEvent* ev) final override;
|
||||||
virtual void hideEvent(QHideEvent* event) final override;
|
void hideEvent(QHideEvent* event) final override;
|
||||||
virtual void showEvent(QShowEvent* event) final override;
|
void showEvent(QShowEvent* event) final override;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
CoreAV* coreav;
|
|
||||||
Friend* f;
|
Friend* f;
|
||||||
CroppingLabel *statusMessageLabel;
|
CroppingLabel *statusMessageLabel;
|
||||||
QMenu statusMessageMenu;
|
QMenu statusMessageMenu;
|
||||||
QLabel *callDuration;
|
QLabel *callDuration;
|
||||||
QTimer *callDurationTimer;
|
QTimer *callDurationTimer;
|
||||||
QTimer typingTimer;
|
QTimer typingTimer;
|
||||||
QTimer *disableCallButtonsTimer;
|
|
||||||
QElapsedTimer timeElapsed;
|
QElapsedTimer timeElapsed;
|
||||||
OfflineMsgEngine *offlineEngine;
|
OfflineMsgEngine *offlineEngine;
|
||||||
QAction* loadHistoryAction;
|
QAction* loadHistoryAction;
|
||||||
QAction* copyStatusAction;
|
QAction* copyStatusAction;
|
||||||
|
|
||||||
QHash<uint, FileTransferInstance*> ftransWidgets;
|
QHash<uint, FileTransferInstance*> ftransWidgets;
|
||||||
QMap<uint32_t, Status> oldStatus;
|
QPointer<CallConfirmWidget> callConfirm;
|
||||||
CallConfirmWidget *callConfirm;
|
|
||||||
bool isTyping;
|
bool isTyping;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -87,7 +87,7 @@ protected slots:
|
|||||||
void onEmoteInsertRequested(QString str);
|
void onEmoteInsertRequested(QString str);
|
||||||
void onSaveLogClicked();
|
void onSaveLogClicked();
|
||||||
void onCopyLogClicked();
|
void onCopyLogClicked();
|
||||||
void clearChatArea(bool);
|
virtual void clearChatArea(bool);
|
||||||
void clearChatArea();
|
void clearChatArea();
|
||||||
void onSelectAllClicked();
|
void onSelectAllClicked();
|
||||||
void showFileMenu();
|
void showFileMenu();
|
||||||
@ -104,7 +104,7 @@ protected:
|
|||||||
void hideNetcam();
|
void hideNetcam();
|
||||||
virtual GenericNetCamView* createNetcam() = 0;
|
virtual GenericNetCamView* createNetcam() = 0;
|
||||||
QString resolveToxId(const ToxId &id);
|
QString resolveToxId(const ToxId &id);
|
||||||
void insertChatMessage(ChatMessage::Ptr msg);
|
virtual void insertChatMessage(ChatMessage::Ptr msg);
|
||||||
void adjustFileMenuPosition();
|
void adjustFileMenuPosition();
|
||||||
virtual void hideEvent(QHideEvent* event) override;
|
virtual void hideEvent(QHideEvent* event) override;
|
||||||
virtual void showEvent(QShowEvent *) override;
|
virtual void showEvent(QShowEvent *) override;
|
||||||
|
@ -47,7 +47,10 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
GroupChatForm::GroupChatForm(Group* chatGroup)
|
GroupChatForm::GroupChatForm(Group* chatGroup)
|
||||||
: group(chatGroup), inCall{false}
|
: audioInputFlag(false)
|
||||||
|
, audioOutputFlag(false)
|
||||||
|
, group(chatGroup)
|
||||||
|
, inCall(false)
|
||||||
{
|
{
|
||||||
nusersLabel = new QLabel();
|
nusersLabel = new QLabel();
|
||||||
|
|
||||||
@ -301,15 +304,16 @@ void GroupChatForm::onMicMuteToggle()
|
|||||||
{
|
{
|
||||||
if (audioInputFlag)
|
if (audioInputFlag)
|
||||||
{
|
{
|
||||||
|
CoreAV* av = Core::getInstance()->getAv();
|
||||||
if (micButton->objectName() == "red")
|
if (micButton->objectName() == "red")
|
||||||
{
|
{
|
||||||
Core::getInstance()->getAv()->muteCallInput(group, false);
|
av->muteCallInput(group, false);
|
||||||
micButton->setObjectName("green");
|
micButton->setObjectName("green");
|
||||||
micButton->setToolTip(tr("Mute microphone"));
|
micButton->setToolTip(tr("Mute microphone"));
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
Core::getInstance()->getAv()->muteCallInput(group, true);
|
av->muteCallInput(group, true);
|
||||||
micButton->setObjectName("red");
|
micButton->setObjectName("red");
|
||||||
micButton->setToolTip(tr("Unmute microphone"));
|
micButton->setToolTip(tr("Unmute microphone"));
|
||||||
}
|
}
|
||||||
@ -322,15 +326,16 @@ void GroupChatForm::onVolMuteToggle()
|
|||||||
{
|
{
|
||||||
if (audioOutputFlag)
|
if (audioOutputFlag)
|
||||||
{
|
{
|
||||||
|
CoreAV* av = Core::getInstance()->getAv();
|
||||||
if (volButton->objectName() == "red")
|
if (volButton->objectName() == "red")
|
||||||
{
|
{
|
||||||
Core::getInstance()->getAv()->muteCallOutput(group, false);
|
av->muteCallOutput(group, false);
|
||||||
volButton->setObjectName("green");
|
volButton->setObjectName("green");
|
||||||
volButton->setToolTip(tr("Mute call"));
|
volButton->setToolTip(tr("Mute call"));
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
Core::getInstance()->getAv()->muteCallOutput(group, true);
|
av->muteCallOutput(group, true);
|
||||||
volButton->setObjectName("red");
|
volButton->setObjectName("red");
|
||||||
volButton->setToolTip(tr("Unmute call"));
|
volButton->setToolTip(tr("Unmute call"));
|
||||||
}
|
}
|
||||||
@ -396,9 +401,10 @@ void GroupChatForm::keyPressEvent(QKeyEvent* ev)
|
|||||||
// Push to talk (CTRL+P)
|
// Push to talk (CTRL+P)
|
||||||
if (ev->key() == Qt::Key_P && (ev->modifiers() & Qt::ControlModifier) && inCall)
|
if (ev->key() == Qt::Key_P && (ev->modifiers() & Qt::ControlModifier) && inCall)
|
||||||
{
|
{
|
||||||
if (Core::getInstance()->getAv()->isGroupCallInputMuted(group))
|
CoreAV* av = Core::getInstance()->getAv();
|
||||||
|
if (!av->isGroupCallInputMuted(group))
|
||||||
{
|
{
|
||||||
Core::getInstance()->getAv()->muteCallInput(group, false);
|
av->muteCallInput(group, false);
|
||||||
micButton->setObjectName("green");
|
micButton->setObjectName("green");
|
||||||
micButton->style()->polish(micButton);
|
micButton->style()->polish(micButton);
|
||||||
Style::repolish(micButton);
|
Style::repolish(micButton);
|
||||||
@ -414,9 +420,10 @@ void GroupChatForm::keyReleaseEvent(QKeyEvent* ev)
|
|||||||
// Push to talk (CTRL+P)
|
// Push to talk (CTRL+P)
|
||||||
if (ev->key() == Qt::Key_P && (ev->modifiers() & Qt::ControlModifier) && inCall)
|
if (ev->key() == Qt::Key_P && (ev->modifiers() & Qt::ControlModifier) && inCall)
|
||||||
{
|
{
|
||||||
if (!Core::getInstance()->getAv()->isGroupCallInputMuted(group))
|
CoreAV* av = Core::getInstance()->getAv();
|
||||||
|
if (av->isGroupCallInputMuted(group))
|
||||||
{
|
{
|
||||||
Core::getInstance()->getAv()->muteCallInput(group, true);
|
av->muteCallInput(group, true);
|
||||||
micButton->setObjectName("red");
|
micButton->setObjectName("red");
|
||||||
micButton->style()->polish(micButton);
|
micButton->style()->polish(micButton);
|
||||||
Style::repolish(micButton);
|
Style::repolish(micButton);
|
||||||
|
@ -60,6 +60,10 @@ private:
|
|||||||
void retranslateUi();
|
void retranslateUi();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
// TODO: flags are deprecated -> remove
|
||||||
|
bool audioInputFlag;
|
||||||
|
bool audioOutputFlag;
|
||||||
|
|
||||||
Group* group;
|
Group* group;
|
||||||
QList<QLabel*> peerLabels;
|
QList<QLabel*> peerLabels;
|
||||||
QMap<int, QTimer*> peerAudioTimers;
|
QMap<int, QTimer*> peerAudioTimers;
|
||||||
|
@ -59,6 +59,7 @@ CallConfirmWidget::CallConfirmWidget(const QWidget *Anchor, const Friend& f) :
|
|||||||
rectRatio(static_cast<qreal>(rectH)/static_cast<qreal>(rectW))
|
rectRatio(static_cast<qreal>(rectH)/static_cast<qreal>(rectW))
|
||||||
{
|
{
|
||||||
setWindowFlags(Qt::SubWindow);
|
setWindowFlags(Qt::SubWindow);
|
||||||
|
setAttribute(Qt::WA_DeleteOnClose);
|
||||||
|
|
||||||
QPalette palette;
|
QPalette palette;
|
||||||
palette.setColor(QPalette::WindowText, Qt::white);
|
palette.setColor(QPalette::WindowText, Qt::white);
|
||||||
|
@ -44,10 +44,10 @@ public slots:
|
|||||||
void reposition();
|
void reposition();
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
virtual void paintEvent(QPaintEvent* event) final override;
|
void paintEvent(QPaintEvent* event) final;
|
||||||
virtual void showEvent(QShowEvent* event) final override;
|
void showEvent(QShowEvent* event) final;
|
||||||
virtual void hideEvent(QHideEvent* event) final override;
|
void hideEvent(QHideEvent* event) final;
|
||||||
virtual bool eventFilter(QObject *, QEvent* event) final override;
|
bool eventFilter(QObject *, QEvent* event) final;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
const QWidget* anchor;
|
const QWidget* anchor;
|
||||||
|
@ -76,7 +76,7 @@ void CroppingLabel::setEditable(bool editable)
|
|||||||
unsetCursor();
|
unsetCursor();
|
||||||
}
|
}
|
||||||
|
|
||||||
void CroppingLabel::setEdlideMode(Qt::TextElideMode elide)
|
void CroppingLabel::setElideMode(Qt::TextElideMode elide)
|
||||||
{
|
{
|
||||||
elideMode = elide;
|
elideMode = elide;
|
||||||
}
|
}
|
||||||
|
@ -32,7 +32,7 @@ public:
|
|||||||
|
|
||||||
void editBegin();
|
void editBegin();
|
||||||
void setEditable(bool editable);
|
void setEditable(bool editable);
|
||||||
void setEdlideMode(Qt::TextElideMode elide);
|
void setElideMode(Qt::TextElideMode elide);
|
||||||
|
|
||||||
void setText(const QString& text);
|
void setText(const QString& text);
|
||||||
QString fullText();
|
QString fullText();
|
||||||
|
@ -955,26 +955,11 @@ void Widget::addFriend(int friendId, const QString &userId)
|
|||||||
|
|
||||||
contactListWidget->addFriendWidget(widget, Status::Offline, s.getFriendCircleID(userToxId));
|
contactListWidget->addFriendWidget(widget, Status::Offline, s.getFriendCircleID(userToxId));
|
||||||
|
|
||||||
Core* core = Nexus::getCore();
|
|
||||||
CoreAV* coreav = core->getAv();
|
|
||||||
connect(&s, &Settings::compactLayoutChanged, widget, &GenericChatroomWidget::compactChange);
|
|
||||||
connect(newfriend, &Friend::displayedNameChanged, this, &Widget::onFriendDisplayChanged);
|
connect(newfriend, &Friend::displayedNameChanged, this, &Widget::onFriendDisplayChanged);
|
||||||
connect(widget, SIGNAL(chatroomWidgetClicked(GenericChatroomWidget*, bool)), this, SLOT(onChatroomWidgetClicked(GenericChatroomWidget*, bool)));
|
connect(widget, &FriendWidget::chatroomWidgetClicked, this, &Widget::onChatroomWidgetClicked);
|
||||||
|
connect(widget, &FriendWidget::chatroomWidgetClicked, friendForm, &ChatForm::focusInput);
|
||||||
|
connect(widget, &FriendWidget::copyFriendIdToClipboard, this, &Widget::copyFriendIdToClipboard);
|
||||||
connect(widget, SIGNAL(removeFriend(int)), this, SLOT(removeFriend(int)));
|
connect(widget, SIGNAL(removeFriend(int)), this, SLOT(removeFriend(int)));
|
||||||
connect(widget, SIGNAL(copyFriendIdToClipboard(int)), this, SLOT(copyFriendIdToClipboard(int)));
|
|
||||||
connect(widget, SIGNAL(chatroomWidgetClicked(GenericChatroomWidget*)), friendForm, SLOT(focusInput()));
|
|
||||||
connect(friendForm, &GenericChatForm::sendMessage, core, &Core::sendMessage);
|
|
||||||
connect(friendForm, &GenericChatForm::sendAction, core, &Core::sendAction);
|
|
||||||
connect(friendForm, &ChatForm::sendFile, core, &Core::sendFile);
|
|
||||||
connect(friendForm, &ChatForm::aliasChanged, widget, &FriendWidget::setAlias);
|
|
||||||
connect(core, &Core::fileReceiveRequested, friendForm, &ChatForm::onFileRecvRequest);
|
|
||||||
connect(coreav, &CoreAV::avInvite, friendForm, &ChatForm::onAvInvite, Qt::BlockingQueuedConnection);
|
|
||||||
connect(coreav, &CoreAV::avStart, friendForm, &ChatForm::onAvStart, Qt::BlockingQueuedConnection);
|
|
||||||
connect(coreav, &CoreAV::avEnd, friendForm, &ChatForm::onAvEnd, Qt::BlockingQueuedConnection);
|
|
||||||
connect(core, &Core::friendAvatarChanged, friendForm, &ChatForm::onAvatarChange);
|
|
||||||
connect(core, &Core::friendAvatarRemoved, friendForm, &ChatForm::onAvatarRemoved);
|
|
||||||
connect(core, &Core::friendAvatarChanged, widget, &FriendWidget::onAvatarChange);
|
|
||||||
connect(core, &Core::friendAvatarRemoved, widget, &FriendWidget::onAvatarRemoved);
|
|
||||||
|
|
||||||
// Try to get the avatar from the cache
|
// Try to get the avatar from the cache
|
||||||
QPixmap avatar = Nexus::getProfile()->loadAvatar(userId);
|
QPixmap avatar = Nexus::getProfile()->loadAvatar(userId);
|
||||||
@ -1155,8 +1140,6 @@ void Widget::onFriendMessageReceived(int friendId, const QString& message, bool
|
|||||||
return;
|
return;
|
||||||
|
|
||||||
QDateTime timestamp = QDateTime::currentDateTime();
|
QDateTime timestamp = QDateTime::currentDateTime();
|
||||||
f->getChatForm()->addMessage(f->getToxId(), message, isAction, timestamp, true);
|
|
||||||
|
|
||||||
Profile* profile = Nexus::getProfile();
|
Profile* profile = Nexus::getProfile();
|
||||||
if (profile->isHistoryEnabled())
|
if (profile->isHistoryEnabled())
|
||||||
profile->getHistory()->addNewMessage(f->getToxId().publicKey, isAction ? ChatForm::ACTION_PREFIX + f->getDisplayedName() + " " + message : message,
|
profile->getHistory()->addNewMessage(f->getToxId().publicKey, isAction ? ChatForm::ACTION_PREFIX + f->getDisplayedName() + " " + message : message,
|
||||||
|
@ -1,83 +1,63 @@
|
|||||||
QPushButton#green
|
QAbstractButton
|
||||||
{
|
{
|
||||||
background-color: #6bc260;
|
border-radius: 5px;
|
||||||
|
border: none;
|
||||||
background-image: url(":/ui/callButton/callButton.svg");
|
background-image: url(":/ui/callButton/callButton.svg");
|
||||||
background-repeat: none;
|
background-repeat: none;
|
||||||
background-position: center;
|
background-position: center;
|
||||||
border: none;
|
|
||||||
border-radius: 5px;
|
|
||||||
width: 50px;
|
|
||||||
height: 40px;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
QPushButton#green:hover
|
QAbstractButton:disabled
|
||||||
{
|
|
||||||
background-color: #79c76f;
|
|
||||||
}
|
|
||||||
|
|
||||||
QPushButton#green:pressed
|
|
||||||
{
|
|
||||||
background-color: #51b244;
|
|
||||||
}
|
|
||||||
|
|
||||||
QPushButton#red
|
|
||||||
{
|
|
||||||
background-color: #c84e4e;
|
|
||||||
background-image: url(":/ui/callButton/callButton.svg");
|
|
||||||
background-repeat: none;
|
|
||||||
background-position: center;
|
|
||||||
border: none;
|
|
||||||
border-radius: 5px;
|
|
||||||
width: 50px;
|
|
||||||
height: 40px;
|
|
||||||
}
|
|
||||||
|
|
||||||
QPushButton#red:hover
|
|
||||||
{
|
|
||||||
background-color: #e87474;
|
|
||||||
}
|
|
||||||
|
|
||||||
QPushButton#red:pressed
|
|
||||||
{
|
|
||||||
background-color: #df3b3b;
|
|
||||||
}
|
|
||||||
|
|
||||||
QPushButton#yellow
|
|
||||||
{
|
|
||||||
background-color: #e6e465;
|
|
||||||
background-image: url(":/ui/callButton/callButton.svg");
|
|
||||||
background-repeat: none;
|
|
||||||
background-position: center;
|
|
||||||
border: none;
|
|
||||||
border-radius: 5px;
|
|
||||||
width: 50px;
|
|
||||||
height: 40px;
|
|
||||||
}
|
|
||||||
|
|
||||||
QPushButton#yellow:hover
|
|
||||||
{
|
|
||||||
background-color: #e8e774;
|
|
||||||
}
|
|
||||||
|
|
||||||
QPushButton#yellow:pressed
|
|
||||||
{
|
|
||||||
background-color: #e3e155;
|
|
||||||
}
|
|
||||||
|
|
||||||
QPushButton#grey
|
|
||||||
{
|
{
|
||||||
background-color: #919191;
|
background-color: #919191;
|
||||||
background-image: url(":/ui/callButton/callButton.svg");
|
|
||||||
background-repeat: none;
|
|
||||||
background-position: center;
|
|
||||||
border: none;
|
|
||||||
border-radius: 5px;
|
|
||||||
width: 50px;
|
|
||||||
height: 40px;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
QPushButton:focus
|
QAbstractButton:focus
|
||||||
{
|
{
|
||||||
outline: none;
|
outline: none;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
QAbstractButton#green
|
||||||
|
{
|
||||||
|
background-color: #6bc260;
|
||||||
|
}
|
||||||
|
|
||||||
|
QAbstractButton#green:hover
|
||||||
|
{
|
||||||
|
background-color: #79c76f;
|
||||||
|
}
|
||||||
|
|
||||||
|
QAbstractButton#green:pressed
|
||||||
|
{
|
||||||
|
background-color: #51b244;
|
||||||
|
}
|
||||||
|
|
||||||
|
QAbstractButton#red
|
||||||
|
{
|
||||||
|
background-color: #c84e4e;
|
||||||
|
}
|
||||||
|
|
||||||
|
QAbstractButton#red:hover
|
||||||
|
{
|
||||||
|
background-color: #e87474;
|
||||||
|
}
|
||||||
|
|
||||||
|
QAbstractButton#red:pressed
|
||||||
|
{
|
||||||
|
background-color: #df3b3b;
|
||||||
|
}
|
||||||
|
|
||||||
|
QAbstractButton#yellow
|
||||||
|
{
|
||||||
|
background-color: #e6e465;
|
||||||
|
}
|
||||||
|
|
||||||
|
QAbstractButton#yellow:hover
|
||||||
|
{
|
||||||
|
background-color: #e8e774;
|
||||||
|
}
|
||||||
|
|
||||||
|
QAbstractButton#yellow:pressed
|
||||||
|
{
|
||||||
|
background-color: #e3e155;
|
||||||
|
}
|
||||||
|
@ -1,38 +1,27 @@
|
|||||||
QPushButton#green
|
QAbstractButton
|
||||||
{
|
{
|
||||||
background-color: transparent;
|
background-color: transparent;
|
||||||
background-image: url(":/ui/micButton/micButton.png");
|
background-image: url(":/ui/micButton/micButton.png");
|
||||||
background-repeat: none;
|
background-repeat: none;
|
||||||
border: none;
|
border: none;
|
||||||
width: 22px;
|
|
||||||
height: 18px;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
QPushButton#green:hover
|
QAbstractButton:disabled
|
||||||
{
|
{
|
||||||
background-image:url(":/ui/micButton/micButtonHover.png");
|
|
||||||
}
|
|
||||||
|
|
||||||
QPushButton#red
|
|
||||||
{
|
|
||||||
background-color: transparent;
|
|
||||||
background-image: url(":/ui/micButton/micButtonPressed.png");
|
|
||||||
background-repeat: none;
|
|
||||||
border: none;
|
|
||||||
width: 22px;
|
|
||||||
height: 18px;
|
|
||||||
}
|
|
||||||
|
|
||||||
QPushButton#grey
|
|
||||||
{
|
|
||||||
background-color: transparent;
|
|
||||||
background-image: url(":/ui/micButton/micButtonDisabled.png");
|
background-image: url(":/ui/micButton/micButtonDisabled.png");
|
||||||
background-repeat: none;
|
|
||||||
border: none;
|
|
||||||
width: 22px;
|
|
||||||
height: 18px;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
QPushButton:focus {
|
QAbstractButton:focus
|
||||||
|
{
|
||||||
outline: none;
|
outline: none;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
QAbstractButton#green:hover
|
||||||
|
{
|
||||||
|
background-image: url(":/ui/micButton/micButtonHover.png");
|
||||||
|
}
|
||||||
|
|
||||||
|
QAbstractButton#red
|
||||||
|
{
|
||||||
|
background-image: url(":/ui/micButton/micButtonPressed.png");
|
||||||
|
}
|
||||||
|
@ -1,82 +1,63 @@
|
|||||||
QPushButton#green
|
QAbstractButton
|
||||||
{
|
{
|
||||||
background-color: #6bc260;
|
|
||||||
background-image: url(":/ui/videoButton/videoButton.svg");
|
background-image: url(":/ui/videoButton/videoButton.svg");
|
||||||
background-repeat: none;
|
background-repeat: none;
|
||||||
background-position: center;
|
background-position: center;
|
||||||
border: none;
|
border: none;
|
||||||
border-radius: 5px;
|
border-radius: 5px;
|
||||||
width: 50px;
|
|
||||||
height: 40px;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
QPushButton#green:hover
|
QAbstractButton:disabled
|
||||||
|
{
|
||||||
|
background-color: #919191;
|
||||||
|
}
|
||||||
|
|
||||||
|
QAbstractButton:focus
|
||||||
|
{
|
||||||
|
outline: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
QAbstractButton#green
|
||||||
|
{
|
||||||
|
background-color: #6bc260;
|
||||||
|
}
|
||||||
|
|
||||||
|
QAbstractButton#green:hover
|
||||||
{
|
{
|
||||||
background-color: #79c76f;
|
background-color: #79c76f;
|
||||||
}
|
}
|
||||||
|
|
||||||
QPushButton#green:pressed
|
QAbstractButton#green:pressed
|
||||||
{
|
{
|
||||||
background-color: #51b244;
|
background-color: #51b244;
|
||||||
}
|
}
|
||||||
|
|
||||||
QPushButton#red
|
QAbstractButton#red
|
||||||
{
|
{
|
||||||
background-color: #c84e4e;
|
background-color: #c84e4e;
|
||||||
background-image: url(":/ui/videoButton/videoButton.svg");
|
|
||||||
background-repeat: none;
|
|
||||||
background-position: center;
|
|
||||||
border: none;
|
|
||||||
border-radius: 5px;
|
|
||||||
width: 50px;
|
|
||||||
height: 40px;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
QPushButton#red:hover
|
QAbstractButton#red:hover
|
||||||
{
|
{
|
||||||
background-color: #e87474;
|
background-color: #e87474;
|
||||||
}
|
}
|
||||||
|
|
||||||
QPushButton#red:pressed
|
QAbstractButton#red:pressed
|
||||||
{
|
{
|
||||||
background-color: #df3b3b;
|
background-color: #df3b3b;
|
||||||
}
|
}
|
||||||
|
|
||||||
QPushButton#yellow
|
QAbstractButton#yellow
|
||||||
{
|
{
|
||||||
background-color: #e6e465;
|
background-color: #e6e465;
|
||||||
background-image: url(":/ui/videoButton/videoButton.svg");
|
|
||||||
background-repeat: none;
|
|
||||||
background-position: center;
|
|
||||||
border: none;
|
|
||||||
border-radius: 5px;
|
|
||||||
width: 50px;
|
|
||||||
height: 40px;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
QPushButton#yellow:hover
|
QAbstractButton#yellow:hover
|
||||||
{
|
{
|
||||||
background-color: #e8e774;
|
background-color: #e8e774;
|
||||||
}
|
}
|
||||||
|
|
||||||
QPushButton#yellow:pressed
|
QAbstractButton#yellow:pressed
|
||||||
{
|
{
|
||||||
background-color: #e3e155;
|
background-color: #e3e155;
|
||||||
}
|
}
|
||||||
|
|
||||||
QPushButton#grey
|
|
||||||
{
|
|
||||||
background-color: #919191;
|
|
||||||
background-image: url(":/ui/videoButton/videoButton.svg");
|
|
||||||
background-repeat: none;
|
|
||||||
background-position: center;
|
|
||||||
border: none;
|
|
||||||
border-radius: 5px;
|
|
||||||
width: 50px;
|
|
||||||
height: 40px;
|
|
||||||
}
|
|
||||||
|
|
||||||
QPushButton:focus
|
|
||||||
{
|
|
||||||
outline: none;
|
|
||||||
}
|
|
||||||
|
@ -1,38 +1,27 @@
|
|||||||
QPushButton#green
|
QAbstractButton
|
||||||
{
|
{
|
||||||
background-color: transparent;
|
background-color: transparent;
|
||||||
background-image: url(":/ui/volButton/volButton.png");
|
background-image: url(":/ui/volButton/volButton.png");
|
||||||
background-repeat: none;
|
background-repeat: none;
|
||||||
border: none;
|
border: none;
|
||||||
width: 22px;
|
|
||||||
height: 18px;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
QPushButton#green:hover
|
QAbstractButton:disabled
|
||||||
|
{
|
||||||
|
background-image: url(":/ui/volButton/volButtonDisabled.png");
|
||||||
|
}
|
||||||
|
|
||||||
|
QAbstractButton:focus
|
||||||
|
{
|
||||||
|
outline: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
QAbstractButton#green:hover
|
||||||
{
|
{
|
||||||
background-image: url(":/ui/volButton/volButtonHover.png");
|
background-image: url(":/ui/volButton/volButtonHover.png");
|
||||||
}
|
}
|
||||||
|
|
||||||
QPushButton#red
|
QAbstractButton#red
|
||||||
{
|
{
|
||||||
background-color: transparent;
|
|
||||||
background-image: url(":/ui/volButton/volButtonPressed.png");
|
background-image: url(":/ui/volButton/volButtonPressed.png");
|
||||||
background-repeat: none;
|
|
||||||
border: none;
|
|
||||||
width: 22px;
|
|
||||||
height: 18px;
|
|
||||||
}
|
|
||||||
|
|
||||||
QPushButton#grey
|
|
||||||
{
|
|
||||||
background-color: transparent;
|
|
||||||
background-image: url(":/ui/volButton/volButtonDisabled.png");
|
|
||||||
background-repeat: none;
|
|
||||||
border: none;
|
|
||||||
width: 22px;
|
|
||||||
height: 18px;
|
|
||||||
}
|
|
||||||
|
|
||||||
QPushButton:focus {
|
|
||||||
outline: none;
|
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user