blob: 89a4bc341ccee432d31218212ee16f8bc4b38dd0 [file] [log] [blame]
Edric Milaret029b95a2015-06-09 09:51:44 -04001/***************************************************************************
Edric Milaretbab169d2016-01-07 15:13:33 -05002 * Copyright (C) 2015-2016 by Savoir-faire Linux *
Edric Milaret029b95a2015-06-09 09:51:44 -04003 * Author: Edric Ladent Milaret <edric.ladent-milaret@savoirfairelinux.com>*
4 * *
5 * This program is free software; you can redistribute it and/or modify *
6 * it under the terms of the GNU General Public License as published by *
7 * the Free Software Foundation; either version 3 of the License, or *
8 * (at your option) any later version. *
9 * *
10 * This program is distributed in the hope that it will be useful, *
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of *
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
13 * GNU General Public License for more details. *
14 * *
15 * You should have received a copy of the GNU General Public License *
16 * along with this program. If not, see <http://www.gnu.org/licenses/>. *
17 **************************************************************************/
18
19#include "videoview.h"
20#include "ui_videoview.h"
21
Edric Milaret029b95a2015-06-09 09:51:44 -040022#include "video/devicemodel.h"
23#include "video/sourcemodel.h"
Edric Milareted0b2802015-10-01 15:10:02 -040024#include "recentmodel.h"
Edric Milaret029b95a2015-06-09 09:51:44 -040025
26#include <QGraphicsOpacityEffect>
27#include <QPropertyAnimation>
28#include <QDesktopWidget>
29#include <QMenu>
Edric Milaret303bbf12015-06-22 14:24:13 -040030#include <QFileDialog>
31#include <QMimeData>
Edric Milaret029b95a2015-06-09 09:51:44 -040032
33#include <memory>
34
35#include "videooverlay.h"
36#include "selectareadialog.h"
37
Edric Milaret80e0b212015-10-16 10:07:43 -040038VideoView::VideoView(QWidget* parent) :
Edric Milaret029b95a2015-06-09 09:51:44 -040039 QWidget(parent),
40 ui(new Ui::VideoView)
41{
42 ui->setupUi(this);
43
Edric Milareta3e47282015-10-23 15:20:30 -040044 connect(&CallModel::instance(), SIGNAL(callStateChanged(Call*, Call::State)),
Edric Milaret029b95a2015-06-09 09:51:44 -040045 this, SLOT(callStateChanged(Call*, Call::State)));
46
47 overlay_ = new VideoOverlay(this);
48 auto effect = new QGraphicsOpacityEffect(overlay_);
49 effect->setOpacity(1.0);
50 overlay_->setGraphicsEffect(effect);
51 fadeAnim_ = new QPropertyAnimation(this);
52 fadeAnim_->setTargetObject(effect);
53 fadeAnim_->setPropertyName("opacity");
54 fadeAnim_->setDuration(fadeOverlayTime_);
55 fadeAnim_->setStartValue(effect->opacity());
56 fadeAnim_->setEndValue(0);
57 fadeAnim_->setEasingCurve(QEasingCurve::OutQuad);
58
Edric Milaret029b95a2015-06-09 09:51:44 -040059 this->setContextMenuPolicy(Qt::CustomContextMenu);
60 connect(this, SIGNAL(customContextMenuRequested(const QPoint&)),
61 this, SLOT(showContextMenu(const QPoint&)));
Edric Milaret3aca8e32015-06-12 10:01:40 -040062 connect(overlay_, &VideoOverlay::setChatVisibility, [=](bool visible) {
63 emit this->setChatVisibility(visible);
64 });
Edric Milaret029b95a2015-06-09 09:51:44 -040065}
66
67VideoView::~VideoView()
68{
69 delete ui;
Edric Milaret01f23842015-06-22 14:46:01 -040070 delete overlay_;
Edric Milaret01f23842015-06-22 14:46:01 -040071 delete fadeAnim_;
Edric Milaret029b95a2015-06-09 09:51:44 -040072}
73
74void
Edric Milaret80e0b212015-10-16 10:07:43 -040075VideoView::resizeEvent(QResizeEvent* event)
Edric Milaret029b95a2015-06-09 09:51:44 -040076{
77 Q_UNUSED(event)
78 overlay_->resize(this->size());
79 overlay_->show();
80 overlay_->raise();
81}
82
83void
84VideoView::enterEvent(QEvent* event)
85{
86 Q_UNUSED(event)
87 fadeAnim_->stop();
88 fadeAnim_->targetObject()->setProperty(fadeAnim_->propertyName(), fadeAnim_->startValue());
89}
90
91void
92VideoView::leaveEvent(QEvent* event)
93{
94 Q_UNUSED(event)
95 fadeAnim_->start(QAbstractAnimation::KeepWhenStopped);
96}
97
98void
99VideoView::callStateChanged(Call* call, Call::State previousState)
100{
101 Q_UNUSED(previousState)
Edric Milaret80e0b212015-10-16 10:07:43 -0400102
Edric Milaret029b95a2015-06-09 09:51:44 -0400103 if (call->state() == Call::State::CURRENT) {
104 ui->videoWidget->show();
Edric Milareted0b2802015-10-01 15:10:02 -0400105 timerConnection_ = connect(call, SIGNAL(changed()), this, SLOT(updateCall()));
Edric Milaret029b95a2015-06-09 09:51:44 -0400106 }
107 else {
Edric Milaret80e0b212015-10-16 10:07:43 -0400108 QObject::disconnect(timerConnection_);
Edric Milaret3aca8e32015-06-12 10:01:40 -0400109 emit setChatVisibility(false);
Edric Milaret029b95a2015-06-09 09:51:44 -0400110 if (isFullScreen())
111 toggleFullScreen();
Edric Milaret029b95a2015-06-09 09:51:44 -0400112 }
113}
114
115void
Edric Milareted0b2802015-10-01 15:10:02 -0400116VideoView::updateCall()
Edric Milaret029b95a2015-06-09 09:51:44 -0400117{
Edric Milaret80e0b212015-10-16 10:07:43 -0400118 if (auto call = CallModel::instance().selectedCall()) {
119 overlay_->setName(call->formattedName());
120 overlay_->setTime(call->length());
121 }
Edric Milaret029b95a2015-06-09 09:51:44 -0400122}
123
124void
125VideoView::mouseDoubleClickEvent(QMouseEvent* e) {
126 QWidget::mouseDoubleClickEvent(e);
127 toggleFullScreen();
128}
129
Edric Milaret80e0b212015-10-16 10:07:43 -0400130void
131VideoView::dragEnterEvent(QDragEnterEvent* event)
Edric Milaret303bbf12015-06-22 14:24:13 -0400132{
133 if (event->mimeData()->hasUrls())
134 event->acceptProposedAction();
135}
136
Edric Milaret80e0b212015-10-16 10:07:43 -0400137void
138VideoView::dropEvent(QDropEvent* event)
Edric Milaret303bbf12015-06-22 14:24:13 -0400139{
140 auto urls = event->mimeData()->urls();
Edric Milareta3e47282015-10-23 15:20:30 -0400141 Video::SourceModel::instance().setFile(urls.at(0));
Edric Milaret303bbf12015-06-22 14:24:13 -0400142}
143
Edric Milaret029b95a2015-06-09 09:51:44 -0400144void
145VideoView::toggleFullScreen()
146{
147 if(isFullScreen()) {
148 this->setParent(oldParent_);
Edric Milaretb46f6492015-09-25 15:28:31 -0400149 oldParent_->layout()->addWidget(this);
Edric Milaret029b95a2015-06-09 09:51:44 -0400150 this->resize(oldSize_.width(), oldSize_.height());
Edric Milaret58f57622015-12-09 09:57:15 -0500151 this->showNormal();
Edric Milaret029b95a2015-06-09 09:51:44 -0400152 } else {
153 oldSize_ = this->size();
154 oldParent_ = static_cast<QWidget*>(this->parent());
155 this->setParent(0);
156 this->showFullScreen();
Edric Milaret029b95a2015-06-09 09:51:44 -0400157 }
158}
159
160void
161VideoView::showContextMenu(const QPoint& pos)
162{
163 QPoint globalPos = this->mapToGlobal(pos);
164
165 QMenu menu;
166
Edric Milareta3e47282015-10-23 15:20:30 -0400167 for (auto device : Video::DeviceModel::instance().devices()) {
Edric Milaret029b95a2015-06-09 09:51:44 -0400168 std::unique_ptr<QAction> deviceAction(new QAction(device->name(), this));
169 deviceAction->setCheckable(true);
Edric Milareta3e47282015-10-23 15:20:30 -0400170 if (device == Video::DeviceModel::instance().activeDevice())
Edric Milaret029b95a2015-06-09 09:51:44 -0400171 deviceAction->setChecked(true);
172 auto ptr = deviceAction.release();
173 menu.addAction(ptr);
174 connect(ptr, &QAction::toggled, [=](bool checked) {
175 if (checked == true) {
Edric Milareta3e47282015-10-23 15:20:30 -0400176 Video::SourceModel::instance().switchTo(device);
177 Video::DeviceModel::instance().setActive(device);
Edric Milaret029b95a2015-06-09 09:51:44 -0400178 }
179 });
180 }
181
182 menu.addSeparator();
183
Edric Milaret53ac6e52015-09-14 13:37:06 -0400184 auto shareAction = new QAction(tr("Share entire screen"), this);
Edric Milaret029b95a2015-06-09 09:51:44 -0400185 menu.addAction(shareAction);
186 connect(shareAction, &QAction::triggered, [=]() {
Edric Milareta3e47282015-10-23 15:20:30 -0400187 Video::SourceModel::instance().setDisplay(0, QApplication::desktop()->rect());
Edric Milaret029b95a2015-06-09 09:51:44 -0400188 });
Edric Milaret53ac6e52015-09-14 13:37:06 -0400189 auto shareAreaAction = new QAction(tr("Share screen area"), this);
Edric Milaret029b95a2015-06-09 09:51:44 -0400190 menu.addAction(shareAreaAction);
191 connect(shareAreaAction, &QAction::triggered, [=]() {
192 SelectAreaDialog selec;
193 selec.exec();
194 });
Edric Milaret53ac6e52015-09-14 13:37:06 -0400195 auto shareFileAction = new QAction(tr("Share file"), this);
Edric Milaret303bbf12015-06-22 14:24:13 -0400196 menu.addAction(shareFileAction);
197 connect(shareFileAction, &QAction::triggered, [=]() {
198 QFileDialog dialog(this);
199 dialog.setFileMode(QFileDialog::AnyFile);
200 QStringList fileNames;
201 if (!dialog.exec())
202 return;
203 fileNames = dialog.selectedFiles();
Edric Milareta3e47282015-10-23 15:20:30 -0400204 Video::SourceModel::instance().setFile(QUrl::fromLocalFile(fileNames.at(0)));
Edric Milaret303bbf12015-06-22 14:24:13 -0400205 });
Edric Milaret029b95a2015-06-09 09:51:44 -0400206
207 menu.exec(globalPos);
208}
209
Edric Milaret80e0b212015-10-16 10:07:43 -0400210void
211VideoView::pushRenderer(Call* call) {
212 if (not call) {
213 disconnect(videoStartedConnection_);
214 return;
215 }
216 if (auto renderer = call->videoRenderer()) {
217 slotVideoStarted(renderer);
218 } else {
219 disconnect(videoStartedConnection_);
220 videoStartedConnection_ = connect(call,
221 SIGNAL(videoStarted(Video::Renderer*)),
222 this,
223 SLOT(slotVideoStarted(Video::Renderer*)));
224 }
225 ui->videoWidget->setPreviewDisplay(call->type() != Call::Type::CONFERENCE);
226}
227
228void
229VideoView::slotVideoStarted(Video::Renderer* renderer) {
230 ui->videoWidget->show();
231 ui->videoWidget->setDistantRenderer(renderer);
232}
233