Select Git revision
videooverlay.cpp
Code owners
Assign users and groups as approvers for specific file changes. Learn more.
videooverlay.cpp 8.31 KiB
/***************************************************************************
* Copyright (C) 2015-2019 by Savoir-faire Linux *
* Author: Edric Ladent Milaret <edric.ladent-milaret@savoirfairelinux.com>*
* Author: Andreas Traczyk <andreas.traczyk@savoirfairelinux.com> *
* *
* This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation; either version 3 of the License, or *
* (at your option) any later version. *
* *
* This program is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU General Public License for more details. *
* *
* You should have received a copy of the GNU General Public License *
* along with this program. If not, see <http://www.gnu.org/licenses/>. *
**************************************************************************/
#include "videooverlay.h"
#include "ui_videooverlay.h"
#include <QTime>
#include <QMouseEvent>
#include "lrcinstance.h"
#include "contactpicker.h"
#include "utils.h"
VideoOverlay::VideoOverlay(QWidget* parent) :
QWidget(parent),
ui(new Ui::VideoOverlay),
oneSecondTimer_(new QTimer(this)),
contactPicker_(new ContactPicker(this))
{
ui->setupUi(this);
setAttribute(Qt::WA_NoSystemBackground);
ui->bottomButtons->setMouseTracking(true);
ui->chatButton->setCheckable(true);
ui->onHoldLabel->setVisible(false);
ui->transferCallButton->setVisible(false);
ui->transferCallButton->setCheckable(true);
contactPicker_->setVisible(false);
contactPicker_->setTitle(QObject::tr("Select peer to transfer to"));
connect(ui->transferCallButton, &QPushButton::toggled, this, &VideoOverlay::on_transferButton_toggled);
connect(contactPicker_, &ContactPicker::contactWillDoTransfer, this, &VideoOverlay::on_transferCall_requested);
}
VideoOverlay::~VideoOverlay()
{
delete ui;
}
void
VideoOverlay::callStarted(const std::string& callId)
{
ui->timerLabel->setText("00:00");
callId_ = callId;
connect(oneSecondTimer_, &QTimer::timeout, this, &VideoOverlay::setTime);
oneSecondTimer_->start(1000);
}
void
VideoOverlay::setName(const QString& name)
{
ui->nameLabel->setText(name);
}
void
VideoOverlay::setTime()
{
if (callId_.empty()) {
return;
}
try {
auto callInfo = LRCInstance::getCurrentCallModel()->getCall(callId_);
if (callInfo.status == lrc::api::call::Status::IN_PROGRESS ||
callInfo.status == lrc::api::call::Status::PAUSED) {
int numSeconds = std::chrono::duration_cast<std::chrono::seconds>(
std::chrono::steady_clock::now() - callInfo.startTime).count();
QTime t(0, 0, numSeconds);
ui->timerLabel->setText(t.toString(numSeconds > 3600 ? "hh:mm:ss" : "mm:ss"));
}
} catch (...) { }
}
void
VideoOverlay::setVideoMuteVisibility(bool visible)
{
ui->noVideoButton->setVisible(visible);
}
bool
VideoOverlay::shouldShowOverlay()
{
if (!LRCInstance::getCurrentCallModel()->hasCall(callId_)) {
return false;
}
auto callInfo = LRCInstance::getCurrentCallModel()->getCall(callId_);
return ui->bottomButtons->underMouse() ||
ui->topInfoBar->underMouse() ||
(callInfo.status == lrc::api::call::Status::PAUSED) ||
contactPicker_->isActiveWindow();
}
void
VideoOverlay::simulateShowChatview(bool checked)
{
ui->chatButton->setChecked(checked);
}
bool
VideoOverlay::getShowChatView()
{
return ui->chatButton->isChecked();
}
void
VideoOverlay::on_hangupButton_clicked()
{
auto convInfo = Utils::getSelectedConversation();
if (!convInfo.uid.empty()) {
auto& callId = convInfo.callId;
auto callModel = LRCInstance::getCurrentCallModel();
if (callModel->hasCall(callId)) {
callModel->hangUp(callId);
}
}
ui->chatButton->setChecked(false);
}
void
VideoOverlay::on_chatButton_toggled(bool checked)
{
emit setChatVisibility(checked);
}
void
VideoOverlay::on_holdButton_clicked()
{
auto callModel = LRCInstance::getCurrentCallModel();
if (callModel->hasCall(callId_)) {
callModel->togglePause(callId_);
auto onHold = callModel->getCall(callId_).status == lrc::api::call::Status::PAUSED;
ui->holdButton->setChecked(!onHold);
ui->onHoldLabel->setVisible(!onHold);
}
}
void
VideoOverlay::on_noMicButton_toggled(bool checked)
{
Q_UNUSED(checked);
auto callModel = LRCInstance::getCurrentCallModel();
if (callModel->hasCall(callId_)) {
callModel->toggleMedia(callId_, lrc::api::NewCallModel::Media::AUDIO);
}
}
void
VideoOverlay::on_noVideoButton_toggled(bool checked)
{
Q_UNUSED(checked);
auto callModel = LRCInstance::getCurrentCallModel();
if (callModel->hasCall(callId_)) {
callModel->toggleMedia(callId_, lrc::api::NewCallModel::Media::VIDEO);
}
}
void
VideoOverlay::on_recButton_clicked()
{
auto callModel = LRCInstance::getCurrentCallModel();
if (callModel->hasCall(callId_)) {
callModel->toggleAudioRecord(callId_);
}
}
void
VideoOverlay::setTransferCallAvailability(bool visible)
{
ui->transferCallButton->setVisible(visible);
}
void
VideoOverlay::on_transferButton_toggled(bool checked)
{
if (callId_.empty() || !checked) {
return;
}
contactPicker_->setType(ContactPicker::Type::TRANSFER);
QPoint globalPos_button = mapToGlobal(ui->transferCallButton->pos());
QPoint globalPos_bottomButtons = mapToGlobal(ui->bottomButtons->pos());
contactPicker_->move(globalPos_button.x(), globalPos_bottomButtons.y() - contactPicker_->height());
// receive the signal that ensure the button checked status is correct and contactpicker
// is properly hidden
Utils::oneShotConnect(contactPicker_, &ContactPicker::willClose, [this](QMouseEvent *event) {
contactPicker_->hide();
// check if current mouse position is on button
auto relativeCursorPos = ui->transferCallButton->mapFromGlobal(event->pos());
if (!ui->transferCallButton->rect().contains(relativeCursorPos)) {
ui->transferCallButton->setChecked(false);
}
});
// for esc key, receive reject signal
Utils::oneShotConnect(contactPicker_, &QDialog::rejected,
[this] {
ui->transferCallButton->setChecked(false);
});
contactPicker_->show();
}
void
VideoOverlay::on_transferCall_requested(const std::string& callId, const std::string& contactUri)
{
auto callModel = LRCInstance::getCurrentCallModel();
contactPicker_->hide();
ui->transferCallButton->setChecked(false);
std::string destCallId;
try {
//check if the call exist - (check non-finished calls)
auto callInfo = callModel->getCallFromURI(contactUri, true);
destCallId = callInfo.id;
} catch(std::exception& e) {
qDebug().noquote() << e.what();
destCallId = "";
}
// if no second call -> blind transfer
// if there is a second call -> attended transfer
if (destCallId.size() == 0) {
callModel->transfer(callId, "sip:" + contactUri);
callModel->hangUp(callId);
}else{
callModel->transferToCall(callId, destCallId);
callModel->hangUp(callId);
callModel->hangUp(destCallId);
}
}
void
VideoOverlay::setCurrentSelectedCalleeDisplayName(const QString& CalleeDisplayName)
{
contactPicker_->setCurrentCalleeDisplayName(CalleeDisplayName);
}
void
VideoOverlay::resetOverlay(bool isAudioMuted, bool isVideoMuted, bool isRecording, bool isHolding)
{
// Block the signals of buttons
Utils::whileBlocking(ui->noMicButton)->setChecked(isAudioMuted);
Utils::whileBlocking(ui->noVideoButton)->setChecked(isVideoMuted);
Utils::whileBlocking(ui->recButton)->setChecked(isRecording);
Utils::whileBlocking(ui->holdButton)->setChecked(isHolding);
Utils::whileBlocking(ui->onHoldLabel)->setVisible(isHolding);
}