diff --git a/linphone-app/CMakeLists.txt b/linphone-app/CMakeLists.txt
index cd0c2afc4..d882c9dd9 100644
--- a/linphone-app/CMakeLists.txt
+++ b/linphone-app/CMakeLists.txt
@@ -133,6 +133,7 @@ set(SOURCES
src/components/calls/CallsListModel.cpp
src/components/calls/CallsListProxyModel.cpp
src/components/camera/Camera.cpp
+ src/components/camera/CameraDummy.cpp
src/components/camera/CameraPreview.cpp
src/components/chat/ChatModel.cpp
src/components/chat-events/ChatCallModel.cpp
@@ -151,7 +152,9 @@ set(SOURCES
src/components/conference/ConferenceProxyModel.cpp
src/components/conferenceInfo/ConferenceInfoModel.cpp
src/components/conferenceInfo/ConferenceInfoListModel.cpp
+ src/components/conferenceInfo/ConferenceInfoMapModel.cpp
src/components/conferenceInfo/ConferenceInfoProxyModel.cpp
+ src/components/conferenceScheduler/ConferenceSchedulerModel.cpp
src/components/contact/ContactModel.cpp
src/components/contact/VcardModel.cpp
src/components/contacts/ContactsImporterModel.cpp
@@ -248,6 +251,7 @@ set(HEADERS
src/components/calls/CallsListModel.hpp
src/components/calls/CallsListProxyModel.hpp
src/components/camera/Camera.hpp
+ src/components/camera/CameraDummy.hpp
src/components/camera/CameraPreview.hpp
src/components/chat/ChatModel.hpp
src/components/chat-events/ChatCallModel.hpp
@@ -267,7 +271,9 @@ set(HEADERS
src/components/conference/ConferenceProxyModel.hpp
src/components/conferenceInfo/ConferenceInfoModel.hpp
src/components/conferenceInfo/ConferenceInfoListModel.hpp
+ src/components/conferenceInfo/ConferenceInfoMapModel.hpp
src/components/conferenceInfo/ConferenceInfoProxyModel.hpp
+ src/components/conferenceScheduler/ConferenceSchedulerModel.hpp
src/components/contact/ContactModel.hpp
src/components/contact/VcardModel.hpp
src/components/contacts/ContactsImporterModel.hpp
diff --git a/linphone-app/resources.qrc b/linphone-app/resources.qrc
index b1661b964..5e987a2ab 100644
--- a/linphone-app/resources.qrc
+++ b/linphone-app/resources.qrc
@@ -14,6 +14,7 @@
assets/images/attachment_custom.svg
assets/images/auto_answer_custom.svg
assets/images/burger_menu_custom.svg
+ assets/images/calendar_participants_custom.svg
assets/images/call_accept_custom.svg
assets/images/call_chat_secure_custom.svg
assets/images/call_chat_unsecure_custom.svg
@@ -292,6 +293,7 @@
ui/modules/Linphone/Chat/ChatMenu.qml
ui/modules/Linphone/Chat/ChatAudioMessage.qml
ui/modules/Linphone/Chat/ChatAudioPreview.qml
+ ui/modules/Linphone/Chat/ChatCalendarMessage.qml
ui/modules/Linphone/Chat/ChatFileMessage.qml
ui/modules/Linphone/Chat/ChatFilePreview.qml
ui/modules/Linphone/Chat/ChatForwardMessage.qml
@@ -342,6 +344,7 @@
ui/modules/Linphone/Styles/Chat/ChatAudioMessageStyle.qml
ui/modules/Linphone/Styles/Chat/ChatAudioPreviewStyle.qml
ui/modules/Linphone/Styles/Chat/ChatFilePreviewStyle.qml
+ ui/modules/Linphone/Styles/Chat/ChatCalendarMessageStyle.qml
ui/modules/Linphone/Styles/Chat/ChatForwardMessageStyle.qml
ui/modules/Linphone/Styles/Chat/ChatReplyMessageStyle.qml
ui/modules/Linphone/Styles/Codecs/CodecsViewerStyle.qml
diff --git a/linphone-app/src/components/Components.hpp b/linphone-app/src/components/Components.hpp
index f518166ac..3da8ab581 100644
--- a/linphone-app/src/components/Components.hpp
+++ b/linphone-app/src/components/Components.hpp
@@ -40,6 +40,7 @@
#include "conferenceInfo/ConferenceInfoModel.hpp"
#include "conferenceInfo/ConferenceInfoListModel.hpp"
#include "conferenceInfo/ConferenceInfoProxyModel.hpp"
+#include "conferenceScheduler/ConferenceSchedulerModel.hpp"
#include "contact/ContactModel.hpp"
#include "contact/VcardModel.hpp"
#include "contacts/ContactsListModel.hpp"
diff --git a/linphone-app/src/components/call/CallModel.cpp b/linphone-app/src/components/call/CallModel.cpp
index 39263786c..820dbfbf2 100644
--- a/linphone-app/src/components/call/CallModel.cpp
+++ b/linphone-app/src/components/call/CallModel.cpp
@@ -420,6 +420,7 @@ void CallModel::handleCallStateChanged (const shared_ptr &call,
break;
case linphone::Call::State::UpdatedByRemote:
+ qWarning() << "UpdatedByRemote :" << (mCall ? mCall->getCurrentParams()->videoEnabled() + QString(" ")+mCall->getRemoteParams()->videoEnabled() : " call NULL");
if (mCall && !mCall->getCurrentParams()->videoEnabled() && mCall->getRemoteParams()->videoEnabled()) {
mCall->deferUpdate();
emit videoRequested();
@@ -663,7 +664,7 @@ bool CallModel::getRemoteVideoEnabled () const {
bool CallModel::getVideoEnabled () const {
if(mCall){
shared_ptr params = mCall->getCurrentParams();
- return params && params->videoEnabled() && getStatus() == CallStatusConnected;
+ return params && params->videoEnabled() && getStatus() == CallStatusConnected && mCall->getState() == linphone::Call::State::StreamsRunning;
}else
return true;
}
@@ -795,7 +796,8 @@ void CallModel::setRemoteDisplayName(const std::string& name){
auto callLog = mCall->getCallLog();
if(name!= "") {
auto core = CoreManager::getInstance()->getCore();
- callLog->setRemoteAddress(Utils::interpretUrl(getFullPeerAddress()));
+ auto address = Utils::interpretUrl(getFullPeerAddress());
+ callLog->setRemoteAddress(address);
}
}
emit fullPeerAddressChanged();
diff --git a/linphone-app/src/components/call/CallModel.hpp b/linphone-app/src/components/call/CallModel.hpp
index 6a3861b08..b9cc7be88 100644
--- a/linphone-app/src/components/call/CallModel.hpp
+++ b/linphone-app/src/components/call/CallModel.hpp
@@ -189,7 +189,7 @@ signals:
void fullPeerAddressChanged();
void transferAddressChanged (const QString &transferAddress);
-private:
+public:
void handleCallEncryptionChanged (const std::shared_ptr &call);
void handleCallStateChanged (const std::shared_ptr &call, linphone::Call::State state);
@@ -255,6 +255,7 @@ private:
static QString generateSavedFilename (const QString &from, const QString &to);
+private:
bool mIsInConference = false;
bool mPausedByRemote = false;
diff --git a/linphone-app/src/components/calls/CallsListModel.cpp b/linphone-app/src/components/calls/CallsListModel.cpp
index 19fa4cccc..1793d03a5 100644
--- a/linphone-app/src/components/calls/CallsListModel.cpp
+++ b/linphone-app/src/components/calls/CallsListModel.cpp
@@ -389,67 +389,8 @@ QVariantMap CallsListModel::createConference(ConferenceInfoModel * conferenceInf
std::shared_ptr timeline;
auto timelineList = CoreManager::getInstance()->getTimelineListModel();
qInfo() << "Conference creation of " << conferenceInfo->getSubject() << " at " << securityLevel << " security";// and with " << conferenceInfo->getConferenceInfo()->getParticipants().size();
-
- std::shared_ptr params = core->createConferenceParams();
- std::list > participants = conferenceInfo->getConferenceInfo()->getParticipants();
- std::shared_ptr localAddress;
-
- /*
- for(auto p : participants){
- ParticipantModel* participant = p.value();
- std::shared_ptr address;
- if(participant) {
- address = Utils::interpretUrl(participant->getSipAddress());
- if(participant->getAdminStatus())
- admins << address;
- }else{
- QString participant = p.toString();
- if( participant != "")
- address = Utils::interpretUrl(participant);
- }
- if( address)
- chatRoomParticipants.push_back( address );
- }*/
- auto proxy = core->getDefaultProxyConfig();
- params->setVideoEnabled(true);
- params->setStartTime(conferenceInfo->getConferenceInfo()->getDateTime());
- params->setEndTime(conferenceInfo->getConferenceInfo()->getDateTime()+conferenceInfo->getConferenceInfo()->getDuration()*60);
- params->setLayout(linphone::ConferenceLayout::Grid);
- //params->setDescription(conferenceInfo->getConferenceInfo()->getDescription());
-
- //params->enableEncryption(securityLevel>0);
-
-// if( securityLevel>0){
-// params->enableEncryption(true);
-// }else
-// params->setBackend(linphone::ChatRoomBackend::Basic);
-// params->enableGroup( subject!="" );
-
-
- if(participants.size() > 0) {
- params->setSubject(conferenceInfo->getSubject() != ""?Utils::appStringToCoreString(conferenceInfo->getSubject()):"Dummy Subject");
- if( !conference) {
- core->createConferenceOnServer(params, localAddress, participants);
- /*
- //conference = core->createConferenceWithParams(params);
- if(conference != nullptr && admins.size() > 0){
- for(auto a : admins) {
- auto p = conference->findParticipant(a);
- if( p )
- conference->setParticipantAdminStatus(p, true);
- else
- qWarning() <<"Cannot set admin for " << a->asString().c_str() << ". It is not found in conference.";
- }
- }
- // Warning: Should not be needed but SDK doesn't ref it
- mConferences.append(std::make_shared(conference));
- //ChatRoomInitializer::setAdminsAsync(params->getSubject(), params->getBackend(), params->groupEnabled(), admins );
- // timeline = timelineList->getTimeline(conference, false);
- */
- }
-
- }
- //result["created"] = (conference != nullptr);
+ auto conferenceScheduler = core->createConferenceScheduler();
+ conferenceScheduler->setInfo(conferenceInfo->getConferenceInfo());
return result;
}
diff --git a/linphone-app/src/components/camera/Camera.cpp b/linphone-app/src/components/camera/Camera.cpp
index 4d1079a23..c969250cd 100644
--- a/linphone-app/src/components/camera/Camera.cpp
+++ b/linphone-app/src/components/camera/Camera.cpp
@@ -28,6 +28,7 @@
#include "components/participant/ParticipantDeviceModel.hpp"
#include "Camera.hpp"
+#include "CameraDummy.hpp"
// =============================================================================
@@ -37,7 +38,6 @@ namespace {
constexpr int MaxFps = 30;
}
-
// =============================================================================
Camera::Camera (QQuickItem *parent) : QQuickFramebufferObject(parent) {
// The fbo content must be y-mirrored because the ms rendering is y-inverted.
@@ -77,41 +77,53 @@ public:
QQuickFramebufferObject::Renderer *Camera::createRenderer () const {
QQuickFramebufferObject::Renderer * renderer = NULL;
if(mIsPreview){
- CoreManager::getInstance()->getCore()->setNativePreviewWindowId(NULL);// Reset
- renderer=(QQuickFramebufferObject::Renderer *)CoreManager::getInstance()->getCore()->getNativePreviewWindowId();
- CoreManager::getInstance()->getCore()->setNativePreviewWindowId(renderer);
+ renderer = (QQuickFramebufferObject::Renderer *)CoreManager::getInstance()->getCore()->getNativePreviewWindowId();
+ if(renderer)
+ CoreManager::getInstance()->getCore()->setNativePreviewWindowId(NULL);// Reset
+ renderer=(QQuickFramebufferObject::Renderer *)CoreManager::getInstance()->getCore()->createNativePreviewWindowId();
+ if(renderer)
+ CoreManager::getInstance()->getCore()->setNativePreviewWindowId(renderer);
}else{
+ bool useDefaultWindow = false;
if(mCallModel){
auto call = mCallModel->getCall();
if(call){
- call->setNativeVideoWindowId(NULL);// Reset
renderer = (QQuickFramebufferObject::Renderer *) call->getNativeVideoWindowId();
- call->setNativeVideoWindowId(renderer);
- }else{
- CoreManager::getInstance()->getCore()->setNativeVideoWindowId(NULL);
- renderer = (QQuickFramebufferObject::Renderer *) CoreManager::getInstance()->getCore()->getNativeVideoWindowId();
- CoreManager::getInstance()->getCore()->setNativeVideoWindowId(renderer);
- }
+ if(renderer)
+ call->setNativeVideoWindowId(NULL);// Reset
+ renderer = (QQuickFramebufferObject::Renderer *) call->createNativeVideoWindowId();
+ if(renderer)
+ call->setNativeVideoWindowId(renderer);
+ }else
+ useDefaultWindow = true;
}else if( mParticipantDeviceModel){
auto participantDevice = mParticipantDeviceModel->getDevice();
if(participantDevice){
- participantDevice->setNativeVideoWindowId(NULL);// Reset
- renderer = (QQuickFramebufferObject::Renderer *) participantDevice->getNativeVideoWindowId();
- participantDevice->setNativeVideoWindowId(renderer);
- }else{
+ renderer = (QQuickFramebufferObject::Renderer *)participantDevice->getNativeVideoWindowId();
+ if(renderer)
+ participantDevice->setNativeVideoWindowId(NULL);// Reset
+ renderer = (QQuickFramebufferObject::Renderer *) participantDevice->createNativeVideoWindowId();
+ if(renderer)
+ participantDevice->setNativeVideoWindowId(renderer);
+ }else
+ useDefaultWindow = true;
+ }
+ if(useDefaultWindow){
+ renderer = (QQuickFramebufferObject::Renderer *)CoreManager::getInstance()->getCore()->getNativeVideoWindowId();
+ if(renderer)
CoreManager::getInstance()->getCore()->setNativeVideoWindowId(NULL);
- enderer = (QQuickFramebufferObject::Renderer *) CoreManager::getInstance()->getCore()->getNativeVideoWindowId();
+ renderer = (QQuickFramebufferObject::Renderer *) CoreManager::getInstance()->getCore()->createNativeVideoWindowId();
+ if(renderer)
CoreManager::getInstance()->getCore()->setNativeVideoWindowId(renderer);
- }
}
}
-
- if(renderer)
- return renderer;
- else{
- qWarning() << "Camera stream couldn't start for Rendering";
- return new SafeFramebuffer();
+ if( !renderer){
+ qWarning() << "Camera stream couldn't start for Rendering. Retrying in 1s";
+ renderer = new CameraDummy();
+ QTimer::singleShot(1000, this, &Camera::requestNewRenderer);
+
}
+ return renderer;
}
// -----------------------------------------------------------------------------
diff --git a/linphone-app/src/components/camera/Camera.hpp b/linphone-app/src/components/camera/Camera.hpp
index 00740ab05..a2fab4825 100644
--- a/linphone-app/src/components/camera/Camera.hpp
+++ b/linphone-app/src/components/camera/Camera.hpp
@@ -55,6 +55,7 @@ signals:
void callChanged (CallModel *callModel);
void isPreviewChanged (bool isPreview);
void participantDeviceModelChanged(ParticipantDeviceModel *participantDeviceModel);
+ void requestNewRenderer();
private:
CallModel *getCallModel () const;
diff --git a/linphone-app/src/components/camera/CameraDummy.cpp b/linphone-app/src/components/camera/CameraDummy.cpp
new file mode 100644
index 000000000..0c65f8f87
--- /dev/null
+++ b/linphone-app/src/components/camera/CameraDummy.cpp
@@ -0,0 +1,44 @@
+/*
+ * Copyright (c) 2010-2020 Belledonne Communications SARL.
+ *
+ * This file is part of linphone-desktop
+ * (see https://www.linphone.org).
+ *
+ * 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 .
+ */
+
+#include
+#include
+#include
+#include
+
+#include "components/core/CoreManager.hpp"
+
+#include "CameraDummy.hpp"
+
+// =============================================================================
+
+
+CameraDummy::CameraDummy(){
+}
+
+QOpenGLFramebufferObject *CameraDummy::createFramebufferObject (const QSize &size){
+ return new QOpenGLFramebufferObject(size);
+}
+
+void CameraDummy::render (){
+}
+
+void CameraDummy::synchronize (QQuickFramebufferObject *item){
+}
\ No newline at end of file
diff --git a/linphone-app/src/components/camera/CameraDummy.hpp b/linphone-app/src/components/camera/CameraDummy.hpp
new file mode 100644
index 000000000..a79df2ad3
--- /dev/null
+++ b/linphone-app/src/components/camera/CameraDummy.hpp
@@ -0,0 +1,37 @@
+/*
+ * Copyright (c) 2022 Belledonne Communications SARL.
+ *
+ * This file is part of linphone-desktop
+ * (see https://www.linphone.org).
+ *
+ * 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 .
+ */
+
+#ifndef CAMERA_DUMMY_H_
+#define CAMERA_DUMMY_H_
+
+#include
+#include
+
+// =============================================================================
+
+class CameraDummy : public QQuickFramebufferObject::Renderer{
+public:
+ CameraDummy();
+ QOpenGLFramebufferObject *createFramebufferObject (const QSize &size) override;
+ void render () override;
+ void synchronize (QQuickFramebufferObject *item) override;
+};
+
+#endif
diff --git a/linphone-app/src/components/camera/CameraPreview.cpp b/linphone-app/src/components/camera/CameraPreview.cpp
index 9a5835476..7e253a5ca 100644
--- a/linphone-app/src/components/camera/CameraPreview.cpp
+++ b/linphone-app/src/components/camera/CameraPreview.cpp
@@ -26,6 +26,7 @@
#include "components/core/CoreManager.hpp"
#include "CameraPreview.hpp"
+#include "CameraDummy.hpp"
// =============================================================================
@@ -74,25 +75,16 @@ CameraPreview::~CameraPreview () {
}
}
-class SafeFramebuffer : public QQuickFramebufferObject::Renderer{
-public:
- SafeFramebuffer(){}
- QOpenGLFramebufferObject *createFramebufferObject (const QSize &size) override{
- return new QOpenGLFramebufferObject(size);
- }
- void render () override{}
- void synchronize (QQuickFramebufferObject *item) override{}
-};
-
QQuickFramebufferObject::Renderer *CameraPreview::createRenderer () const {
- QQuickFramebufferObject::Renderer * renderer;
- CoreManager::getInstance()->getCore()->setNativePreviewWindowId(NULL);// Reset
- renderer=(QQuickFramebufferObject::Renderer *)CoreManager::getInstance()->getCore()->getNativePreviewWindowId();
- CoreManager::getInstance()->getCore()->setNativePreviewWindowId(renderer);
+ QQuickFramebufferObject::Renderer * renderer = (QQuickFramebufferObject::Renderer *)CoreManager::getInstance()->getCore()->getNativePreviewWindowId();
if(renderer)
- return renderer;
- else{
- qWarning() << "Preview stream couldn't start for Rendering";
- return new SafeFramebuffer();
- }
+ CoreManager::getInstance()->getCore()->setNativePreviewWindowId(NULL);// Reset
+ renderer = (QQuickFramebufferObject::Renderer *) CoreManager::getInstance()->getCore()->createNativePreviewWindowId();
+ if( !renderer ) {
+ qWarning() << "Preview stream couldn't start for Rendering. Retrying in 1s";
+ renderer = new CameraDummy();
+ QTimer::singleShot(1000, this, &CameraPreview::requestNewRenderer);
+ }else
+ CoreManager::getInstance()->getCore()->setNativePreviewWindowId(renderer);
+ return renderer;
}
diff --git a/linphone-app/src/components/camera/CameraPreview.hpp b/linphone-app/src/components/camera/CameraPreview.hpp
index 2a057ef30..3411d5e0b 100644
--- a/linphone-app/src/components/camera/CameraPreview.hpp
+++ b/linphone-app/src/components/camera/CameraPreview.hpp
@@ -23,24 +23,26 @@
#include
#include
-#include
// =============================================================================
class CameraPreview : public QQuickFramebufferObject {
- Q_OBJECT;
-
+ Q_OBJECT
+
public:
- CameraPreview (QQuickItem *parent = Q_NULLPTR);
- ~CameraPreview ();
-
- QQuickFramebufferObject::Renderer *createRenderer () const override;
+ CameraPreview (QQuickItem *parent = Q_NULLPTR);
+ ~CameraPreview ();
+
+ QQuickFramebufferObject::Renderer *createRenderer () const override;
+
+signals:
+ void requestNewRenderer();
private:
- QTimer *mRefreshTimer = nullptr;
-
- static QMutex mCounterMutex;
- static int mCounter;
+ QTimer *mRefreshTimer = nullptr;
+
+ static QMutex mCounterMutex;
+ static int mCounter;
};
#endif // CAMERA_PREVIEW_H_
diff --git a/linphone-app/src/components/chat-room/ChatRoomModel.cpp b/linphone-app/src/components/chat-room/ChatRoomModel.cpp
index 8cd1192bb..f673f8d91 100644
--- a/linphone-app/src/components/chat-room/ChatRoomModel.cpp
+++ b/linphone-app/src/components/chat-room/ChatRoomModel.cpp
@@ -236,10 +236,17 @@ ChatRoomModel::ChatRoomModel (std::shared_ptr chatRoom, QObj
connect(contact, &ContactModel::contactUpdated, this, &ChatRoomModel::fullPeerAddressChanged);
}
}
-
+ // Get Max updatetime from chat room and last call event
+ auto callHistory = CallsListModel::getCallHistory(getParticipantAddress(), Utils::coreStringToAppString(mChatRoom->getLocalAddress()->asStringUriOnly()));
+ if(callHistory.size() > 0){
+ auto callDate = callHistory.front()->getStartDate();
+ if( callHistory.front()->getStatus() == linphone::Call::Status::Success )
+ callDate += callHistory.front()->getDuration();
+ setLastUpdateTime(QDateTime::fromMSecsSinceEpoch(max(mChatRoom->getLastUpdateTime(), callDate )*1000));
+ }else
+ setLastUpdateTime(QDateTime::fromMSecsSinceEpoch(mChatRoom->getLastUpdateTime()*1000));
}else
mParticipantListModel = nullptr;
-
}
ChatRoomModel::~ChatRoomModel () {
diff --git a/linphone-app/src/components/conference/ConferenceModel.cpp b/linphone-app/src/components/conference/ConferenceModel.cpp
index da1a31239..096256e40 100644
--- a/linphone-app/src/components/conference/ConferenceModel.cpp
+++ b/linphone-app/src/components/conference/ConferenceModel.cpp
@@ -64,29 +64,36 @@ std::shared_ptr ConferenceModel::getConference()const{
//-----------------------------------------------------------------------------------------------------------------------
void ConferenceModel::onParticipantAdded(const std::shared_ptr & conference, const std::shared_ptr & participant){
qWarning() << "onParticipantAdded is not yet implemented.";
+ qWarning() << "Me devices : " << conference->getMe()->getDevices().size();
}
void ConferenceModel::onParticipantRemoved(const std::shared_ptr & conference, const std::shared_ptr & participant){
qWarning() << "onParticipantRemoved is not yet implemented.";
+ qWarning() << "Me devices : " << conference->getMe()->getDevices().size();
}
void ConferenceModel::onParticipantDeviceAdded(const std::shared_ptr & conference, const std::shared_ptr & participantDevice){
+ qWarning() << "Me devices : " << conference->getMe()->getDevices().size();
emit participantDeviceAdded(participantDevice);
}
void ConferenceModel::onParticipantDeviceRemoved(const std::shared_ptr & conference, const std::shared_ptr & participantDevice){
+ qWarning() << "Me devices : " << conference->getMe()->getDevices().size();
emit participantDeviceRemoved(participantDevice);
}
void ConferenceModel::onParticipantAdminStatusChanged(const std::shared_ptr & conference, const std::shared_ptr & participant){
}
void ConferenceModel::onParticipantDeviceLeft(const std::shared_ptr & conference, const std::shared_ptr & participantDevice){
+ qWarning() << "Me devices : " << conference->getMe()->getDevices().size();
emit participantDeviceLeft(participantDevice);
}
void ConferenceModel::onParticipantDeviceJoined(const std::shared_ptr & conference, const std::shared_ptr & participantDevice){
+ qWarning() << "Me devices : " << conference->getMe()->getDevices().size();
emit participantDeviceJoined(participantDevice);
}
-void ConferenceModel::onParticipantDeviceMediaChanged(const std::shared_ptr & conference, const std::shared_ptr & device){
- qWarning() << "onParticipantDeviceMediaChanged is not yet implemented.";
+void ConferenceModel::onParticipantDeviceMediaChanged(const std::shared_ptr & conference, const std::shared_ptr & participantDevice){
+ qWarning() << "ConferenceModel::onParticipantDeviceMediaChanged: " << (int)participantDevice->getStreamAvailability(linphone::StreamType::Video) << ". Me devices : " << conference->getMe()->getDevices().size();
+ emit participantDeviceMediaChanged(participantDevice);
}
void ConferenceModel::onStateChanged(const std::shared_ptr & conference, linphone::Conference::State newState){
- qWarning() << "onStateChanged is not yet implemented.";
+ emit conferenceStateChanged(newState);
}
void ConferenceModel::onSubjectChanged(const std::shared_ptr & conference, const std::string & subject){
qWarning() << "onSubjectChanged is not yet implemented.";
diff --git a/linphone-app/src/components/conference/ConferenceModel.hpp b/linphone-app/src/components/conference/ConferenceModel.hpp
index 6885b82e3..9ce75fc53 100644
--- a/linphone-app/src/components/conference/ConferenceModel.hpp
+++ b/linphone-app/src/components/conference/ConferenceModel.hpp
@@ -56,6 +56,8 @@ signals:
void participantDeviceRemoved(const std::shared_ptr & participantDevice);
void participantDeviceLeft(const std::shared_ptr & participantDevice);
void participantDeviceJoined(const std::shared_ptr & participantDevice);
+ void participantDeviceMediaChanged(const std::shared_ptr & participantDevice);
+ void conferenceStateChanged(linphone::Conference::State newState);
private:
std::shared_ptr mConference;
diff --git a/linphone-app/src/components/conferenceInfo/ConferenceInfoListModel.cpp b/linphone-app/src/components/conferenceInfo/ConferenceInfoListModel.cpp
index be7e8f007..d571cd2b6 100644
--- a/linphone-app/src/components/conferenceInfo/ConferenceInfoListModel.cpp
+++ b/linphone-app/src/components/conferenceInfo/ConferenceInfoListModel.cpp
@@ -36,14 +36,16 @@
// =============================================================================
ConferenceInfoListModel::ConferenceInfoListModel (QObject *parent) : QAbstractListModel(parent) {
- auto conferenceInfos = CoreManager::getInstance()->getCore()->getConferenceInformationList();
- for(auto conferenceInfo : conferenceInfos){
- mList << ConferenceInfoModel::create( conferenceInfo );
- }
+ //auto conferenceInfos = CoreManager::getInstance()->getCore()->getConferenceInformationList();
+ //for(auto conferenceInfo : conferenceInfos){
+// auto conferenceInfoModel = ConferenceInfoModel::create( conferenceInfo );
+// mList << conferenceInfoModel;
+ //mMappedList[conferenceInfoModel->getDateTime().date()].push_back(conferenceInfoModel.get());
+// }
}
int ConferenceInfoListModel::rowCount (const QModelIndex &) const {
- return mList.count();
+ return mList.size();
}
QHash ConferenceInfoListModel::roleNames () const {
@@ -55,35 +57,46 @@ QHash ConferenceInfoListModel::roleNames () const {
QVariant ConferenceInfoListModel::data (const QModelIndex &index, int role) const {
int row = index.row();
- if (!index.isValid() || row < 0 || row >= mList.count())
+ if (!index.isValid() || row < 0 || row >= mList.size())
return QVariant();
+ auto it = mList.begin() + row;
if (role == Qt::DisplayRole)
- return QVariant::fromValue(mList[row].get());
+ return QVariant::fromValue(it->get());
- //return QVariant();
+ return QVariant();
+}
+
+ConferenceInfoModel* ConferenceInfoListModel::getAt(const int& index) const {
+ return mList[index].get();
}
// -----------------------------------------------------------------------------
-
-
+void ConferenceInfoListModel::add(std::shared_ptr conferenceInfoModel){
+ int row = mList.size();
+ beginInsertRows(QModelIndex(), row,row);
+ mList << conferenceInfoModel;
+ endInsertRows();
+}
+// Should not be called as item that need to be removed are usually a cell, not a row
bool ConferenceInfoListModel::removeRow (int row, const QModelIndex &parent) {
return removeRows(row, 1, parent);
}
bool ConferenceInfoListModel::removeRows (int row, int count, const QModelIndex &parent) {
+/*
int limit = row + count - 1;
- if (row < 0 || count < 0 || limit >= mList.count())
+ if (row < 0 || count < 0 || limit >= mMappedList.count())
return false;
beginRemoveRows(parent, row, limit);
for (int i = 0; i < count; ++i)
- mList.takeAt(row)->deleteLater();
+ mMappedList.takeAt(row)->deleteLater();
endRemoveRows();
-
+ */
return true;
}
diff --git a/linphone-app/src/components/conferenceInfo/ConferenceInfoListModel.hpp b/linphone-app/src/components/conferenceInfo/ConferenceInfoListModel.hpp
index 395b42c6e..f6a5528bb 100644
--- a/linphone-app/src/components/conferenceInfo/ConferenceInfoListModel.hpp
+++ b/linphone-app/src/components/conferenceInfo/ConferenceInfoListModel.hpp
@@ -23,6 +23,7 @@
#include
#include
+#include
// =============================================================================
@@ -38,14 +39,16 @@ public:
QHash roleNames () const override;
QVariant data (const QModelIndex &index, int role = Qt::DisplayRole) const override;
-
+ ConferenceInfoModel* getAt(const int& index) const;
+ void add(std::shared_ptr conferenceInfoModel);
private:
bool removeRow (int row, const QModelIndex &parent = QModelIndex());
bool removeRows (int row, int count, const QModelIndex &parent = QModelIndex()) override;
QList> mList;
+ //QMap> mMappedList;
};
-
+Q_DECLARE_METATYPE(QList*)
#endif
diff --git a/linphone-app/src/components/conferenceInfo/ConferenceInfoMapModel.cpp b/linphone-app/src/components/conferenceInfo/ConferenceInfoMapModel.cpp
new file mode 100644
index 000000000..144e1162d
--- /dev/null
+++ b/linphone-app/src/components/conferenceInfo/ConferenceInfoMapModel.cpp
@@ -0,0 +1,77 @@
+/*
+ * Copyright (c) 2021 Belledonne Communications SARL.
+ *
+ * This file is part of linphone-desktop
+ * (see https://www.linphone.org).
+ *
+ * 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 .
+ */
+
+#include "ConferenceInfoMapModel.hpp"
+
+#include
+#include
+#include
+
+#include "app/App.hpp"
+#include "components/conference/ConferenceAddModel.hpp"
+#include "components/conference/ConferenceHelperModel.hpp"
+#include "components/core/CoreHandlers.hpp"
+#include "components/core/CoreManager.hpp"
+#include "components/settings/SettingsModel.hpp"
+#include "utils/Utils.hpp"
+
+#include "ConferenceInfoListModel.hpp"
+#include "ConferenceInfoModel.hpp"
+
+// =============================================================================
+
+ConferenceInfoMapModel::ConferenceInfoMapModel (QObject *parent) : QAbstractListModel(parent) {
+ auto conferenceInfos = CoreManager::getInstance()->getCore()->getConferenceInformationList();
+ for(auto conferenceInfo : conferenceInfos){
+ auto conferenceInfoModel = ConferenceInfoModel::create( conferenceInfo );
+ QDate t = conferenceInfoModel->getDateTime().date();
+ if( !mMappedList.contains(t))
+ mMappedList[t] = new ConferenceInfoListModel();
+ mMappedList[t]->add(conferenceInfoModel);
+ }
+}
+
+int ConferenceInfoMapModel::rowCount (const QModelIndex &) const {
+ return mMappedList.size();
+}
+
+QHash ConferenceInfoMapModel::roleNames () const {
+ QHash roles;
+ roles[Qt::DisplayRole] = "modelData";
+ roles[Qt::DisplayRole + 1] = "date";
+ return roles;
+}
+
+QVariant ConferenceInfoMapModel::data (const QModelIndex &index, int role) const {
+ int row = index.row();
+
+ if (!index.isValid() || row < 0 || row >= mMappedList.size())
+ return QVariant();
+ auto it = mMappedList.begin() + row;
+
+ if (role == Qt::DisplayRole)
+ return QVariant::fromValue(*it);
+ else if( role == Qt::DisplayRole+1)
+ return QVariant::fromValue(it.key());
+
+ return QVariant();
+}
+
+// -----------------------------------------------------------------------------
diff --git a/linphone-app/src/components/conferenceInfo/ConferenceInfoMapModel.hpp b/linphone-app/src/components/conferenceInfo/ConferenceInfoMapModel.hpp
new file mode 100644
index 000000000..68d6047d6
--- /dev/null
+++ b/linphone-app/src/components/conferenceInfo/ConferenceInfoMapModel.hpp
@@ -0,0 +1,48 @@
+/*
+ * Copyright (c) 2021 Belledonne Communications SARL.
+ *
+ * This file is part of linphone-desktop
+ * (see https://www.linphone.org).
+ *
+ * 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 .
+ */
+
+#ifndef _CONFERENCE_INFO_MAP_MODEL_H_
+#define _CONFERENCE_INFO_MAP_MODEL_H_
+
+#include
+#include
+#include
+
+// =============================================================================
+
+class ConferenceInfoListModel;
+
+class ConferenceInfoMapModel : public QAbstractListModel {
+ Q_OBJECT
+
+public:
+ ConferenceInfoMapModel (QObject *parent = Q_NULLPTR);
+
+ int rowCount (const QModelIndex &index = QModelIndex()) const override;
+
+ QHash roleNames () const override;
+ QVariant data (const QModelIndex &index, int role = Qt::DisplayRole) const override;
+
+private:
+ QMap mMappedList;
+
+};
+Q_DECLARE_METATYPE(ConferenceInfoMapModel*)
+#endif
diff --git a/linphone-app/src/components/conferenceInfo/ConferenceInfoModel.cpp b/linphone-app/src/components/conferenceInfo/ConferenceInfoModel.cpp
index d5c3f76dd..1710d484e 100644
--- a/linphone-app/src/components/conferenceInfo/ConferenceInfoModel.cpp
+++ b/linphone-app/src/components/conferenceInfo/ConferenceInfoModel.cpp
@@ -45,6 +45,7 @@
#include "components/contact/ContactModel.hpp"
#include "components/contact/VcardModel.hpp"
#include "components/contacts/ContactsListModel.hpp"
+#include "components/conferenceScheduler/ConferenceSchedulerModel.hpp"
#include "components/core/CoreHandlers.hpp"
#include "components/core/CoreManager.hpp"
#include "components/notifier/Notifier.hpp"
@@ -75,7 +76,7 @@ using namespace std;
std::shared_ptr ConferenceInfoModel::create(std::shared_ptr conferenceInfo){
std::shared_ptr model = std::make_shared(conferenceInfo);
if(model){
- //model->mSelf = model;
+ model->mSelf = model;
//chatRoom->addListener(model);
return model;
}else
@@ -85,6 +86,9 @@ std::shared_ptr ConferenceInfoModel::create(std::shared_ptr
ConferenceInfoModel::ConferenceInfoModel (QObject * parent) : QObject(parent){
//App::getInstance()->getEngine()->setObjectOwnership(this, QQmlEngine::CppOwnership);// Avoid QML to destroy it when passing by Q_INVOKABLE
mConferenceInfo = linphone::Factory::get()->createConferenceInfo();
+ auto accountAddress = CoreManager::getInstance()->getCore()->getDefaultAccount()->getContactAddress();
+ accountAddress->clean();
+ mConferenceInfo->setOrganizer(accountAddress);
}
ConferenceInfoModel::ConferenceInfoModel (std::shared_ptr conferenceInfo, QObject * parent) : QObject(parent){
@@ -147,6 +151,10 @@ QString ConferenceInfoModel::getUri() const{
return QString::fromStdString(mConferenceInfo->getUri()->asString());
}
+bool ConferenceInfoModel::isScheduled() const{
+ return mIsScheduled;
+}
+
//------------------------------------------------------------------------------------------------
void ConferenceInfoModel::setDateTime(const QDateTime& dateTime){
@@ -178,3 +186,55 @@ void ConferenceInfoModel::setDescription(const QString& description){
void ConferenceInfoModel::setParticipants(ParticipantListModel * participants){
mConferenceInfo->setParticipants(participants->getParticipants());
}
+
+void ConferenceInfoModel::setIsScheduled(const bool& on){
+ if( mIsScheduled != on){
+ mIsScheduled = on;
+ emit isScheduledChanged();
+ }
+}
+
+//-------------------------------------------------------------------------------------------------
+
+void ConferenceInfoModel::createConference(const int& securityLevel, const int& inviteMode) {
+ CoreManager::getInstance()->getTimelineListModel()->mAutoSelectAfterCreation = false;
+ shared_ptr core = CoreManager::getInstance()->getCore();
+ static std::shared_ptr conference;
+ qInfo() << "Conference creation of " << getSubject() << " at " << securityLevel << " security, organized by " << getOrganizer();// and with " << conferenceInfo->getConferenceInfo()->getParticipants().size();
+
+ if( true || isScheduled()){
+ mConferenceSchedulerModel = ConferenceSchedulerModel::create(this);
+ connect(mConferenceSchedulerModel.get(), &ConferenceSchedulerModel::invitationsSent, this, &ConferenceInfoModel::onInvitationsSent);
+
+ mConferenceSchedulerModel->getConferenceScheduler()->setInfo(mConferenceInfo);
+ }else{
+ auto conferenceParameters = core->createConferenceParams();
+ conferenceParameters->enableAudio(true);
+ conferenceParameters->enableVideo(true);
+ conferenceParameters->setDescription(mConferenceInfo->getDescription());
+ conferenceParameters->setSubject(mConferenceInfo->getSubject());
+ conferenceParameters->setStartTime(mConferenceInfo->getDateTime());
+ conferenceParameters->setEndTime(mConferenceInfo->getDateTime() + (mConferenceInfo->getDuration() * 60));
+ conferenceParameters->enableLocalParticipant(true);
+ //conferenceParameters->enableOneParticipantConference(true);
+ /*
+ if(true) {//Remote
+ conferenceParameters->setConferenceFactoryUri(core->getDefaultAccount()->getContactAddress()->asStringUriOnly());
+ }else
+ conferenceParameters->setConferenceFactoryUri(nullptr);
+ */
+ conference = core->createConferenceWithParams(conferenceParameters);
+
+ //auto parameters = CoreManager::getInstance()->getCore()->createCallParams(nullptr);
+ //parameters->enableVideo(true);
+ //conference->inviteParticipants(mConferenceInfo->getParticipants(), parameters);
+ }
+}
+
+//-------------------------------------------------------------------------------------------------
+
+
+void ConferenceInfoModel::onInvitationsSent(const std::list> & failedInvitations) {
+ mConferenceSchedulerModel->getConferenceScheduler()->removeListener(mConferenceSchedulerModel);
+ emit invitationsSent();
+}
\ No newline at end of file
diff --git a/linphone-app/src/components/conferenceInfo/ConferenceInfoModel.hpp b/linphone-app/src/components/conferenceInfo/ConferenceInfoModel.hpp
index 6cae02ad1..a947ee9ed 100644
--- a/linphone-app/src/components/conferenceInfo/ConferenceInfoModel.hpp
+++ b/linphone-app/src/components/conferenceInfo/ConferenceInfoModel.hpp
@@ -26,8 +26,9 @@
#include
class ParticipantListModel;
+class ConferenceSchedulerModel;
-class ConferenceInfoModel : public QObject{
+class ConferenceInfoModel : public QObject {
Q_OBJECT
public:
@@ -40,6 +41,7 @@ public:
Q_PROPERTY(QString description READ getDescription WRITE setDescription NOTIFY descriptionChanged)
Q_PROPERTY(QString displayNamesToString READ displayNamesToString NOTIFY participantsChanged)
Q_PROPERTY(QString uri READ getUri NOTIFY uriChanged)
+ Q_PROPERTY(bool isScheduled READ isScheduled WRITE setIsScheduled NOTIFY isScheduledChanged)
//Q_PROPERTY(participants READ getParticipants WRITE setParticipants NOTIFY participantsChanged)
@@ -59,15 +61,25 @@ public:
QString getDescription() const;
Q_INVOKABLE QString displayNamesToString()const;
QString getUri() const;
+ bool isScheduled() const;
void setDateTime(const QDateTime& dateTime);
void setDuration(const int& duration);
void setSubject(const QString& subject);
void setOrganizer(const QString& organizerAddress);
void setDescription(const QString& description);
+ void setIsScheduled(const bool& on);
Q_INVOKABLE void setParticipants(ParticipantListModel * participants);
+// Tools
+ Q_INVOKABLE void createConference(const int& securityLevel, const int& inviteMode);
+
+// SCHEDULER
+
+ //virtual void onStateChanged(const std::shared_ptr & conferenceScheduler, linphone::ConferenceSchedulerState state) override;
+ virtual void onInvitationsSent(const std::list> & failedInvitations);
+
signals:
void dateTimeChanged();
@@ -77,12 +89,19 @@ signals:
void descriptionChanged();
void participantsChanged();
void uriChanged();
+ void isScheduledChanged();
+
+ void conferenceCreated();
+ void invitationsSent();
private:
std::shared_ptr mConferenceInfo;
-
+ std::shared_ptr mConferenceSchedulerModel = nullptr;
+ std::weak_ptr mSelf; // For Linphone listener
+ bool mIsScheduled = true;
};
Q_DECLARE_METATYPE(std::shared_ptr)
+Q_DECLARE_METATYPE(ConferenceInfoModel*)
#endif
diff --git a/linphone-app/src/components/conferenceInfo/ConferenceInfoProxyModel.cpp b/linphone-app/src/components/conferenceInfo/ConferenceInfoProxyModel.cpp
index ed941c200..4ecda8630 100644
--- a/linphone-app/src/components/conferenceInfo/ConferenceInfoProxyModel.cpp
+++ b/linphone-app/src/components/conferenceInfo/ConferenceInfoProxyModel.cpp
@@ -22,6 +22,7 @@
#include "components/core/CoreManager.hpp"
#include "ConferenceInfoListModel.hpp"
+#include "ConferenceInfoMapModel.hpp"
#include "ConferenceInfoProxyModel.hpp"
// =============================================================================
@@ -29,7 +30,7 @@
using namespace std;
ConferenceInfoProxyModel::ConferenceInfoProxyModel (QObject *parent) : QSortFilterProxyModel(parent) {
- setSourceModel(new ConferenceInfoListModel());
+ setSourceModel(new ConferenceInfoMapModel());
sort(0, Qt::DescendingOrder);
}
@@ -38,10 +39,10 @@ bool ConferenceInfoProxyModel::filterAcceptsRow (int sourceRow, const QModelInde
}
bool ConferenceInfoProxyModel::lessThan (const QModelIndex &left, const QModelIndex &right) const {
- const ConferenceInfoModel *deviceA = sourceModel()->data(left).value();
- const ConferenceInfoModel *deviceB = sourceModel()->data(right).value();
+ const ConferenceInfoListModel* deviceA = sourceModel()->data(left).value();
+ const ConferenceInfoListModel* deviceB = sourceModel()->data(right).value();
- return deviceA->getDateTime() < deviceB->getDateTime();
+ return deviceA->getAt(0)->getDateTime() < deviceB->getAt(0)->getDateTime();
}
QVariant ConferenceInfoProxyModel::getAt(int row){
diff --git a/linphone-app/src/components/conferenceScheduler/ConferenceSchedulerModel.cpp b/linphone-app/src/components/conferenceScheduler/ConferenceSchedulerModel.cpp
new file mode 100644
index 000000000..01de9fed8
--- /dev/null
+++ b/linphone-app/src/components/conferenceScheduler/ConferenceSchedulerModel.cpp
@@ -0,0 +1,62 @@
+/*
+ * Copyright (c) 2021 Belledonne Communications SARL.
+ *
+ * This file is part of linphone-desktop
+ * (see https://www.linphone.org).
+ *
+ * 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 .
+ */
+
+#include "ConferenceSchedulerModel.hpp"
+
+#include
+#include "app/App.hpp"
+#include "components/core/CoreManager.hpp"
+
+// =============================================================================
+std::shared_ptr ConferenceSchedulerModel::create( QObject *parent){
+ std::shared_ptr model = std::make_shared(parent);
+ if(model){
+ model->mSelf = model;
+ model->mConferenceScheduler->addListener(model);
+ return model;
+ }
+ return nullptr;
+}
+
+ConferenceSchedulerModel::ConferenceSchedulerModel (QObject * parent) : QObject(parent){
+ App::getInstance()->getEngine()->setObjectOwnership(this, QQmlEngine::CppOwnership);// Avoid QML to destroy it when passing by Q_INVOKABLE
+ mConferenceScheduler = CoreManager::getInstance()->getCore()->createConferenceScheduler();
+}
+
+ConferenceSchedulerModel::~ConferenceSchedulerModel () {
+}
+
+std::shared_ptr ConferenceSchedulerModel::getConferenceScheduler(){
+ return mConferenceScheduler;
+}
+
+void ConferenceSchedulerModel::onStateChanged(const std::shared_ptr & conferenceScheduler, linphone::ConferenceSchedulerState state) {
+ emit stateChanged(state);
+ qWarning() << "ConferenceSchedulerModel::onStateChanged : " << (int)state;
+ if( state == linphone::ConferenceSchedulerState::Ready) {
+ std::shared_ptr params = CoreManager::getInstance()->getCore()->createDefaultChatRoomParams();
+ params->setBackend(linphone::ChatRoomBackend::Basic);
+ mConferenceScheduler->sendInvitations(params);
+ }
+}
+
+void ConferenceSchedulerModel::onInvitationsSent(const std::shared_ptr & conferenceScheduler, const std::list> & failedInvitations) {
+ emit invitationsSent(failedInvitations);
+}
\ No newline at end of file
diff --git a/linphone-app/src/components/conferenceScheduler/ConferenceSchedulerModel.hpp b/linphone-app/src/components/conferenceScheduler/ConferenceSchedulerModel.hpp
new file mode 100644
index 000000000..110dae8ad
--- /dev/null
+++ b/linphone-app/src/components/conferenceScheduler/ConferenceSchedulerModel.hpp
@@ -0,0 +1,54 @@
+/*
+ * Copyright (c) 2021 Belledonne Communications SARL.
+ *
+ * This file is part of linphone-desktop
+ * (see https://www.linphone.org).
+ *
+ * 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 .
+ */
+
+#ifndef CONFERENCE_SCHEDULER_MODEL_H_
+#define CONFERENCE_SCHEDULER_MODEL_H_
+
+#include
+#include
+#include
+
+class ConferenceSchedulerModel : public QObject
+ , public linphone::ConferenceSchedulerListener
+{
+ Q_OBJECT
+
+public:
+ static std::shared_ptr create(QObject *parent = Q_NULLPTR);
+ ConferenceSchedulerModel (QObject * parent = nullptr);
+ ~ConferenceSchedulerModel ();
+ std::shared_ptr getConferenceScheduler();
+
+ virtual void onStateChanged(const std::shared_ptr & conferenceScheduler, linphone::ConferenceSchedulerState state) override;
+ virtual void onInvitationsSent(const std::shared_ptr & conferenceScheduler, const std::list> & failedInvitations) override;
+
+signals:
+ void stateChanged(linphone::ConferenceSchedulerState state);
+ void invitationsSent(const std::list> & failedInvitations);
+
+private:
+ std::shared_ptr mConferenceScheduler;
+ std::weak_ptr mSelf; // Used for Linphone Listener
+
+};
+
+Q_DECLARE_METATYPE(std::shared_ptr)
+
+#endif
diff --git a/linphone-app/src/components/content/ContentModel.cpp b/linphone-app/src/components/content/ContentModel.cpp
index 3b6b6011b..6ad886e17 100644
--- a/linphone-app/src/components/content/ContentModel.cpp
+++ b/linphone-app/src/components/content/ContentModel.cpp
@@ -87,6 +87,13 @@ QString ContentModel::getUtf8Text() const{
return QString::fromStdString(mContent->getUtf8Text());
}
+ConferenceInfoModel * ContentModel::getConferenceInfoModel(){
+ if( !mConferenceInfoModel && isIcalendar()){
+ mConferenceInfoModel = ConferenceInfoModel::create(linphone::Factory::get()->createConferenceInfoFromIcalendarContent(mContent));
+ }
+ return mConferenceInfoModel.get();
+}
+
void ContentModel::setFileOffset(quint64 fileOffset){
if( mFileOffset != fileOffset) {
mFileOffset = fileOffset;
@@ -109,6 +116,7 @@ void ContentModel::setWasDownloaded(bool wasDownloaded){
void ContentModel::setContent(std::shared_ptr content){
mContent = content;
emit nameChanged();
+ mConferenceInfoModel = nullptr;
if(isFile() || isFileEncrypted() || isFileTransfer() ){
QString path = Utils::coreStringToAppString(mContent->getFilePath());
if (!path.isEmpty())
diff --git a/linphone-app/src/components/content/ContentModel.hpp b/linphone-app/src/components/content/ContentModel.hpp
index e382c8907..386e3c90d 100644
--- a/linphone-app/src/components/content/ContentModel.hpp
+++ b/linphone-app/src/components/content/ContentModel.hpp
@@ -29,6 +29,8 @@
#include
#include "components/chat-events/ChatMessageModel.hpp"
+class ChatMessageModel;
+class ConferenceInfoModel;
class ContentModel : public QObject{
Q_OBJECT
@@ -44,6 +46,7 @@ public:
Q_PROPERTY(bool wasDownloaded MEMBER mWasDownloaded WRITE setWasDownloaded NOTIFY wasDownloadedChanged)
Q_PROPERTY(QString filePath READ getFilePath CONSTANT)
Q_PROPERTY(ChatMessageModel * chatMessageModel READ getChatMessageModel CONSTANT)
+ Q_PROPERTY(ConferenceInfoModel * conferenceInfoModel READ getConferenceInfoModel CONSTANT)
Q_PROPERTY(QString text READ getUtf8Text CONSTANT)
std::shared_ptr getContent()const;
@@ -54,6 +57,7 @@ public:
QString getThumbnail() const;
QString getFilePath() const;
QString getUtf8Text() const;
+ ConferenceInfoModel * getConferenceInfoModel();//Create a conference Info if not set
void setFileOffset(quint64 fileOffset);
void setThumbnail(const QString& data);
@@ -93,6 +97,7 @@ private:
std::shared_ptr mContent;
ChatMessageModel* mChatMessageModel;
ChatMessageModel::AppDataManager mAppData; // Used if there is no Chat Message model set.
+ std::shared_ptr mConferenceInfoModel;
};
Q_DECLARE_METATYPE(std::shared_ptr)
diff --git a/linphone-app/src/components/core/CoreHandlers.cpp b/linphone-app/src/components/core/CoreHandlers.cpp
index 9422428ec..2dc4af776 100644
--- a/linphone-app/src/components/core/CoreHandlers.cpp
+++ b/linphone-app/src/components/core/CoreHandlers.cpp
@@ -325,7 +325,32 @@ void CoreHandlers::onEcCalibrationResult(
}
//------------------------------ CONFERENCE INFO
+void CoreHandlers::onConferenceInfoReceived(const std::shared_ptr & core, const std::shared_ptr & conferenceInfo) {
+ qWarning() << "onConferenceInfoReceived";
+/*
+ qWarning() << "onConferenceInfoReceived : sending invitation only for known participants (API fail? this should be done from SDK)";
+ qWarning() << "onConferenceInfoReceived : Duration: " << conferenceInfo->getDuration();
+
+ for(auto participant : conferenceInfo->getParticipants()){
+ std::shared_ptr params = core->createDefaultChatRoomParams();
+ std::list> participants;
+ std::shared_ptr chatRoom;
+ chatRoom = core->searchChatRoom(params, conferenceInfo->getOrganizer()
+ , participant
+ , participants);
+ if(chatRoom) {
+ auto timeLine = CoreManager::getInstance()->getTimelineListModel()->getChatRoomModel(chatRoom, true);
+ if(timeLine)
+ timeLine->sendMessage("Conference invitation : " +QString::fromStdString(conferenceInfo->getUri()->asString()));
+ else
+ qWarning() << "Cannot use a timeline for invitation";
+ }else
+ qWarning() << "Cannot use a chatroom for invitation";
+ }
+ */
+}
+/*
void CoreHandlers::onConferenceInfoCreated(const std::shared_ptr & core, const std::shared_ptr & conferenceInfo){
qWarning() << "onConferenceInfoCreated : sending invitation only for known participants (API fail? this should be done from SDK)";
qWarning() << "onConferenceInfoCreated : Duration: " << conferenceInfo->getDuration();
@@ -358,4 +383,5 @@ void CoreHandlers::onConferenceInfoParticipantSent(const std::shared_ptr & core, const std::shared_ptr & conferenceInfo, const std::shared_ptr & participant, linphone::ConferenceInfoError error){
qWarning() << "onConferenceInfoParticipantError";
-}
\ No newline at end of file
+}
+*/
\ No newline at end of file
diff --git a/linphone-app/src/components/core/CoreHandlers.hpp b/linphone-app/src/components/core/CoreHandlers.hpp
index 05c32be87..7b8952fcb 100644
--- a/linphone-app/src/components/core/CoreHandlers.hpp
+++ b/linphone-app/src/components/core/CoreHandlers.hpp
@@ -186,13 +186,14 @@ private:
) override;
// Conference Info
+ virtual void onConferenceInfoReceived(const std::shared_ptr & core, const std::shared_ptr & conferenceInfo) override;
+ /*
virtual void onConferenceInfoCreated(const std::shared_ptr & core, const std::shared_ptr & conferenceInfo);
virtual void onConferenceInfoOnSent(const std::shared_ptr & core, const std::shared_ptr & conferenceInfo);
virtual void onConferenceInfoParticipantSent(const std::shared_ptr & core, const std::shared_ptr & conferenceInfo, const std::shared_ptr & participant);
virtual void onConferenceInfoParticipantError(const std::shared_ptr & core, const std::shared_ptr & conferenceInfo, const std::shared_ptr & participant, linphone::ConferenceInfoError error);
+ */
-
- // ---------------------------------------------------------------------------
};
#endif // CORE_HANDLERS_H_
diff --git a/linphone-app/src/components/participant/ParticipantDeviceListModel.cpp b/linphone-app/src/components/participant/ParticipantDeviceListModel.cpp
index 1f284946c..f5183fd50 100644
--- a/linphone-app/src/components/participant/ParticipantDeviceListModel.cpp
+++ b/linphone-app/src/components/participant/ParticipantDeviceListModel.cpp
@@ -19,6 +19,7 @@
*/
#include
+#include
#include "app/App.hpp"
@@ -34,6 +35,7 @@ ParticipantDeviceListModel::ParticipantDeviceListModel (std::shared_ptr(device, false);
connect(this, &ParticipantDeviceListModel::securityLevelChanged, deviceModel.get(), &ParticipantDeviceModel::onSecurityLevelChanged);
+ connect(this, &ParticipantDeviceListModel::participantDeviceMediaChanged, deviceModel.get(), &ParticipantDeviceModel::videoEnabledChanged);
mList << deviceModel;
}
}
@@ -42,26 +44,30 @@ ParticipantDeviceListModel::ParticipantDeviceListModel (CallModel * callModel, Q
if(callModel && callModel->isConference()) {
mCallModel = callModel;
auto conferenceModel = callModel->getConferenceModel();
- auto meDevices = conferenceModel->getConference()->getMe()->getDevices();
- if(meDevices.size() > 0)
- mList << std::make_shared(meDevices.front(), true);// Add Me in device list
- else
- mList << std::make_shared(nullptr, true);
+ /*
+ mList << std::make_shared(callModel, true);// Add Me in device list
+ qWarning() << "Me devices : " << conferenceModel->getConference()->getMe()->getDevices().size();
+// auto meDevices = conferenceModel->getConference()->getMe()->getDevices();
+ // if(meDevices.size() > 0)
+
std::list> devices = conferenceModel->getConference()->getParticipantDeviceList();
- for(auto device : devices){
- auto deviceModel = std::make_shared(device, false);
- connect(this, &ParticipantDeviceListModel::securityLevelChanged, deviceModel.get(), &ParticipantDeviceModel::onSecurityLevelChanged);
- mList << deviceModel;
- }
+ updateDevices(devices);
+ qWarning() << "Instanciate Participant Device list model with " << mList.size() << " devices";
+ */
connect(conferenceModel.get(), &ConferenceModel::participantDeviceAdded, this, &ParticipantDeviceListModel::onParticipantDeviceAdded);
+ connect(conferenceModel.get(), &ConferenceModel::participantDeviceRemoved, this, &ParticipantDeviceListModel::onParticipantDeviceRemoved);
+ connect(conferenceModel.get(), &ConferenceModel::participantDeviceMediaChanged, this, &ParticipantDeviceListModel::onParticipantDeviceMediaChanged);
+ connect(conferenceModel.get(), &ConferenceModel::conferenceStateChanged, this, &ParticipantDeviceListModel::onConferenceStateChanged);
}
}
int ParticipantDeviceListModel::rowCount (const QModelIndex &index) const{
+ qWarning() << "rowCount: " << mList.count();
return mList.count();
}
int ParticipantDeviceListModel::count(){
+ qWarning() << "count: " << mList.count();
return mList.count();
}
@@ -72,12 +78,43 @@ void ParticipantDeviceListModel::updateDevices(std::shared_ptr(device, false);
connect(this, &ParticipantDeviceListModel::securityLevelChanged, deviceModel.get(), &ParticipantDeviceModel::onSecurityLevelChanged);
+ connect(this, &ParticipantDeviceListModel::participantDeviceMediaChanged, deviceModel.get(), &ParticipantDeviceModel::videoEnabledChanged);
mList << deviceModel;
}
endResetModel();
+ emit countChanged();
emit layoutChanged();
}
+void ParticipantDeviceListModel::updateDevices(const std::list>& devices, const bool& isMe){
+ QList> devicesToAdd;
+ //auto meDevices = mCallModel->getConferenceModel()->getConference()->getMe()->getDevices();
+ for(auto device : devices){
+ auto deviceAddress = device->getAddress();
+ //bool isMe = false;
+ //for(auto meDevice : meDevices)
+ //isMe |= meDevice->getAddress() == deviceAddress;
+ //if( !isMe) {
+ auto exist = std::find_if(mList.begin(), mList.end(), [deviceAddress](const std::shared_ptr& activeDevice){
+ return deviceAddress == activeDevice->getDevice()->getAddress();
+ });
+ if(exist == mList.end()){
+ auto deviceModel = std::make_shared(device, isMe);
+ connect(this, &ParticipantDeviceListModel::securityLevelChanged, deviceModel.get(), &ParticipantDeviceModel::onSecurityLevelChanged);
+ connect(this, &ParticipantDeviceListModel::participantDeviceMediaChanged, deviceModel.get(), &ParticipantDeviceModel::videoEnabledChanged);
+ devicesToAdd << deviceModel;
+ }
+ //}
+ }
+ if(devicesToAdd.size() > 0){
+ int row = mList.count();
+ beginInsertRows(QModelIndex(), row, row+devicesToAdd.size()-1);
+ mList << devicesToAdd;
+ endInsertRows();
+ emit countChanged();
+ }
+}
+
QHash ParticipantDeviceListModel::roleNames () const {
QHash roles;
roles[Qt::DisplayRole] = "$participantDevice";
@@ -124,37 +161,79 @@ void ParticipantDeviceListModel::onSecurityLevelChanged(std::shared_ptr & participantDevice){
+ qWarning() << "Adding participant";
auto conferenceModel = mCallModel->getConferenceModel();
std::list> devices = conferenceModel->getConference()->getParticipantDeviceList();
for(auto realParticipantDevice : devices){
if( realParticipantDevice == participantDevice){
int row = mList.count();
beginInsertRows(QModelIndex(), row, row);
- auto deviceModel = std::make_shared(realParticipantDevice, this);
+ auto deviceModel = std::make_shared(realParticipantDevice, false);
connect(this, &ParticipantDeviceListModel::securityLevelChanged, deviceModel.get(), &ParticipantDeviceModel::onSecurityLevelChanged);
+ connect(this, &ParticipantDeviceListModel::participantDeviceMediaChanged, deviceModel.get(), &ParticipantDeviceModel::videoEnabledChanged);
mList << deviceModel;
endInsertRows();
- emit layoutChanged();
+ emit countChanged();
+ //emit layoutChanged();
return;
}
}
qWarning() << "No participant device found from const linphone::ParticipantDevice at onParticipantDeviceAdded";
}
+
void ParticipantDeviceListModel::onParticipantDeviceRemoved(const std::shared_ptr & participantDevice){
+ qWarning() << "Removing participant";
int row = 0;
for(auto device : mList){
if( device->getDevice() == participantDevice){
removeRow(row);
- emit layoutChanged();
+ emit countChanged();
+ //emit layoutChanged();
return;
}
++row;
}
qWarning() << "No participant device found from const linphone::ParticipantDevice at onParticipantDeviceRemoved";
}
+
void ParticipantDeviceListModel::onParticipantDeviceJoined(const std::shared_ptr & participantDevice){
qWarning() << "onParticipantDeviceJoined is not yet implemented. Current participants count: " << mList.size();
}
+
void ParticipantDeviceListModel::onParticipantDeviceLeft(const std::shared_ptr & participantDevice){
qWarning() << "onParticipantDeviceLeft is not yet implemented. Current participants count: " << mList.size();
+}
+
+void ParticipantDeviceListModel::onParticipantDeviceMediaChanged(const std::shared_ptr & participantDevice) {
+ emit participantDeviceMediaChanged();
+}
+void ParticipantDeviceListModel::onConferenceStateChanged(linphone::Conference::State newState){
+ if(newState == linphone::Conference::State::Created){
+ if(mCallModel && mCallModel->isConference()) {
+ auto conferenceModel = mCallModel->getConferenceModel();
+ updateDevices(mCallModel->getConferenceModel()->getConference()->getMe()->getDevices(), true);
+ updateDevices(conferenceModel->getConference()->getParticipantDeviceList(), false);
+ }
+
+ /*
+ auto devices = mCallModel->getConferenceModel()->getConference()->getMe()->getDevices();
+ if(devices.size() > 0 && mList.size() == 1){
+ //qWarning() << "Adding Me in list. Count=" << mList.size();
+ beginInsertRows(QModelIndex(), 0, 0);
+ mList.push_front(std::make_shared(mCallModel, true));// Add Me in device list
+ endInsertRows();
+ emit countChanged();
+ emit layoutChanged();
+ qWarning() << "M added in list. Count=" << mList.size() << ".\n\tConfVideo is enabled:" << mCallModel->getConferenceModel()->getConference()->getCurrentParams()->videoEnabled()
+ << "\n\tCallVideo is enabled: " << mCallModel->getVideoEnabled();
+ }else
+ qWarning() << "Me cannot be add : no Me device.";
+ }else {
+ if(!mCallModel)
+ qWarning() << "Cannot add me : no call.";
+ else
+ qWarning() << "Cannot add me : No in conf.";
+ }
+ */
+ }
}
\ No newline at end of file
diff --git a/linphone-app/src/components/participant/ParticipantDeviceListModel.hpp b/linphone-app/src/components/participant/ParticipantDeviceListModel.hpp
index 061f18580..99d31650e 100644
--- a/linphone-app/src/components/participant/ParticipantDeviceListModel.hpp
+++ b/linphone-app/src/components/participant/ParticipantDeviceListModel.hpp
@@ -43,6 +43,7 @@ public:
int count();
void updateDevices(std::shared_ptr participant);
+ void updateDevices(const std::list>& devices, const bool& isMe);
virtual QHash roleNames () const override;
virtual QVariant data (const QModelIndex &index, int role = Qt::DisplayRole) const override;
@@ -54,9 +55,13 @@ public slots:
void onParticipantDeviceRemoved(const std::shared_ptr & participantDevice);
void onParticipantDeviceJoined(const std::shared_ptr & participantDevice);
void onParticipantDeviceLeft(const std::shared_ptr & participantDevice);
+ void onParticipantDeviceMediaChanged(const std::shared_ptr & participantDevice);
+ void onConferenceStateChanged(linphone::Conference::State newState);
signals:
void securityLevelChanged(std::shared_ptr device);
+ void countChanged();
+ void participantDeviceMediaChanged();
private:
bool removeRow (int row, const QModelIndex &parent = QModelIndex());
diff --git a/linphone-app/src/components/participant/ParticipantDeviceModel.cpp b/linphone-app/src/components/participant/ParticipantDeviceModel.cpp
index f63db4c05..4fd231596 100644
--- a/linphone-app/src/components/participant/ParticipantDeviceModel.cpp
+++ b/linphone-app/src/components/participant/ParticipantDeviceModel.cpp
@@ -28,8 +28,17 @@
// =============================================================================
ParticipantDeviceModel::ParticipantDeviceModel (std::shared_ptr device, const bool& isMe, QObject *parent) : QObject(parent) {
+ App::getInstance()->getEngine()->setObjectOwnership(this, QQmlEngine::CppOwnership);// Avoid QML to destroy it when passing by Q_INVOKABLE
mIsMe = isMe;
mParticipantDevice = device;
+ mCall = nullptr;
+}
+
+ParticipantDeviceModel::ParticipantDeviceModel (CallModel * call, const bool& isMe, QObject *parent) : QObject(parent) {
+ App::getInstance()->getEngine()->setObjectOwnership(this, QQmlEngine::CppOwnership);// Avoid QML to destroy it when passing by Q_INVOKABLE
+ mIsMe = isMe;
+ mCall = call;
+ connect(call, &CallModel::statusChanged, this, &ParticipantDeviceModel::videoEnabledChanged);
}
// -----------------------------------------------------------------------------
@@ -60,8 +69,9 @@ std::shared_ptr ParticipantDeviceModel::getDevice(
}
bool ParticipantDeviceModel::isVideoEnabled() const{
- return mParticipantDevice && (mParticipantDevice->getVideoDirection() == linphone::MediaDirection::SendRecv
- || mParticipantDevice->getVideoDirection() == linphone::MediaDirection::SendOnly);
+ if(mParticipantDevice)
+ qWarning() << "VideoEnabled: " << (int)mParticipantDevice->getStreamAvailability(linphone::StreamType::Video);
+ return mParticipantDevice && mParticipantDevice->getStreamAvailability(linphone::StreamType::Video);
}
bool ParticipantDeviceModel::isMe() const{
diff --git a/linphone-app/src/components/participant/ParticipantDeviceModel.hpp b/linphone-app/src/components/participant/ParticipantDeviceModel.hpp
index 7542431db..98a01664d 100644
--- a/linphone-app/src/components/participant/ParticipantDeviceModel.hpp
+++ b/linphone-app/src/components/participant/ParticipantDeviceModel.hpp
@@ -28,11 +28,14 @@
#include
#include
+class CallModel;
+
class ParticipantDeviceModel : public QObject {
Q_OBJECT
public:
ParticipantDeviceModel (std::shared_ptr device, const bool& isMe = false, QObject *parent = nullptr);
+ ParticipantDeviceModel (CallModel * call, const bool& isMe = true, QObject *parent = nullptr);
Q_PROPERTY(QString name READ getName CONSTANT)
Q_PROPERTY(QString address READ getAddress CONSTANT)
@@ -63,6 +66,7 @@ private:
bool mIsMe = false;
std::shared_ptr mParticipantDevice;
+ CallModel * mCall;
};
diff --git a/linphone-app/src/components/participant/ParticipantDeviceProxyModel.cpp b/linphone-app/src/components/participant/ParticipantDeviceProxyModel.cpp
index a5f7e8c3a..2e77e1ff8 100644
--- a/linphone-app/src/components/participant/ParticipantDeviceProxyModel.cpp
+++ b/linphone-app/src/components/participant/ParticipantDeviceProxyModel.cpp
@@ -61,12 +61,26 @@ ParticipantDeviceModel *ParticipantDeviceProxyModel::getAt(int row){
CallModel * ParticipantDeviceProxyModel::getCallModel() const{
return mCallModel;
}
+
+int ParticipantDeviceProxyModel::getCount() const{
+ ParticipantDeviceListModel* devices = dynamic_cast(sourceModel());
+ if(devices)
+ return devices->rowCount();
+ else
+ return 0;
+}
void ParticipantDeviceProxyModel::setCallModel(CallModel * callModel){
mCallModel = callModel;
- setSourceModel(new ParticipantDeviceListModel(mCallModel));
+ auto sourceModel = new ParticipantDeviceListModel(mCallModel);
+ connect(sourceModel, &ParticipantDeviceListModel::countChanged, this, &ParticipantDeviceProxyModel::countChanged);
+ setSourceModel(sourceModel);
+ emit countChanged();
}
-
+
void ParticipantDeviceProxyModel::setParticipant(ParticipantModel * participant){
- setSourceModel(participant->getParticipantDevices().get());
+ auto sourceModel = participant->getParticipantDevices().get();
+ connect(sourceModel, &ParticipantDeviceListModel::countChanged, this, &ParticipantDeviceProxyModel::countChanged);
+ setSourceModel(sourceModel);
+ emit countChanged();
}
\ No newline at end of file
diff --git a/linphone-app/src/components/participant/ParticipantDeviceProxyModel.hpp b/linphone-app/src/components/participant/ParticipantDeviceProxyModel.hpp
index d794eabc2..7feebd1c9 100644
--- a/linphone-app/src/components/participant/ParticipantDeviceProxyModel.hpp
+++ b/linphone-app/src/components/participant/ParticipantDeviceProxyModel.hpp
@@ -39,10 +39,12 @@ class ParticipantDeviceProxyModel : public QSortFilterProxyModel {
public:
Q_PROPERTY(CallModel * callModel READ getCallModel WRITE setCallModel NOTIFY callModelChanged)
+ Q_PROPERTY(int count READ getCount NOTIFY countChanged)
ParticipantDeviceProxyModel (QObject *parent = nullptr);
Q_INVOKABLE ParticipantDeviceModel* getAt(int row);
CallModel * getCallModel() const;
+ Q_INVOKABLE int getCount() const;
void setCallModel(CallModel * callModel);
@@ -50,6 +52,7 @@ public:
signals:
void callModelChanged();
+ void countChanged();
protected:
virtual bool filterAcceptsRow (int sourceRow, const QModelIndex &sourceParent) const override;
diff --git a/linphone-app/src/components/timeline/TimelineListModel.cpp b/linphone-app/src/components/timeline/TimelineListModel.cpp
index b7af65897..b22efadcc 100644
--- a/linphone-app/src/components/timeline/TimelineListModel.cpp
+++ b/linphone-app/src/components/timeline/TimelineListModel.cpp
@@ -384,11 +384,11 @@ void TimelineListModel::onCallStateChanged (const std::shared_ptr &call){
- std::shared_ptr core = CoreManager::getInstance()->getCore();
- std::shared_ptr params = core->createDefaultChatRoomParams();
- std::list> participants;
-
-// Find all chat rooms with local address. If not, create one.
+ std::shared_ptr core = CoreManager::getInstance()->getCore();
+ std::shared_ptr params = core->createDefaultChatRoomParams();
+ std::list> participants;
+ if( !call->getConference() && false ){
+ // Find all chat rooms with local address. If not, create one.
bool isOutgoing = (call->getDir() == linphone::Call::Dir::Outgoing) ;
bool found = false;
auto callLog = call->getCallLog();
@@ -429,6 +429,7 @@ void TimelineListModel::onCallCreated(const std::shared_ptr &cal
participants << Utils::coreStringToAppString(remoteAddress->asStringUriOnly());
CoreManager::getInstance()->getCallsListModel()->createChatRoom("", (createSecureChatRoom?1:0), callLocalAddress, participants, isOutgoing);
}
+ }
}
/*
diff --git a/linphone-app/ui/modules/Common/Form/Mosaic.qml b/linphone-app/ui/modules/Common/Form/Mosaic.qml
index a11a0e8c4..4115100fa 100644
--- a/linphone-app/ui/modules/Common/Form/Mosaic.qml
+++ b/linphone-app/ui/modules/Common/Form/Mosaic.qml
@@ -164,6 +164,8 @@ ColumnLayout{
removeDisplaced: defaultTransition
populate:defaultTransition
+ onItemCountChanged: console.log("Mosaic "+model+" itemCount: " +itemCount +" => " + (model.count ? " count="+model.count :( model.length ? " length":" no" )))
+
}
/*
ListView{
diff --git a/linphone-app/ui/modules/Linphone/Chat/ChatCalendarMessage.qml b/linphone-app/ui/modules/Linphone/Chat/ChatCalendarMessage.qml
new file mode 100644
index 000000000..59348f782
--- /dev/null
+++ b/linphone-app/ui/modules/Linphone/Chat/ChatCalendarMessage.qml
@@ -0,0 +1,143 @@
+import QtQuick 2.7
+import QtQuick.Layouts 1.3
+
+import Clipboard 1.0
+import Common 1.0
+import Linphone 1.0
+
+import Common.Styles 1.0
+import Linphone.Styles 1.0
+import TextToSpeech 1.0
+import Utils 1.0
+import Units 1.0
+import UtilsCpp 1.0
+import LinphoneEnums 1.0
+
+import ColorsList 1.0
+
+import 'Message.js' as Logic
+
+// =============================================================================
+
+Loader{
+ id: mainItem
+ property ContentModel contentModel
+ property ConferenceInfoModel conferenceInfoModel: contentModel && active ? contentModel.conferenceInfoModel : null
+ property int maxWidth : parent.width
+ property int fitHeight: active && item ? item.fitHeight + ChatCalendarMessageStyle.heightMargin*2 : 0
+ property int fitWidth: active && item ? Math.max(item.fitWidth, maxWidth/2) + ChatCalendarMessageStyle.widthMargin*2 : 0
+ width: parent.width
+ height: fitHeight
+
+ property font customFont : SettingsModel.textMessageFont
+ active: (mainItem.contentModel && mainItem.contentModel.isIcalendar()) || (!mainItem.contentModel && mainItem.conferenceInfoModel)
+
+ sourceComponent: MouseArea{
+ id: loadedItem
+ property int fitHeight: layout.fitHeight
+ property int fitWidth: layout.fitWidth
+
+ anchors.fill: parent
+ anchors.leftMargin: ChatCalendarMessageStyle.widthMargin
+ anchors.rightMargin: ChatCalendarMessageStyle.widthMargin
+ anchors.topMargin: ChatCalendarMessageStyle.heightMargin
+ anchors.bottomMargin: ChatCalendarMessageStyle.heightMargin
+
+ clip: false
+
+ cursorShape: Qt.ArrowCursor
+ hoverEnabled: true
+ onClicked: CallsListModel.launchVideoCall(mainItem.conferenceInfoModel.uri, '', 0)
+
+ ColumnLayout{
+ id: layout
+ property int fitHeight: Layout.minimumHeight
+ property int fitWidth: Layout.minimumWidth
+ anchors.fill: parent
+ spacing: 0
+ RowLayout {
+ Layout.fillWidth: true
+ Layout.preferredWidth: parent.width // Need this because fillWidth is not enough...
+ Layout.preferredHeight: ChatCalendarMessageStyle.schedule.iconSize
+ spacing: 10
+ RowLayout {
+ id: scheduleRow
+ Layout.fillWidth: true
+ Layout.preferredHeight: ChatCalendarMessageStyle.schedule.iconSize
+ Layout.leftMargin: 5
+ spacing: ChatCalendarMessageStyle.schedule.spacing
+
+ Icon{
+ icon: ChatCalendarMessageStyle.schedule.icon
+ iconSize: ChatCalendarMessageStyle.schedule.iconSize
+ overwriteColor: ChatCalendarMessageStyle.schedule.color
+ }
+
+ Text {
+ id: conferenceTime
+ Layout.fillWidth: true
+ Layout.minimumWidth: implicitWidth
+ verticalAlignment: Qt.AlignVCenter
+ color: ChatCalendarMessageStyle.schedule.color
+ elide: Text.ElideRight
+ font.pointSize: ChatCalendarMessageStyle.schedule.pointSize
+ text: Qt.formatDateTime(mainItem.conferenceInfoModel.dateTime, '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.rightMargin: 10
+ verticalAlignment: Qt.AlignVCenter
+ color: ChatCalendarMessageStyle.schedule.color
+ elide: Text.ElideRight
+ font.pointSize: ChatCalendarMessageStyle.schedule.pointSize
+ text: 'Organisateur : ' +UtilsCpp.getDisplayName(mainItem.conferenceInfoModel.organizer)
+ }
+ }
+ Text{
+ id: title
+ Layout.fillWidth: true
+ Layout.minimumWidth: implicitWidth
+ Layout.topMargin: 10
+ Layout.leftMargin: 10
+ Layout.alignment: Qt.AlignRight
+ color: ChatCalendarMessageStyle.subject.color
+ font.pointSize: ChatCalendarMessageStyle.subject.pointSize
+ font.weight: Font.Bold
+ text: mainItem.conferenceInfoModel.subject
+ }
+ RowLayout {
+ id: participantsRow
+ Layout.fillWidth: true
+ Layout.fillHeight: true
+ Layout.leftMargin: 5
+
+ spacing: ChatCalendarMessageStyle.participants.spacing
+
+ Icon{
+ icon: ChatCalendarMessageStyle.participants.icon
+ iconSize: ChatCalendarMessageStyle.participants.iconSize
+ overwriteColor: ChatCalendarMessageStyle.participants.color
+ }
+
+ Text {
+ id: participantsList
+ Layout.fillWidth: true
+ Layout.minimumWidth: implicitWidth
+ color: ChatCalendarMessageStyle.participants.color
+ elide: Text.ElideRight
+ font.pointSize: ChatCalendarMessageStyle.participants.pointSize
+ text: mainItem.conferenceInfoModel.displayNamesToString
+ }
+ }
+ }
+ }
+}
+
diff --git a/linphone-app/ui/modules/Linphone/Chat/ChatContent.qml b/linphone-app/ui/modules/Linphone/Chat/ChatContent.qml
index c1bfe93bc..ac18f583c 100644
--- a/linphone-app/ui/modules/Linphone/Chat/ChatContent.qml
+++ b/linphone-app/ui/modules/Linphone/Chat/ChatContent.qml
@@ -20,8 +20,8 @@ Column{
id: mainItem
property ContentModel contentModel
- property int fitHeight: message.fitHeight + fileMessage.fitHeight + audioMessage.fitHeight
- property int fitWidth: message.fitWidth + fileMessage.fitWidth + audioMessage.fitWidth
+ property int fitHeight: calendarMessage.fitHeight + message.fitHeight + fileMessage.fitHeight + audioMessage.fitHeight
+ property int fitWidth: calendarMessage.fitWidth + message.fitWidth + fileMessage.fitWidth + audioMessage.fitWidth
property color backgroundColor
property string lastTextSelected
property alias textColor: message.color
@@ -29,6 +29,7 @@ Column{
signal rightClicked()
+ property int maxWidth
height: fitHeight
anchors.left: parent ? parent.left : undefined
anchors.right: parent ? parent.right : undefined
@@ -37,6 +38,12 @@ Column{
property bool isOutgoing : contentModel && contentModel.chatMessageModel && (contentModel.chatMessageModel.isOutgoing || contentModel.chatMessageModel.state == LinphoneEnums.ChatMessageStateIdle);
+ ChatCalendarMessage{
+ id: calendarMessage
+ contentModel: mainItem.contentModel
+ width: parent.width
+ maxWidth: mainItem.maxWidth
+ }
ChatAudioMessage{
id: audioMessage
contentModel: mainItem.contentModel
@@ -54,4 +61,4 @@ Column{
color: isOutgoing ? ChatStyle.entry.message.outgoing.text.color : ChatStyle.entry.message.incoming.text.color
onRightClicked: mainItem.rightClicked()
}
-}
\ No newline at end of file
+}
diff --git a/linphone-app/ui/modules/Linphone/Chat/ChatFileMessage.qml b/linphone-app/ui/modules/Linphone/Chat/ChatFileMessage.qml
index f919c4241..a441239ce 100644
--- a/linphone-app/ui/modules/Linphone/Chat/ChatFileMessage.qml
+++ b/linphone-app/ui/modules/Linphone/Chat/ChatFileMessage.qml
@@ -27,7 +27,7 @@ Row {
signal copySelectionDone()
signal forwardClicked()
height: fitHeight
- visible: contentModel && (contentModel.isFile() || contentModel.isFileTransfer()) && !contentModel.isVoiceRecording()
+ visible: contentModel && !contentModel.isIcalendar() && (contentModel.isFile() || contentModel.isFileTransfer()) && !contentModel.isVoiceRecording()
// ---------------------------------------------------------------------------
// File message.
// ---------------------------------------------------------------------------
diff --git a/linphone-app/ui/modules/Linphone/Chat/ChatForwardMessage.qml b/linphone-app/ui/modules/Linphone/Chat/ChatForwardMessage.qml
index c2919fd75..5e68a4469 100644
--- a/linphone-app/ui/modules/Linphone/Chat/ChatForwardMessage.qml
+++ b/linphone-app/ui/modules/Linphone/Chat/ChatForwardMessage.qml
@@ -50,7 +50,7 @@ Item {
id: headerText
height: icon.height
verticalAlignment: Qt.AlignVCenter
- // Anonymized forward : this is wanted.
+ // Anonymized forward : do not get display name, this is wanted.
//property string forwardInfo: mainChatMessageModel ? mainChatMessageModel.getForwardInfoDisplayName : ''
//: 'Forwarded' : Header on a message that contains a forward.
text: qsTr('Forwarded')// + (forwardInfo ? ' : ' +forwardInfo : '')
diff --git a/linphone-app/ui/modules/Linphone/Chat/Message.qml b/linphone-app/ui/modules/Linphone/Chat/Message.qml
index 96bbe341c..6281a127a 100644
--- a/linphone-app/ui/modules/Linphone/Chat/Message.qml
+++ b/linphone-app/ui/modules/Linphone/Chat/Message.qml
@@ -104,6 +104,7 @@ Item {
interactive: false
delegate:
ChatContent{
+ maxWidth: container.width
contentModel: modelData
onFitWidthChanged:{
rectangle.updateWidth()
diff --git a/linphone-app/ui/modules/Linphone/Styles/Chat/ChatCalendarMessageStyle.qml b/linphone-app/ui/modules/Linphone/Styles/Chat/ChatCalendarMessageStyle.qml
new file mode 100644
index 000000000..19ae72fad
--- /dev/null
+++ b/linphone-app/ui/modules/Linphone/Styles/Chat/ChatCalendarMessageStyle.qml
@@ -0,0 +1,82 @@
+pragma Singleton
+import QtQml 2.2
+
+import Units 1.0
+import ColorsList 1.0
+
+// =============================================================================
+
+QtObject {
+ property string sectionName : 'ChatCalendarMessage'
+ property int heightMargin: 5
+ property int widthMargin: 5
+ property int minWidth: 300
+
+ property int actionButtonsSize: 36
+ property int avatarSize: 30
+ property int deleteButtonSize: 22
+ property int height: 50
+ property int leftMargin: 40
+ property int bottomMargin: 10
+ property int presenceLevelSize: 12
+ property int rightMargin: 25
+ property int spacing: 15
+
+ property QtObject backgroundColor: QtObject {
+ property color normal: ColorsList.add(sectionName+'_conference_bg_n', 'conference_bg').color
+ property color hovered: ColorsList.add(sectionName+'_conference_bg_h', 'g10').color
+ }
+
+ property QtObject border: QtObject {
+ property color color: ColorsList.add(sectionName+'_conference_border', 'f').color
+ property int width: 1
+ }
+
+ property QtObject indicator: QtObject {
+ property color color: ColorsList.add(sectionName+'_conference_indicator', 'i').color
+ property int width: 5
+ }
+
+ property QtObject schedule: QtObject {
+ property int spacing: 0
+ property int pointSize: Units.dp * 10
+ property string icon : 'schedule_custom'
+ property int iconSize: 30
+ property color color: ColorsList.add(sectionName+'_schedule', 'j').color
+ }
+ property QtObject subject: QtObject {
+ property int spacing: 5
+ property int pointSize: Units.dp * 11
+ property color color: ColorsList.add(sectionName+'_subject', 'j').color
+ }
+ property QtObject participants: QtObject {
+ property int spacing: 5
+ property int pointSize: Units.dp * 10
+ property string icon : 'calendar_participants_custom'
+ property int iconSize: 30
+ property color color: ColorsList.add(sectionName+'_participants', 'j').color
+ }
+
+ property QtObject organizer: QtObject {
+ property color color: ColorsList.add(sectionName+'_conference_organizer', 'j').color
+ property int pointSize: Units.dp * 10
+ property int width: 220
+ }
+
+
+
+ /*
+ property color color: ColorsList.add(sectionName, 'q').color
+ property QtObject header: QtObject{
+ property color color: ColorsList.add(sectionName+'_header', 'h').color
+ property int pointSizeOffset: -3
+ property QtObject forwardIcon: QtObject{
+ property string icon : 'menu_forward_custom'
+ property int iconSize: 22
+ }
+ }
+
+ property int padding: 8
+ */
+
+}
diff --git a/linphone-app/ui/modules/Linphone/Styles/qmldir b/linphone-app/ui/modules/Linphone/Styles/qmldir
index b0d90c152..246137b5e 100644
--- a/linphone-app/ui/modules/Linphone/Styles/qmldir
+++ b/linphone-app/ui/modules/Linphone/Styles/qmldir
@@ -13,6 +13,7 @@ singleton ChatStyle 1.0 Chat/ChatStyle.qml
singleton ChatAudioMessageStyle 1.0 Chat/ChatAudioMessageStyle.qml
singleton ChatAudioPreviewStyle 1.0 Chat/ChatAudioPreviewStyle.qml
singleton ChatFilePreviewStyle 1.0 Chat/ChatFilePreviewStyle.qml
+singleton ChatCalendarMessageStyle 1.0 Chat/ChatCalendarMessageStyle.qml
singleton ChatForwardMessageStyle 1.0 Chat/ChatForwardMessageStyle.qml
singleton ChatReplyMessageStyle 1.0 Chat/ChatReplyMessageStyle.qml
diff --git a/linphone-app/ui/modules/Linphone/qmldir b/linphone-app/ui/modules/Linphone/qmldir
index d9f533348..95f2a6b98 100644
--- a/linphone-app/ui/modules/Linphone/qmldir
+++ b/linphone-app/ui/modules/Linphone/qmldir
@@ -17,6 +17,7 @@ CallStatistics 1.0 Calls/CallStatistics.qml
Chat 1.0 Chat/Chat.qml
ChatAudioMessage 1.0 Chat/ChatAudioMessage.qml
ChatAudioPreview 1.0 Chat/ChatAudioPreview.qml
+ChatCalendarMessage 1.0 Chat/ChatCalendarMessage.qml
ChatMessagePreview 1.0 Chat/ChatMessagePreview.qml
ChatForwardMessage 1.0 Chat/ChatForwardMessage.qml
ChatReplyMessage 1.0 Chat/ChatReplyMessage.qml
diff --git a/linphone-app/ui/views/App/Calls/EndedCall.qml b/linphone-app/ui/views/App/Calls/EndedCall.qml
index 72fa5710a..128694ccb 100644
--- a/linphone-app/ui/views/App/Calls/EndedCall.qml
+++ b/linphone-app/ui/views/App/Calls/EndedCall.qml
@@ -68,7 +68,7 @@ Rectangle {
image: _sipAddressObserver.contact && _sipAddressObserver.contact.vcard.avatar
username: contactDescription.username
- height: Logic.computeAvatarSize(CallStyle.container.avatar.maxSize)
+ height: Logic.computeAvatarSize(container, CallStyle.container.avatar.maxSize)
width: height
}
}
diff --git a/linphone-app/ui/views/App/Calls/Incall.js b/linphone-app/ui/views/App/Calls/Incall.js
index 7f0b778eb..6377bc736 100644
--- a/linphone-app/ui/views/App/Calls/Incall.js
+++ b/linphone-app/ui/views/App/Calls/Incall.js
@@ -28,7 +28,7 @@
// =============================================================================
-function computeAvatarSize (maxSize) {
+function computeAvatarSize (container, maxSize) {
var height = container.height
var width = container.width
@@ -71,39 +71,39 @@ function handleStatusChanged (status) {
}
}
-function handleVideoRequested () {
- var call = incall.call
+function handleVideoRequested (call) {
+ console.log("handleVideoRequested")
if (window.virtualWindowVisible || !Linphone.SettingsModel.videoSupported) {
call.rejectVideoRequest()
return
}
-
+ /*
// Close dialog after 10s.
var timeout = Utils.setTimeout(incall, 10000, function () {
call.statusChanged.disconnect(endedHandler)
window.detachVirtualWindow()
call.rejectVideoRequest()
})
-
+ */
// Close dialog if call is ended.
var endedHandler = function (status) {
if (status === Linphone.CallModel.CallStatusEnded) {
- Utils.clearTimeout(timeout)
+ Utils.clearTimeout(timeout)
call.statusChanged.disconnect(endedHandler)
window.detachVirtualWindow()
}
}
-
call.statusChanged.connect(endedHandler)
-
+console.log("D")
// Ask video to user.
window.attachVirtualWindow(Utils.buildDialogUri('ConfirmDialog'), {
descriptionText: qsTr('acceptVideoDescription'),
}, function (status) {
- Utils.clearTimeout(timeout)
+ //Utils.clearTimeout(timeout)
call.statusChanged.disconnect(endedHandler)
-
+ console.log("E: "+status)
if (status) {
+ console.log("TOTO")
call.acceptVideoRequest()
} else {
call.rejectVideoRequest()
diff --git a/linphone-app/ui/views/App/Calls/Incall.qml b/linphone-app/ui/views/App/Calls/Incall.qml
index fb65c15a8..c06edc4f6 100644
--- a/linphone-app/ui/views/App/Calls/Incall.qml
+++ b/linphone-app/ui/views/App/Calls/Incall.qml
@@ -45,7 +45,7 @@ Rectangle {
onCameraFirstFrameReceived: Logic.handleCameraFirstFrameReceived(width, height)
onStatusChanged: Logic.handleStatusChanged (status)
- onVideoRequested: Logic.handleVideoRequested()
+ onVideoRequested: Logic.handleVideoRequested(call)
}
ColumnLayout {
@@ -239,7 +239,7 @@ Rectangle {
IncallAvatar {
call: incall.call
- height: Logic.computeAvatarSize(CallStyle.container.avatar.maxSize)
+ height: Logic.computeAvatarSize(container, CallStyle.container.avatar.maxSize)
width: height
}
}
@@ -261,7 +261,9 @@ Rectangle {
width: container.width
Component.onDestruction: {
resetWindowId()
+ console.log("Camera incall destroyed")
}
+ Component.onCompleted: console.log("Camera incall completed")
}
}
@@ -406,7 +408,9 @@ Rectangle {
isPreview: true
Component.onDestruction: {
resetWindowId()
+ console.log("Camera preview incall destroyed")
}
+ Component.onCompleted: console.log("Camera preview incall completed")
}
}
}
diff --git a/linphone-app/ui/views/App/Calls/IncallAvatar.qml b/linphone-app/ui/views/App/Calls/IncallAvatar.qml
index b666e4407..3e8f6db39 100644
--- a/linphone-app/ui/views/App/Calls/IncallAvatar.qml
+++ b/linphone-app/ui/views/App/Calls/IncallAvatar.qml
@@ -14,8 +14,9 @@ Avatar {
property var participantDeviceModel
readonly property var _sipAddressObserver: call ? SipAddressesModel.getSipAddressObserver(call.fullPeerAddress, call.fullLocalAddress)
- : SipAddressesModel.getSipAddressObserver(participantDeviceModel.address, '')
- readonly property var _username: UtilsCpp.getDisplayName(_sipAddressObserver.peerAddress)
+ : participantDeviceModel ? SipAddressesModel.getSipAddressObserver(participantDeviceModel.address, '')
+ : null
+ readonly property var _username: _sipAddressObserver ? UtilsCpp.getDisplayName(_sipAddressObserver.peerAddress) : ''
backgroundColor: CallStyle.container.avatar.backgroundColor
foregroundColor: call && call.status === CallModel.CallStatusPaused
@@ -30,7 +31,7 @@ Avatar {
return null;
}
- username: call && call.status === CallModel.CallStatusPaused || !_username? '' : _username
+ username: call && (call.status === CallModel.CallStatusPaused) || !_username? '' : _username
Text {
anchors.fill: parent
@@ -44,6 +45,6 @@ Avatar {
text: '❙❙'
textFormat: Text.RichText
- visible: call && call.status === CallModel.CallStatusPaused
+ visible: call && (call.status === CallModel.CallStatusPaused) || false
}
}
diff --git a/linphone-app/ui/views/App/Calls/VideoConference.qml b/linphone-app/ui/views/App/Calls/VideoConference.qml
index c452267e0..a460bac2a 100644
--- a/linphone-app/ui/views/App/Calls/VideoConference.qml
+++ b/linphone-app/ui/views/App/Calls/VideoConference.qml
@@ -21,21 +21,31 @@ Rectangle {
id: conference
property CallModel callModel
-
+ property var _fullscreen: null
+ /*
onCallModelChanged: if(callModel) {
grid.setParticipantDevicesMode()
}else
grid.setTestMode()
+ */
// ---------------------------------------------------------------------------
color: VideoConferenceStyle.backgroundColor
-
+ /*
Component.onCompleted: {
if(!callModel){
grid.setTestMode()
}else
grid.setParticipantDevicesMode()
}
+ */
+ Connections {
+ target: callModel
+
+ onCameraFirstFrameReceived: Logic.handleCameraFirstFrameReceived(width, height)
+ onStatusChanged: Logic.handleStatusChanged (status)
+ onVideoRequested: Logic.handleVideoRequested(callModel)
+ }
// ---------------------------------------------------------------------------
ColumnLayout {
@@ -120,6 +130,7 @@ Rectangle {
id: grid
anchors.fill: parent
+
property int radius : 8
function setTestMode(){
grid.clear()
@@ -142,6 +153,7 @@ Rectangle {
id: participantDevices
callModel: conference.callModel
}
+ /*
property ListModel defaultList : ListModel{}
Component.onCompleted: {
if( conference.callModel ){
@@ -150,15 +162,20 @@ Rectangle {
}
}
model: defaultList
-
-
+ */
+ model: participantDevices
+ onCountChanged: {console.log("Delegate count = "+count+"/"+participantDevices.count)}
delegate: Rectangle{
- color: !conference.callModel && gridModel.defaultList.get(index).color ? gridModel.defaultList.get(index).color : ''
+ id: avatarCell
+ property ParticipantDeviceModel currentDevice: gridModel.participantDevices.getAt(index)
+ onCurrentDeviceChanged: console.log("currentDevice changed: " +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.peerAddress+", isMe:"+currentDevice.isMe)
Item {
id: container
@@ -174,30 +191,60 @@ Rectangle {
IncallAvatar {
//call: gridModel.participantDevices.get(index).call
- participantDeviceModel: gridModel.participantDevices.getAt(index)
- height: Logic.computeAvatarSize(CallStyle.container.avatar.maxSize)
+ participantDeviceModel: avatarCell.currentDevice
+ height: Logic.computeAvatarSize(container, CallStyle.container.avatar.maxSize)
width: height
+ Component.onCompleted: console.log("Avatar completed"+ " ["+index+"]")
+ Component.onDestruction: console.log("Avatar destroyed"+ " ["+index+"]")
}
}
-
+ Loader {
+ anchors.centerIn: parent
+
+ active: avatarCell.currentDevice && (!avatarCell.currentDevice.videoEnabled || conference._fullscreen)
+ sourceComponent: avatar
+ }
Loader {
id: cameraLoader
- anchors.centerIn: parent
+ //anchors.centerIn: parent
+ anchors.fill: parent
+ property bool isVideoEnabled : avatarCell.currentDevice && avatarCell.currentDevice.videoEnabled
+ property bool t_fullscreen: conference._fullscreen
+ property bool tCallModel: conference.callModel
+ property bool resetActive: false
+ onIsVideoEnabledChanged: console.log("Video is enabled : " +isVideoEnabled + " ["+index+"]")
+ onT_fullscreenChanged: console.log("_fullscreen changed: " +t_fullscreen+ " ["+index+"]")
+ onTCallModelChanged: console.log("CallModel changed: " +tCallModel+ " ["+index+"]")
- active: conference.callModel && (gridModel.participantDevices.getAt(index).videoEnabled && !_fullscreen)
+ active: !resetActive && avatarCell.currentDevice && (avatarCell.currentDevice.videoEnabled && !conference._fullscreen)
+ onActiveChanged: {console.log("Active Changed: "+active+ " ["+index+"]")
+ if(!active && resetActive){
+ resetActive = false
+ active = true
+ }
+ }
- sourceComponent: conference.callModel ? gridModel.participantDevices.getAt(index).isMe ? cameraPreview : camera
+ sourceComponent: avatarCell.currentDevice ?
+ avatarCell.currentDevice.isMe ? ( true ? cameraPreview : null )
+ : camera
: null
+ onSourceComponentChanged: console.log("SourceComponent Changed: "+sourceComponent+ " ["+index+"]")
+
Component {
id: camera
Camera {
//call: grid.get(modelIndex).call
- participantDeviceModel: gridModel.participantDevices.getAt(index)
- height: container.height
- width: container.width
+ participantDeviceModel: avatarCell.currentDevice
+ //height: container.height
+ //width: container.width
+ anchors.fill: parent
+ onRequestNewRenderer: {cameraLoader.resetActive = true}
+
+ Component.onCompleted: console.log("Camera completed"+ " ["+index+"]")
+ Component.onDestruction: console.log("Camera destroyed"+ " ["+index+"]")
}
}
Component {
@@ -205,18 +252,15 @@ Rectangle {
Camera {
anchors.fill: parent
- call: incall.call
+ //call: incall.call
isPreview: true
+ onRequestNewRenderer: {cameraLoader.resetActive = true}
+
+ Component.onCompleted: console.log("Preview completed"+ " ["+index+"]")
+ Component.onDestruction: console.log("Preview destroyed"+ " ["+index+"]")
}
}
}
-
- Loader {
- anchors.centerIn: parent
-
- active: conference.callModel && (!gridModel.participantDevices.getAt(index).videoEnabled || _fullscreen)
- sourceComponent: avatar
- }
}
MouseArea{
anchors.fill: parent
diff --git a/linphone-app/ui/views/App/Main/Conferences.qml b/linphone-app/ui/views/App/Main/Conferences.qml
index 4c32dced7..5f12bcebc 100644
--- a/linphone-app/ui/views/App/Main/Conferences.qml
+++ b/linphone-app/ui/views/App/Main/Conferences.qml
@@ -27,8 +27,7 @@ ColumnLayout {
color: ConferencesStyle.bar.backgroundColor
Text{
anchors.verticalCenter: parent.center
- anchors.left: parent.left
- anchors.right: parent.right
+ anchors.fill: parent
anchors.leftMargin: 40
@@ -77,25 +76,11 @@ ColumnLayout {
section {
criteria: ViewSection.FullString
delegate: sectionHeading
- property: 'dateTime'
+ property: 'date'
}
model: ConferenceInfoProxyModel{}
-
- /* ListModel{
- ListElement{date: '2020/12/01'; time: '10:00:00';duration: 60;organizerName: 'Dupont';subject:'Atelier loisir: boumbo en folie';participantes: 'Martin, Jordy, allelouilla, Artemis Gordon, jobarteam' }
- ListElement{date: '2020/12/01'; time: '14:00:00';duration: 30;organizerName: 'Moi';subject:'TOTO';participantes: 'Julien' }
- ListElement{date: '2020/12/01'; time: '10:10:00';duration: 120;organizerName: 'Henri';subject:'Eskimirbief, mais ou est donc Willy?';participantes: 'Julien'}
- ListElement{date: '2020/12/04'; time: '09:00:00';duration: 300;organizerName: 'Houlahoup';subject:'Atelier loisir: boumbo en folie';participantes: 'Martin, Jordy, allelouilla, Artemis Gordon, jobarteam'}
- ListElement{date: '2020/12/05'; time: '10:00:00';duration: 60;organizerName: 'Dupont';subject:'1. Atelier loisir: boumbo en folie';participantes: 'Martin, Jordy, allelouilla, Artemis Gordon, jobarteam' }
- ListElement{date: '2020/12/05'; time: '10:00:00';duration: 60;organizerName: 'Dupont';subject:'2. Atelier loisir: boumbo en folie';participantes: 'Martin, Jordy, allelouilla, Artemis Gordon, jobarteam' }
-
- ListElement{date: '2020/12/06'; time: '10:00:00';duration: 60;organizerName: 'Dupont';subject:'1. Atelier loisir: boumbo en folie';participantes: 'Martin, Jordy, allelouilla, Artemis Gordon, jobarteam' }
- ListElement{date: '2020/12/06'; time: '10:00:00';duration: 60;organizerName: 'Dupont';subject:'2. Atelier loisir: boumbo en folie';participantes: 'Martin, Jordy, allelouilla, Artemis Gordon, jobarteam' }
- ListElement{date: '2020/12/06'; time: '10:00:00';duration: 60;organizerName: 'Dupont';subject:'3. Atelier loisir: boumbo en folie';participantes: 'Martin, Jordy, allelouilla, Artemis Gordon, jobarteam' }
- ListElement{date: '2020/12/06'; time: '10:00:00';duration: 60;organizerName: 'Dupont';subject:'4. Atelier loisir: boumbo en folie';participantes: 'Martin, Jordy, allelouilla, Artemis Gordon, jobarteam' }
- }*/
// -----------------------------------------------------------------------
// Heading.
// -----------------------------------------------------------------------
@@ -144,92 +129,39 @@ ColumnLayout {
//----------------------------------------------------------------------------------------------
//----------------------------------------------------------------------------------------------
- delegate: Rectangle {
- id: entry
-
+ delegate: Item {
+ implicitHeight: calendarGrid.height + ConferencesStyle.conference.bottomMargin
anchors {
- left: parent ? parent.left : undefined
- leftMargin: 0
- right: parent ? parent.right : undefined
- rightMargin: 0
- }
- radius: 6
- color: ConferencesStyle.conference.backgroundColor.normal
- implicitHeight: layout.height + ConferencesStyle.conference.bottomMargin
-
- // ---------------------------------------------------------------------
- MouseArea {
- id: mouseArea
-
- cursorShape: Qt.ArrowCursor
- hoverEnabled: true
- implicitHeight: layout.height
- width: parent.width + parent.anchors.rightMargin
- //acceptedButtons: Qt.NoButton
- onClicked: CallsListModel.launchVideoCall(modelData.uri, '', 0)
- ColumnLayout{
- id: layout
- spacing: 0
- width: entry.width
+ left: parent ? parent.left : undefined
+ leftMargin: 10
+ right: parent ? parent.right : undefined
+ rightMargin: 10
+ }
+ GridView{
+ id: calendarGrid
+ //anchors.fill: parent
+ cellWidth: (container.width-20)/2
+ cellHeight: 112
+ model: modelData
+ height: cellHeight * ( (count+1) /2)
+ width: container.width - 20
+ delegate:Rectangle {
+ id: entry
+ width: calendarGrid.cellWidth -10
+ height: calendarGrid.cellHeight -10
+ radius: 6
+ color: ConferencesStyle.conference.backgroundColor.normal
- RowLayout {
- RowLayout {
- id: scheduleRow
- spacing: ConferencesStyle.conference.spacing
-
- Icon{
- icon: ConferencesStyle.conference.schedule.icon
- iconSize: ConferencesStyle.conference.schedule.iconSize
- overwriteColor: ConferencesStyle.conference.schedule.color
- }
-
- Text {
- Layout.fillWidth: true
- color: ConferencesStyle.conference.schedule.color
- elide: Text.ElideRight
- font.pointSize: ConferencesStyle.conference.schedule.pointSize
- text: Qt.formatDateTime(modelData.dateTime, 'yyyy/MM/dd hh:mm')
- +', end at: ' +Qt.formatDateTime(modelData.endDateTime, 'yyyy/MM/dd hh:mm')
- }
- }
- Text{
- Layout.fillWidth: true
- Layout.alignment: Qt.AlignRight
- color: ConferencesStyle.conference.schedule.color
- font.pointSize: ConferencesStyle.conference.schedule.pointSize
- text: 'Organisateur : ' +UtilsCpp.getDisplayName(modelData.organizer)
- }
+ ChatCalendarMessage{
+ id: calendarMessage
+ conferenceInfoModel: modelData
+ width: calendarGrid.cellWidth
+ maxWidth: calendarGrid.cellWidth
}
- Text{
- Layout.fillWidth: true
- Layout.alignment: Qt.AlignRight
- color: ConferencesStyle.conference.schedule.color
- font.pointSize: ConferencesStyle.conference.schedule.pointSize
- text: modelData.subject
- }
- RowLayout {
- id: participantsRow
- spacing: ConferencesStyle.conference.spacing
-
- Icon{
- icon: ConferencesStyle.conference.participants.icon
- iconSize: ConferencesStyle.conference.participants.iconSize
- overwriteColor: ConferencesStyle.conference.participants.color
- }
-
- Text {
- Layout.fillWidth: true
- color: ConferencesStyle.conference.participants.color
- elide: Text.ElideRight
- font.pointSize: ConferencesStyle.conference.participants.pointSize
- text: modelData.displayNamesToString
- }
- }
}
}
}
-
}
}
}
diff --git a/linphone-app/ui/views/App/Main/Dialogs/NewConference.qml b/linphone-app/ui/views/App/Main/Dialogs/NewConference.qml
index 8cc1b228d..195311d4d 100644
--- a/linphone-app/ui/views/App/Main/Dialogs/NewConference.qml
+++ b/linphone-app/ui/views/App/Main/Dialogs/NewConference.qml
@@ -17,7 +17,13 @@ import ColorsList 1.0
DialogPlus {
id: conferenceManager
- property ConferenceInfoModel conferenceInfoModel: ConferenceInfoModel{}
+ property ConferenceInfoModel conferenceInfoModel: ConferenceInfoModel{
+ onConferenceCreated: console.log("Conference has been created.")
+ onInvitationsSent: {
+ console.log("Conference => invitations sent. Check in log for invite states.")
+ exit(1)
+ }
+ }
readonly property int minParticipants: 1
@@ -98,6 +104,7 @@ DialogPlus {
}
onClicked: {
+ conferenceInfoModel.isScheduled = scheduledSwitch.checked
if( scheduledSwitch.checked){
var startDateTime = new Date()
startDateTime.setDate(dateField.getDate())
@@ -110,11 +117,11 @@ DialogPlus {
conferenceInfoModel.setParticipants(selectedParticipants.participantListModel)
- var callsWindow = App.getCallsWindow()
- App.smartShowWindow(callsWindow)
- callsWindow.openConference()
- CallsListModel.createConference(conferenceInfoModel, secureSwitch.checked, getInviteMode(), false )
- exit(1)
+ //var callsWindow = App.getCallsWindow()
+ //App.smartShowWindow(callsWindow)
+ //callsWindow.openConference()
+ //CallsListModel.createConference(conferenceInfoModel, secureSwitch.checked, getInviteMode(), false )
+ conferenceInfoModel.createConference(secureSwitch.checked, getInviteMode())
}
TooltipArea{
visible: AccountSettingsModel.conferenceURI == '' || subject.text == '' || selectedParticipants.count < conferenceManager.minParticipants
@@ -205,7 +212,7 @@ DialogPlus {
checked: true
onClicked: {
- //checked = !checked
+ checked = !checked
}
indicatorStyle: SwitchStyle.aux
}
diff --git a/linphone-app/ui/views/App/Settings/Dialogs/SettingsVideoPreview.qml b/linphone-app/ui/views/App/Settings/Dialogs/SettingsVideoPreview.qml
index 96e6efdb4..30940ed81 100644
--- a/linphone-app/ui/views/App/Settings/Dialogs/SettingsVideoPreview.qml
+++ b/linphone-app/ui/views/App/Settings/Dialogs/SettingsVideoPreview.qml
@@ -8,23 +8,32 @@ import App.Styles 1.0
// =============================================================================
DialogPlus {
- id: dialog
-
- buttons: [
- TextButtonB {
- text: qsTr('confirm')
-
- onClicked: exit(1)
- }
- ]
-
- buttonsAlignment: Qt.AlignCenter
- height: SettingsVideoPreviewStyle.height
- width: SettingsVideoPreviewStyle.width
-
- // ---------------------------------------------------------------------------
-
- CameraPreview {
- anchors.fill: parent
- }
+ id: dialog
+
+ buttons: [
+ TextButtonB {
+ text: qsTr('confirm')
+
+ onClicked: exit(1)
+ }
+ ]
+
+ buttonsAlignment: Qt.AlignCenter
+ height: SettingsVideoPreviewStyle.height
+ width: SettingsVideoPreviewStyle.width
+
+ // ---------------------------------------------------------------------------
+ Loader{
+ id: previewLoader
+ anchors.fill: parent
+ sourceComponent: CameraPreview {
+ anchors.fill: parent
+ onRequestNewRenderer: previewLoader.active = false
+ }
+ active: true
+ onActiveChanged: {
+ console.log("Active changed : " +active)
+ if(!active) active = true
+ }
+ }
}