Commit 80e0b21f authored by Edric Milaret's avatar Edric Milaret Committed by gerrit2

conference : UI implementation

- add a button on to add people
- add a button to join call with a parent
(launched with add people button)
- reuse transferdialog to present the information for add people
- rename transferdialog to callutilsdialog
- add a method to set the current distant renderer instead of being
dependant of LRC signals
- various code clean-up

Tuleap: #29
Change-Id: I7f8875011702b586f2155e87c60f43f806494e65
parent 5ac7ef23
......@@ -56,8 +56,8 @@ SOURCES += main.cpp\
contactpicker.cpp \
contactmethodpicker.cpp \
globalsystemtray.cpp \
transferdialog.cpp \
smartlistdelegate.cpp
smartlistdelegate.cpp \
callutilsdialog.cpp
HEADERS += mainwindow.h \
callwidget.h \
......@@ -84,8 +84,8 @@ HEADERS += mainwindow.h \
contactmethodpicker.h \
settingskey.h \
globalsystemtray.h \
transferdialog.h \
smartlistdelegate.h
smartlistdelegate.h \
callutilsdialog.h
FORMS += mainwindow.ui \
callwidget.ui \
......@@ -99,7 +99,7 @@ FORMS += mainwindow.ui \
videooverlay.ui \
contactpicker.ui \
contactmethodpicker.ui \
transferdialog.ui
callutilsdialog.ui
win32: LIBS += -lole32 -luuid -lshlwapi
......
......@@ -16,57 +16,74 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>. *
**************************************************************************/
#include "transferdialog.h"
#include "ui_transferdialog.h"
#include "callutilsdialog.h"
#include "ui_callutilsdialog.h"
#include "callmodel.h"
#include "phonedirectorymodel.h"
#include "recentmodel.h"
#include "contactmethod.h"
#include "person.h"
TransferDialog::TransferDialog(QWidget *parent) :
CallUtilsDialog::CallUtilsDialog(QWidget* parent) :
QDialog(parent),
ui(new Ui::TransferDialog),
activeProxy_(nullptr)
ui(new Ui::CallUtilsDialog),
confMode_(false),
smartListDelegate_(nullptr),
notCurrentProxyModel_(nullptr)
{
ui->setupUi(this);
this->setWindowFlags(Qt::CustomizeWindowHint);
this->setWindowFlags(Qt::FramelessWindowHint);
this->setWindowFlags(Qt::FramelessWindowHint | Qt::Popup);
}
TransferDialog::~TransferDialog()
CallUtilsDialog::~CallUtilsDialog()
{
delete smartListDelegate_;
delete notCurrentProxyModel_;
delete ui;
}
void
TransferDialog::showEvent(QShowEvent *event)
CallUtilsDialog::showEvent(QShowEvent* event)
{
Q_UNUSED(event)
ui->numberBar->clear();
selectedCall_ = nullptr;
if (not activeProxy_) {
activeProxy_ = new ActiveCallsProxyModel(&CallModel::instance());
activeProxy_->setDynamicSortFilter(false);
if (not notCurrentProxyModel_) {
notCurrentProxyModel_ = new NotCurrentProxyModel(&RecentModel::instance());
}
ui->activeCallsView->setModel(activeProxy_);
ui->activeCallsView->clearSelection();
ui->contactView->setModel(notCurrentProxyModel_);
if (not smartListDelegate_) {
smartListDelegate_ = new SmartListDelegate();
}
ui->contactView->setItemDelegate(smartListDelegate_);
}
void
TransferDialog::on_transferButton_clicked()
void CallUtilsDialog::removeProxyModel()
{
ui->contactView->setModel(nullptr);
}
void CallUtilsDialog::closeEvent(QCloseEvent* event)
{
//This prevent a crash happening in Qt5.5 in QSortFilterProxyModel
Q_UNUSED(event)
removeProxyModel();
}
void
CallUtilsDialog::on_transferButton_clicked()
{
auto callList = CallModel::instance().getActiveCalls();
for (auto c : callList) {
if (c->state() == Call::State::CURRENT) {
if (not ui->numberBar->text().isEmpty()) {
auto number = PhoneDirectoryModel::instance().getNumber(ui->numberBar->text());
CallModel::instance().transfer(c, number);
} else if (selectedCall_) {
CallModel::instance().attendedTransfer(c, selectedCall_);
}
removeProxyModel();
this->close();
return;
}
......@@ -74,33 +91,47 @@ TransferDialog::on_transferButton_clicked()
}
void
TransferDialog::removeProxyModel()
CallUtilsDialog::setConfMode(bool active)
{
//This prevent a crash happening in Qt5.5 in QSortFilterProxyModel
ui->activeCallsView->setModel(nullptr);
confMode_ = active;
ui->transferButton->setVisible(not active);
ui->numberBar->setVisible(not active);
}
void
TransferDialog::on_activeCallsView_doubleClicked(const QModelIndex &index)
CallUtilsDialog::on_contactView_doubleClicked(const QModelIndex& index)
{
Q_UNUSED(index)
removeProxyModel();
auto callList = CallModel::instance().getActiveCalls();
for (auto c : callList) {
if (c->state() == Call::State::CURRENT) {
if (c != selectedCall_) {
CallModel::instance().attendedTransfer(c, selectedCall_);
this->close();
if (not index.isValid())
return;
auto realIdx = notCurrentProxyModel_->mapToSource(index);
if (not RecentModel::instance().hasActiveCall(realIdx)) {
ContactMethod* m = nullptr;
if (auto cm = realIdx.data(static_cast<int>(Call::Role::ContactMethod)).value<ContactMethod*>()) {
m = cm;
} else {
if (auto person = realIdx.data(static_cast<int>(Person::Role::Object)).value<Person*>()) {
m = person->phoneNumbers().first();
}
}
if (confMode_) {
if (m && !RecentModel::instance().index(0, 0, realIdx).isValid()) {
Call* c = CallModel::instance().dialingCall(m, CallModel::instance().selectedCall());
c->performAction(Call::Action::ACCEPT);
}
}
void
TransferDialog::on_activeCallsView_clicked(const QModelIndex &index)
{
selectedCall_ = CallModel::instance().getCall(index);
} else {
if (m) {
auto activeCall = CallModel::instance().selectedCall();
CallModel::instance().transfer(activeCall, m);
}
}
} else {
auto activeCall = CallModel::instance().selectedCall();
auto call = RecentModel::instance().getActiveCall(realIdx);
if (not confMode_)
CallModel::instance().attendedTransfer(activeCall, call);
else
CallModel::instance().createJoinOrMergeConferenceFromCall(activeCall, call);
}
this->close();
}
......@@ -22,15 +22,18 @@
#include <QSortFilterProxyModel>
#include "callmodel.h"
#include "recentmodel.h"
#include "smartlistdelegate.h"
namespace Ui {
class TransferDialog;
class CallUtilsDialog;
}
class ActiveCallsProxyModel : public QSortFilterProxyModel
class NotCurrentProxyModel : public QSortFilterProxyModel
{
public:
ActiveCallsProxyModel(QAbstractItemModel* parent) : QSortFilterProxyModel(parent)
NotCurrentProxyModel(QAbstractItemModel* parent) : QSortFilterProxyModel(parent)
{
setSourceModel(parent);
}
......@@ -41,32 +44,34 @@ public:
auto idx = sourceModel()->index(source_row,0,source_parent);
if (not idx.isValid())
return false;
return idx.data(static_cast<int>(Call::Role::State))
.value<Call::State>() != Call::State::CURRENT;
auto call = RecentModel::instance().getActiveCall(idx);
return not call || not (call->state() == Call::State::CURRENT);
}
};
class TransferDialog : public QDialog
class CallUtilsDialog : public QDialog
{
Q_OBJECT
public:
explicit TransferDialog(QWidget *parent = 0);
~TransferDialog();
explicit CallUtilsDialog(QWidget* parent = 0);
~CallUtilsDialog();
void setConfMode(bool active);
//UI SLOTS
protected slots:
void showEvent(QShowEvent *event);
void showEvent(QShowEvent* event);
void closeEvent(QCloseEvent* event);
private slots:
void on_transferButton_clicked();
void on_activeCallsView_doubleClicked(const QModelIndex &index);
void on_activeCallsView_clicked(const QModelIndex &index);
void on_contactView_doubleClicked(const QModelIndex& index);
private:
Ui::TransferDialog *ui;
Call *selectedCall_;
ActiveCallsProxyModel *activeProxy_;
Ui::CallUtilsDialog* ui;
bool confMode_;
SmartListDelegate* smartListDelegate_;
NotCurrentProxyModel* notCurrentProxyModel_;
void removeProxyModel();
};
......
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>TransferDialog</class>
<widget class="QDialog" name="TransferDialog">
<class>CallUtilsDialog</class>
<widget class="QDialog" name="CallUtilsDialog">
<property name="geometry">
<rect>
<x>0</x>
......@@ -13,18 +13,23 @@
<property name="windowTitle">
<string>Dialog</string>
</property>
<layout class="QGridLayout" name="gridLayout" rowstretch="0,0,0,0" columnstretch="0,0">
<item row="1" column="0">
<widget class="QListView" name="activeCallsView"/>
</item>
<item row="3" column="0" colspan="2">
<widget class="QPushButton" name="transferButton">
<property name="text">
<string>Transfer</string>
<layout class="QVBoxLayout" name="verticalLayout">
<property name="leftMargin">
<number>0</number>
</property>
</widget>
<property name="topMargin">
<number>4</number>
</property>
<property name="rightMargin">
<number>0</number>
</property>
<property name="bottomMargin">
<number>1</number>
</property>
<item>
<widget class="QListView" name="contactView"/>
</item>
<item row="2" column="0">
<item>
<widget class="QLineEdit" name="numberBar">
<property name="placeholderText">
<string>or type number...</string>
......@@ -34,10 +39,10 @@
</property>
</widget>
</item>
<item row="0" column="0">
<widget class="QLabel" name="label">
<item>
<widget class="QPushButton" name="transferButton">
<property name="text">
<string>Current Calls</string>
<string>Transfer</string>
</property>
</widget>
</item>
......
......@@ -150,8 +150,8 @@ CallWidget::CallWidget(QWidget *parent) :
findRingAccount();
} catch (...) {
qDebug() << "INIT ERROR";
} catch (const std::exception& e) {
qDebug() << "INIT ERROR" << e.what();
}
}
......@@ -270,9 +270,6 @@ CallWidget::callStateChanged(Call* call, Call::State previousState)
if (call == nullptr)
return;
//Force update of smartList
ui->smartList->setFocus();
if (call->state() == Call::State::OVER
|| call->state() == Call::State::ERROR
|| call->state() == Call::State::FAILURE
......@@ -349,8 +346,8 @@ void
CallWidget::setActualCall(Call* value)
{
actualCall_ = value;
if (value)
CallModel::instance().selectCall(value);
ui->videoWidget->pushRenderer(value);
}
void
......@@ -395,18 +392,14 @@ CallWidget::smartListSelectionChanged(const QItemSelection &newSel, const QItemS
Q_UNUSED(oldSel)
auto newIdx = newSel.indexes().first();
if (newIdx.parent().isValid())
if (not newIdx.isValid())
return;
auto newIdxCall = RecentModel::instance().getActiveCall(RecentModel::instance().peopleProxy()->mapToSource(newIdx));
if (newIdxCall == actualCall_)
return;
if (actualCall_ != nullptr) {
actualCall_->performAction(Call::Action::HOLD);
}
if (newIdxCall) {
newIdxCall->performAction(Call::Action::HOLD);
setActualCall(newIdxCall);
ui->stackedWidget->setCurrentWidget(ui->videoPage);
} else {
......
......@@ -21,15 +21,14 @@
#include "callmodel.h"
VideoOverlay::VideoOverlay(QWidget *parent) :
VideoOverlay::VideoOverlay(QWidget* parent) :
QWidget(parent),
ui(new Ui::VideoOverlay),
transferDialog_(new TransferDialog())
transferDialog_(new CallUtilsDialog())
{
ui->setupUi(this);
ui->chatButton->setCheckable(true);
ui->transferButton->setCheckable(true);
actionModel_ = CallModel::instance().userActionModel();
setAttribute(Qt::WA_NoSystemBackground);
......@@ -62,6 +61,10 @@ VideoOverlay::VideoOverlay(QWidget *parent) :
muteVideo->setChecked(idx.data(Qt::CheckStateRole).value<bool>());
muteVideo->setEnabled(idx.flags() & Qt::ItemIsEnabled);
break;
case UserActionModel::Action::HOLD:
ui->holdButton->setChecked(idx.data(Qt::CheckStateRole).value<bool>());
ui->holdButton->setEnabled(idx.flags() & Qt::ItemIsEnabled);
break;
default:
break;
}
......@@ -69,6 +72,30 @@ VideoOverlay::VideoOverlay(QWidget *parent) :
});
ui->moreButton->setMenu(menu_);
connect(CallModel::instance().selectionModel(), &QItemSelectionModel::currentChanged, [=](const QModelIndex &current, const QModelIndex &previous) {
Q_UNUSED(previous)
Call* c = current.data(static_cast<int>(Call::Role::Object)).value<Call*>();
if (c) {
if (c->hasParentCall()) {
ui->holdButton->hide();
ui->moreButton->hide();
ui->transferButton->hide();
ui->addPersonButton->hide();
ui->chatButton->hide();
ui->joinButton->show();
} else {
ui->holdButton->show();
ui->moreButton->show();
ui->transferButton->show();
ui->addPersonButton->show();
ui->chatButton->show();
ui->joinButton->hide();
}
}
});
}
VideoOverlay::~VideoOverlay()
......@@ -90,13 +117,6 @@ VideoOverlay::setTime(const QString& time)
ui->timerLabel->setText(time);
}
void
VideoOverlay::on_holdButton_toggled(bool checked)
{
Q_UNUSED(checked)
actionModel_->execute(UserActionModel::Action::HOLD);
}
void
VideoOverlay::on_hangupButton_clicked()
{
......@@ -111,9 +131,36 @@ VideoOverlay::on_chatButton_toggled(bool checked)
}
void
VideoOverlay::on_transferButton_toggled(bool checked)
VideoOverlay::on_transferButton_clicked()
{
transferDialog_->setConfMode(false);
auto pos = this->mapToGlobal(ui->transferButton->pos());
transferDialog_->move(pos.x() + ui->transferButton->width(), pos.y() - (transferDialog_->height()/2));
checked ? transferDialog_->show() : transferDialog_->hide();
transferDialog_->move(pos.x()
- transferDialog_->size().width()/2
+ ui->transferButton->size().width()/2,
pos.y() - (transferDialog_->height()));
transferDialog_->show();
}
void
VideoOverlay::on_addPersonButton_clicked()
{
transferDialog_->setConfMode(true);
auto pos = this->mapToGlobal(ui->addPersonButton->pos());
transferDialog_->move(pos.x()
- transferDialog_->size().width()/2
+ ui->addPersonButton->size().width()/2,
pos.y() - (transferDialog_->height()));
transferDialog_->show();
}
void
VideoOverlay::on_holdButton_clicked()
{
actionModel_->execute(UserActionModel::Action::HOLD);
}
void VideoOverlay::on_joinButton_clicked()
{
CallModel::instance().selectedCall()->joinToParent();
}
......@@ -23,7 +23,7 @@
#include "useractionmodel.h"
#include "transferdialog.h"
#include "callutilsdialog.h"
namespace Ui {
class VideoOverlay;
......@@ -34,25 +34,27 @@ class VideoOverlay : public QWidget
Q_OBJECT
public:
explicit VideoOverlay(QWidget *parent = 0);
explicit VideoOverlay(QWidget* parent = 0);
~VideoOverlay();
public:
void setName(const QString &name);
void setTime(const QString &time);
void setName(const QString& name);
void setTime(const QString& time);
//UI SLOTS
private slots:
void on_holdButton_toggled(bool checked);
void on_hangupButton_clicked();
void on_chatButton_toggled(bool checked);
void on_transferButton_toggled(bool checked);
void on_transferButton_clicked();
void on_addPersonButton_clicked();
void on_holdButton_clicked();
void on_joinButton_clicked();
private:
Ui::VideoOverlay *ui;
Ui::VideoOverlay* ui;
UserActionModel* actionModel_;
QMenu* menu_;
TransferDialog *transferDialog_;
CallUtilsDialog* transferDialog_;
signals:
void setChatVisibility(bool visible);
......
......@@ -23,22 +23,8 @@
<string/>
</property>
<layout class="QGridLayout" name="gridLayout">
<item row="1" column="2">
<widget class="QPushButton" name="hangupButton">
<property name="text">
<string>Hangup</string>
</property>
</widget>
</item>
<item row="1" column="5">
<widget class="QPushButton" name="moreButton">
<property name="text">
<string>...</string>
</property>
</widget>
</item>
<item row="1" column="0">
<spacer name="horizontalSpacer">
<item row="1" column="8">
<spacer name="horizontalSpacer_2">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
......@@ -50,21 +36,15 @@
</property>
</spacer>
</item>
<item row="1" column="6">
<spacer name="horizontalSpacer_2">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>40</width>
<height>20</height>
</size>
<item row="1" column="2">
<widget class="QPushButton" name="hangupButton">
<property name="text">
<string>Hangup</string>
</property>
</spacer>
</widget>
</item>
<item row="0" column="0" alignment="Qt::AlignTop">
<widget class="QLabel" name="nameLabel">
<item row="0" column="8" alignment="Qt::AlignRight|Qt::AlignTop">
<widget class="QLabel" name="timerLabel">
<property name="palette">
<palette>
<active>
......@@ -103,12 +83,26 @@
</palette>
</property>
<property name="text">
<string/>
<string>00:00</string>
</property>
</widget>
</item>
<item row="0" column="6" alignment="Qt::AlignRight|Qt::AlignTop">
<widget class="QLabel" name="timerLabel">
<item row="1" column="4">
<widget class="QPushButton" name="addPersonButton">
<property name="text">
<string>Add People</string>
</property>
</widget>
</item>
<item row="1" column="7">
<widget class="QPushButton" name="moreButton">
<property name="text">
<string>...</string>
</property>
</widget>
</item>
<item row="0" column="0" alignment="Qt::AlignTop">
<widget class="QLabel" name="nameLabel">
<property name="palette">
<palette>
<active>
......@@ -147,10 +141,30 @@
</palette>
</property>
<property name="text">
<string>00:00</string>
<string/>
</property>
</widget>
</item>
<item row="1" column="3">
<widget class="QPushButton" name="chatButton">
<property name="text">
<string>Chat</string>
</property>
</widget>
</item>
<item row="1" column="0">
<spacer name="horizontalSpacer">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>40</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
<item row="1" column="1">
<widget class="QPushButton" name="holdButton">
<property name="text">
......@@ -161,17 +175,17 @@
</property>
</widget>
</item>
<item row="1" column="3">
<widget class="QPushButton" name="chatButton">
<item row="1" column="6">
<widget class="QPushButton" name="transferButton">
<property name="text">
<string>Chat</string>
<string>Transfer</string>
</property>
</widget>
</item>
<item row="1" column="4">
<widget class="QPushButton" name="transferButton">
<item row="1" column="5">
<widget class="QPushButton" name="joinButton">
<property name="text">
<string>Transfer</string>
<string>Join</string>
</property>
</widget>
</item>
......
......@@ -35,7 +35,7 @@
#include "videooverlay.h"
#include "selectareadialog.h"
VideoView::VideoView(QWidget *parent) :
VideoView::VideoView(QWidget* parent) :
QWidget(parent),
ui(new Ui::VideoView)
{
......@@ -72,7 +72,7 @@ VideoView::~VideoView()
}
void
VideoView::resizeEvent(QResizeEvent *event)
VideoView::resizeEvent(QResizeEvent* event)
{
Q_UNUSED(event)
overlay_->resize(this->size());
......@@ -99,24 +99,26 @@ void
VideoView::callStateChanged(Call* call, Call::State previousState)
{
Q_UNUSED(previousState)
if (call->state() == Call::State::CURRENT) {
ui->videoWidget->show();
timerConnection_ = connect(call, SIGNAL(changed()), this, SLOT(updateCall()));
}
else {
QObject::disconnect(timerConnection_);
emit setChatVisibility(false);
if (isFullScreen())
toggleFullScreen();
QObject::disconnect(timerConnection_);
}
}
void
VideoView::updateCall()
{
auto call = CallModel::instance().selectedCall();
if (auto call = CallModel::instance().selectedCall()) {
overlay_->setName(call->formattedName());
overlay_->setTime(call->length());
}
}
void
......@@ -125,13 +127,15 @@ VideoView::mouseDoubleClickEvent(QMouseEvent* e) {
toggleFullScreen();
}
void VideoView::dragEnterEvent(QDragEnterEvent *event)
void
VideoView::dragEnterEvent(QDragEnterEvent* event)
{
if (event->mimeData()->hasUrls())
event->acceptProposedAction();
}
void VideoView::dropEvent(QDropEvent *event)
void
VideoView::dropEvent(QDropEvent* event)
{
auto urls = event->mimeData()->urls();
Video::SourceModel::instance().setFile(urls.at(0));
......@@ -204,3 +208,27 @@ VideoView::showContextMenu(const QPoint& pos)
menu.exec(globalPos);
}
void
VideoView::pushRenderer(Call* call) {
if (not call) {
disconnect(videoStartedConnection_);
return;
}
if (auto renderer = call->videoRenderer()) {
slotVideoStarted(renderer);
} else {
disconnect(videoStartedConnection_);
videoStartedConnection_ = connect(call,
SIGNAL(videoStarted(Video::Renderer*)),
this,
SLOT(slotVideoStarted(Video::Renderer*)));
}