This commit is contained in:
Julien Wadel 2022-04-22 17:40:54 +02:00
parent 9ab931da4d
commit 0965e88615
39 changed files with 767 additions and 548 deletions

View file

@ -5,8 +5,8 @@
viewBox="0 0 80 80"
version="1.1"
id="svg12"
sodipodi:docname="search.svg"
inkscape:version="1.1 (c68e22c387, 2021-05-23)"
sodipodi:docname="search_custom.svg"
inkscape:version="1.1.2 (0a00cf5339, 2022-02-04)"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns="http://www.w3.org/2000/svg"

Before

Width:  |  Height:  |  Size: 3.3 KiB

After

Width:  |  Height:  |  Size: 3.3 KiB

View file

@ -965,6 +965,7 @@ void App::setAutoStart (bool enabled) {
void App::openAppAfterInit (bool mustBeIconified) {
qInfo() << QStringLiteral("Open " APPLICATION_NAME " app.");
auto coreManager = CoreManager::getInstance();
coreManager->getSettingsModel()->updateCameraMode();
// Create other windows.
mCallsWindow = createSubWindow(mEngine, Constants::QmlViewCallsWindow);
mSettingsWindow = createSubWindow(mEngine, Constants::QmlViewSettingsWindow);

View file

@ -182,17 +182,21 @@ void CallsListModel::launchVideoCall (const QString &sipAddress, const QString&
return;
shared_ptr<linphone::CallParams> params = core->createCallParams(nullptr);
bool enableVideo = options.contains("video") ? options["video"].toBool() : true;
params->enableVideo(enableVideo);
if( enableVideo ){
params->setVideoDirection(linphone::MediaDirection::SendRecv);
params->setConferenceVideoLayout(linphone::ConferenceLayout::Grid);
}
params->setConferenceVideoLayout(linphone::ConferenceLayout::Grid);
params->enableMic(options.contains("micro") ? options["micro"].toBool() : true);
params->enableAudio(options.contains("audio") ? options["audio"].toBool() : true); // ???
bool enableVideo = options.contains("video") ? options["video"].toBool() : true;
bool enableSpeaker = options.contains("audio") ? options["audio"].toBool() : true;
params->enableVideo(enableVideo);
params->setAccount(core->getDefaultAccount());
CallModel::setRecordFile(params, Utils::coreStringToAppString(address->getUsername()));
CallModel::prepareTransfert(core->inviteAddressWithParams(address, params), prepareTransfertAddress);
auto call = core->inviteAddressWithParams(address, params);
call->setSpeakerMuted(!enableSpeaker);
qWarning() << "Launch Video call camera: " << enableVideo << " speaker:" << enableSpeaker << ", micro:" << params->micEnabled();
CallModel::prepareTransfert(call, prepareTransfertAddress);
}
ChatRoomModel* CallsListModel::launchSecureChat (const QString &sipAddress) const {

View file

@ -43,7 +43,7 @@ int Camera::mPreviewCounter;
// =============================================================================
Camera::Camera (QQuickItem *parent) : QQuickFramebufferObject(parent) {
setTextureFollowsItemSize(true);
// The fbo content must be y-mirrored because the ms rendering is y-inverted.
setMirrorVertically(true);

View file

@ -147,6 +147,17 @@ bool ConferenceInfoModel::isScheduled() const{
return mIsScheduled;
}
QVariantList ConferenceInfoModel::getParticipants() const{
QVariantList addresses;
for(auto item : mConferenceInfo->getParticipants()){
QVariantMap participant;
participant["displayName"] = Utils::getDisplayName(item);
participant["address"] = QString::fromStdString(item->asStringUriOnly());
addresses << participant;
}
return addresses;
}
//------------------------------------------------------------------------------------------------
void ConferenceInfoModel::setDateTime(const QDateTime& dateTime){

View file

@ -63,6 +63,7 @@ public:
Q_INVOKABLE QString displayNamesToString()const;
QString getUri() const;
bool isScheduled() const;
Q_INVOKABLE QVariantList getParticipants() const;
void setDateTime(const QDateTime& dateTime);
void setDuration(const int& duration);

View file

@ -343,7 +343,6 @@ void CoreManager::migrate () {
mCore->enableLimeX3Dh(true);
}
config->setInt(SettingsModel::UiSection, Constants::RcVersionName, Constants::RcVersionCurrent);
}

View file

@ -227,6 +227,13 @@ void ParticipantDeviceListModel::onParticipantDeviceRemoved(const std::shared_pt
}
void ParticipantDeviceListModel::onParticipantDeviceJoined(const std::shared_ptr<const linphone::ParticipantDevice> & participantDevice){
for(auto item : mList) {
auto device = item.objectCast<ParticipantDeviceModel>();
if(device->getDevice() == participantDevice) {
device->setPaused(false);
return;
}
}
onParticipantDeviceAdded(participantDevice);
/*
for(auto item : mList) {
@ -242,7 +249,7 @@ void ParticipantDeviceListModel::onParticipantDeviceLeft(const std::shared_ptr<c
for(auto item : mList) {
auto device = item.objectCast<ParticipantDeviceModel>();
if(device->getDevice() == participantDevice) {
emit device->videoEnabledChanged();
device->setPaused(true);
return;
}
}

View file

@ -20,6 +20,8 @@
#include "ParticipantDeviceListener.hpp"
#include <QDebug>
// =============================================================================
ParticipantDeviceListener::ParticipantDeviceListener(QObject *parent) : QObject(parent) {
@ -27,10 +29,12 @@ ParticipantDeviceListener::ParticipantDeviceListener(QObject *parent) : QObject(
//--------------------------------------------------------------------
void ParticipantDeviceListener::onIsSpeakingChanged(const std::shared_ptr<linphone::ParticipantDevice> & participantDevice, bool isSpeaking) {
qWarning() << "onIsSpeakingChanged " << isSpeaking;
emit isSpeakingChanged(participantDevice, isSpeaking);
}
void ParticipantDeviceListener::onIsMuted(const std::shared_ptr<linphone::ParticipantDevice> & participantDevice, bool isMutedVar) {
qWarning() << "onIsMuted " << isMutedVar << " vs " << participantDevice->getIsMuted();
emit isMuted(participantDevice, isMutedVar);
}

View file

@ -41,9 +41,11 @@ ParticipantDeviceModel::ParticipantDeviceModel (CallModel * callModel, std::shar
App::getInstance()->getEngine()->setObjectOwnership(this, QQmlEngine::CppOwnership);// Avoid QML to destroy it when passing by Q_INVOKABLE
mIsMe = isMe;
mParticipantDevice = device;
mParticipantDeviceListener = std::make_shared<ParticipantDeviceListener>(nullptr);
if( device)
if( device) {
mParticipantDeviceListener = std::make_shared<ParticipantDeviceListener>(nullptr);
connectTo(mParticipantDeviceListener.get());
device->addListener(mParticipantDeviceListener);
}
mCall = callModel;
if(mCall)
connect(mCall, &CallModel::statusChanged, this, &ParticipantDeviceModel::onCallStatusChanged);
@ -109,6 +111,18 @@ QString ParticipantDeviceModel::getAddress() const{
: "";
}
bool ParticipantDeviceModel::getPaused() const{
return mIsPaused;
}
bool ParticipantDeviceModel::getIsSpeaking() const{
return mIsSpeaking;
}
bool ParticipantDeviceModel::getIsMuted() const{
return mParticipantDevice ? mParticipantDevice->getIsMuted() : false;
}
std::shared_ptr<linphone::ParticipantDevice> ParticipantDeviceModel::getDevice(){
return mParticipantDevice;
}
@ -117,6 +131,20 @@ bool ParticipantDeviceModel::isVideoEnabled() const{
return mIsVideoEnabled;
}
void ParticipantDeviceModel::setPaused(bool paused){
if(mIsPaused != paused){
mIsPaused = paused;
emit isPausedChanged();
}
}
void ParticipantDeviceModel::setIsSpeaking(bool speaking){
if(mIsSpeaking != speaking){
mIsSpeaking = speaking;
emit isSpeakingChanged();
}
}
void ParticipantDeviceModel::updateVideoEnabled(){
bool enabled = mParticipantDevice && mParticipantDevice->getStreamAvailability(linphone::StreamType::Video) &&
( mParticipantDevice->getStreamCapability(linphone::StreamType::Video) == linphone::MediaDirection::SendRecv
@ -147,8 +175,10 @@ void ParticipantDeviceModel::onCallStatusChanged(){
//--------------------------------------------------------------------
void ParticipantDeviceModel::onIsSpeakingChanged(const std::shared_ptr<linphone::ParticipantDevice> & participantDevice, bool isSpeaking) {
setIsSpeaking(isSpeaking);
}
void ParticipantDeviceModel::onIsMuted(const std::shared_ptr<linphone::ParticipantDevice> & participantDevice, bool isMuted) {
emit isMutedChanged();
}
void ParticipantDeviceModel::onConferenceJoined(const std::shared_ptr<linphone::ParticipantDevice> & participantDevice) {
updateVideoEnabled();

View file

@ -51,6 +51,9 @@ public:
Q_PROPERTY(time_t timeOfJoining READ getTimeOfJoining CONSTANT)
Q_PROPERTY(bool videoEnabled READ isVideoEnabled NOTIFY videoEnabledChanged)
Q_PROPERTY(bool isMe READ isMe CONSTANT)
Q_PROPERTY(bool isPaused READ getPaused WRITE setPaused NOTIFY isPausedChanged)
Q_PROPERTY(bool isSpeaking READ getIsSpeaking WRITE setIsSpeaking NOTIFY isSpeakingChanged)
Q_PROPERTY(bool isMuted READ getIsMuted NOTIFY isMutedChanged)
QString getName() const;
QString getDisplayName() const;
@ -59,9 +62,15 @@ public:
time_t getTimeOfJoining() const;
bool isVideoEnabled() const;
bool isMe() const;
bool getPaused() const;
bool getIsSpeaking() const;
bool getIsMuted() const;
std::shared_ptr<linphone::ParticipantDevice> getDevice();
void setPaused(bool paused);
void setIsSpeaking(bool speaking);
//void deviceSecurityLevelChanged(std::shared_ptr<const linphone::Address> device);
virtual void onIsSpeakingChanged(const std::shared_ptr<linphone::ParticipantDevice> & participantDevice, bool isSpeaking);
virtual void onIsMuted(const std::shared_ptr<linphone::ParticipantDevice> & participantDevice, bool isMuted);
@ -79,11 +88,16 @@ public slots:
signals:
void securityLevelChanged();
void videoEnabledChanged();
void isPausedChanged();
void isSpeakingChanged();
void isMutedChanged();
private:
bool mIsMe = false;
bool mIsVideoEnabled;
bool mIsPaused = false;
bool mIsSpeaking = false;
std::shared_ptr<linphone::ParticipantDevice> mParticipantDevice;
std::shared_ptr<ParticipantDeviceListener> mParticipantDeviceListener; // This is passed to linpĥone object and must be in shared_ptr

View file

@ -555,6 +555,12 @@ void SettingsModel::setShowVideoCodecs (bool status) {
emit showVideoCodecsChanged(status);
}
// =============================================================================
void SettingsModel::updateCameraMode(){
auto mode = mConfig->getString("video", "main_display_mode", "BlackBars");
mConfig->setString("video", "main_display_mode", mode);
mConfig->setString("video", "other_display_mode", mode);
}
// =============================================================================
// Chat & calls.
// =============================================================================

View file

@ -332,6 +332,8 @@ public:
bool getShowVideoCodecs () const;
void setShowVideoCodecs (bool status);
void updateCameraMode();
// Chat & calls. -------------------------------------------------------------
bool getAutoAnswerStatus () const;

View file

@ -9,8 +9,12 @@ import Common.Styles 1.0
Rectangle {
property alias text: textArea.text
property alias placeholderText: textArea.placeholderText
readonly property alias length: textArea.length
property alias boundsBehavior: flickable.boundsBehavior
property alias font: textArea.font
property alias textColor: textArea.color
property alias readOnly: textArea.readOnly
height: TextAreaFieldStyle.background.height
width: TextAreaFieldStyle.background.width

View file

@ -1,4 +1,4 @@
import QtQuick 2.15
import QtQuick 2.12
import QtQuick.Controls 2.2
import QtQuick.Layouts 1.0
import QtQml.Models 2.12
@ -85,7 +85,7 @@ ColumnLayout{
}*/
GridView{
id: grid
property int margin: 10
property int itemCount: model.count ? model.count :( model.length ? model.length : 0)
property int columns: 1
property int rows: 1
@ -100,8 +100,8 @@ ColumnLayout{
function getRowCount(itemCount){
return columns > 1 ? (itemCount-1) / columns + 1 : 1
}
property int computedWidth: (mainLayout.width - 5 ) / columns
property int computedHeight: (mainLayout.height - 5 ) / rows
property int computedWidth: (mainLayout.width - grid.margin ) / columns
property int computedHeight: (mainLayout.height - grid.margin ) / rows
cellWidth: ( squaredDisplay ? Math.min(computedWidth, computedHeight) : computedWidth)
cellHeight: ( squaredDisplay ? Math.min(computedWidth, computedHeight) : computedHeight)

View file

@ -77,6 +77,7 @@ Item {
icon: 'search_custom'
overwriteColor: SearchBoxStyle.iconColor
iconSize: height
readOnly: !searchBox.enabled
width: parent.width

View file

@ -14,11 +14,11 @@ ListView {
// ---------------------------------------------------------------------------
readonly property var selectedCall: calls._selectedCall
readonly property CallModel selectedCall: calls._selectedCall
property var conferenceModel
property var _selectedCall
property CallModel _selectedCall: null
// ---------------------------------------------------------------------------

View file

@ -20,8 +20,9 @@ Item {
property bool isPreview: !container.currentDevice || container.currentDevice.isMe
property bool isFullscreen: false
property bool hideCamera: false //callModel.pausedByUser
property bool showCloseButton: true
signal closeRequested()
property bool isPaused: false
property bool isVideoEnabled: !container.currentDevice || (container.currentDevice && container.currentDevice.videoEnabled)
function resetActive(){
resetTimer.resetActive()
@ -43,17 +44,13 @@ Item {
}
Loader {
id: cameraLoader
property bool isVideoEnabled: !container.currentDevice || (container.currentDevice && container.currentDevice.videoEnabled)
property bool resetActive: false
property int cameraMode: isVideoEnabled ? container.isPreview ? 1 : 2 : 0
onCameraModeChanged: console.log(cameraMode)
anchors.fill: parent
active: !resetActive && isVideoEnabled //avatarCell.currentDevice && (avatarCell.currentDevice.videoEnabled && !conference._fullscreen)
sourceComponent: cameraMode == 1 ? cameraPreview : cameraMode == 2 ? camera : null
active: !resetActive && container.isVideoEnabled //avatarCell.currentDevice && (avatarCell.currentDevice.videoEnabled && !conference._fullscreen)
sourceComponent: container.isVideoEnabled && !container.isPaused? camera : null
Timer{
id: resetTimer
@ -75,65 +72,13 @@ Item {
Camera {
participantDeviceModel: container.currentDevice
anchors.fill: parent
isPreview: container.isPreview
onRequestNewRenderer: {resetTimer.resetActive()}
Component.onDestruction: {resetWindowId()}
Component.onCompleted: console.log("Completed Camera")
Text{
id: username
anchors.right: parent.right
anchors.left: parent.left
anchors.bottom: parent.bottom
anchors.margins: 10
elide: Text.ElideRight
maximumLineCount: 1
text: container.currentDevice.displayName
font.pointSize: CameraViewStyle.contactDescription.pointSize
font.weight: CameraViewStyle.contactDescription.weight
color: CameraViewStyle.contactDescription.color
}/*
DropShadow {
anchors.fill: username
source: username
verticalOffset: 2
color: "#80000000"
radius: 1
samples: 3
}*/
Glow {
anchors.fill: username
//spread: 1
radius: 12
samples: 25
color: "#80000000"
source: username
}
}
}
Component {
id: cameraPreview
Camera {
anchors.fill: parent
isPreview: true
onRequestNewRenderer: {resetTimer.resetActive()}
Component.onDestruction: {resetWindowId();}
Component.onCompleted: console.log("Completed Preview")
Rectangle{
anchors.fill: parent
color: 'black'
visible: container.hideCamera
}
ActionButton{
visible: container.showCloseButton
anchors.right: parent.right
anchors.top: parent.top
anchors.rightMargin: 15
anchors.topMargin: 15
isCustom: true
colorSet: CameraViewStyle.closePreview
onClicked: container.closeRequested()
}
}
}
}
}
}

View file

@ -12,13 +12,31 @@ Item{
id: mainItem
property alias currentDevice: camera.currentDevice
property alias hideCamera: camera.hideCamera
property alias showCloseButton: camera.showCloseButton
property alias isPaused: camera.isPaused
property bool showCloseButton: true
property color color : CameraViewStyle.backgroundColor
signal closeRequested()
MouseArea{
anchors.fill: parent
onClicked: {camera.resetActive()}
onClicked: camera.resetActive()
}
RectangularGlow {
id: effect
anchors.fill: backgroundArea
glowRadius: 4
spread: 0.9
color: CameraViewStyle.border.color
cornerRadius: backgroundArea.radius + glowRadius
visible: mainItem.currentDevice && mainItem.currentDevice.isSpeaking
}
Rectangle {
id: backgroundArea
color: mainItem.color
anchors.fill: parent
radius: CameraViewStyle.radius
}
Rectangle{
id: showArea
anchors.fill: parent
@ -30,12 +48,12 @@ Item{
id: camera
anchors.fill: parent
visible: false
onCloseRequested: mainItem.closeRequested()
}
OpacityMask{
id: renderedCamera
anchors.fill: parent
source: camera
maskSource: showArea
maskSource: backgroundArea
invert:false
visible: true
@ -56,4 +74,87 @@ Item{
//transform: ( camera.isPreview ? mirroredRotationMatrix : rotationMatrix)
*/
}
Rectangle{
id: hideView
anchors.fill: parent
color: CameraViewStyle.pauseView.backgroundColor
radius: CameraViewStyle.radius
visible: mainItem.isPaused
onVisibleChanged: console.log(visible)
Rectangle{
anchors.centerIn: parent
height: CameraViewStyle.pauseView.button.iconSize
width: height
radius: width/2
color: CameraViewStyle.pauseView.button.backgroundNormalColor
Icon{
anchors.centerIn: parent
icon: CameraViewStyle.pauseView.button.icon
overwriteColor: CameraViewStyle.pauseView.button.foregroundNormalColor
iconSize: CameraViewStyle.pauseView.button.iconSize
}
}
}
Text{
id: username
visible: mainItem.currentDevice
anchors.right: parent.right
anchors.left: parent.left
anchors.bottom: parent.bottom
anchors.margins: 10
elide: Text.ElideRight
maximumLineCount: 1
text: mainItem.currentDevice && mainItem.currentDevice.displayName + (mainItem.isPaused ? ' (en pause)' : '')
font.pointSize: CameraViewStyle.contactDescription.pointSize
font.weight: CameraViewStyle.contactDescription.weight
color: CameraViewStyle.contactDescription.color
}
/*
DropShadow {
anchors.fill: username
source: username
verticalOffset: 2
color: "#80000000"
radius: 1
samples: 3
}*/
Glow {
anchors.fill: username
//spread: 1
radius: 12
samples: 25
color: "#80000000"
source: username
}
ActionButton{
visible: mainItem.showCloseButton && camera.isPreview
anchors.right: parent.right
anchors.top: parent.top
anchors.rightMargin: 15
anchors.topMargin: 15
isCustom: true
colorSet: CameraViewStyle.closePreview
onClicked: mainItem.closeRequested()
}
Rectangle{
visible: mainItem.currentDevice && mainItem.currentDevice.isMuted
onVisibleChanged: console.log(visible)
anchors.left: parent.left
anchors.top: parent.top
anchors.leftMargin: 15
anchors.topMargin: 15
height: CameraViewStyle.isMuted.button.iconSize
width: height
radius: width/2
color: CameraViewStyle.isMuted.button.backgroundNormalColor
Icon{
anchors.centerIn: parent
icon: CameraViewStyle.isMuted.button.icon
overwriteColor: CameraViewStyle.isMuted.button.foregroundNormalColor
iconSize: CameraViewStyle.isMuted.button.iconSize
}
}
}

View file

@ -22,30 +22,33 @@ import 'Message.js' as Logic
Loader{
id: mainItem
property ContentModel contentModel
property ConferenceInfoModel conferenceInfoModel: contentModel && active ? contentModel.conferenceInfoModel : null
property ConferenceInfoModel conferenceInfoModel: contentModel ? contentModel.conferenceInfoModel : null
property int maxWidth : parent.width
property int fitHeight: active && item ? item.fitHeight + ChatCalendarMessageStyle.heightMargin*2 : 0
property int fitHeight: active && item ? item.fitHeight + ChatCalendarMessageStyle.topMargin+ChatCalendarMessageStyle.bottomMargin + (isExpanded? 200 : 0): 0
property int fitWidth: active && item ? Math.max(item.fitWidth, maxWidth/2) + ChatCalendarMessageStyle.widthMargin*2 : 0
property bool containsMouse: false
property int gotoButtonMode: -1 //-1: hide, 0:goto, 1:MoreInfo
property bool isExpanded : false
signal expandToggle()
width: parent.width
height: fitHeight
height: parent.height
property font customFont : SettingsModel.textMessageFont
active: (mainItem.contentModel && mainItem.contentModel.isIcalendar()) || (!mainItem.contentModel && mainItem.conferenceInfoModel)
active: mainItem.conferenceInfoModel
// (mainItem.contentModel && mainItem.contentModel.isIcalendar()) || (!mainItem.contentModel && mainItem.conferenceInfoModel)
sourceComponent: MouseArea{
id: loadedItem
property int fitHeight: layout.fitHeight + ChatCalendarMessageStyle.heightMargin
property int fitHeight: layout.fitHeight + ChatCalendarMessageStyle.topMargin+ChatCalendarMessageStyle.bottomMargin
property int fitWidth: layout.fitWidth
anchors.fill: parent
anchors.leftMargin: ChatCalendarMessageStyle.widthMargin
anchors.rightMargin: ChatCalendarMessageStyle.widthMargin
anchors.topMargin: ChatCalendarMessageStyle.heightMargin
anchors.bottomMargin: ChatCalendarMessageStyle.heightMargin
anchors.topMargin: ChatCalendarMessageStyle.topMargin
anchors.bottomMargin: ChatCalendarMessageStyle.bottomMargin
clip: false
@ -62,13 +65,13 @@ Loader{
RowLayout {
Layout.fillWidth: true
Layout.preferredWidth: parent.width // Need this because fillWidth is not enough...
Layout.preferredHeight: ChatCalendarMessageStyle.schedule.iconSize
Layout.preferredHeight: ChatCalendarMessageStyle.lineHeight
Layout.topMargin: 5
spacing: 10
RowLayout {
id: scheduleRow
Layout.fillWidth: true
Layout.preferredHeight: ChatCalendarMessageStyle.schedule.iconSize
Layout.preferredHeight: ChatCalendarMessageStyle.lineHeight
Layout.leftMargin: 5
spacing: ChatCalendarMessageStyle.schedule.spacing
@ -87,18 +90,15 @@ Loader{
elide: Text.ElideRight
font.pointSize: ChatCalendarMessageStyle.schedule.pointSize
text: Qt.formatDateTime(mainItem.conferenceInfoModel.dateTime, 'hh:mm')
+' - ' +Qt.formatDateTime(mainItem.conferenceInfoModel.endDateTime, 'hh:mm')
+' - ' +Qt.formatDateTime(mainItem.conferenceInfoModel.endDateTime, 'hh:mm')
}
}
Item{
Layout.fillWidth: true
Layout.fillHeight: true
}
Text{
Layout.fillHeight: true
Layout.minimumWidth: implicitWidth
Layout.preferredWidth: implicitWidth
Layout.fillWidth: true
//Layout.minimumWidth: implicitWidth
//Layout.preferredWidth: implicitWidth
Layout.rightMargin: 15
horizontalAlignment: Qt.AlignRight
verticalAlignment: Qt.AlignVCenter
color: ChatCalendarMessageStyle.schedule.color
elide: Text.ElideRight
@ -109,7 +109,7 @@ Loader{
Text{
id: title
Layout.fillWidth: true
Layout.minimumWidth: implicitWidth
//Layout.preferredHeight:
Layout.leftMargin: 10
Layout.alignment: Qt.AlignRight
color: ChatCalendarMessageStyle.subject.color
@ -120,7 +120,7 @@ Loader{
RowLayout {
id: participantsRow
Layout.fillWidth: true
Layout.fillHeight: true
Layout.preferredHeight: ChatCalendarMessageStyle.lineHeight
Layout.leftMargin: 5
Layout.rightMargin: 15
@ -148,33 +148,67 @@ Loader{
isCustom: true
colorSet: mainItem.gotoButtonMode == 0 ? ChatCalendarMessageStyle.gotoButton : ChatCalendarMessageStyle.infoButton
backgroundRadius: width/2
onClicked: mainItem.isExpanded = !mainItem.isExpanded
onClicked: mainItem.expandToggle()
}
}
Text{
id: descriptionTitle
visible: mainItem.isExpanded
ColumnLayout{
id: expandedDescription
Layout.fillWidth: true
Layout.minimumWidth: implicitWidth
Layout.leftMargin: 10
color: ChatCalendarMessageStyle.subject.color
font.pointSize: ChatCalendarMessageStyle.subject.pointSize
font.weight: Font.Bold
text: 'Description :'
}
Text{
id: description
Layout.fillHeight: true
visible: mainItem.isExpanded
Layout.fillWidth: true
Layout.minimumWidth: implicitWidth
Layout.leftMargin: 10
color: ChatCalendarMessageStyle.description.color
font.pointSize: ChatCalendarMessageStyle.description.pointSize
//font.weight: Font.Bold
elide: Text.ElideRight
maximumLineCount: 100
text: mainItem.conferenceInfoModel.description
ScrollableListView{
id: expandedParticipantsList
Layout.fillWidth: true
Layout.minimumHeight: Math.min( count * ChatCalendarMessageStyle.lineHeight, parent.height/2)
Layout.leftMargin: 10
spacing: 0
visible: mainItem.isExpanded
onVisibleChanged: model= mainItem.conferenceInfoModel.getParticipants()
delegate: Row{
spacing: 5
width: expandedParticipantsList.width
height: ChatCalendarMessageStyle.lineHeight
Text{text: modelData.displayName
color: ChatCalendarMessageStyle.description.color
font.pointSize: ChatCalendarMessageStyle.description.pointSize
elide: Text.ElideRight
wrapMode: TextEdit.WordWrap
}
Text{text: '('+modelData.address+')'
color: ChatCalendarMessageStyle.description.color
font.pointSize: ChatCalendarMessageStyle.description.pointSize
elide: Text.ElideRight
wrapMode: TextEdit.WordWrap
}
}
}
Text{
id: descriptionTitle
Layout.fillWidth: true
Layout.leftMargin: 10
color: ChatCalendarMessageStyle.subject.color
font.pointSize: ChatCalendarMessageStyle.subject.pointSize
font.weight: Font.Bold
text: 'Description :'
}
TextAreaField{
id: description
Layout.fillWidth: true
Layout.fillHeight: true
Layout.leftMargin: 10
color: 'transparent'
readOnly: true
textColor: ChatCalendarMessageStyle.description.color
font.pointSize: ChatCalendarMessageStyle.description.pointSize
border.width: 0
//font.weight: Font.Bold
//elide: Text.ElideRight
//wrapMode: TextEdit.WordWrap
text: mainItem.conferenceInfoModel.description
}
}
}
}

View file

@ -43,6 +43,9 @@ Column{
contentModel: mainItem.contentModel
width: parent.width
maxWidth: mainItem.maxWidth
gotoButtonMode: 1
onExpandToggle: isExpanded=!isExpanded
height: fitHeight
}
ChatAudioMessage{
id: audioMessage

View file

@ -47,7 +47,7 @@ Item{
FileView{
height:mainListView.height-ChatFilePreviewStyle.filePreview.heightMargins
width: height * ChatFilePreviewStyle.filePreview.format
anchors.verticalCenter: parent.verticalCenter
anchors.verticalCenter: ScrollableListView.contentItem.verticalCenter
anchors.verticalCenterOffset: 7
//anchors.horizontalCenter: parent.horizontalCenter
thumbnail: $modelData.thumbnail

View file

@ -19,6 +19,12 @@ QtObject {
property int weight: Font.Bold
}
property QtObject border: QtObject {
property color color: ColorsList.add(sectionName+'_border', 'b').color
property int width: 2
}
//------------------------------------------------------------------------------
property QtObject closePreview: QtObject {
property int iconSize: 40
@ -32,5 +38,24 @@ QtObject {
property color foregroundPressedColor : ColorsList.addImageColor(sectionName+'_'+name+'_fg_p', icon, 'me_p_b_inv_fg').color
}
//------------------------------------------------------------------------------
property QtObject pauseView: QtObject{
property color backgroundColor : ColorsList.add(sectionName+'_pauseView_bg_n', 'l').color
property QtObject button: QtObject {
property int iconSize: 80
property string icon : 'pause_custom'
property string name : 'pause'
property color backgroundNormalColor : ColorsList.addImageColor(sectionName+'_'+name+'_bg', icon, 's_n_b_bg').color
property color foregroundNormalColor : ColorsList.addImageColor(sectionName+'_'+name+'_fg', icon, 's_n_b_fg').color
}
}
property QtObject isMuted: QtObject{
property color backgroundColor : ColorsList.add(sectionName+'_isMuted_bg', 'l').color
property QtObject button: QtObject {
property int iconSize: 40
property string icon : 'micro_off_custom'
property string name : 'isMuted'
property color backgroundNormalColor : ColorsList.addImageColor(sectionName+'_'+name+'_bg', icon, 's_d_b_bg').color
property color foregroundNormalColor : ColorsList.addImageColor(sectionName+'_'+name+'_fg', icon, 's_d_b_fg').color
}
}
}

View file

@ -8,7 +8,7 @@ import ColorsList 1.0
QtObject {
property string sectionName : 'ChatCalendarMessage'
property int heightMargin: 0
property int topMargin: 0
property int widthMargin: 5
property int minWidth: 300
@ -21,6 +21,7 @@ QtObject {
property int presenceLevelSize: 12
property int rightMargin: 25
property int spacing: 15
property int lineHeight: 20
property QtObject backgroundColor: QtObject {
property color normal: ColorsList.add(sectionName+'_conference_bg_n', 'conference_bg').color

View file

@ -186,7 +186,7 @@ ScrollableListView {
}
icon: sipAddressesView.headerButtonIcon
iconSize: SipAddressesViewStyle.header.iconSize
iconSize: parent.height
visible: icon.length > 0
}

View file

@ -191,10 +191,11 @@ ScrollableListView {
}
icon: sipAddressesView.headerButtonIcon
iconSize: SipAddressesViewStyle.header.iconSize
iconSize: parent.height
overwriteColor: sipAddressesView.headerButtonOverwriteColor
visible: icon.length > 0
}
}
}

View file

@ -513,6 +513,14 @@ function formatElapsedTime (seconds) {
return (h === 0 ? '' : h + ':') + m + ':' + s
}
function buildDate(date, time){
var dateTime = new Date()
dateTime.setFullYear(date.getFullYear(), date.getMonth(), date.getDate())
dateTime.setHours(time.getHours())
dateTime.setMinutes(time.getMinutes())
dateTime.setSeconds(time.getSeconds())
return dateTime
}
// -----------------------------------------------------------------------------
function formatSize (size) {

View file

@ -73,7 +73,7 @@ function getContent (call, conferenceInfoModel) {
if(conferenceInfoModel)
return waitingRoom
else
return videoConference
return null
}
var status = call.status
@ -97,9 +97,6 @@ function getContent (call, conferenceInfoModel) {
if(call.isConference)
return videoConference
if(!call && window.conferenceInfoModel)
return waitingRoom;
return incall
}

View file

@ -17,7 +17,9 @@ Window {
// ---------------------------------------------------------------------------
// `{}` is a workaround to avoid `TypeError: Cannot read property...` when calls list is empty
readonly property var call: ( calls.selectedCall?calls.selectedCall:{
readonly property CallModel call: calls.selectedCall
/*
?calls.selectedCall:{
callError: '',
isOutgoing: true,
recording: false,
@ -29,6 +31,7 @@ Window {
videoEnabled: false,
chatRoomModel:null
});
*/
property ConferenceInfoModel conferenceInfoModel
readonly property bool chatIsOpened: !rightPaned.isClosed()
readonly property bool callsIsOpened: !mainPaned.isClosed()
@ -44,14 +47,14 @@ Window {
rightPaned.close()
}
function conferenceManagerResult(exitValue){
function endOfProcess(exitValue){
window.detachVirtualWindow();
if(exitValue == 0 && calls.count == 0)
close();
}
function openConferenceManager (params) {
Logic.openConferenceManager(params, conferenceManagerResult)
Logic.openConferenceManager(params, endOfProcess)
}
function setHeight (height) {
@ -250,6 +253,7 @@ Window {
id: waitingRoom
WaitingRoom{
conferenceInfoModel: window.conferenceInfoModel
onCancel: endOfProcess(0)
}
}
Component {
@ -266,13 +270,13 @@ Window {
childA: Loader {
id: middlePane
anchors.fill: parent
sourceComponent: Logic.getContent(calls.selectedCall, window.conferenceInfoModel)
sourceComponent: Logic.getContent(window.call, window.conferenceInfoModel)
onSourceComponentChanged: {
if( sourceComponent == waitingRoom)
mainPaned.close()
rightPaned.childAItem.update()
}// Force update when loading a new Content. It's just to be sure
active: calls.selectedCall || window.conferenceInfoModel
active: window.call || window.conferenceInfoModel
}
childB: Loader {
@ -291,7 +295,7 @@ Window {
target: CallsListModel
onCallTransferAsked: Logic.handleCallTransferAsked(callModel)
onCallAttendedTransferAsked: Logic.handleCallAttendedTransferAsked(callModel)
onCallConferenceAsked: {console.log('Openning : '+conferenceInfoModel);Logic.openWaitingRoom(conferenceInfoModel)}
onCallConferenceAsked: Logic.openWaitingRoom(conferenceInfoModel)
onRowsRemoved: Logic.tryToCloseWindow()
}
}

View file

@ -27,7 +27,7 @@ Rectangle {
property bool cameraIsReady : false
property bool previewIsReady : false
property var call
property CallModel call
property var _sipAddressObserver: SipAddressesModel.getSipAddressObserver(call.fullPeerAddress, call.fullLocalAddress)

View file

@ -26,7 +26,7 @@ Rectangle {
property ConferenceModel conferenceModel: callModel && callModel.getConferenceModel()
property var _fullscreen: null
property bool listCallsOpened: true
signal openListCallsRequest()
// ---------------------------------------------------------------------------
@ -41,128 +41,175 @@ Rectangle {
}
// ---------------------------------------------------------------------------
ColumnLayout {
Rectangle{
MouseArea{
anchors.fill: parent
}
anchors.fill: parent
spacing: 0
// -------------------------------------------------------------------------
// Conference info.
// -------------------------------------------------------------------------
RowLayout{
// Aux features
Layout.topMargin: 10
Layout.leftMargin: 25
Layout.rightMargin: 25
visible: callModel.pausedByUser
color: VideoConferenceStyle.pauseArea.backgroundColor
z: 1
ColumnLayout{
anchors.fill: parent
spacing: 10
ActionButton{
isCustom: true
backgroundRadius: width/2
colorSet: VideoConferenceStyle.buttons.callsList
visible: !listCallsOpened
onClicked: openListCallsRequest()
}
ActionButton{
id: keypadButton
isCustom: true
backgroundRadius: width/2
colorSet: VideoConferenceStyle.buttons.dialpad
onClicked: telKeypad.visible = !telKeypad.visible
}
// Title
Text{
Timer{
id: elapsedTimeRefresher
running: true
interval: 1000
repeat: true
onTriggered: parent.elaspedTime = ' - ' +Utils.formatElapsedTime(conferenceModel.getElapsedSeconds())
}
property string elaspedTime
horizontalAlignment: Qt.AlignHCenter
Item{
Layout.fillWidth: true
text: conferenceModel.subject+ elaspedTime
color: VideoConferenceStyle.title.color
font.pointSize: VideoConferenceStyle.title.pointSize
}
// Mode buttons
ActionButton{
isCustom: true
backgroundRadius: width/2
colorSet: VideoConferenceStyle.buttons.screenSharing
Layout.fillHeight: true
}
ActionButton{
Layout.alignment: Qt.AlignCenter
isCustom: true
colorSet: VideoConferenceStyle.pauseArea.play
backgroundRadius: width/2
colorSet: VideoConferenceStyle.buttons.recordOff
onClicked: callModel.pausedByUser = !callModel.pausedByUser
}
ActionButton{
isCustom: true
backgroundRadius: width/2
colorSet: VideoConferenceStyle.buttons.screenshot
Text{
Layout.alignment: Qt.AlignCenter
text: 'Vous êtes actuellement en dehors de la conférence.'
font.pointSize: VideoConferenceStyle.pauseArea.title.pointSize
font.weight: VideoConferenceStyle.pauseArea.title.weight
color: VideoConferenceStyle.pauseArea.title.color
}
ActionButton{
isCustom: true
backgroundRadius: width/2
colorSet: VideoConferenceStyle.buttons.fullscreen
Text{
Layout.alignment: Qt.AlignCenter
text: 'Cliquez sur le bouton "play" pour la rejoindre.'
font.pointSize: VideoConferenceStyle.pauseArea.description.pointSize
font.weight: VideoConferenceStyle.pauseArea.description.weight
color: VideoConferenceStyle.pauseArea.description.color
}
Item{
Layout.fillWidth: true
Layout.preferredHeight: 140
}
}
}
// -------------------------------------------------------------------------
// Conference info.
// -------------------------------------------------------------------------
RowLayout{
id: featuresRow
// Aux features
anchors.top: parent.top
anchors.left: parent.left
anchors.right: parent.right
anchors.topMargin: 10
anchors.leftMargin: 25
anchors.rightMargin: 25
spacing: 10
ActionButton{
isCustom: true
backgroundRadius: width/2
colorSet: VideoConferenceStyle.buttons.callsList
visible: !listCallsOpened
onClicked: openListCallsRequest()
}
ActionButton{
id: keypadButton
isCustom: true
backgroundRadius: width/2
colorSet: VideoConferenceStyle.buttons.dialpad
onClicked: telKeypad.visible = !telKeypad.visible
}
// Title
Text{
Timer{
id: elapsedTimeRefresher
running: true
interval: 1000
repeat: true
onTriggered: if(conferenceModel) parent.elaspedTime = ' - ' +Utils.formatElapsedTime(conferenceModel.getElapsedSeconds())
}
property string elaspedTime
horizontalAlignment: Qt.AlignHCenter
Layout.fillWidth: true
text: conferenceModel ? conferenceModel.subject+ elaspedTime : ''
color: VideoConferenceStyle.title.color
font.pointSize: VideoConferenceStyle.title.pointSize
}
// Mode buttons
ActionButton{
isCustom: true
backgroundRadius: width/2
colorSet: VideoConferenceStyle.buttons.screenSharing
visible: false //TODO
}
ActionButton{
isCustom: true
backgroundRadius: width/2
colorSet: VideoConferenceStyle.buttons.recordOff
visible: false //TODO
}
ActionButton{
isCustom: true
backgroundRadius: width/2
colorSet: VideoConferenceStyle.buttons.screenshot
visible: false //TODO
}
ActionButton{
isCustom: true
backgroundRadius: width/2
colorSet: VideoConferenceStyle.buttons.fullscreen
visible: false //TODO
}
// -------------------------------------------------------------------------
// Contacts visual.
// -------------------------------------------------------------------------
}
// -------------------------------------------------------------------------
// Contacts visual.
// -------------------------------------------------------------------------
MouseArea{
id: mainGrid
anchors.top: featuresRow.bottom
anchors.left: parent.left
anchors.right: parent.right
anchors.bottom: actionsButtons.top
MouseArea{
id: mainGrid
Layout.fillHeight: true
Layout.fillWidth: true
Layout.leftMargin: 70
Layout.rightMargin: 70
Layout.topMargin: 15
Layout.bottomMargin: 20
onClicked: {
if(!conference.callModel)
grid.add({color: '#'+ Math.floor(Math.random()*255).toString(16)
+Math.floor(Math.random()*255).toString(16)
+Math.floor(Math.random()*255).toString(16)})
}
/*
anchors.leftMargin: 70
anchors.rightMargin: 70
anchors.topMargin: 15
anchors.bottomMargin: 20
onClicked: {
if(!conference.callModel)
grid.add({color: '#'+ Math.floor(Math.random()*255).toString(16)
+Math.floor(Math.random()*255).toString(16)
+Math.floor(Math.random()*255).toString(16)})
}
/*
ParticipantDeviceProxyModel{
id: participantDevices
callModel: conference.callModel
}*/
Mosaic {
id: grid
anchors.fill: parent
//anchors.centerIn: parent
//width: parent.width
//height: parent.height
squaredDisplay: true
property int radius : 8
function setTestMode(){
grid.clear()
gridModel.model = gridModel.defaultList
for(var i = 0 ; i < 5 ; ++i)
grid.add({color: '#'+ Math.floor(Math.random()*255).toString(16)
+Math.floor(Math.random()*255).toString(16)
+Math.floor(Math.random()*255).toString(16)})
console.log("Setting test mode : count=" + gridModel.defaultList.count)
Mosaic {
id: grid
anchors.fill: parent
squaredDisplay: true
function setTestMode(){
grid.clear()
gridModel.model = gridModel.defaultList
for(var i = 0 ; i < 5 ; ++i)
grid.add({color: '#'+ Math.floor(Math.random()*255).toString(16)
+Math.floor(Math.random()*255).toString(16)
+Math.floor(Math.random()*255).toString(16)})
console.log("Setting test mode : count=" + gridModel.defaultList.count)
}
function setParticipantDevicesMode(){
console.log("Setting participant mode : count=" + gridModel.participantDevices.count)
grid.clear()
gridModel.model = gridModel.participantDevices
}
delegateModel: DelegateModel{
id: gridModel
property ParticipantDeviceProxyModel participantDevices : ParticipantDeviceProxyModel {
id: participantDevices
callModel: conference.callModel
showMe: true
}
function setParticipantDevicesMode(){
console.log("Setting participant mode : count=" + gridModel.participantDevices.count)
grid.clear()
gridModel.model = gridModel.participantDevices
}
delegateModel: DelegateModel{
id: gridModel
property ParticipantDeviceProxyModel participantDevices : ParticipantDeviceProxyModel {
id: participantDevices
callModel: conference.callModel
showMe: true
}
/*
/*
property ListModel defaultList : ListModel{}
Component.onCompleted: {
if( conference.callModel ){
@ -172,190 +219,197 @@ Rectangle {
}
model: defaultList
*/
model: participantDevices
onCountChanged: {console.log("Delegate count = "+count+"/"+participantDevices.count)}
delegate: Rectangle{
id: avatarCell
property ParticipantDeviceModel currentDevice: gridModel.participantDevices.getAt(index)
onCurrentDeviceChanged: console.log("currentDevice changed: " +currentDevice + (currentDevice?", me:"+currentDevice.isMe:'')+" ["+index+"]")
color: /*!conference.callModel && gridModel.defaultList.get(index).color ? gridModel.defaultList.get(index).color : */'#AAAAAAAA'
//color: gridModel.model.get(index) && gridModel.model.get(index).color ? gridModel.model.get(index).color : '' // modelIndex is a custom index because by Mosaic modelisation, it is not accessible.
//color: $modelData.color ? $modelData.color : ''
radius: grid.radius
height: grid.cellHeight - 5
width: grid.cellWidth - 5
Component.onCompleted: console.log("Completed: ["+index+"] " +(currentDevice?currentDevice.peerAddress+", isMe:"+currentDevice.isMe : '') )
CameraView{
anchors.fill: parent
currentDevice: avatarCell.currentDevice
hideCamera: callModel.pausedByUser
onCloseRequested: grid.remove( index)
}
model: participantDevices
onCountChanged: {console.log("Delegate count = "+count+"/"+participantDevices.count)}
delegate: Item{
id: avatarCell
property ParticipantDeviceModel currentDevice: gridModel.participantDevices.getAt(index)
onCurrentDeviceChanged: console.log("currentDevice changed: " +currentDevice + (currentDevice?", me:"+currentDevice.isMe:'')+" ["+index+"]")
//color: 'black' /*!conference.callModel && gridModel.defaultList.get(index).color ? gridModel.defaultList.get(index).color : */
//color: gridModel.model.get(index) && gridModel.model.get(index).color ? gridModel.model.get(index).color : '' // modelIndex is a custom index because by Mosaic modelisation, it is not accessible.
//color: $modelData.color ? $modelData.color : ''
height: grid.cellHeight - 10
width: grid.cellWidth - 10
Component.onCompleted: console.log("Completed: ["+index+"] " +(currentDevice?currentDevice.peerAddress+", isMe:"+currentDevice.isMe : '') )
CameraView{
anchors.fill: parent
currentDevice: avatarCell.currentDevice
isPaused: callModel.pausedByUser || avatarCell.currentDevice && avatarCell.currentDevice.isPaused //callModel.pausedByUser
onCloseRequested: grid.remove( index)
color: 'black'
}
}
}
}
// -------------------------------------------------------------------------
// Action Buttons.
// -------------------------------------------------------------------------
}
// -------------------------------------------------------------------------
// Action Buttons.
// -------------------------------------------------------------------------
// Security
ActionButton{
visible: false // TODO
anchors.left: parent.left
anchors.bottom: parent.bottom
anchors.bottomMargin: 30
anchors.leftMargin: 25
height: VideoConferenceStyle.buttons.secure.buttonSize
width: height
isCustom: true
iconIsCustom: false
backgroundRadius: width/2
colorSet: VideoConferenceStyle.buttons.secure
icon: 'secure_level_1'
}
// Action buttons
RowLayout{
id: actionsButtons
anchors.horizontalCenter: parent.horizontalCenter
anchors.bottom: parent.bottom
anchors.bottomMargin: 30
height: 60
spacing: 30
z: 2
RowLayout{
Layout.fillWidth: true
Layout.bottomMargin: 40
Layout.leftMargin: 25
Layout.rightMargin: 25
// Security
ActionButton{
//Layout.preferredHeight: VideoConferenceStyle.buttons.buttonSize
//Layout.preferredWidth: VideoConferenceStyle.buttons.buttonSize
height: VideoConferenceStyle.buttons.secure.buttonSize
width: height
isCustom: true
iconIsCustom: false
backgroundRadius: width/2
colorSet: VideoConferenceStyle.buttons.secure
spacing: 10
Row {
spacing: 2
visible: SettingsModel.muteMicrophoneEnabled
property bool microMuted: callModel.microMuted
icon: 'secure_level_1'
}
Item{
Layout.fillWidth: true
}
// Action buttons
RowLayout{
Layout.alignment: Qt.AlignCenter
spacing: 30
RowLayout{
spacing: 10
Row {
spacing: 2
visible: SettingsModel.muteMicrophoneEnabled
property bool microMuted: callModel.microMuted
VuMeter {
enabled: !parent.microMuted
Timer {
interval: 50
repeat: true
running: parent.enabled
onTriggered: parent.value = callModel.microVu
}
}
ActionSwitch {
id: micro
isCustom: true
backgroundRadius: 90
colorSet: parent.microMuted ? VideoConferenceStyle.buttons.microOff : VideoConferenceStyle.buttons.microOn
onClicked: callModel.microMuted = !parent.microMuted
}
}
Row {
spacing: 2
property bool speakerMuted: callModel.speakerMuted
VuMeter {
enabled: !parent.speakerMuted
Timer {
interval: 50
repeat: true
running: parent.enabled
onTriggered: parent.value = callModel.speakerVu
}
}
ActionSwitch {
id: speaker
isCustom: true
backgroundRadius: 90
colorSet: parent.speakerMuted ? VideoConferenceStyle.buttons.speakerOff : VideoConferenceStyle.buttons.speakerOn
onClicked: callModel.speakerMuted = !parent.speakerMuted
}
}
ActionSwitch {
id: camera
isCustom: true
backgroundRadius: 90
colorSet: callModel && callModel.videoEnabled ? VideoConferenceStyle.buttons.cameraOn : VideoConferenceStyle.buttons.cameraOff
updating: callModel.videoEnabled && callModel.updating
onClicked: if(callModel) callModel.videoEnabled = !callModel.videoEnabled
}
}
RowLayout{
spacing: 10
ActionButton{
isCustom: true
backgroundRadius: width/2
visible: SettingsModel.callPauseEnabled
updating: callModel.updating
colorSet: callModel.pausedByUser ? VideoConferenceStyle.buttons.play : VideoConferenceStyle.buttons.pause
onClicked: callModel.pausedByUser = !callModel.pausedByUser
}
ActionButton{
isCustom: true
backgroundRadius: width/2
colorSet: VideoConferenceStyle.buttons.hangup
onClicked: callModel.terminate()
}
}
}
Item{
Layout.fillWidth: true
}
// Panel buttons
RowLayout{
ActionButton{
isCustom: true
backgroundRadius: width/2
colorSet: VideoConferenceStyle.buttons.chat
visible: false // TODO for next version
}
ActionButton{
isCustom: true
backgroundRadius: width/2
colorSet: VideoConferenceStyle.buttons.participants
}
ActionButton {
id: callQuality
isCustom: true
backgroundRadius: 4
colorSet: VideoConferenceStyle.buttons.callQuality
percentageDisplayed: 0
onClicked: {console.log("opening stats");Logic.openCallStatistics();console.log("Stats should be opened")}
VuMeter {
enabled: !parent.microMuted
Timer {
interval: 500
interval: 50
repeat: true
running: true
triggeredOnStart: true
onTriggered: {
// Note: `quality` is in the [0, 5] interval and -1.
var quality = callModel.quality
if(quality >= 0)
callQuality.percentageDisplayed = quality * 100 / 5
else
callQuality.percentageDisplayed = 0
}
}
CallStatistics {
id: callStatistics
running: parent.enabled
call: callModel
width: conference.width
relativeTo: keypadButton
relativeY: CallStyle.header.stats.relativeY
onClosed: Logic.handleCallStatisticsClosed()
onOpened: console.log("Stats Opened: " +call+", " +width +", "+relativeY)
onTriggered: parent.value = callModel.microVu
}
}
ActionButton{
ActionSwitch {
id: micro
isCustom: true
backgroundRadius: width/2
colorSet: VideoConferenceStyle.buttons.options
backgroundRadius: 90
colorSet: parent.microMuted ? VideoConferenceStyle.buttons.microOff : VideoConferenceStyle.buttons.microOn
onClicked: callModel.microMuted = !parent.microMuted
}
}
Row {
spacing: 2
property bool speakerMuted: callModel.speakerMuted
VuMeter {
enabled: !parent.speakerMuted
Timer {
interval: 50
repeat: true
running: parent.enabled
onTriggered: parent.value = callModel.speakerVu
}
}
ActionSwitch {
id: speaker
isCustom: true
backgroundRadius: 90
colorSet: parent.speakerMuted ? VideoConferenceStyle.buttons.speakerOff : VideoConferenceStyle.buttons.speakerOn
onClicked: callModel.speakerMuted = !parent.speakerMuted
}
}
ActionSwitch {
id: camera
isCustom: true
backgroundRadius: 90
colorSet: callModel && callModel.videoEnabled ? VideoConferenceStyle.buttons.cameraOn : VideoConferenceStyle.buttons.cameraOff
updating: callModel.videoEnabled && callModel.updating
onClicked: if(callModel) callModel.videoEnabled = !callModel.videoEnabled
}
}
RowLayout{
spacing: 10
ActionButton{
isCustom: true
backgroundRadius: width/2
visible: SettingsModel.callPauseEnabled
updating: callModel.updating
colorSet: callModel.pausedByUser ? VideoConferenceStyle.buttons.play : VideoConferenceStyle.buttons.pause
onClicked: callModel.pausedByUser = !callModel.pausedByUser
}
ActionButton{
isCustom: true
backgroundRadius: width/2
colorSet: VideoConferenceStyle.buttons.hangup
onClicked: callModel.terminate()
}
}
}
// Panel buttons
RowLayout{
anchors.right: parent.right
anchors.bottom: parent.bottom
anchors.bottomMargin: 30
anchors.rightMargin: 25
height: 60
ActionButton{
isCustom: true
backgroundRadius: width/2
colorSet: VideoConferenceStyle.buttons.chat
visible: false // TODO for next version
}
ActionButton{
isCustom: true
backgroundRadius: width/2
colorSet: VideoConferenceStyle.buttons.participants
visible: false // TODO
}
ActionButton {
id: callQuality
isCustom: true
backgroundRadius: 4
colorSet: VideoConferenceStyle.buttons.callQuality
percentageDisplayed: 0
onClicked: {console.log("opening stats");Logic.openCallStatistics();console.log("Stats should be opened")}
Timer {
interval: 500
repeat: true
running: true
triggeredOnStart: true
onTriggered: {
// Note: `quality` is in the [0, 5] interval and -1.
var quality = callModel.quality
if(quality >= 0)
callQuality.percentageDisplayed = quality * 100 / 5
else
callQuality.percentageDisplayed = 0
}
}
CallStatistics {
id: callStatistics
call: callModel
width: conference.width
relativeTo: keypadButton
relativeY: CallStyle.header.stats.relativeY
onClosed: Logic.handleCallStatisticsClosed()
onOpened: console.log("Stats Opened: " +call+", " +width +", "+relativeY)
}
}
ActionButton{
isCustom: true
backgroundRadius: width/2
colorSet: VideoConferenceStyle.buttons.options
visible: false //TODO
}
}
// ---------------------------------------------------------------------------
// TelKeypad.
// ---------------------------------------------------------------------------

View file

@ -11,8 +11,12 @@ import App.Styles 1.0
// =============================================================================
Rectangle {
id: mainItem
color: WaitingRoomStyle.backgroundColor
property ConferenceInfoModel conferenceInfoModel
signal cancel()
ColumnLayout {
anchors.fill: parent
Text{
@ -35,42 +39,6 @@ Rectangle {
width : height
}
}
/*
Loader{
id: previewLoader
Layout.fillWidth: true
Layout.fillHeight: true
sourceComponent: Item{
anchors.top:parent.top
anchors.bottom: parent.bottom
width : height
Rectangle{
id: showArea
anchors.fill: parent
radius: 10
visible:false
color: 'red'
}
CameraPreview {
id: preview
anchors.fill: parent
onRequestNewRenderer: {previewLoader.active = false; previewLoader.active = true}
visible: false
}
OpacityMask{
anchors.fill: preview
source: preview
maskSource: showArea
visible: true
rotation: 180
}
}
active: true
}*/
// -------------------------------------------------------------------------
// Action Buttons.
// -------------------------------------------------------------------------
@ -137,7 +105,7 @@ Rectangle {
TextButtonA {
text: 'CANCEL'
onClicked: console.log('cancel')
onClicked: mainItem.cancel()
}
TextButtonB {
text: 'DEMARRER'
@ -146,51 +114,6 @@ Rectangle {
}
}
/*
GridLayout {
columns: parent.width < CallStyle.actionArea.lowWidth && call.videoEnabled ? 1 : 2
rowSpacing: ActionBarStyle.spacing
anchors {
left: parent.left
leftMargin: CallStyle.actionArea.leftButtonsGroupMargin
verticalCenter: parent.verticalCenter
}
ActionSwitch {
isCustom: true
backgroundRadius: 90
colorSet: enabled ? CallStyle.buttons.microOn : CallStyle.buttons.microOff
enabled: !call.microMuted
onClicked: call.microMuted = enabled
}
}
Item {
anchors.centerIn: parent
height: CallStyle.actionArea.userVideo.height
width: CallStyle.actionArea.userVideo.width
visible: call.videoEnabled
}
ActionBar {
anchors {
right: parent.right
rightMargin: CallStyle.actionArea.rightButtonsGroupMargin
verticalCenter: parent.verticalCenter
}
iconSize: CallStyle.actionArea.iconSize
ActionButton {
isCustom: true
backgroundRadius: 90
colorSet: CallStyle.buttons.hangup
onClicked: call.terminate()
}
}
*/
}
}

View file

@ -147,29 +147,35 @@ ColumnLayout {
}
GridView{
id: calendarGrid
//anchors.fill: parent
cellWidth: (mainItem.width-20)/2
cellHeight: 100
property bool expanded : false //anchors.fill: parent
cellWidth: width/2
cellHeight: expanded ? 300 : 100
model: $modelData
height: cellHeight * ( (count+1) /2)
width: mainItem.width - 20
delegate:Rectangle {
id: entry
width: calendarGrid.cellWidth -10
height: calendarGrid.cellHeight -10
width: calendarGrid.cellWidth-10
height: calendarGrid.cellHeight-10
radius: 6
color: mainItem.filterType == ConferenceInfoProxyModel.Ended ? ConferencesStyle.conference.backgroundColor.ended
: ConferencesStyle.conference.backgroundColor.scheduled
border.color: calendarMessage.containsMouse ? ConferencesStyle.conference.selectedBorder.color : 'transparent'
border.color: calendarMessage.containsMouse || calendarMessage.isExpanded ? ConferencesStyle.conference.selectedBorder.color : 'transparent'
border.width: ConferencesStyle.conference.selectedBorder.width
ChatCalendarMessage{
id: calendarMessage
anchors.centerIn: parent
width: parent.width
height: parent.height
conferenceInfoModel: $modelData
width: calendarGrid.cellWidth
maxWidth: calendarGrid.cellWidth
//width: calendarGrid.cellWidth
//maxWidth: calendarGrid.cellWidth
gotoButtonMode: mainItem.filterType == ConferenceInfoProxyModel.Scheduled ? 1
: mainItem.filterType == ConferenceInfoProxyModel.Ended ? -1
: 0
onExpandToggle: calendarGrid.expanded = !calendarGrid.expanded
isExpanded: calendarGrid.expanded
}
}
}

View file

@ -13,6 +13,7 @@ import Units 1.0
import UtilsCpp 1.0
import ColorsList 1.0
import 'qrc:/ui/scripts/Utils/utils.js' as Utils
// =============================================================================
DialogPlus {
@ -34,12 +35,13 @@ DialogPlus {
Layout.alignment: Qt.AlignLeft
Layout.leftMargin: 15
spacing:4
visible: false // TODO
Text {
Layout.fillWidth: true
//: 'Would you like to encrypt your conference?' : Ask about setting the conference as secured.
text:qsTr('askEncryption')
color: NewConferenceStyle.askEncryptionColor
font.pointSize: Units.dp * 11
font.pointSize: NewConferenceStyle.titles.pointSize
font.weight: Font.DemiBold
}
Item{
@ -106,18 +108,8 @@ DialogPlus {
onClicked: {
conferenceInfoModel.isScheduled = scheduledSwitch.checked
if( scheduledSwitch.checked){
var startDateTime = new Date()
var d = dateField.getDate()
var t = timeField.getTime()
console.log("A " +startDateTime)
startDateTime.setFullYear(d.getFullYear(), d.getMonth(), d.getDate())
console.log("B " +startDateTime)
startDateTime.setHours(t.getHours())
console.log("C " +startDateTime)
startDateTime.setMinutes(t.getMinutes())
console.log("D " +startDateTime)
var startDateTime = Utils.buidDate(dateField.getDate(), timeField.getTime())
startDateTime.setSeconds(0)
console.log("E " +startDateTime)
conferenceInfoModel.dateTime = startDateTime
conferenceInfoModel.duration = durationField.text
}
@ -130,7 +122,7 @@ DialogPlus {
//App.smartShowWindow(callsWindow)
//callsWindow.openConference()
//CallsListModel.createConference(conferenceInfoModel, secureSwitch.checked, getInviteMode(), false )
conferenceInfoModel.createConference(secureSwitch.checked, getInviteMode())
conferenceInfoModel.createConference(false && secureSwitch.checked, getInviteMode()) // TODO remove false when Encryption is ready to use
}
TooltipArea{
visible: AccountSettingsModel.conferenceURI == '' || subject.text == '' || selectedParticipants.count < conferenceManager.minParticipants
@ -183,9 +175,9 @@ DialogPlus {
textFormat: Text.RichText
//: 'Subject' : Label of a text field about the subject of the chat room
text :qsTr('subjectLabel') +'<span style="color:red">*</span>'
color: NewConferenceStyle.subjectTitleColor
font.pointSize: Units.dp * 11
font.weight: Font.DemiBold
color: NewConferenceStyle.titles.textColor
font.pointSize: NewConferenceStyle.titles.pointSize
font.weight: NewConferenceStyle.titles.weight
}
TextField {
id:subject
@ -230,9 +222,9 @@ DialogPlus {
Layout.rightMargin: 15
//: 'Would you like to schedule your conference?' : Ask about setting the conference as scheduled.
text: 'Souhaitez-vous programmer cette conférence pour plus tard ?'
color: NewConferenceStyle.askEncryptionColor
font.pointSize: Units.dp * 10
font.weight: Font.DemiBold
color: NewConferenceStyle.titles.textColor
font.pointSize: NewConferenceStyle.titles.pointSize
font.weight: NewConferenceStyle.titles.weight
wrapMode: Text.WordWrap
}
}
@ -249,11 +241,12 @@ DialogPlus {
Text{text: 'Date*'; Layout.preferredWidth: parent.cellWidth}
Text{text: 'Heure de début*'; Layout.preferredWidth: parent.cellWidth}
Text{text: 'Durée'; Layout.preferredWidth: parent.cellWidth}
Text{text: 'Fuseau horaire'; Layout.preferredWidth: parent.cellWidth}
Text{textFormat: Text.RichText; text: 'Date'+'<span style="color:red">*</span>'; Layout.preferredWidth: parent.cellWidth; wrapMode: Text.WordWrap; color: NewConferenceStyle.titles.textColor; font.weight: NewConferenceStyle.titles.weight; font.pointSize: NewConferenceStyle.titles.pointSize }
Text{textFormat: Text.RichText; text: 'Heure de début'+'<span style="color:red">*</span>'; Layout.preferredWidth: parent.cellWidth; wrapMode: Text.WordWrap; color: NewConferenceStyle.titles.textColor; font.weight: NewConferenceStyle.titles.weight; font.pointSize: NewConferenceStyle.titles.pointSize }
Text{textFormat: Text.RichText; text: 'Durée'; Layout.preferredWidth: parent.cellWidth; wrapMode: Text.WordWrap; color: NewConferenceStyle.titles.textColor; font.weight: NewConferenceStyle.titles.weight; font.pointSize: NewConferenceStyle.titles.pointSize }
Text{textFormat: Text.RichText; text: 'Fuseau horaire'; Layout.preferredWidth: parent.cellWidth; wrapMode: Text.WordWrap; color: NewConferenceStyle.titles.textColor; font.weight: NewConferenceStyle.titles.weight; font.pointSize: NewConferenceStyle.titles.pointSize }
TextField{id: dateField; Layout.preferredWidth: parent.cellWidth
color: NewConferenceStyle.fields.textColor; font.weight: NewConferenceStyle.fields.weight; font.pointSize: NewConferenceStyle.fields.pointSize
function getDate(){
return Date.fromLocaleDateString(scheduleForm.locale, text,'yyyy/MM/dd')
}
@ -276,6 +269,7 @@ DialogPlus {
}
}
TextField{id: timeField; Layout.preferredWidth: parent.cellWidth
color: NewConferenceStyle.fields.textColor; font.weight: NewConferenceStyle.fields.weight; font.pointSize: NewConferenceStyle.fields.pointSize
function getTime(){
return Date.fromLocaleTimeString(scheduleForm.locale, timeField.text, 'hh:mm')
}
@ -300,14 +294,14 @@ DialogPlus {
}
}
}
NumericField{id: durationField; text: '1200'; Layout.preferredWidth: parent.cellWidth}
TextField{ text: 'Paris'; readOnly: true; Layout.preferredWidth: parent.cellWidth}
NumericField{id: durationField; text: '1200'; Layout.preferredWidth: parent.cellWidth; color: NewConferenceStyle.fields.textColor; font.weight: NewConferenceStyle.fields.weight; font.pointSize: NewConferenceStyle.fields.pointSize}
TextField{ text: 'Paris'; readOnly: true; Layout.preferredWidth: parent.cellWidth; color: NewConferenceStyle.fields.textColor; font.weight: NewConferenceStyle.fields.weight; font.pointSize: NewConferenceStyle.fields.pointSize}
function updateDateTime(){
var storedDate = new Date()
var storedDate
if( dateField.text != '' && timeField.text != ''){
storedDate.setDate(dateField.getDate())
storedDate.setTime(timeField.getTime() )
}
storedDate = Utils.buildDate(dateField.getDate(), timeField.getTime() )
}else
storedDate = new Date()
var currentDate = new Date()
if(currentDate >= storedDate){
var nextStoredDate = UtilsCpp.addMinutes(new Date(), 1)
@ -337,16 +331,16 @@ DialogPlus {
textFormat: Text.RichText
//: 'Add a description' : Label of a text field about the description of the conference
text : 'Ajouter une description'
color: NewConferenceStyle.subjectTitleColor
font.pointSize: Units.dp * 10
font.weight: Font.DemiBold
color: NewConferenceStyle.titles.textColor
font.pointSize: NewConferenceStyle.titles.pointSize
font.weight: NewConferenceStyle.titles.weight
}
TextAreaField {
id: description
Layout.fillWidth: true
Layout.fillHeight: true
//: 'Description' : Placeholder in a form about setting a description
//placeholderText : 'Description'
placeholderText : 'Description'
text: ''
Keys.onReturnPressed: nextItemInFocusChain().forceActiveFocus()
TooltipArea{
@ -372,7 +366,7 @@ DialogPlus {
}
CheckBoxText {
id: inviteEmailCheckBox
visible: false // TODO
text: 'Envoyer l\'invitation via mon adresse mail'
width: parent.width

View file

@ -31,6 +31,7 @@ DialogPlus {
anchors.centerIn: parent
height: parent.height
width: height
showCloseButton: false
}
}

View file

@ -16,8 +16,8 @@ QtObject {
property QtObject callsList: QtObject {
property color color: ColorsList.add(sectionName+'_list_bg', 'q').color
property int defaultWidth: 250
property int maximumWidth: 250
property int minimumWidth: 110
property int maximumWidth: 300
property int minimumWidth: 200
property QtObject header: QtObject {
property color color1: ColorsList.add(sectionName+'_list_header_a', 'q').color

View file

@ -1,5 +1,6 @@
pragma Singleton
import QtQml 2.2
import QtQuick 2.7
import Units 1.0
import ColorsList 1.0
@ -30,6 +31,32 @@ QtObject {
}
}
}
property QtObject pauseArea: QtObject {
property color backgroundColor: ColorsList.add(sectionName+'_paused_bg', 'l50').color
property QtObject title: QtObject{
property color color: ColorsList.add(sectionName+'_paused_title', 'q').color
property int pointSize: Units.dp * 12
property int weight: Font.Bold
}
property QtObject description: QtObject{
property color color: ColorsList.add(sectionName+'_paused_description', 'q').color
property int pointSize: Units.dp * 9
property int weight: Font.Medium
}
property QtObject play: QtObject {
property int iconSize: 240
property string icon : 'play_custom'
property string name : 'paused_play'
property color backgroundNormalColor : ColorsList.addImageColor(sectionName+'_'+name+'_bg_n', icon, 's_p_b_bg').color
property color backgroundHoveredColor : ColorsList.addImageColor(sectionName+'_'+name+'_bg_h', icon, 's_h_b_bg').color
property color backgroundPressedColor : ColorsList.addImageColor(sectionName+'_'+name+'_bg_p', icon, 's_n_b_bg').color
property color backgroundUpdatingColor : ColorsList.addImageColor(sectionName+'_'+name+'_bg_u', icon, 's_p_b_bg').color
property color foregroundNormalColor : ColorsList.addImageColor(sectionName+'_'+name+'_fg_n', icon, 's_p_b_fg').color
property color foregroundHoveredColor : ColorsList.addImageColor(sectionName+'_'+name+'_fg_h', icon, 's_h_b_fg').color
property color foregroundPressedColor : ColorsList.addImageColor(sectionName+'_'+name+'_fg_p', icon, 's_n_b_fg').color
property color foregroundUpdatingColor : ColorsList.addImageColor(sectionName+'_'+name+'_fg_u', icon, 's_p_b_fg').color
}
}
property QtObject actionArea: QtObject {
property int height: 100
property int iconSize: 40

View file

@ -17,6 +17,17 @@ QtObject {
property color addressesAdminColor: ColorsList.add(sectionName+'_addresses_admin', 'g').color
property color requiredColor: ColorsList.add(sectionName+'_required_text', 'g').color
property QtObject titles: QtObject{
property color textColor: ColorsList.add(sectionName+'_schedule_titles', 'g').color
property int weight: Font.DemiBold
property real pointSize: Units.dp * 10
}
property QtObject fields: QtObject{
property color textColor: ColorsList.add(sectionName+'_schedule_fields', 'g').color
property int weight: Font.Medium
property real pointSize: Units.dp * 9
}
property QtObject addParticipant: QtObject {
property int iconSize: 30

@ -1 +1 @@
Subproject commit e1f89e97bc75f297a5cb485e4ae91e0c81fa9add
Subproject commit 4afd627aece46fb9803116844dba9132ec82772a