Skip to content
Snippets Groups Projects
Select Git revision
  • e64c7469d5b8f4e4e7d3840058f0d6a9c73b1a91
  • master default protected
  • release/202005
  • release/202001
  • release/201912
  • release/201911
  • release/201910
  • release/201908
  • release/201906
  • release/201905
  • release/201904
  • release/201903
  • release/201902
  • release/201901
  • release/201812
  • release/201811
  • release/201808
  • releases/beta1
  • packaging
  • native
  • release-0.2.x
  • 1.0.0
  • 0.2.0
  • 0.1.1
  • 0.1.0
25 results

videooverlay.cpp

Blame
  • 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);
    }