videoview.cpp 6.41 KB
Newer Older
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29
/***************************************************************************
 * Copyright (C) 2015 by Savoir-Faire Linux                                *
 * Author: Edric Ladent Milaret <edric.ladent-milaret@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 "videoview.h"
#include "ui_videoview.h"

#include "callmodel.h"
#include "video/devicemodel.h"
#include "video/sourcemodel.h"

#include <QGraphicsOpacityEffect>
#include <QPropertyAnimation>
#include <QDesktopWidget>
#include <QMenu>
Edric Milaret's avatar
Edric Milaret committed
30 31
#include <QFileDialog>
#include <QMimeData>
32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64

#include <memory>

#include "videooverlay.h"
#include "selectareadialog.h"

VideoView::VideoView(QWidget *parent) :
    QWidget(parent),
    ui(new Ui::VideoView)
{
    ui->setupUi(this);

    connect(CallModel::instance(), SIGNAL(callStateChanged(Call*, Call::State)),
            this, SLOT(callStateChanged(Call*, Call::State)));

    overlay_ = new VideoOverlay(this);
    auto effect = new QGraphicsOpacityEffect(overlay_);
    effect->setOpacity(1.0);
    overlay_->setGraphicsEffect(effect);
    fadeAnim_ = new QPropertyAnimation(this);
    fadeAnim_->setTargetObject(effect);
    fadeAnim_->setPropertyName("opacity");
    fadeAnim_->setDuration(fadeOverlayTime_);
    fadeAnim_->setStartValue(effect->opacity());
    fadeAnim_->setEndValue(0);
    fadeAnim_->setEasingCurve(QEasingCurve::OutQuad);

    timerLength_ =  new QTimer(this);
    connect(timerLength_, SIGNAL(timeout()), this, SLOT(updateTimer()));

    this->setContextMenuPolicy(Qt::CustomContextMenu);
    connect(this, SIGNAL(customContextMenuRequested(const QPoint&)),
        this, SLOT(showContextMenu(const QPoint&)));
65 66 67
    connect(overlay_, &VideoOverlay::setChatVisibility, [=](bool visible) {
        emit this->setChatVisibility(visible);
    });
68 69 70 71 72
}

VideoView::~VideoView()
{
    delete ui;
Edric Milaret's avatar
Edric Milaret committed
73 74 75
    delete overlay_;
    delete timerLength_;
    delete fadeAnim_;
76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111
}

void
VideoView::resizeEvent(QResizeEvent *event)
{
    Q_UNUSED(event)
    overlay_->resize(this->size());
    overlay_->show();
    overlay_->raise();
}

void
VideoView::enterEvent(QEvent* event)
{
    Q_UNUSED(event)
    fadeAnim_->stop();
    fadeAnim_->targetObject()->setProperty(fadeAnim_->propertyName(), fadeAnim_->startValue());
}

void
VideoView::leaveEvent(QEvent* event)
{
    Q_UNUSED(event)
    fadeAnim_->start(QAbstractAnimation::KeepWhenStopped);
}

void
VideoView::callStateChanged(Call* call, Call::State previousState)
{
   Q_UNUSED(previousState)
    if (call->state() == Call::State::CURRENT) {
        ui->videoWidget->show();
        timerLength_->start(1000);
        overlay_->setName(call->formattedName());
    }
    else {
112
        emit setChatVisibility(false);
113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131
        ui->videoWidget->hide();
        if (isFullScreen())
            toggleFullScreen();
        timerLength_->stop();
    }
}

void
VideoView::updateTimer()
{
    overlay_->setTime(CallModel::instance()->selectedCall()->length());
}

void
VideoView::mouseDoubleClickEvent(QMouseEvent* e) {
    QWidget::mouseDoubleClickEvent(e);
    toggleFullScreen();
}

Edric Milaret's avatar
Edric Milaret committed
132 133 134 135 136 137 138 139 140 141 142 143
void VideoView::dragEnterEvent(QDragEnterEvent *event)
{
    if (event->mimeData()->hasUrls())
        event->acceptProposedAction();
}

void VideoView::dropEvent(QDropEvent *event)
{
    auto urls = event->mimeData()->urls();
    Video::SourceModel::instance()->setFile(urls.at(0));
}

144 145 146 147 148
void
VideoView::toggleFullScreen()
{
    if(isFullScreen()) {
        this->setParent(oldParent_);
149
        oldParent_->layout()->addWidget(this);
150
        this->resize(oldSize_.width(), oldSize_.height());
151
        this->show();
152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184
    } else {
        oldSize_ = this->size();
        oldParent_ = static_cast<QWidget*>(this->parent());
        this->setParent(0);
        this->showFullScreen();
        this->show();
    }
}

void
VideoView::showContextMenu(const QPoint& pos)
{
    QPoint globalPos = this->mapToGlobal(pos);

    QMenu menu;

    for (auto device : Video::DeviceModel::instance()->devices()) {
        std::unique_ptr<QAction> deviceAction(new QAction(device->name(), this));
        deviceAction->setCheckable(true);
        if (device == Video::DeviceModel::instance()->activeDevice())
            deviceAction->setChecked(true);
        auto ptr = deviceAction.release();
        menu.addAction(ptr);
        connect(ptr, &QAction::toggled, [=](bool checked) {
            if (checked == true) {
                Video::SourceModel::instance()->switchTo(device);
                Video::DeviceModel::instance()->setActive(device);
            }
        });
    }

    menu.addSeparator();

185
    auto shareAction = new QAction(tr("Share entire screen"), this);
186 187 188 189
    menu.addAction(shareAction);
    connect(shareAction, &QAction::triggered, [=]() {
        Video::SourceModel::instance()->setDisplay(0, QApplication::desktop()->rect());
    });
190
    auto shareAreaAction = new QAction(tr("Share screen area"), this);
191 192 193 194 195
    menu.addAction(shareAreaAction);
    connect(shareAreaAction, &QAction::triggered, [=]() {
        SelectAreaDialog selec;
        selec.exec();
    });
196
    auto shareFileAction = new QAction(tr("Share file"), this);
Edric Milaret's avatar
Edric Milaret committed
197 198 199 200 201 202 203 204 205 206
    menu.addAction(shareFileAction);
    connect(shareFileAction, &QAction::triggered, [=]() {
        QFileDialog dialog(this);
        dialog.setFileMode(QFileDialog::AnyFile);
        QStringList fileNames;
        if (!dialog.exec())
            return;
        fileNames = dialog.selectedFiles();
        Video::SourceModel::instance()->setFile(QUrl::fromLocalFile(fileNames.at(0)));
    });
207 208 209 210

    menu.exec(globalPos);
}