diff --git a/src/core/coreav.cpp b/src/core/coreav.cpp index a80c207f3..5846ec1c8 100644 --- a/src/core/coreav.cpp +++ b/src/core/coreav.cpp @@ -175,7 +175,9 @@ bool CoreAV::anyActiveCalls() 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; } /** diff --git a/src/widget/form/chatform.cpp b/src/widget/form/chatform.cpp index 8c8f0e7ab..430517aeb 100644 --- a/src/widget/form/chatform.cpp +++ b/src/widget/form/chatform.cpp @@ -17,63 +17,65 @@ along with qTox. If not, see . */ -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include +#include "chatform.h" + #include -#include -#include -#include +#include +#include #include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + #include #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) 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) 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(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() { 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() if (paths.isEmpty()) return; + Core* core = Core::getInstance(); for (QString path : paths) { QFile file(path); @@ -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() 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) 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) { 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) 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) 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,216 +406,121 @@ 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); + } +} + +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 - 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(); - connect(disableCallButtonsTimer, SIGNAL(timeout()), - this, SLOT(onEnableCallButtons())); - disableCallButtonsTimer->start(1500); // 1.5sec - qDebug() << "timer started!!"; - } -} + const Status fs = f->getStatus(); + callButton->setEnabled(fs != Status::Offline); + videoButton->setEnabled(fs != Status::Offline); -void ChatForm::disableCallButtons() -{ - // Prevents race enable / disable / onEnable, when it should be disabled - if (disableCallButtonsTimer) - { - disableCallButtonsTimer->stop(); - delete disableCallButtonsTimer; - disableCallButtonsTimer = nullptr; + if (callButton->isEnabled()) + { + callButton->setObjectName("green"); + callButton->setToolTip(tr("Start audio call")); + } + + if (videoButton->isEnabled()) + { + videoButton->setObjectName("green"); + videoButton->setToolTip(tr("Start video call")); + } } - micButton->setObjectName("grey"); - micButton->style()->polish(micButton); - micButton->setToolTip(""); - micButton->disconnect(); - volButton->setObjectName("grey"); - volButton->style()->polish(volButton); - volButton->setToolTip(""); - volButton->disconnect(); + callButton->setStyleSheet(Style::getStylesheet(QStringLiteral(":/ui/callButton/callButton.css"))); + videoButton->setStyleSheet(Style::getStylesheet(QStringLiteral(":/ui/videoButton/videoButton.css"))); - callButton->setObjectName("grey"); - callButton->style()->polish(callButton); - 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; - } + updateMuteMicButton(); + updateMuteVolButton(); } void ChatForm::onMicMuteToggle() { - if (audioInputFlag) - { - coreav->toggleMuteCallInput(f); - if (micButton->objectName() == "red") - { - micButton->setObjectName("green"); - micButton->setToolTip(tr("Mute microphone")); - } - else - { - micButton->setObjectName("red"); - micButton->setToolTip(tr("Unmute microphone")); - } + CoreAV* av = Core::getInstance()->getAv(); - Style::repolish(micButton); - } + av->toggleMuteCallInput(f); + updateMuteMicButton(); } void ChatForm::onVolMuteToggle() { - if (audioOutputFlag) - { - coreav->toggleMuteCallOutput(f); - if (volButton->objectName() == "red") - { - volButton->setObjectName("green"); - volButton->setToolTip(tr("Mute call")); - } - else - { - volButton->setObjectName("red"); - volButton->setToolTip(tr("Unmute call")); - } + CoreAV* av = Core::getInstance()->getAv(); - 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; 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()) 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) - disableCallButtons(); - else if (old == Status::Offline && status != Status::Offline) - enableCallButtons(); + updateCallButtons(); - 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; avatar->setPixmap(pic); @@ -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) 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) 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) { 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() } } -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() } } +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() 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()); diff --git a/src/widget/form/chatform.h b/src/widget/form/chatform.h index a592a3851..babf1af2e 100644 --- a/src/widget/form/chatform.h +++ b/src/widget/form/chatform.h @@ -56,77 +56,81 @@ public: static const QString ACTION_PREFIX; signals: - void sendFile(uint32_t friendId, QString, QString, long long); void aliasChanged(const QString& alias); public slots: void startFileSend(ToxFile file); void onFileRecvRequest(ToxFile file); - void onAvInvite(uint32_t FriendId, bool video); - void onAvStart(uint32_t FriendId, bool video); - void onAvEnd(uint32_t FriendId); - void onAvatarChange(uint32_t FriendId, const QPixmap& pic); - void onAvatarRemoved(uint32_t FriendId); + void onAvInvite(uint32_t friendId, bool video); + void onAvStart(uint32_t friendId, bool video); + void onAvEnd(uint32_t friendId); + void onAvatarChange(uint32_t friendId, const QPixmap& pic); + void onAvatarRemoved(uint32_t friendId); private slots: + void clearChatArea(bool notInForm) override final; + + void onDeliverOfflineMessages(); + void onLoadChatHistory(); void onSendTriggered(); void onTextEditChanged(); void onAttachClicked(); void onCallTriggered(); void onVideoCallTriggered(); void onAnswerCallTriggered(); - void onHangupCallTriggered(); - void onCancelCallTriggered(); void onRejectCallTriggered(); void onMicMuteToggle(); 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 onUpdateTime(); - void onEnableCallButtons(); void onScreenshotClicked(); void onScreenshotTaken(const QPixmap &pixmap); void doScreenshot(); - void onMessageInserted(); void onCopyStatusMessage(); private: + void updateMuteMicButton(); + void updateMuteVolButton(); void retranslateUi(); void showOutgoingCall(bool video); void startCounter(); void stopCounter(); QString secondsToDHMS(quint32 duration); - void enableCallButtons(); - void disableCallButtons(); + void updateCallButtons(); void SendMessageStr(QString msg); protected: - virtual GenericNetCamView* createNetcam() final override; - // drag & drop - virtual void dragEnterEvent(QDragEnterEvent* ev) final override; - virtual void dropEvent(QDropEvent* ev) final override; - virtual void hideEvent(QHideEvent* event) final override; - virtual void showEvent(QShowEvent* event) final override; + GenericNetCamView* createNetcam() final override; + void insertChatMessage(ChatMessage::Ptr msg) final override; + void dragEnterEvent(QDragEnterEvent* ev) final override; + void dropEvent(QDropEvent* ev) final override; + void hideEvent(QHideEvent* event) final override; + void showEvent(QShowEvent* event) final override; private: - CoreAV* coreav; Friend* f; CroppingLabel *statusMessageLabel; QMenu statusMessageMenu; QLabel *callDuration; QTimer *callDurationTimer; QTimer typingTimer; - QTimer *disableCallButtonsTimer; QElapsedTimer timeElapsed; OfflineMsgEngine *offlineEngine; QAction* loadHistoryAction; QAction* copyStatusAction; QHash ftransWidgets; - QMap oldStatus; - CallConfirmWidget *callConfirm; + QPointer callConfirm; bool isTyping; }; diff --git a/src/widget/form/genericchatform.h b/src/widget/form/genericchatform.h index 750fb6f8b..b88cd09b7 100644 --- a/src/widget/form/genericchatform.h +++ b/src/widget/form/genericchatform.h @@ -87,7 +87,7 @@ protected slots: void onEmoteInsertRequested(QString str); void onSaveLogClicked(); void onCopyLogClicked(); - void clearChatArea(bool); + virtual void clearChatArea(bool); void clearChatArea(); void onSelectAllClicked(); void showFileMenu(); @@ -104,7 +104,7 @@ protected: void hideNetcam(); virtual GenericNetCamView* createNetcam() = 0; QString resolveToxId(const ToxId &id); - void insertChatMessage(ChatMessage::Ptr msg); + virtual void insertChatMessage(ChatMessage::Ptr msg); void adjustFileMenuPosition(); virtual void hideEvent(QHideEvent* event) override; virtual void showEvent(QShowEvent *) override; diff --git a/src/widget/form/groupchatform.cpp b/src/widget/form/groupchatform.cpp index 3474a6b08..79e4f5548 100644 --- a/src/widget/form/groupchatform.cpp +++ b/src/widget/form/groupchatform.cpp @@ -47,7 +47,10 @@ */ GroupChatForm::GroupChatForm(Group* chatGroup) - : group(chatGroup), inCall{false} + : audioInputFlag(false) + , audioOutputFlag(false) + , group(chatGroup) + , inCall(false) { nusersLabel = new QLabel(); @@ -301,15 +304,16 @@ void GroupChatForm::onMicMuteToggle() { if (audioInputFlag) { + CoreAV* av = Core::getInstance()->getAv(); if (micButton->objectName() == "red") { - Core::getInstance()->getAv()->muteCallInput(group, false); + av->muteCallInput(group, false); micButton->setObjectName("green"); micButton->setToolTip(tr("Mute microphone")); } else { - Core::getInstance()->getAv()->muteCallInput(group, true); + av->muteCallInput(group, true); micButton->setObjectName("red"); micButton->setToolTip(tr("Unmute microphone")); } @@ -322,15 +326,16 @@ void GroupChatForm::onVolMuteToggle() { if (audioOutputFlag) { + CoreAV* av = Core::getInstance()->getAv(); if (volButton->objectName() == "red") { - Core::getInstance()->getAv()->muteCallOutput(group, false); + av->muteCallOutput(group, false); volButton->setObjectName("green"); volButton->setToolTip(tr("Mute call")); } else { - Core::getInstance()->getAv()->muteCallOutput(group, true); + av->muteCallOutput(group, true); volButton->setObjectName("red"); volButton->setToolTip(tr("Unmute call")); } @@ -396,9 +401,10 @@ void GroupChatForm::keyPressEvent(QKeyEvent* ev) // Push to talk (CTRL+P) 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->style()->polish(micButton); Style::repolish(micButton); @@ -414,9 +420,10 @@ void GroupChatForm::keyReleaseEvent(QKeyEvent* ev) // Push to talk (CTRL+P) 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->style()->polish(micButton); Style::repolish(micButton); diff --git a/src/widget/form/groupchatform.h b/src/widget/form/groupchatform.h index afb290a3a..39c2a17c3 100644 --- a/src/widget/form/groupchatform.h +++ b/src/widget/form/groupchatform.h @@ -60,6 +60,10 @@ private: void retranslateUi(); private: + // TODO: flags are deprecated -> remove + bool audioInputFlag; + bool audioOutputFlag; + Group* group; QList peerLabels; QMap peerAudioTimers; diff --git a/src/widget/tool/callconfirmwidget.cpp b/src/widget/tool/callconfirmwidget.cpp index a911e732c..5e0d09de7 100644 --- a/src/widget/tool/callconfirmwidget.cpp +++ b/src/widget/tool/callconfirmwidget.cpp @@ -59,6 +59,7 @@ CallConfirmWidget::CallConfirmWidget(const QWidget *Anchor, const Friend& f) : rectRatio(static_cast(rectH)/static_cast(rectW)) { setWindowFlags(Qt::SubWindow); + setAttribute(Qt::WA_DeleteOnClose); QPalette palette; palette.setColor(QPalette::WindowText, Qt::white); diff --git a/src/widget/tool/callconfirmwidget.h b/src/widget/tool/callconfirmwidget.h index 19a4d438e..a498e260e 100644 --- a/src/widget/tool/callconfirmwidget.h +++ b/src/widget/tool/callconfirmwidget.h @@ -44,10 +44,10 @@ public slots: void reposition(); protected: - virtual void paintEvent(QPaintEvent* event) final override; - virtual void showEvent(QShowEvent* event) final override; - virtual void hideEvent(QHideEvent* event) final override; - virtual bool eventFilter(QObject *, QEvent* event) final override; + void paintEvent(QPaintEvent* event) final; + void showEvent(QShowEvent* event) final; + void hideEvent(QHideEvent* event) final; + bool eventFilter(QObject *, QEvent* event) final; private: const QWidget* anchor; diff --git a/src/widget/tool/croppinglabel.cpp b/src/widget/tool/croppinglabel.cpp index 634ae4b53..8f0a0f35b 100644 --- a/src/widget/tool/croppinglabel.cpp +++ b/src/widget/tool/croppinglabel.cpp @@ -76,7 +76,7 @@ void CroppingLabel::setEditable(bool editable) unsetCursor(); } -void CroppingLabel::setEdlideMode(Qt::TextElideMode elide) +void CroppingLabel::setElideMode(Qt::TextElideMode elide) { elideMode = elide; } diff --git a/src/widget/tool/croppinglabel.h b/src/widget/tool/croppinglabel.h index eb023cf51..a87344373 100644 --- a/src/widget/tool/croppinglabel.h +++ b/src/widget/tool/croppinglabel.h @@ -32,7 +32,7 @@ public: void editBegin(); void setEditable(bool editable); - void setEdlideMode(Qt::TextElideMode elide); + void setElideMode(Qt::TextElideMode elide); void setText(const QString& text); QString fullText(); diff --git a/src/widget/widget.cpp b/src/widget/widget.cpp index 0568d4db2..7faf72ef9 100644 --- a/src/widget/widget.cpp +++ b/src/widget/widget.cpp @@ -955,26 +955,11 @@ void Widget::addFriend(int friendId, const QString &userId) 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(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(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 QPixmap avatar = Nexus::getProfile()->loadAvatar(userId); @@ -1155,8 +1140,6 @@ void Widget::onFriendMessageReceived(int friendId, const QString& message, bool return; QDateTime timestamp = QDateTime::currentDateTime(); - f->getChatForm()->addMessage(f->getToxId(), message, isAction, timestamp, true); - Profile* profile = Nexus::getProfile(); if (profile->isHistoryEnabled()) profile->getHistory()->addNewMessage(f->getToxId().publicKey, isAction ? ChatForm::ACTION_PREFIX + f->getDisplayedName() + " " + message : message, diff --git a/ui/callButton/callButton.css b/ui/callButton/callButton.css index 4aaf2fddb..f09f4b74d 100644 --- a/ui/callButton/callButton.css +++ b/ui/callButton/callButton.css @@ -1,83 +1,63 @@ -QPushButton#green +QAbstractButton { - background-color: #6bc260; + border-radius: 5px; + border: none; background-image: url(":/ui/callButton/callButton.svg"); background-repeat: none; background-position: center; - border: none; - border-radius: 5px; - width: 50px; - height: 40px; } -QPushButton#green:hover -{ - 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 +QAbstractButton:disabled { 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; } +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; +} diff --git a/ui/micButton/micButton.css b/ui/micButton/micButton.css index df03739ee..0a01aae39 100644 --- a/ui/micButton/micButton.css +++ b/ui/micButton/micButton.css @@ -1,38 +1,27 @@ -QPushButton#green +QAbstractButton { background-color: transparent; background-image: url(":/ui/micButton/micButton.png"); background-repeat: 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-repeat: none; - border: none; - width: 22px; - height: 18px; } -QPushButton:focus { +QAbstractButton:focus +{ outline: none; } + +QAbstractButton#green:hover +{ + background-image: url(":/ui/micButton/micButtonHover.png"); +} + +QAbstractButton#red +{ + background-image: url(":/ui/micButton/micButtonPressed.png"); +} diff --git a/ui/videoButton/videoButton.css b/ui/videoButton/videoButton.css index 6b7c95972..350b0a53a 100644 --- a/ui/videoButton/videoButton.css +++ b/ui/videoButton/videoButton.css @@ -1,82 +1,63 @@ -QPushButton#green +QAbstractButton { - background-color: #6bc260; background-image: url(":/ui/videoButton/videoButton.svg"); background-repeat: none; background-position: center; border: none; 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; } -QPushButton#green:pressed +QAbstractButton#green:pressed { background-color: #51b244; } -QPushButton#red +QAbstractButton#red { 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; } -QPushButton#red:pressed +QAbstractButton#red:pressed { background-color: #df3b3b; } -QPushButton#yellow +QAbstractButton#yellow { 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; } -QPushButton#yellow:pressed +QAbstractButton#yellow:pressed { 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; -} diff --git a/ui/volButton/volButton.css b/ui/volButton/volButton.css index 2d3b33546..b537ee217 100644 --- a/ui/volButton/volButton.css +++ b/ui/volButton/volButton.css @@ -1,38 +1,27 @@ -QPushButton#green +QAbstractButton { background-color: transparent; background-image: url(":/ui/volButton/volButton.png"); background-repeat: 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"); } -QPushButton#red +QAbstractButton#red { - background-color: transparent; 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; }