/*
* 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 "ConferenceInfoModel.hpp"
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include "app/App.hpp"
#include "app/paths/Paths.hpp"
#include "app/providers/ThumbnailProvider.hpp"
#include "components/calls/CallsListModel.hpp"
#include "components/chat-events/ChatCallModel.hpp"
#include "components/chat-events/ChatEvent.hpp"
#include "components/chat-events/ChatMessageModel.hpp"
#include "components/chat-events/ChatNoticeModel.hpp"
#include "components/contact/ContactModel.hpp"
#include "components/contact/VcardModel.hpp"
#include "components/contacts/ContactsListModel.hpp"
#include "components/conferenceScheduler/ConferenceScheduler.hpp"
#include "components/core/CoreHandlers.hpp"
#include "components/core/CoreManager.hpp"
#include "components/notifier/Notifier.hpp"
#include "components/other/timeZone/TimeZoneModel.hpp"
#include "components/settings/AccountSettingsModel.hpp"
#include "components/settings/SettingsModel.hpp"
#include "components/participant/ParticipantModel.hpp"
#include "components/participant/ParticipantListModel.hpp"
#include "components/presence/Presence.hpp"
#include "components/recorder/RecorderManager.hpp"
#include "components/recorder/RecorderModel.hpp"
#include "components/timeline/TimelineModel.hpp"
#include "components/timeline/TimelineListModel.hpp"
#include "components/core/event-count-notifier/AbstractEventCountNotifier.hpp"
#include "utils/QExifImageHeader.hpp"
#include "utils/Utils.hpp"
#include "utils/Constants.hpp"
#include "utils/LinphoneEnums.hpp"
// =============================================================================
using namespace std;
// -----------------------------------------------------------------------------
// -----------------------------------------------------------------------------
QSharedPointer ConferenceInfoModel::create(std::shared_ptr conferenceInfo){
return QSharedPointer::create(conferenceInfo);
}
ConferenceInfoModel::ConferenceInfoModel (QObject * parent) : QObject(parent){
//App::getInstance()->getEngine()->setObjectOwnership(this, QQmlEngine::CppOwnership);// Avoid QML to destroy it when passing by Q_INVOKABLE
mTimeZone = QTimeZone::systemTimeZone();
mConferenceInfo = linphone::Factory::get()->createConferenceInfo();
QDateTime currentDateTime = QDateTime::currentDateTime();
QDateTime utc = currentDateTime.addSecs( -mTimeZone.offsetFromUtc(currentDateTime));
mConferenceInfo->setDateTime(utc.toMSecsSinceEpoch() / 1000);
mConferenceInfo->setDuration(1200);
mIsScheduled = true;
auto accountAddress = CoreManager::getInstance()->getCore()->getDefaultAccount()->getContactAddress();
accountAddress->clean();
mConferenceInfo->setOrganizer(accountAddress);
}
ConferenceInfoModel::ConferenceInfoModel (std::shared_ptr conferenceInfo, QObject * parent) : QObject(parent){
App::getInstance()->getEngine()->setObjectOwnership(this, QQmlEngine::CppOwnership);// Avoid QML to destroy it when passing by Q_INVOKABLE
mTimeZone = QTimeZone::systemTimeZone();
mConferenceInfo = conferenceInfo;
mIsScheduled = true;
}
ConferenceInfoModel::~ConferenceInfoModel () {
}
std::shared_ptr ConferenceInfoModel::getConferenceInfo(){
return mConferenceInfo;
}
//------------------------------------------------------------------------------------------------
QDateTime ConferenceInfoModel::getDateTimeUtc() const{
return QDateTime::fromMSecsSinceEpoch(mConferenceInfo->getDateTime() * 1000);
}
QDateTime ConferenceInfoModel::getDateTimeSystem() const{
QDateTime utc = getDateTimeUtc();
QDateTime system = utc.addSecs(mTimeZone.offsetFromUtc(utc));
return system;
}
int ConferenceInfoModel::getDuration() const{
return mConferenceInfo->getDuration();
}
QDateTime ConferenceInfoModel::getEndDateTime() const{
return getDateTimeUtc().addSecs(getDuration()*60);
}
QString ConferenceInfoModel::getOrganizer() const{
return QString::fromStdString(mConferenceInfo->getOrganizer()->asString());
}
QString ConferenceInfoModel::getSubject() const{
return QString::fromStdString(mConferenceInfo->getSubject());
}
QString ConferenceInfoModel::getDescription() const{
return QString::fromStdString(mConferenceInfo->getDescription());
}
QString ConferenceInfoModel::displayNamesToString()const{
QStringList txt;
for(auto participant : mConferenceInfo->getParticipants()){
if(participant){
QString displayName = Utils::getDisplayName(participant);
if(displayName != "")
txt << displayName;
}
}
return txt.join(", ");
}
QString ConferenceInfoModel::getUri() const{
auto address = mConferenceInfo->getUri();
return address->isValid() && !address->getDomain().empty() ? QString::fromStdString(address->asString()) : "";
}
bool ConferenceInfoModel::isScheduled() const{
return mIsScheduled;
}
QVariantList ConferenceInfoModel::getParticipants() const{
QVariantList addresses;
for(auto item : mConferenceInfo->getParticipants()){
QVariantMap participant;
participant["displayName"] = Utils::getDisplayName(item);
participant["address"] = QString::fromStdString(item->asStringUriOnly());
addresses << participant;
}
return addresses;
}
TimeZoneModel* ConferenceInfoModel::getTimeZoneModel() const{
TimeZoneModel * model = new TimeZoneModel(mTimeZone);
App::getInstance()->getEngine()->setObjectOwnership(model, QQmlEngine::JavaScriptOwnership);
return model;
}
//------------------------------------------------------------------------------------------------
// Convert into UTC with TimeZone
void ConferenceInfoModel::setDateTime(const QDateTime& dateTime){
QDateTime utc = dateTime.addSecs( -mTimeZone.offsetFromUtc(dateTime));
mConferenceInfo->setDateTime(utc.toMSecsSinceEpoch() / 1000);
emit dateTimeChanged();
}
void ConferenceInfoModel::setDuration(const int& duration){
qWarning() << "Set Duration: " << duration;
mConferenceInfo->setDuration(duration);
emit durationChanged();
}
void ConferenceInfoModel::setSubject(const QString& subject){
mConferenceInfo->setSubject(subject.toStdString());
emit subjectChanged();
}
void ConferenceInfoModel::setOrganizer(const QString& organizerAddress){
mConferenceInfo->setOrganizer(Utils::interpretUrl(organizerAddress));
emit organizerChanged();
}
void ConferenceInfoModel::setDescription(const QString& description){
mConferenceInfo->setDescription(description.toStdString());
emit descriptionChanged();
}
void ConferenceInfoModel::setParticipants(ParticipantListModel * participants){
mConferenceInfo->setParticipants(participants->getParticipants());
}
void ConferenceInfoModel::setTimeZoneModel(TimeZoneModel * model){
if( mTimeZone != model->getTimeZone()){
mTimeZone = model->getTimeZone();
emit timeZoneModelChanged();
}
}
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()){
mConferenceScheduler = ConferenceScheduler::create();
connect(mConferenceScheduler.get(), &ConferenceScheduler::invitationsSent, this, &ConferenceInfoModel::onInvitationsSent);
connect(mConferenceScheduler.get(), &ConferenceScheduler::stateChanged, this, &ConferenceInfoModel::onStateChanged);
mConferenceScheduler->getConferenceScheduler()->setInfo(mConferenceInfo);
}else{
auto conferenceParameters = core->createConferenceParams(nullptr);
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::onStateChanged(linphone::ConferenceSchedulerState state){
qDebug() << "ConferenceInfoModel::onStateChanged: " << (int) state;
if( state == linphone::ConferenceSchedulerState::Ready)
emit conferenceCreated();
else if( state == linphone::ConferenceSchedulerState::Error)
emit conferenceCreationFailed();
}
void ConferenceInfoModel::onInvitationsSent(const std::list> & failedInvitations) {
qDebug() << "ConferenceInfoModel::onInvitationsSent";
emit invitationsSent();
}