mirror of
https://gitlab.linphone.org/BC/public/linphone-desktop.git
synced 2026-01-17 19:38:09 +00:00
Country, start conference, dates, combobox, calendar, popup, effectimage, meeting details, conference scheduler
This commit is contained in:
parent
893c3d7485
commit
c824bd6c83
102 changed files with 8876 additions and 483 deletions
|
|
@ -41,17 +41,23 @@
|
|||
#include "core/call/CallProxy.hpp"
|
||||
#include "core/camera/CameraGui.hpp"
|
||||
#include "core/fps-counter/FPSCounter.hpp"
|
||||
#include "core/conference/ConferenceInfoGui.hpp"
|
||||
#include "core/conference/ConferenceInfoProxy.hpp"
|
||||
#include "core/friend/FriendCore.hpp"
|
||||
#include "core/friend/FriendGui.hpp"
|
||||
#include "core/friend/FriendInitialProxy.hpp"
|
||||
#include "core/logger/QtLogger.hpp"
|
||||
#include "core/login/LoginPage.hpp"
|
||||
#include "core/notifier/Notifier.hpp"
|
||||
#include "core/participant/ParticipantDeviceCore.hpp"
|
||||
#include "core/participant/ParticipantGui.hpp"
|
||||
#include "core/participant/ParticipantProxy.hpp"
|
||||
#include "core/phone-number/PhoneNumber.hpp"
|
||||
#include "core/phone-number/PhoneNumberProxy.hpp"
|
||||
#include "core/search/MagicSearchProxy.hpp"
|
||||
#include "core/setting/SettingsCore.hpp"
|
||||
#include "core/singleapplication/singleapplication.h"
|
||||
#include "core/timezone/TimeZone.hpp"
|
||||
#include "core/timezone/TimeZoneProxy.hpp"
|
||||
#include "core/variant/VariantList.hpp"
|
||||
#include "model/object/VariantObject.hpp"
|
||||
#include "tool/Constants.hpp"
|
||||
|
|
@ -184,7 +190,14 @@ void App::initCppInterfaces() {
|
|||
|
||||
qmlRegisterType<PhoneNumberProxy>(Constants::MainQmlUri, 1, 0, "PhoneNumberProxy");
|
||||
qmlRegisterType<VariantObject>(Constants::MainQmlUri, 1, 0, "VariantObject");
|
||||
qmlRegisterType<VariantList>(Constants::MainQmlUri, 1, 0, "VariantList");
|
||||
|
||||
qmlRegisterType<ParticipantProxy>(Constants::MainQmlUri, 1, 0, "ParticipantProxy");
|
||||
qmlRegisterType<ParticipantGui>(Constants::MainQmlUri, 1, 0, "ParticipantGui");
|
||||
qmlRegisterType<ConferenceInfoProxy>(Constants::MainQmlUri, 1, 0, "ConferenceInfoProxy");
|
||||
qmlRegisterType<ConferenceInfoGui>(Constants::MainQmlUri, 1, 0, "ConferenceInfoGui");
|
||||
|
||||
qmlRegisterType<PhoneNumberProxy>(Constants::MainQmlUri, 1, 0, "PhoneNumberProxy");
|
||||
qmlRegisterUncreatableType<PhoneNumber>(Constants::MainQmlUri, 1, 0, "PhoneNumber", QLatin1String("Uncreatable"));
|
||||
qmlRegisterType<AccountProxy>(Constants::MainQmlUri, 1, 0, "AccountProxy");
|
||||
qmlRegisterType<AccountGui>(Constants::MainQmlUri, 1, 0, "AccountGui");
|
||||
|
|
@ -192,15 +205,14 @@ void App::initCppInterfaces() {
|
|||
qmlRegisterUncreatableType<CallCore>(Constants::MainQmlUri, 1, 0, "CallCore", QLatin1String("Uncreatable"));
|
||||
qmlRegisterType<CallProxy>(Constants::MainQmlUri, 1, 0, "CallProxy");
|
||||
qmlRegisterType<CallHistoryProxy>(Constants::MainQmlUri, 1, 0, "CallHistoryProxy");
|
||||
qmlRegisterType<VariantList>(Constants::MainQmlUri, 1, 0, "VariantList");
|
||||
qmlRegisterType<CallGui>(Constants::MainQmlUri, 1, 0, "CallGui");
|
||||
qmlRegisterType<FriendGui>(Constants::MainQmlUri, 1, 0, "FriendGui");
|
||||
qmlRegisterUncreatableType<FriendCore>(Constants::MainQmlUri, 1, 0, "FriendCore", QLatin1String("Uncreatable"));
|
||||
qmlRegisterType<MagicSearchProxy>(Constants::MainQmlUri, 1, 0, "MagicSearchProxy");
|
||||
qmlRegisterType<FriendInitialProxy>(Constants::MainQmlUri, 1, 0, "FriendInitialProxy");
|
||||
qmlRegisterType<CameraGui>(Constants::MainQmlUri, 1, 0, "CameraGui");
|
||||
qmlRegisterType<FPSCounter>(Constants::MainQmlUri, 1, 0, "FPSCounter");
|
||||
|
||||
qmlRegisterType<TimeZoneProxy>(Constants::MainQmlUri, 1, 0, "TimeZoneProxy");
|
||||
LinphoneEnums::registerMetaTypes();
|
||||
}
|
||||
|
||||
|
|
@ -208,12 +220,13 @@ void App::initCppInterfaces() {
|
|||
|
||||
void App::clean() {
|
||||
// Wait 500ms to let time for log te be stored.
|
||||
delete mNotifier;
|
||||
mNotifier = nullptr;
|
||||
// mNotifier destroyed in mEngine deletion as it is its parent
|
||||
delete mEngine;
|
||||
mEngine = nullptr;
|
||||
mSettings.reset();
|
||||
mSettings = nullptr;
|
||||
if (mSettings) {
|
||||
mSettings.reset();
|
||||
mSettings = nullptr;
|
||||
}
|
||||
mLinphoneThread->wait(250);
|
||||
qApp->processEvents(QEventLoop::AllEvents, 250);
|
||||
mLinphoneThread->exit();
|
||||
|
|
|
|||
|
|
@ -17,7 +17,6 @@ list(APPEND _LINPHONEAPP_SOURCES
|
|||
core/fps-counter/FPSCounter.cpp
|
||||
core/friend/FriendCore.cpp
|
||||
core/friend/FriendGui.cpp
|
||||
core/friend/FriendInitialProxy.cpp
|
||||
core/logger/QtLogger.cpp
|
||||
core/login/LoginPage.cpp
|
||||
core/notifier/Notifier.cpp
|
||||
|
|
@ -36,6 +35,24 @@ list(APPEND _LINPHONEAPP_SOURCES
|
|||
core/proxy/SortFilterProxy.cpp
|
||||
|
||||
core/variant/VariantList.cpp
|
||||
|
||||
core/conference/ConferenceCore.cpp
|
||||
core/conference/ConferenceInfoCore.cpp
|
||||
core/conference/ConferenceInfoGui.cpp
|
||||
core/conference/ConferenceInfoList.cpp
|
||||
core/conference/ConferenceInfoProxy.cpp
|
||||
|
||||
core/timezone/TimeZoneList.cpp
|
||||
core/timezone/TimeZoneProxy.cpp
|
||||
core/timezone/TimeZone.cpp
|
||||
|
||||
core/participant/ParticipantCore.cpp
|
||||
core/participant/ParticipantGui.cpp
|
||||
core/participant/ParticipantDeviceCore.cpp
|
||||
# core/participant/ParticipantDeviceList.cpp
|
||||
# core/participant/ParticipantDeviceProxy.cpp
|
||||
core/participant/ParticipantList.cpp
|
||||
core/participant/ParticipantProxy.cpp
|
||||
)
|
||||
|
||||
## Single Application
|
||||
|
|
|
|||
|
|
@ -42,6 +42,7 @@ CallHistoryCore::CallHistoryCore(const std::shared_ptr<linphone::CallLog> &callL
|
|||
App::getInstance()->mEngine->setObjectOwnership(this, QQmlEngine::CppOwnership);
|
||||
// Should be call from model Thread
|
||||
mustBeInLinphoneThread(getClassName());
|
||||
mCallHistoryModel = std::make_shared<CallHistoryModel>(callLog);
|
||||
|
||||
auto addr = callLog->getRemoteAddress()->clone();
|
||||
addr->clean();
|
||||
|
|
@ -49,7 +50,6 @@ CallHistoryCore::CallHistoryCore(const std::shared_ptr<linphone::CallLog> &callL
|
|||
// mRemoteAddress->clean();
|
||||
mStatus = LinphoneEnums::fromLinphone(callLog->getStatus());
|
||||
mDate = QDateTime::fromMSecsSinceEpoch(callLog->getStartDate() * 1000);
|
||||
mCallHistoryModel = std::make_shared<CallHistoryModel>(callLog);
|
||||
mIsOutgoing = callLog->getDir() == linphone::Call::Dir::Outgoing;
|
||||
mDuration = QString::number(callLog->getDuration());
|
||||
}
|
||||
|
|
|
|||
|
|
@ -22,7 +22,6 @@
|
|||
#include "CallHistoryGui.hpp"
|
||||
#include "core/App.hpp"
|
||||
#include "model/object/VariantObject.hpp"
|
||||
#include "tool/Utils.hpp"
|
||||
#include <QSharedPointer>
|
||||
#include <linphone++/linphone.hh>
|
||||
|
||||
|
|
@ -81,7 +80,7 @@ void CallHistoryList::setSelf(QSharedPointer<CallHistoryList> me) {
|
|||
[this]() { mModelConnection->invokeToCore([this]() { lUpdate(); }); });
|
||||
mModelConnection->makeConnectToModel(&CoreModel::callLogUpdated,
|
||||
[this]() { mModelConnection->invokeToCore([this]() { lUpdate(); }); });
|
||||
lUpdate();
|
||||
emit lUpdate();
|
||||
}
|
||||
|
||||
void CallHistoryList::removeAllEntries() {
|
||||
|
|
|
|||
|
|
@ -21,7 +21,6 @@
|
|||
#include "CallHistoryProxy.hpp"
|
||||
#include "CallHistoryGui.hpp"
|
||||
#include "CallHistoryList.hpp"
|
||||
#include "tool/Utils.hpp"
|
||||
|
||||
DEFINE_ABSTRACT_OBJECT(CallHistoryProxy)
|
||||
|
||||
|
|
|
|||
481
Linphone/core/conference/ConferenceCore.cpp
Normal file
481
Linphone/core/conference/ConferenceCore.cpp
Normal file
|
|
@ -0,0 +1,481 @@
|
|||
// /*
|
||||
// * Copyright (c) 2010-2024 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 <http://www.gnu.org/licenses/>.
|
||||
// */
|
||||
|
||||
// #include "CallCore.hpp"
|
||||
// #include "core/App.hpp"
|
||||
// #include "model/tool/ToolModel.hpp"
|
||||
// #include "tool/Utils.hpp"
|
||||
// #include "tool/thread/SafeConnection.hpp"
|
||||
|
||||
// DEFINE_ABSTRACT_OBJECT(CallCore)
|
||||
|
||||
// QVariant createDeviceVariant(const QString &id, const QString &name) {
|
||||
// QVariantMap map;
|
||||
// map.insert("id", id);
|
||||
// map.insert("name", name);
|
||||
// return map;
|
||||
// }
|
||||
|
||||
// QSharedPointer<CallCore> CallCore::create(const std::shared_ptr<linphone::Call> &call) {
|
||||
// auto sharedPointer = QSharedPointer<CallCore>(new CallCore(call), &QObject::deleteLater);
|
||||
// sharedPointer->setSelf(sharedPointer);
|
||||
// sharedPointer->moveToThread(App::getInstance()->thread());
|
||||
// return sharedPointer;
|
||||
// }
|
||||
|
||||
// CallCore::CallCore(const std::shared_ptr<linphone::Call> &call) : QObject(nullptr) {
|
||||
// qDebug() << "[CallCore] new" << this;
|
||||
// App::getInstance()->mEngine->setObjectOwnership(this, QQmlEngine::CppOwnership);
|
||||
// // Should be call from model Thread
|
||||
// mustBeInLinphoneThread(getClassName());
|
||||
// mDir = LinphoneEnums::fromLinphone(call->getDir());
|
||||
// mCallModel = Utils::makeQObject_ptr<CallModel>(call);
|
||||
// mCallModel->setSelf(mCallModel);
|
||||
// mDuration = call->getDuration();
|
||||
// mMicrophoneMuted = call->getMicrophoneMuted();
|
||||
// mSpeakerMuted = call->getSpeakerMuted();
|
||||
// mCameraEnabled = call->cameraEnabled();
|
||||
// mState = LinphoneEnums::fromLinphone(call->getState());
|
||||
// mPeerAddress = Utils::coreStringToAppString(call->getRemoteAddress()->asStringUriOnly());
|
||||
// mStatus = LinphoneEnums::fromLinphone(call->getCallLog()->getStatus());
|
||||
// mTransferState = LinphoneEnums::fromLinphone(call->getTransferState());
|
||||
// auto token = Utils::coreStringToAppString(mCallModel->getAuthenticationToken());
|
||||
// auto localToken = mDir == LinphoneEnums::CallDir::Incoming ? token.left(2).toUpper() : token.right(2).toUpper();
|
||||
// auto remoteToken = mDir == LinphoneEnums::CallDir::Outgoing ? token.left(2).toUpper() : token.right(2).toUpper();
|
||||
// mEncryption = LinphoneEnums::fromLinphone(call->getParams()->getMediaEncryption());
|
||||
// auto tokenVerified = call->getAuthenticationTokenVerified();
|
||||
// mLocalSas = localToken;
|
||||
// mRemoteSas = remoteToken;
|
||||
// mIsSecured = (mEncryption == LinphoneEnums::MediaEncryption::Zrtp && tokenVerified) ||
|
||||
// mEncryption == LinphoneEnums::MediaEncryption::Srtp ||
|
||||
// mEncryption == LinphoneEnums::MediaEncryption::Dtls;
|
||||
// mPaused = mState == LinphoneEnums::CallState::Pausing || mState == LinphoneEnums::CallState::Paused ||
|
||||
// mState == LinphoneEnums::CallState::PausedByRemote;
|
||||
// mRemoteVideoEnabled = call->getRemoteParams() && call->getRemoteParams()->videoEnabled();
|
||||
// mRecording = call->getParams() && call->getParams()->isRecording();
|
||||
// mRemoteRecording = call->getRemoteParams() && call->getRemoteParams()->isRecording();
|
||||
// mSpeakerVolumeGain = mCallModel->getSpeakerVolumeGain();
|
||||
// // TODO : change this with settings value when settings done
|
||||
// if (mSpeakerVolumeGain < 0) {
|
||||
// call->setSpeakerVolumeGain(0.5);
|
||||
// mSpeakerVolumeGain = 0.5;
|
||||
// }
|
||||
// mMicrophoneVolumeGain = call->getMicrophoneVolumeGain();
|
||||
// // TODO : change this with settings value when settings done
|
||||
// if (mMicrophoneVolumeGain < 0) {
|
||||
// call->setMicrophoneVolumeGain(0.5);
|
||||
// mMicrophoneVolumeGain = 0.5;
|
||||
// }
|
||||
// mMicrophoneVolume = call->getRecordVolume();
|
||||
// mRecordable = mState == LinphoneEnums::CallState::StreamsRunning;
|
||||
// }
|
||||
|
||||
// CallCore::~CallCore() {
|
||||
// qDebug() << "[CallCore] delete" << this;
|
||||
// mustBeInMainThread("~" + getClassName());
|
||||
// emit mCallModel->removeListener();
|
||||
// }
|
||||
|
||||
// void CallCore::setSelf(QSharedPointer<CallCore> me) {
|
||||
// mCallModelConnection = QSharedPointer<SafeConnection<CallCore, CallModel>>(
|
||||
// new SafeConnection<CallCore, CallModel>(me, mCallModel), &QObject::deleteLater);
|
||||
// mCallModelConnection->makeConnectToCore(&CallCore::lSetMicrophoneMuted, [this](bool isMuted) {
|
||||
// mCallModelConnection->invokeToModel([this, isMuted]() { mCallModel->setMicrophoneMuted(isMuted); });
|
||||
// });
|
||||
// mCallModelConnection->makeConnectToModel(&CallModel::microphoneMutedChanged, [this](bool isMuted) {
|
||||
// mCallModelConnection->invokeToCore([this, isMuted]() { setMicrophoneMuted(isMuted); });
|
||||
// });
|
||||
// mCallModelConnection->makeConnectToModel(&CallModel::remoteVideoEnabledChanged, [this](bool enabled) {
|
||||
// mCallModelConnection->invokeToCore([this, enabled]() { setRemoteVideoEnabled(enabled); });
|
||||
// });
|
||||
// mCallModelConnection->makeConnectToCore(&CallCore::lSetSpeakerMuted, [this](bool isMuted) {
|
||||
// mCallModelConnection->invokeToModel([this, isMuted]() { mCallModel->setSpeakerMuted(isMuted); });
|
||||
// });
|
||||
// mCallModelConnection->makeConnectToModel(&CallModel::speakerMutedChanged, [this](bool isMuted) {
|
||||
// mCallModelConnection->invokeToCore([this, isMuted]() { setSpeakerMuted(isMuted); });
|
||||
// });
|
||||
// mCallModelConnection->makeConnectToCore(&CallCore::lSetCameraEnabled, [this](bool enabled) {
|
||||
// mCallModelConnection->invokeToModel([this, enabled]() { mCallModel->setCameraEnabled(enabled); });
|
||||
// });
|
||||
// mCallModelConnection->makeConnectToCore(&CallCore::lStartRecording, [this]() {
|
||||
// mCallModelConnection->invokeToModel([this]() { mCallModel->startRecording(); });
|
||||
// });
|
||||
// mCallModelConnection->makeConnectToCore(&CallCore::lStopRecording, [this]() {
|
||||
// mCallModelConnection->invokeToModel([this]() { mCallModel->stopRecording(); });
|
||||
// });
|
||||
// mCallModelConnection->makeConnectToModel(&CallModel::recordingChanged, [this](bool recording) {
|
||||
// mCallModelConnection->invokeToCore([this, recording]() { setRecording(recording); });
|
||||
// });
|
||||
// mCallModelConnection->makeConnectToCore(&CallCore::lVerifyAuthenticationToken, [this](bool verified) {
|
||||
// mCallModelConnection->invokeToModel(
|
||||
// [this, verified]() { mCallModel->setAuthenticationTokenVerified(verified); });
|
||||
// });
|
||||
// mCallModelConnection->makeConnectToModel(&CallModel::authenticationTokenVerifiedChanged, [this](bool verified) {
|
||||
// mCallModelConnection->invokeToCore([this, verified]() { setIsSecured(verified); });
|
||||
// });
|
||||
// mCallModelConnection->makeConnectToModel(
|
||||
// &CallModel::remoteRecording, [this](const std::shared_ptr<linphone::Call> &call, bool recording) {
|
||||
// mCallModelConnection->invokeToCore([this, recording]() { setRemoteRecording(recording); });
|
||||
// });
|
||||
// mCallModelConnection->makeConnectToModel(&CallModel::cameraEnabledChanged, [this](bool enabled) {
|
||||
// mCallModelConnection->invokeToCore([this, enabled]() { setCameraEnabled(enabled); });
|
||||
// });
|
||||
// mCallModelConnection->makeConnectToModel(&CallModel::durationChanged, [this](int duration) {
|
||||
// mCallModelConnection->invokeToCore([this, duration]() { setDuration(duration); });
|
||||
// });
|
||||
// mCallModelConnection->makeConnectToModel(&CallModel::microphoneVolumeChanged, [this](float volume) {
|
||||
// mCallModelConnection->invokeToCore([this, volume]() { setMicrophoneVolume(volume); });
|
||||
// });
|
||||
// mCallModelConnection->makeConnectToModel(
|
||||
// &CallModel::stateChanged, [this](linphone::Call::State state, const std::string &message) {
|
||||
// mCallModelConnection->invokeToCore([this, state, message]() {
|
||||
// setState(LinphoneEnums::fromLinphone(state), Utils::coreStringToAppString(message));
|
||||
// });
|
||||
// });
|
||||
// mCallModelConnection->makeConnectToModel(&CallModel::statusChanged, [this](linphone::Call::Status status) {
|
||||
// mCallModelConnection->invokeToCore([this, status]() { setStatus(LinphoneEnums::fromLinphone(status)); });
|
||||
// });
|
||||
// mCallModelConnection->makeConnectToModel(&CallModel::stateChanged,
|
||||
// [this](linphone::Call::State state, const std::string &message) {
|
||||
// mCallModelConnection->invokeToCore([this, state]() {
|
||||
// setRecordable(state == linphone::Call::State::StreamsRunning);
|
||||
// });
|
||||
// });
|
||||
// mCallModelConnection->makeConnectToCore(&CallCore::lSetPaused, [this](bool paused) {
|
||||
// mCallModelConnection->invokeToModel([this, paused]() { mCallModel->setPaused(paused); });
|
||||
// });
|
||||
// mCallModelConnection->makeConnectToModel(&CallModel::pausedChanged, [this](bool paused) {
|
||||
// mCallModelConnection->invokeToCore([this, paused]() { setPaused(paused); });
|
||||
// });
|
||||
|
||||
// mCallModelConnection->makeConnectToCore(&CallCore::lTransferCall, [this](const QString &address) {
|
||||
// mCallModelConnection->invokeToModel(
|
||||
// [this, address]() { mCallModel->transferTo(ToolModel::interpretUrl(address)); });
|
||||
// });
|
||||
// mCallModelConnection->makeConnectToModel(
|
||||
// &CallModel::transferStateChanged,
|
||||
// [this](const std::shared_ptr<linphone::Call> &call, linphone::Call::State state) {
|
||||
// mCallModelConnection->invokeToCore([this, state]() {
|
||||
// QString message;
|
||||
// if (state == linphone::Call::State::Error) {
|
||||
// message = "L'appel n'a pas pu être transféré.";
|
||||
// }
|
||||
// setTransferState(LinphoneEnums::fromLinphone(state), message);
|
||||
// });
|
||||
// });
|
||||
// mCallModelConnection->makeConnectToModel(
|
||||
// &CallModel::encryptionChanged,
|
||||
// [this](const std::shared_ptr<linphone::Call> &call, bool on, const std::string &authenticationToken) {
|
||||
// auto encryption = LinphoneEnums::fromLinphone(call->getCurrentParams()->getMediaEncryption());
|
||||
// auto tokenVerified = mCallModel->getAuthenticationTokenVerified();
|
||||
// auto token = Utils::coreStringToAppString(mCallModel->getAuthenticationToken());
|
||||
// mCallModelConnection->invokeToCore([this, call, encryption, tokenVerified, token]() {
|
||||
// if (token.size() == 4) {
|
||||
// auto localToken =
|
||||
// mDir == LinphoneEnums::CallDir::Incoming ? token.left(2).toUpper() : token.right(2).toUpper();
|
||||
// auto remoteToken =
|
||||
// mDir == LinphoneEnums::CallDir::Outgoing ? token.left(2).toUpper() : token.right(2).toUpper();
|
||||
// setLocalSas(localToken);
|
||||
// setRemoteSas(remoteToken);
|
||||
// }
|
||||
// setEncryption(encryption);
|
||||
// setIsSecured((encryption == LinphoneEnums::MediaEncryption::Zrtp && tokenVerified) ||
|
||||
// encryption == LinphoneEnums::MediaEncryption::Srtp ||
|
||||
// encryption == LinphoneEnums::MediaEncryption::Dtls);
|
||||
// });
|
||||
// });
|
||||
// mCallModelConnection->makeConnectToCore(&CallCore::lSetSpeakerVolumeGain, [this](float gain) {
|
||||
// mCallModelConnection->invokeToModel([this, gain]() { mCallModel->setSpeakerVolumeGain(gain); });
|
||||
// });
|
||||
// mCallModelConnection->makeConnectToModel(&CallModel::speakerVolumeGainChanged, [this](float gain) {
|
||||
// mCallModelConnection->invokeToCore([this, gain]() { setSpeakerVolumeGain(gain); });
|
||||
// });
|
||||
// mCallModelConnection->makeConnectToCore(&CallCore::lSetMicrophoneVolumeGain, [this](float gain) {
|
||||
// mCallModelConnection->invokeToModel([this, gain]() { mCallModel->setMicrophoneVolumeGain(gain); });
|
||||
// });
|
||||
// mCallModelConnection->makeConnectToModel(&CallModel::microphoneVolumeGainChanged, [this](float gain) {
|
||||
// mCallModelConnection->invokeToCore([this, gain]() { setMicrophoneVolumeGain(gain); });
|
||||
// });
|
||||
// mCallModelConnection->makeConnectToCore(&CallCore::lSetInputAudioDevice, [this](const QString &id) {
|
||||
// mCallModelConnection->invokeToModel([this, id]() {
|
||||
// if (auto device = ToolModel::findAudioDevice(id)) {
|
||||
// mCallModel->setInputAudioDevice(device);
|
||||
// }
|
||||
// });
|
||||
// });
|
||||
// mCallModelConnection->makeConnectToModel(&CallModel::inputAudioDeviceChanged, [this](const std::string &id) {
|
||||
// mCallModelConnection->invokeToCore([this, id]() {});
|
||||
// });
|
||||
// mCallModelConnection->makeConnectToCore(&CallCore::lSetOutputAudioDevice, [this](const QString &id) {
|
||||
// mCallModelConnection->invokeToModel([this, id]() {
|
||||
// if (auto device = ToolModel::findAudioDevice(id)) {
|
||||
// mCallModel->setOutputAudioDevice(device);
|
||||
// }
|
||||
// });
|
||||
// });
|
||||
// mCallModelConnection->makeConnectToCore(&CallCore::lAccept, [this](bool withVideo) {
|
||||
// mCallModelConnection->invokeToModel([this, withVideo]() { mCallModel->accept(withVideo); });
|
||||
// });
|
||||
// mCallModelConnection->makeConnectToCore(
|
||||
// &CallCore::lDecline, [this]() { mCallModelConnection->invokeToModel([this]() { mCallModel->decline(); }); });
|
||||
// mCallModelConnection->makeConnectToCore(&CallCore::lTerminate, [this]() {
|
||||
// mCallModelConnection->invokeToModel([this]() { mCallModel->terminate(); });
|
||||
// });
|
||||
// mCallModelConnection->makeConnectToCore(&CallCore::lTerminateAllCalls, [this]() {
|
||||
// mCallModelConnection->invokeToModel([this]() { mCallModel->terminateAllCalls(); });
|
||||
// });
|
||||
// }
|
||||
|
||||
// QString CallCore::getPeerAddress() const {
|
||||
// return mPeerAddress;
|
||||
// }
|
||||
|
||||
// LinphoneEnums::CallStatus CallCore::getStatus() const {
|
||||
// return mStatus;
|
||||
// }
|
||||
|
||||
// void CallCore::setStatus(LinphoneEnums::CallStatus status) {
|
||||
// mustBeInMainThread(log().arg(Q_FUNC_INFO));
|
||||
// if (mStatus != status) {
|
||||
// mStatus = status;
|
||||
// emit statusChanged(mStatus);
|
||||
// }
|
||||
// }
|
||||
|
||||
// LinphoneEnums::CallDir CallCore::getDir() const {
|
||||
// return mDir;
|
||||
// }
|
||||
|
||||
// void CallCore::setDir(LinphoneEnums::CallDir dir) {
|
||||
// mustBeInMainThread(log().arg(Q_FUNC_INFO));
|
||||
// if (mDir != dir) {
|
||||
// mDir = dir;
|
||||
// emit dirChanged(mDir);
|
||||
// }
|
||||
// }
|
||||
|
||||
// LinphoneEnums::CallState CallCore::getState() const {
|
||||
// return mState;
|
||||
// }
|
||||
|
||||
// void CallCore::setState(LinphoneEnums::CallState state, const QString &message) {
|
||||
// mustBeInMainThread(log().arg(Q_FUNC_INFO));
|
||||
// if (mState != state) {
|
||||
// mState = state;
|
||||
// if (state == LinphoneEnums::CallState::Error) setLastErrorMessage(message);
|
||||
// emit stateChanged(mState);
|
||||
// }
|
||||
// }
|
||||
|
||||
// QString CallCore::getLastErrorMessage() const {
|
||||
// return mLastErrorMessage;
|
||||
// }
|
||||
// void CallCore::setLastErrorMessage(const QString &message) {
|
||||
// if (mLastErrorMessage != message) {
|
||||
// mLastErrorMessage = message;
|
||||
// emit lastErrorMessageChanged();
|
||||
// }
|
||||
// }
|
||||
|
||||
// int CallCore::getDuration() {
|
||||
// return mDuration;
|
||||
// }
|
||||
|
||||
// void CallCore::setDuration(int duration) {
|
||||
// if (mDuration != duration) {
|
||||
// mDuration = duration;
|
||||
// emit durationChanged(mDuration);
|
||||
// }
|
||||
// }
|
||||
|
||||
// bool CallCore::getSpeakerMuted() const {
|
||||
// return mSpeakerMuted;
|
||||
// }
|
||||
|
||||
// void CallCore::setSpeakerMuted(bool isMuted) {
|
||||
// if (mSpeakerMuted != isMuted) {
|
||||
// mSpeakerMuted = isMuted;
|
||||
// emit speakerMutedChanged();
|
||||
// }
|
||||
// }
|
||||
|
||||
// bool CallCore::getMicrophoneMuted() const {
|
||||
// return mMicrophoneMuted;
|
||||
// }
|
||||
|
||||
// void CallCore::setMicrophoneMuted(bool isMuted) {
|
||||
// if (mMicrophoneMuted != isMuted) {
|
||||
// mMicrophoneMuted = isMuted;
|
||||
// emit microphoneMutedChanged();
|
||||
// }
|
||||
// }
|
||||
|
||||
// bool CallCore::getCameraEnabled() const {
|
||||
// return mCameraEnabled;
|
||||
// }
|
||||
|
||||
// void CallCore::setCameraEnabled(bool enabled) {
|
||||
// if (mCameraEnabled != enabled) {
|
||||
// mCameraEnabled = enabled;
|
||||
// emit cameraEnabledChanged();
|
||||
// }
|
||||
// }
|
||||
|
||||
// bool CallCore::getPaused() const {
|
||||
// return mPaused;
|
||||
// }
|
||||
|
||||
// void CallCore::setPaused(bool paused) {
|
||||
// if (mPaused != paused) {
|
||||
// mPaused = paused;
|
||||
// emit pausedChanged();
|
||||
// }
|
||||
// }
|
||||
|
||||
// bool CallCore::isSecured() const {
|
||||
// return mIsSecured;
|
||||
// }
|
||||
|
||||
// void CallCore::setIsSecured(bool secured) {
|
||||
// if (mIsSecured != secured) {
|
||||
// mIsSecured = secured;
|
||||
// emit securityUpdated();
|
||||
// }
|
||||
// }
|
||||
|
||||
// QString CallCore::getLocalSas() {
|
||||
// return mLocalSas;
|
||||
// }
|
||||
|
||||
// QString CallCore::getRemoteSas() {
|
||||
// return mRemoteSas;
|
||||
// }
|
||||
|
||||
// void CallCore::setLocalSas(const QString &sas) {
|
||||
// if (mLocalSas != sas) {
|
||||
// mLocalSas = sas;
|
||||
// emit localSasChanged();
|
||||
// }
|
||||
// }
|
||||
|
||||
// void CallCore::setRemoteSas(const QString &sas) {
|
||||
// if (mRemoteSas != sas) {
|
||||
// mRemoteSas = sas;
|
||||
// emit remoteSasChanged();
|
||||
// }
|
||||
// }
|
||||
|
||||
// LinphoneEnums::MediaEncryption CallCore::getEncryption() const {
|
||||
// return mEncryption;
|
||||
// }
|
||||
|
||||
// void CallCore::setEncryption(LinphoneEnums::MediaEncryption encryption) {
|
||||
// if (mEncryption != encryption) {
|
||||
// mEncryption = encryption;
|
||||
// emit securityUpdated();
|
||||
// }
|
||||
// }
|
||||
|
||||
// bool CallCore::getRemoteVideoEnabled() const {
|
||||
// return mRemoteVideoEnabled;
|
||||
// }
|
||||
|
||||
// void CallCore::setRemoteVideoEnabled(bool enabled) {
|
||||
// if (mRemoteVideoEnabled != enabled) {
|
||||
// mRemoteVideoEnabled = enabled;
|
||||
// emit remoteVideoEnabledChanged(mRemoteVideoEnabled);
|
||||
// }
|
||||
// }
|
||||
|
||||
// bool CallCore::getRecording() const {
|
||||
// return mRecording;
|
||||
// }
|
||||
// void CallCore::setRecording(bool recording) {
|
||||
// if (mRecording != recording) {
|
||||
// mRecording = recording;
|
||||
// emit recordingChanged();
|
||||
// }
|
||||
// }
|
||||
|
||||
// bool CallCore::getRemoteRecording() const {
|
||||
// return mRemoteRecording;
|
||||
// }
|
||||
// void CallCore::setRemoteRecording(bool recording) {
|
||||
// if (mRemoteRecording != recording) {
|
||||
// mRemoteRecording = recording;
|
||||
// emit remoteRecordingChanged();
|
||||
// }
|
||||
// }
|
||||
|
||||
// bool CallCore::getRecordable() const {
|
||||
// return mRecordable;
|
||||
// }
|
||||
// void CallCore::setRecordable(bool recordable) {
|
||||
// if (mRecordable != recordable) {
|
||||
// mRecordable = recordable;
|
||||
// emit recordableChanged();
|
||||
// }
|
||||
// }
|
||||
|
||||
// float CallCore::getSpeakerVolumeGain() const {
|
||||
// return mSpeakerVolumeGain;
|
||||
// }
|
||||
// void CallCore::setSpeakerVolumeGain(float gain) {
|
||||
// if (mSpeakerVolumeGain != gain) {
|
||||
// mSpeakerVolumeGain = gain;
|
||||
// emit speakerVolumeGainChanged();
|
||||
// }
|
||||
// }
|
||||
|
||||
// float CallCore::getMicrophoneVolume() const {
|
||||
// return mMicrophoneVolume;
|
||||
// }
|
||||
// void CallCore::setMicrophoneVolume(float vol) {
|
||||
// if (mMicrophoneVolume != vol) {
|
||||
// mMicrophoneVolume = vol;
|
||||
// emit microphoneVolumeChanged();
|
||||
// }
|
||||
// }
|
||||
|
||||
// float CallCore::getMicrophoneVolumeGain() const {
|
||||
// return mMicrophoneVolumeGain;
|
||||
// }
|
||||
// void CallCore::setMicrophoneVolumeGain(float gain) {
|
||||
// if (mMicrophoneVolumeGain != gain) {
|
||||
// mMicrophoneVolumeGain = gain;
|
||||
// emit microphoneVolumeGainChanged();
|
||||
// }
|
||||
// }
|
||||
|
||||
// LinphoneEnums::CallState CallCore::getTransferState() const {
|
||||
// return mTransferState;
|
||||
// }
|
||||
|
||||
// void CallCore::setTransferState(LinphoneEnums::CallState state, const QString &message) {
|
||||
// if (mTransferState != state) {
|
||||
// mTransferState = state;
|
||||
// if (state == LinphoneEnums::CallState::Error) setLastErrorMessage(message);
|
||||
// emit transferStateChanged();
|
||||
// }
|
||||
// }
|
||||
|
||||
// std::shared_ptr<CallModel> CallCore::getModel() const {
|
||||
// return mCallModel;
|
||||
// }
|
||||
224
Linphone/core/conference/ConferenceCore.hpp
Normal file
224
Linphone/core/conference/ConferenceCore.hpp
Normal file
|
|
@ -0,0 +1,224 @@
|
|||
// /*
|
||||
// * Copyright (c) 2010-2024 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 <http://www.gnu.org/licenses/>.
|
||||
// */
|
||||
|
||||
// #ifndef CONFERENCE_CORE_H_
|
||||
// #define CONFERENCE_CORE_H_
|
||||
|
||||
// #include "model/conference/ConferenceModel.hpp"
|
||||
// #include "tool/LinphoneEnums.hpp"
|
||||
// #include "tool/thread/SafeConnection.hpp"
|
||||
// #include <QObject>
|
||||
// #include <QSharedPointer>
|
||||
// #include <linphone++/linphone.hh>
|
||||
|
||||
// class ConferenceCore : public QObject, public AbstractObject {
|
||||
// Q_OBJECT
|
||||
|
||||
// // Q_PROPERTY(QString peerDisplayName MEMBER mPeerDisplayName)
|
||||
// Q_PROPERTY(LinphoneEnums::ConferenceStatus status READ getStatus NOTIFY statusChanged)
|
||||
// Q_PROPERTY(LinphoneEnums::ConferenceDir dir READ getDir NOTIFY dirChanged)
|
||||
// Q_PROPERTY(LinphoneEnums::ConferenceState state READ getState NOTIFY stateChanged)
|
||||
// Q_PROPERTY(QString lastErrorMessage READ getLastErrorMessage NOTIFY lastErrorMessageChanged)
|
||||
// Q_PROPERTY(int duration READ getDuration NOTIFY durationChanged)
|
||||
// Q_PROPERTY(bool speakerMuted READ getSpeakerMuted WRITE lSetSpeakerMuted NOTIFY speakerMutedChanged)
|
||||
// Q_PROPERTY(bool microphoneMuted READ getMicrophoneMuted WRITE lSetMicrophoneMuted NOTIFY microphoneMutedChanged)
|
||||
// Q_PROPERTY(bool cameraEnabled READ getCameraEnabled WRITE lSetCameraEnabled NOTIFY cameraEnabledChanged)
|
||||
// Q_PROPERTY(bool paused READ getPaused WRITE lSetPaused NOTIFY pausedChanged)
|
||||
// Q_PROPERTY(QString peerAddress READ getPeerAddress CONSTANT)
|
||||
// Q_PROPERTY(bool isSecured READ isSecured NOTIFY securityUpdated)
|
||||
// Q_PROPERTY(LinphoneEnums::MediaEncryption encryption READ getEncryption NOTIFY securityUpdated)
|
||||
// Q_PROPERTY(QString localSas READ getLocalSas WRITE setLocalSas MEMBER mLocalSas NOTIFY localSasChanged)
|
||||
// Q_PROPERTY(QString remoteSas WRITE setRemoteSas MEMBER mRemoteSas NOTIFY remoteSasChanged)
|
||||
// Q_PROPERTY(
|
||||
// bool remoteVideoEnabled READ getRemoteVideoEnabled WRITE setRemoteVideoEnabled NOTIFY remoteVideoEnabledChanged)
|
||||
// Q_PROPERTY(bool recording READ getRecording WRITE setRecording NOTIFY recordingChanged)
|
||||
// Q_PROPERTY(bool remoteRecording READ getRemoteRecording WRITE setRemoteRecording NOTIFY remoteRecordingChanged)
|
||||
// Q_PROPERTY(bool recordable READ getRecordable WRITE setRecordable NOTIFY recordableChanged)
|
||||
// Q_PROPERTY(
|
||||
// float speakerVolumeGain READ getSpeakerVolumeGain WRITE setSpeakerVolumeGain NOTIFY speakerVolumeGainChanged)
|
||||
// Q_PROPERTY(float microphoneVolumeGain READ getMicrophoneVolumeGain WRITE setMicrophoneVolumeGain NOTIFY
|
||||
// microphoneVolumeGainChanged)
|
||||
// Q_PROPERTY(float microVolume READ getMicrophoneVolume WRITE setMicrophoneVolume NOTIFY microphoneVolumeChanged)
|
||||
// Q_PROPERTY(LinphoneEnums::ConferenceState transferState READ getTransferState NOTIFY transferStateChanged)
|
||||
|
||||
// public:
|
||||
// // Should be call from model Thread. Will be automatically in App thread after initialization
|
||||
// static QSharedPointer<ConferenceCore> create(const std::shared_ptr<linphone::Conference> &call);
|
||||
// ConferenceCore(const std::shared_ptr<linphone::Conference> &call);
|
||||
// ~ConferenceCore();
|
||||
// void setSelf(QSharedPointer<ConferenceCore> me);
|
||||
|
||||
// QString getPeerAddress() const;
|
||||
|
||||
// LinphoneEnums::ConferenceStatus getStatus() const;
|
||||
// void setStatus(LinphoneEnums::ConferenceStatus status);
|
||||
|
||||
// LinphoneEnums::ConferenceDir getDir() const;
|
||||
// void setDir(LinphoneEnums::ConferenceDir dir);
|
||||
|
||||
// LinphoneEnums::ConferenceState getState() const;
|
||||
// void setState(LinphoneEnums::ConferenceState state, const QString &message);
|
||||
|
||||
// QString getLastErrorMessage() const;
|
||||
// void setLastErrorMessage(const QString &message);
|
||||
|
||||
// int getDuration();
|
||||
// void setDuration(int duration);
|
||||
|
||||
// bool getSpeakerMuted() const;
|
||||
// void setSpeakerMuted(bool isMuted);
|
||||
|
||||
// bool getMicrophoneMuted() const;
|
||||
// void setMicrophoneMuted(bool isMuted);
|
||||
|
||||
// bool getCameraEnabled() const;
|
||||
// void setCameraEnabled(bool enabled);
|
||||
|
||||
// bool getPaused() const;
|
||||
// void setPaused(bool paused);
|
||||
|
||||
// bool isSecured() const;
|
||||
// void setIsSecured(bool secured);
|
||||
|
||||
// QString getLocalSas();
|
||||
// void setLocalSas(const QString &sas);
|
||||
// QString getRemoteSas();
|
||||
// void setRemoteSas(const QString &sas);
|
||||
|
||||
// LinphoneEnums::MediaEncryption getEncryption() const;
|
||||
// void setEncryption(LinphoneEnums::MediaEncryption encryption);
|
||||
|
||||
// bool getRemoteVideoEnabled() const;
|
||||
// void setRemoteVideoEnabled(bool enabled);
|
||||
|
||||
// bool getRecording() const;
|
||||
// void setRecording(bool recording);
|
||||
|
||||
// bool getRemoteRecording() const;
|
||||
// void setRemoteRecording(bool recording);
|
||||
|
||||
// bool getRecordable() const;
|
||||
// void setRecordable(bool recordable);
|
||||
|
||||
// float getSpeakerVolumeGain() const;
|
||||
// void setSpeakerVolumeGain(float gain);
|
||||
|
||||
// float getMicrophoneVolumeGain() const;
|
||||
// void setMicrophoneVolumeGain(float gain);
|
||||
|
||||
// float getMicrophoneVolume() const;
|
||||
// void setMicrophoneVolume(float vol);
|
||||
|
||||
// QString getInputDeviceName() const;
|
||||
// void setInputDeviceName(const QString &id);
|
||||
|
||||
// LinphoneEnums::ConferenceState getTransferState() const;
|
||||
// void setTransferState(LinphoneEnums::ConferenceState state, const QString &message);
|
||||
|
||||
// std::shared_ptr<ConferenceModel> getModel() const;
|
||||
|
||||
// signals:
|
||||
// void statusChanged(LinphoneEnums::ConferenceStatus status);
|
||||
// void stateChanged(LinphoneEnums::ConferenceState state);
|
||||
// void dirChanged(LinphoneEnums::ConferenceDir dir);
|
||||
// void lastErrorMessageChanged();
|
||||
// void durationChanged(int duration);
|
||||
// void speakerMutedChanged();
|
||||
// void microphoneMutedChanged();
|
||||
// void cameraEnabledChanged();
|
||||
// void pausedChanged();
|
||||
// void transferStateChanged();
|
||||
// void securityUpdated();
|
||||
// void localSasChanged();
|
||||
// void remoteSasChanged();
|
||||
// void remoteVideoEnabledChanged(bool remoteVideoEnabled);
|
||||
// void recordingChanged();
|
||||
// void remoteRecordingChanged();
|
||||
// void recordableChanged();
|
||||
// void speakerVolumeGainChanged();
|
||||
// void microphoneVolumeChanged();
|
||||
// void microphoneVolumeGainChanged();
|
||||
|
||||
// // Linphone commands
|
||||
// void lAccept(bool withVideo); // Accept an incoming call
|
||||
// void lDecline(); // Decline an incoming call
|
||||
// void lTerminate(); // Hangup a call
|
||||
// void lTerminateAllConferences(); // Hangup all calls
|
||||
// void lSetSpeakerMuted(bool muted);
|
||||
// void lSetMicrophoneMuted(bool isMuted);
|
||||
// void lSetCameraEnabled(bool enabled);
|
||||
// void lSetPaused(bool paused);
|
||||
// void lTransferConference(const QString &dest);
|
||||
// void lStartRecording();
|
||||
// void lStopRecording();
|
||||
// void lVerifyAuthenticationToken(bool verified);
|
||||
// void lSetSpeakerVolumeGain(float gain);
|
||||
// void lSetMicrophoneVolumeGain(float gain);
|
||||
// void lSetInputAudioDevice(const QString &id);
|
||||
// void lSetOutputAudioDevice(const QString &id);
|
||||
|
||||
// /* TODO
|
||||
// Q_INVOKABLE void acceptWithVideo();
|
||||
|
||||
// Q_INVOKABLE void askForTransfer();
|
||||
// Q_INVOKABLE void askForAttendedTransfer();
|
||||
// Q_INVOKABLE bool transferTo(const QString &sipAddress);
|
||||
// Q_INVOKABLE bool transferToAnother(const QString &peerAddress);
|
||||
|
||||
// Q_INVOKABLE bool getRemoteVideoEnabled() const;
|
||||
// Q_INVOKABLE void acceptVideoRequest();
|
||||
// Q_INVOKABLE void rejectVideoRequest();
|
||||
|
||||
// Q_INVOKABLE void takeSnapshot();
|
||||
|
||||
// Q_INVOKABLE void sendDtmf(const QString &dtmf);
|
||||
// Q_INVOKABLE void verifyAuthenticationToken(bool verify);
|
||||
// Q_INVOKABLE void updateStreams();
|
||||
// */
|
||||
// private:
|
||||
// std::shared_ptr<ConferenceModel> mConferenceModel;
|
||||
// LinphoneEnums::ConferenceStatus mStatus;
|
||||
// LinphoneEnums::ConferenceState mState;
|
||||
// LinphoneEnums::ConferenceState mTransferState;
|
||||
// LinphoneEnums::ConferenceDir mDir;
|
||||
// LinphoneEnums::MediaEncryption mEncryption;
|
||||
// QString mLastErrorMessage;
|
||||
// QString mPeerAddress;
|
||||
// bool mIsSecured;
|
||||
// int mDuration = 0;
|
||||
// bool mSpeakerMuted;
|
||||
// bool mMicrophoneMuted;
|
||||
// bool mCameraEnabled;
|
||||
// bool mPaused = false;
|
||||
// bool mRemoteVideoEnabled = false;
|
||||
// bool mRecording = false;
|
||||
// bool mRemoteRecording = false;
|
||||
// bool mRecordable = false;
|
||||
// QString mLocalSas;
|
||||
// QString mRemoteSas;
|
||||
// float mSpeakerVolumeGain;
|
||||
// float mMicrophoneVolume;
|
||||
// float mMicrophoneVolumeGain;
|
||||
// QSharedPointer<SafeConnection<ConferenceCore, ConferenceModel>> mConferenceModelConnection;
|
||||
|
||||
// DECLARE_ABSTRACT_OBJECT
|
||||
// };
|
||||
// Q_DECLARE_METATYPE(ConferenceCore *)
|
||||
// #endif
|
||||
576
Linphone/core/conference/ConferenceInfoCore.cpp
Normal file
576
Linphone/core/conference/ConferenceInfoCore.cpp
Normal file
|
|
@ -0,0 +1,576 @@
|
|||
/*
|
||||
* 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 <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "ConferenceInfoCore.hpp"
|
||||
|
||||
#include "core/App.hpp"
|
||||
#include "core/proxy/ListProxy.hpp"
|
||||
#include "model/object/VariantObject.hpp"
|
||||
#include "model/tool/ToolModel.hpp"
|
||||
#include "tool/Utils.hpp"
|
||||
#include "tool/thread/SafeConnection.hpp"
|
||||
|
||||
DEFINE_ABSTRACT_OBJECT(ConferenceInfoCore)
|
||||
|
||||
QSharedPointer<ConferenceInfoCore>
|
||||
ConferenceInfoCore::create(std::shared_ptr<linphone::ConferenceInfo> conferenceInfo) {
|
||||
auto sharedPointer =
|
||||
QSharedPointer<ConferenceInfoCore>(new ConferenceInfoCore(conferenceInfo), &QObject::deleteLater);
|
||||
sharedPointer->setSelf(sharedPointer);
|
||||
if (isInLinphoneThread()) sharedPointer->moveToThread(App::getInstance()->thread());
|
||||
return sharedPointer;
|
||||
}
|
||||
|
||||
ConferenceInfoCore::ConferenceInfoCore(std::shared_ptr<linphone::ConferenceInfo> conferenceInfo, QObject *parent)
|
||||
: QObject(parent) {
|
||||
App::getInstance()->mEngine->setObjectOwnership(this, QQmlEngine::CppOwnership);
|
||||
mTimeZoneModel = QSharedPointer<TimeZoneModel>(new TimeZoneModel(
|
||||
QTimeZone::systemTimeZone())); // Always return system timezone because this info is not stored in database.
|
||||
|
||||
if (conferenceInfo) {
|
||||
mustBeInLinphoneThread(getClassName());
|
||||
mConferenceInfoModel = Utils::makeQObject_ptr<ConferenceInfoModel>(conferenceInfo);
|
||||
auto confSchedulerModel = mConferenceInfoModel->getConferenceScheduler();
|
||||
if (!confSchedulerModel) {
|
||||
auto confScheduler = CoreModel::getInstance()->getCore()->createConferenceScheduler();
|
||||
confSchedulerModel = Utils::makeQObject_ptr<ConferenceSchedulerModel>(confScheduler);
|
||||
mConferenceInfoModel->setConferenceScheduler(confSchedulerModel);
|
||||
}
|
||||
auto address = conferenceInfo->getUri();
|
||||
mUri = address && address->isValid() && !address->getDomain().empty()
|
||||
? Utils::coreStringToAppString(address->asStringUriOnly())
|
||||
: "";
|
||||
mDateTime = QDateTime::fromMSecsSinceEpoch(conferenceInfo->getDateTime() * 1000, Qt::LocalTime);
|
||||
mDuration = conferenceInfo->getDuration();
|
||||
mEndDateTime = mDateTime.addSecs(mDuration * 60);
|
||||
mOrganizerAddress = Utils::coreStringToAppString(conferenceInfo->getOrganizer()->asStringUriOnly());
|
||||
mOrganizerName = Utils::coreStringToAppString(conferenceInfo->getOrganizer()->getDisplayName());
|
||||
if (mOrganizerName.isEmpty()) {
|
||||
mOrganizerName = Utils::coreStringToAppString(conferenceInfo->getOrganizer()->getUsername());
|
||||
mOrganizerName.replace(".", " ");
|
||||
}
|
||||
mSubject = Utils::coreStringToAppString(conferenceInfo->getSubject());
|
||||
mDescription = Utils::coreStringToAppString(conferenceInfo->getDescription());
|
||||
mIsEnded = getDateTimeUtc().addSecs(mDuration * 60) < QDateTime::currentDateTimeUtc();
|
||||
|
||||
for (auto item : conferenceInfo->getParticipantInfos()) {
|
||||
QVariantMap participant;
|
||||
auto address = item->getAddress();
|
||||
auto name = Utils::coreStringToAppString(address->getDisplayName());
|
||||
if (name.isEmpty()) {
|
||||
name = Utils::coreStringToAppString(address->getUsername());
|
||||
name.replace(".", " ");
|
||||
}
|
||||
participant["displayName"] = name;
|
||||
participant["address"] = Utils::coreStringToAppString(address->asStringUriOnly());
|
||||
participant["role"] = (int)LinphoneEnums::fromLinphone(item->getRole());
|
||||
mParticipants.append(participant);
|
||||
}
|
||||
mConferenceInfoState = LinphoneEnums::fromLinphone(conferenceInfo->getState());
|
||||
} else {
|
||||
auto defaultAccount = CoreModel::getInstance()->getCore()->getDefaultAccount();
|
||||
if (defaultAccount) {
|
||||
auto accountAddress = defaultAccount->getContactAddress();
|
||||
if (accountAddress) {
|
||||
auto cleanedClonedAddress = accountAddress->clone();
|
||||
cleanedClonedAddress->clean();
|
||||
mOrganizerAddress = Utils::coreStringToAppString(cleanedClonedAddress->asStringUriOnly());
|
||||
qDebug() << "set organizer address" << mOrganizerAddress;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
connect(this, &ConferenceInfoCore::endDateTimeChanged,
|
||||
[this] { setDuration(mDateTime.secsTo(mEndDateTime) / 60.0); });
|
||||
connect(this, &ConferenceInfoCore::durationChanged, [this] { setEndDateTime(mDateTime.addSecs(mDuration * 60)); });
|
||||
}
|
||||
|
||||
ConferenceInfoCore::ConferenceInfoCore(const ConferenceInfoCore &conferenceInfoCore) {
|
||||
mDateTime = conferenceInfoCore.mDateTime;
|
||||
mEndDateTime = conferenceInfoCore.mEndDateTime;
|
||||
mDuration = conferenceInfoCore.mDuration;
|
||||
mOrganizerAddress = conferenceInfoCore.mOrganizerAddress;
|
||||
mOrganizerName = conferenceInfoCore.mOrganizerName;
|
||||
mSubject = conferenceInfoCore.mSubject;
|
||||
mDescription = conferenceInfoCore.mDescription;
|
||||
mUri = conferenceInfoCore.mUri;
|
||||
mParticipants = conferenceInfoCore.mParticipants;
|
||||
mTimeZoneModel = conferenceInfoCore.mTimeZoneModel;
|
||||
mIsScheduled = conferenceInfoCore.mIsScheduled;
|
||||
mIsEnded = conferenceInfoCore.mIsEnded;
|
||||
mInviteMode = conferenceInfoCore.mInviteMode;
|
||||
mConferenceInfoState = conferenceInfoCore.mConferenceInfoState;
|
||||
}
|
||||
|
||||
ConferenceInfoCore::~ConferenceInfoCore() {
|
||||
mustBeInMainThread("~" + getClassName());
|
||||
mCheckEndTimer.stop();
|
||||
}
|
||||
|
||||
void ConferenceInfoCore::reset(const ConferenceInfoCore &conf) {
|
||||
setDateTime(conf.getDateTimeSystem());
|
||||
setDuration(conf.getDuration());
|
||||
setOrganizerAddress(conf.getOrganizerAddress());
|
||||
setOrganizerName(conf.getOrganizerName());
|
||||
setSubject(conf.getSubject());
|
||||
setDescription(conf.getDescription());
|
||||
setUri(conf.getUri());
|
||||
resetParticipants(conf.getParticipants());
|
||||
setTimeZoneModel(conf.getTimeZoneModel());
|
||||
setIsScheduled(conf.isScheduled());
|
||||
setIsEnded(conf.isEnded());
|
||||
setInviteMode(conf.getInviteMode());
|
||||
setConferenceInfoState(conf.getConferenceInfoState());
|
||||
}
|
||||
|
||||
void ConferenceInfoCore::setSelf(SafeSharedPointer<ConferenceInfoCore> me) {
|
||||
setSelf(me.mQDataWeak.lock());
|
||||
}
|
||||
void ConferenceInfoCore::setSelf(QSharedPointer<ConferenceInfoCore> me) {
|
||||
if (me) {
|
||||
if (mConferenceInfoModel) {
|
||||
mCoreModelConnection = nullptr;
|
||||
mConfInfoModelConnection = QSharedPointer<SafeConnection<ConferenceInfoCore, ConferenceInfoModel>>(
|
||||
new SafeConnection<ConferenceInfoCore, ConferenceInfoModel>(me, mConferenceInfoModel),
|
||||
&QObject::deleteLater);
|
||||
|
||||
mConfInfoModelConnection->makeConnectToModel(&ConferenceInfoModel::dateTimeChanged,
|
||||
[this](const QDateTime &date) {
|
||||
mConfInfoModelConnection->invokeToCore([this, date] {
|
||||
setDateTime(date);
|
||||
setIsEnded(computeIsEnded());
|
||||
});
|
||||
});
|
||||
mConfInfoModelConnection->makeConnectToModel(&ConferenceInfoModel::durationChanged, [this](int duration) {
|
||||
mConfInfoModelConnection->invokeToCore([this, duration] {
|
||||
setDuration(duration);
|
||||
setIsEnded(computeIsEnded());
|
||||
});
|
||||
});
|
||||
mConfInfoModelConnection->makeConnectToModel(
|
||||
&ConferenceInfoModel::stateChanged, [this](linphone::ConferenceScheduler::State state) {
|
||||
qDebug() << "conf state changed" << LinphoneEnums::fromLinphone(state);
|
||||
mConfInfoModelConnection->invokeToCore([this] {});
|
||||
});
|
||||
|
||||
mConfInfoModelConnection->makeConnectToCore(&ConferenceInfoCore::lDeleteConferenceInfo,
|
||||
[this]() { mConferenceInfoModel->deleteConferenceInfo(); });
|
||||
mConfInfoModelConnection->makeConnectToModel(&ConferenceInfoModel::conferenceInfoDeleted,
|
||||
&ConferenceInfoCore::removed);
|
||||
|
||||
mConfInfoModelConnection->makeConnectToModel(
|
||||
&ConferenceInfoModel::stateChanged,
|
||||
[this](linphone::ConferenceScheduler::State state) { qDebug() << "conf state changed"; });
|
||||
mConfInfoModelConnection->makeConnectToModel(
|
||||
&ConferenceInfoModel::invitationsSent,
|
||||
[this](const std::list<std::shared_ptr<linphone::Address>> &failedInvitations) {
|
||||
qDebug() << "invitations sent";
|
||||
});
|
||||
} else { // Create
|
||||
mCoreModelConnection = QSharedPointer<SafeConnection<ConferenceInfoCore, CoreModel>>(
|
||||
new SafeConnection<ConferenceInfoCore, CoreModel>(me, CoreModel::getInstance()), &QObject::deleteLater);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------------------------
|
||||
|
||||
// Note conferenceInfo->getDateTime uses UTC
|
||||
QDateTime ConferenceInfoCore::getDateTimeUtc() const {
|
||||
return getDateTimeSystem().toUTC();
|
||||
}
|
||||
|
||||
QDateTime ConferenceInfoCore::getDateTimeSystem() const {
|
||||
return mDateTime;
|
||||
}
|
||||
|
||||
int ConferenceInfoCore::getDuration() const {
|
||||
return mDuration;
|
||||
}
|
||||
|
||||
QDateTime ConferenceInfoCore::getEndDateTime() const {
|
||||
return mDateTime.addSecs(mDuration * 60);
|
||||
}
|
||||
|
||||
QDateTime ConferenceInfoCore::getEndDateTimeUtc() const {
|
||||
return getEndDateTime().toUTC();
|
||||
}
|
||||
|
||||
QString ConferenceInfoCore::getOrganizerName() const {
|
||||
return mOrganizerName;
|
||||
}
|
||||
|
||||
QString ConferenceInfoCore::getOrganizerAddress() const {
|
||||
return mOrganizerAddress;
|
||||
}
|
||||
|
||||
QString ConferenceInfoCore::getSubject() const {
|
||||
return mSubject;
|
||||
}
|
||||
|
||||
QString ConferenceInfoCore::getDescription() const {
|
||||
return mDescription;
|
||||
}
|
||||
|
||||
void ConferenceInfoCore::setDateTime(const QDateTime &date) {
|
||||
if (date != mDateTime) {
|
||||
mDateTime = date;
|
||||
emit dateTimeChanged();
|
||||
}
|
||||
}
|
||||
|
||||
void ConferenceInfoCore::setEndDateTime(const QDateTime &date) {
|
||||
if (date != mEndDateTime) {
|
||||
mEndDateTime = date;
|
||||
emit endDateTimeChanged();
|
||||
}
|
||||
}
|
||||
|
||||
void ConferenceInfoCore::setDuration(int duration) {
|
||||
if (duration != mDuration) {
|
||||
mDuration = duration;
|
||||
emit durationChanged();
|
||||
}
|
||||
}
|
||||
|
||||
void ConferenceInfoCore::setSubject(const QString &subject) {
|
||||
if (subject != mSubject) {
|
||||
mSubject = subject;
|
||||
emit subjectChanged();
|
||||
}
|
||||
}
|
||||
|
||||
void ConferenceInfoCore::setOrganizerName(const QString &organizer) {
|
||||
if (organizer != mOrganizerName) {
|
||||
mOrganizerName = organizer;
|
||||
emit organizerNameChanged();
|
||||
}
|
||||
}
|
||||
|
||||
void ConferenceInfoCore::setOrganizerAddress(const QString &organizer) {
|
||||
if (organizer != mOrganizerAddress) {
|
||||
mOrganizerAddress = organizer;
|
||||
emit organizerAddressChanged();
|
||||
}
|
||||
}
|
||||
|
||||
void ConferenceInfoCore::setUri(const QString &uri) {
|
||||
if (uri != mUri) {
|
||||
mUri = uri;
|
||||
emit uriChanged();
|
||||
}
|
||||
}
|
||||
|
||||
void ConferenceInfoCore::setTimeZoneModel(TimeZoneModel *model) {
|
||||
if (mTimeZoneModel->getDisplayName() != model->getDisplayName() ||
|
||||
mTimeZoneModel->getCountryName() != model->getCountryName() ||
|
||||
mTimeZoneModel->getOffsetFromUtc() != model->getOffsetFromUtc() ||
|
||||
mTimeZoneModel->getStandardTimeOffset() != model->getStandardTimeOffset() ||
|
||||
mTimeZoneModel->getTimeZone() != model->getTimeZone()) {
|
||||
|
||||
mTimeZoneModel = QSharedPointer<TimeZoneModel>(model);
|
||||
emit timeZoneModelChanged();
|
||||
}
|
||||
}
|
||||
|
||||
void ConferenceInfoCore::setDescription(const QString &description) {
|
||||
if (description != mDescription) {
|
||||
mDescription = description;
|
||||
emit descriptionChanged();
|
||||
}
|
||||
}
|
||||
|
||||
QString ConferenceInfoCore::getUri() const {
|
||||
return mUri;
|
||||
}
|
||||
|
||||
bool ConferenceInfoCore::isScheduled() const {
|
||||
return mIsScheduled;
|
||||
}
|
||||
|
||||
bool ConferenceInfoCore::computeIsEnded() const {
|
||||
return getEndDateTimeUtc() < QDateTime::currentDateTimeUtc();
|
||||
}
|
||||
|
||||
bool ConferenceInfoCore::isEnded() const {
|
||||
return mIsEnded;
|
||||
}
|
||||
|
||||
int ConferenceInfoCore::getInviteMode() const {
|
||||
return mInviteMode;
|
||||
}
|
||||
|
||||
QVariantList ConferenceInfoCore::getParticipants() const {
|
||||
return mParticipants;
|
||||
}
|
||||
|
||||
int ConferenceInfoCore::getParticipantCount() const {
|
||||
return mParticipants.size();
|
||||
}
|
||||
|
||||
void ConferenceInfoCore::addParticipant(const QString &address) {
|
||||
for (auto &participant : mParticipants) {
|
||||
auto map = participant.toMap();
|
||||
if (map["address"].toString() == address) return;
|
||||
}
|
||||
QVariantMap participant;
|
||||
auto displayNameObj = Utils::getDisplayName(address);
|
||||
if (displayNameObj) participant["displayName"] = displayNameObj->getValue();
|
||||
participant["address"] = address;
|
||||
participant["role"] = (int)LinphoneEnums::ParticipantRole::Listener;
|
||||
mParticipants.append(participant);
|
||||
emit participantsChanged();
|
||||
}
|
||||
|
||||
void ConferenceInfoCore::removeParticipant(const QString &address) {
|
||||
for (int i = 0; i < mParticipants.size(); ++i) {
|
||||
auto map = mParticipants[i].toMap();
|
||||
if (map["address"].toString() == address) {
|
||||
mParticipants.remove(i);
|
||||
emit participantsChanged();
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void ConferenceInfoCore::removeParticipant(const int &index) {
|
||||
mParticipants.remove(index);
|
||||
emit participantsChanged();
|
||||
}
|
||||
|
||||
QString ConferenceInfoCore::getParticipantAddressAt(const int &index) {
|
||||
if (index < 0 || index >= mParticipants.size()) return QString();
|
||||
auto map = mParticipants[index].toMap();
|
||||
return map["address"].toString();
|
||||
}
|
||||
|
||||
void ConferenceInfoCore::clearParticipants() {
|
||||
mParticipants.clear();
|
||||
emit participantsChanged();
|
||||
}
|
||||
|
||||
void ConferenceInfoCore::resetParticipants(QVariantList participants) {
|
||||
mParticipants = participants;
|
||||
}
|
||||
|
||||
void ConferenceInfoCore::resetParticipants(const QStringList &adresses) {
|
||||
mParticipants.clear();
|
||||
for (auto &address : adresses) {
|
||||
QVariantMap participant;
|
||||
QString name;
|
||||
auto nameObj = Utils::getDisplayName(address);
|
||||
if (nameObj) name = nameObj->getValue().toString();
|
||||
participant["displayName"] = name;
|
||||
participant["address"] = address;
|
||||
participant["role"] = (int)LinphoneEnums::ParticipantRole::Listener;
|
||||
mParticipants.append(participant);
|
||||
}
|
||||
emit participantsChanged();
|
||||
}
|
||||
|
||||
int ConferenceInfoCore::getParticipantIndex(const QString &address) {
|
||||
for (int i = 0; i < mParticipants.count(); ++i) {
|
||||
auto map = mParticipants[i].toMap();
|
||||
if (map["address"].toString() == address) {
|
||||
return i;
|
||||
}
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
TimeZoneModel *ConferenceInfoCore::getTimeZoneModel() const {
|
||||
return mTimeZoneModel.get();
|
||||
}
|
||||
|
||||
// QString ConferenceInfoCore::getIcalendarString() const {
|
||||
// return Utils::coreStringToAppString(mConferenceInfoModel->getIcalendarString());
|
||||
// }
|
||||
|
||||
LinphoneEnums::ConferenceInfoState ConferenceInfoCore::getConferenceInfoState() const {
|
||||
return mConferenceInfoState;
|
||||
}
|
||||
|
||||
// LinphoneEnums::ConferenceSchedulerState ConferenceInfoCore::getConferenceSchedulerState() const {
|
||||
// return LinphoneEnums::fromLinphone(mLastConferenceSchedulerState);
|
||||
// }
|
||||
|
||||
//------------------------------------------------------------------------------------------------
|
||||
// Datetime is in Custom (Locale/UTC/System). Convert into UTC for conference info
|
||||
|
||||
void ConferenceInfoCore::setIsScheduled(const bool &on) {
|
||||
if (mIsScheduled != on) {
|
||||
mIsScheduled = on;
|
||||
emit isScheduledChanged();
|
||||
}
|
||||
}
|
||||
|
||||
void ConferenceInfoCore::setIsEnded(bool ended) {
|
||||
if (mIsEnded != ended) {
|
||||
mIsEnded = ended;
|
||||
if (mIsEnded) mCheckEndTimer.stop(); // No need to run the timer.
|
||||
else mCheckEndTimer.start();
|
||||
emit isEndedChanged();
|
||||
}
|
||||
}
|
||||
|
||||
void ConferenceInfoCore::setInviteMode(const int &mode) {
|
||||
if (mode != mInviteMode) {
|
||||
mInviteMode = mode;
|
||||
emit inviteModeChanged();
|
||||
}
|
||||
}
|
||||
|
||||
void ConferenceInfoCore::setConferenceInfoState(LinphoneEnums::ConferenceInfoState state) {
|
||||
if (state != mConferenceInfoState) {
|
||||
mConferenceInfoState = state;
|
||||
emit conferenceInfoStateChanged();
|
||||
}
|
||||
}
|
||||
|
||||
void ConferenceInfoCore::writeFromModel(const std::shared_ptr<ConferenceInfoModel> &model) {
|
||||
mustBeInLinphoneThread(getClassName() + "::writeFromModel()");
|
||||
setDateTime(model->getDateTime());
|
||||
setDuration(model->getDuration());
|
||||
setSubject(model->getSubject());
|
||||
setOrganizerName(model->getOrganizerName());
|
||||
setOrganizerAddress(model->getOrganizerAddress());
|
||||
setDescription(model->getDescription());
|
||||
QStringList participantAddresses;
|
||||
for (auto &infos : model->getParticipantInfos()) {
|
||||
participantAddresses.append(Utils::coreStringToAppString(infos->getAddress()->asStringUriOnly()));
|
||||
}
|
||||
resetParticipants(participantAddresses);
|
||||
}
|
||||
|
||||
void ConferenceInfoCore::writeIntoModel(std::shared_ptr<ConferenceInfoModel> model) {
|
||||
mustBeInLinphoneThread(getClassName() + "::writeIntoModel()");
|
||||
model->setDateTime(mDateTime);
|
||||
model->setDuration(mDuration);
|
||||
model->setSubject(mSubject);
|
||||
model->setOrganizer(mOrganizerAddress);
|
||||
model->setDescription(mDescription);
|
||||
std::list<std::shared_ptr<linphone::ParticipantInfo>> participantInfos;
|
||||
for (auto &p : mParticipants) {
|
||||
auto map = p.toMap();
|
||||
auto address = map["address"].toString();
|
||||
auto linAddr = ToolModel::interpretUrl(address);
|
||||
auto infos = linphone::Factory::get()->createParticipantInfo(linAddr);
|
||||
participantInfos.push_back(infos);
|
||||
}
|
||||
model->setParticipantInfos(participantInfos);
|
||||
}
|
||||
|
||||
void ConferenceInfoCore::save() {
|
||||
mustBeInMainThread(getClassName() + "::save()");
|
||||
ConferenceInfoCore *thisCopy = new ConferenceInfoCore(*this); // Pointer to avoid multiple copies in lambdas
|
||||
if (mConferenceInfoModel) {
|
||||
mConfInfoModelConnection->invokeToModel([this, thisCopy]() { // Copy values to avoid concurrency
|
||||
mustBeInLinphoneThread(getClassName() + "::save()");
|
||||
thisCopy->writeIntoModel(mConferenceInfoModel);
|
||||
thisCopy->deleteLater();
|
||||
});
|
||||
} else {
|
||||
mCoreModelConnection->invokeToModel([this, thisCopy]() {
|
||||
auto linphoneConf =
|
||||
CoreModel::getInstance()->getCore()->findConferenceInformationFromUri(ToolModel::interpretUrl(mUri));
|
||||
|
||||
if (linphoneConf == nullptr) {
|
||||
linphoneConf = linphone::Factory::get()->createConferenceInfo();
|
||||
}
|
||||
auto defaultAccount = CoreModel::getInstance()->getCore()->getDefaultAccount();
|
||||
if (defaultAccount) {
|
||||
auto accountAddress = defaultAccount->getContactAddress();
|
||||
if (accountAddress) {
|
||||
auto cleanedClonedAddress = accountAddress->clone();
|
||||
cleanedClonedAddress->clean();
|
||||
if (!linphoneConf->getOrganizer()) linphoneConf->setOrganizer(cleanedClonedAddress);
|
||||
if (mOrganizerAddress.isEmpty())
|
||||
mOrganizerAddress = Utils::coreStringToAppString(accountAddress->asStringUriOnly());
|
||||
}
|
||||
}
|
||||
mConferenceInfoModel = Utils::makeQObject_ptr<ConferenceInfoModel>(linphoneConf);
|
||||
// mConferenceInfoModel->createConferenceScheduler();
|
||||
auto confSchedulerModel = mConferenceInfoModel->getConferenceScheduler();
|
||||
if (!confSchedulerModel) {
|
||||
auto confScheduler = CoreModel::getInstance()->getCore()->createConferenceScheduler();
|
||||
confSchedulerModel = Utils::makeQObject_ptr<ConferenceSchedulerModel>(confScheduler);
|
||||
mConferenceInfoModel->setConferenceScheduler(confSchedulerModel);
|
||||
}
|
||||
thisCopy->writeIntoModel(mConferenceInfoModel);
|
||||
thisCopy->deleteLater();
|
||||
confSchedulerModel->setInfo(linphoneConf);
|
||||
mCoreModelConnection->invokeToCore([this]() { setSelf(mCoreModelConnection->mCore); });
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
void ConferenceInfoCore::undo() {
|
||||
if (mConferenceInfoModel) {
|
||||
mConfInfoModelConnection->invokeToModel([this]() {
|
||||
ConferenceInfoCore *conf = new ConferenceInfoCore(*this);
|
||||
conf->writeFromModel(mConferenceInfoModel);
|
||||
conf->moveToThread(App::getInstance()->thread());
|
||||
mConfInfoModelConnection->invokeToCore([this, conf]() mutable {
|
||||
this->reset(*conf);
|
||||
conf->deleteLater();
|
||||
});
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
void ConferenceInfoCore::cancelConference() {
|
||||
if (!mConferenceInfoModel) return;
|
||||
mConferenceInfoModel->cancelConference();
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------------------------------------
|
||||
|
||||
// void ConferenceInfoCore::createConference(const int &securityLevel) {
|
||||
// CoreModel::getInstance()->getTimelineListModel()->mAutoSelectAfterCreation = false;
|
||||
// shared_ptr<linphone::Core> core = CoreManager::getInstance()->getCore();
|
||||
// static std::shared_ptr<linphone::Conference> conference;
|
||||
// qInfo() << "Conference creation of " << getSubject() << " at " << securityLevel << " security, organized by "
|
||||
// << getOrganizer() << " for " << getDateTimeSystem().toString();
|
||||
// qInfo() << "Participants:";
|
||||
// for (auto p : mConferenceInfoModel->getParticipants())
|
||||
// qInfo() << "\t" << p->asString().c_str();
|
||||
|
||||
// mConferenceScheduler = ConferenceScheduler::create();
|
||||
// mConferenceScheduler->mSendInvite = mInviteMode;
|
||||
// connect(mConferenceScheduler.get(), &ConferenceScheduler::invitationsSent, this,
|
||||
// &ConferenceInfoCore::onInvitationsSent);
|
||||
// connect(mConferenceScheduler.get(), &ConferenceScheduler::stateChanged, this,
|
||||
// &ConferenceInfoCore::onConferenceSchedulerStateChanged);
|
||||
// mConferenceScheduler->getConferenceScheduler()->setInfo(mConferenceInfoModel);
|
||||
// }
|
||||
|
||||
//-------------------------------------------------------------------------------------------------
|
||||
|
||||
// void ConferenceInfoCore::onConferenceSchedulerStateChanged(linphone::ConferenceScheduler::State state) {
|
||||
// qDebug() << "ConferenceInfoCore::onConferenceSchedulerStateChanged: " << (int)state;
|
||||
// mLastConferenceSchedulerState = state;
|
||||
// if (state == linphone::ConferenceScheduler::State::Ready) emit conferenceCreated();
|
||||
// else if (state == linphone::ConferenceScheduler::State::Error) emit conferenceCreationFailed();
|
||||
// emit conferenceInfoChanged();
|
||||
// }
|
||||
void ConferenceInfoCore::onInvitationsSent(const std::list<std::shared_ptr<linphone::Address>> &failedInvitations) {
|
||||
qDebug() << "ConferenceInfoCore::onInvitationsSent";
|
||||
emit invitationsSent();
|
||||
}
|
||||
187
Linphone/core/conference/ConferenceInfoCore.hpp
Normal file
187
Linphone/core/conference/ConferenceInfoCore.hpp
Normal file
|
|
@ -0,0 +1,187 @@
|
|||
/*
|
||||
* 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 <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef CONFERENCE_INFO_CORE_H_
|
||||
#define CONFERENCE_INFO_CORE_H_
|
||||
|
||||
#include "core/timezone/TimeZone.hpp"
|
||||
#include "model/conference/ConferenceInfoModel.hpp"
|
||||
#include "tool/LinphoneEnums.hpp"
|
||||
#include "tool/thread/SafeConnection.hpp"
|
||||
#include <linphone++/linphone.hh>
|
||||
|
||||
#include <QDateTime>
|
||||
#include <QObject>
|
||||
#include <QSharedPointer>
|
||||
#include <QTimeZone>
|
||||
#include <QTimer>
|
||||
|
||||
class ParticipantListModel;
|
||||
// class TimeZoneModel;
|
||||
|
||||
class ConferenceInfoCore : public QObject, public AbstractObject {
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
Q_PROPERTY(TimeZoneModel *timeZoneModel READ getTimeZoneModel WRITE setTimeZoneModel NOTIFY timeZoneModelChanged)
|
||||
Q_PROPERTY(QDateTime dateTime READ getDateTimeSystem WRITE setDateTime NOTIFY dateTimeChanged)
|
||||
Q_PROPERTY(QDateTime endDateTime READ getEndDateTime WRITE setEndDateTime NOTIFY endDateTimeChanged)
|
||||
Q_PROPERTY(QDateTime dateTimeUtc READ getDateTimeUtc NOTIFY dateTimeChanged)
|
||||
Q_PROPERTY(int duration READ getDuration WRITE setDuration NOTIFY durationChanged)
|
||||
Q_PROPERTY(
|
||||
QString organizerAddress READ getOrganizerAddress WRITE setOrganizerAddress NOTIFY organizerAddressChanged)
|
||||
Q_PROPERTY(QString organizerName READ getOrganizerName WRITE setOrganizerName NOTIFY organizerNameChanged)
|
||||
Q_PROPERTY(QString subject READ getSubject WRITE setSubject NOTIFY subjectChanged)
|
||||
Q_PROPERTY(QString description READ getDescription WRITE setDescription NOTIFY descriptionChanged)
|
||||
Q_PROPERTY(QString uri READ getUri NOTIFY uriChanged)
|
||||
Q_PROPERTY(bool isScheduled READ isScheduled WRITE setIsScheduled NOTIFY isScheduledChanged)
|
||||
Q_PROPERTY(bool isEnded READ isEnded WRITE setIsEnded NOTIFY isEndedChanged)
|
||||
Q_PROPERTY(int inviteMode READ getInviteMode WRITE setInviteMode NOTIFY inviteModeChanged)
|
||||
Q_PROPERTY(int participantCount READ getParticipantCount NOTIFY participantsChanged)
|
||||
Q_PROPERTY(QVariantList participants READ getParticipants NOTIFY participantsChanged)
|
||||
Q_PROPERTY(LinphoneEnums::ConferenceInfoState state READ getConferenceInfoState NOTIFY conferenceInfoStateChanged)
|
||||
// Q_PROPERTY(LinphoneEnums::ConferenceSchedulerState conferenceSchedulerState READ getConferenceSchedulerState
|
||||
// NOTIFY
|
||||
// conferenceSchedulerStateChanged)
|
||||
|
||||
static QSharedPointer<ConferenceInfoCore> create(std::shared_ptr<linphone::ConferenceInfo> conferenceInfo);
|
||||
ConferenceInfoCore(std::shared_ptr<linphone::ConferenceInfo> conferenceInfo, QObject *parent = nullptr);
|
||||
ConferenceInfoCore(const ConferenceInfoCore &conferenceInfoCore);
|
||||
~ConferenceInfoCore();
|
||||
void reset(const ConferenceInfoCore &contact);
|
||||
|
||||
void setSelf(SafeSharedPointer<ConferenceInfoCore> me);
|
||||
void setSelf(QSharedPointer<ConferenceInfoCore> me);
|
||||
|
||||
QDateTime getDateTimeUtc() const;
|
||||
QDateTime getDateTimeSystem() const;
|
||||
int getDuration() const;
|
||||
QDateTime getEndDateTime() const;
|
||||
QDateTime getEndDateTimeUtc() const;
|
||||
QString getOrganizerName() const;
|
||||
QString getOrganizerAddress() const;
|
||||
QString getSubject() const;
|
||||
QString getDescription() const;
|
||||
QString getUri() const;
|
||||
bool isScheduled() const;
|
||||
void setIsScheduled(const bool &on);
|
||||
bool computeIsEnded() const;
|
||||
bool isEnded() const;
|
||||
void setIsEnded(bool ended);
|
||||
int getInviteMode() const;
|
||||
QVariantList getParticipants() const;
|
||||
// Q_INVOKABLE QVariantList getAllParticipants() const;
|
||||
int getParticipantCount() const;
|
||||
TimeZoneModel *getTimeZoneModel() const;
|
||||
// QString getIcalendarString() const;
|
||||
LinphoneEnums::ConferenceInfoState getConferenceInfoState() const;
|
||||
// LinphoneEnums::ConferenceSchedulerState getConferenceSchedulerState() const;
|
||||
|
||||
void setDateTime(const QDateTime &date);
|
||||
void setEndDateTime(const QDateTime &date);
|
||||
void setDuration(int duration);
|
||||
void setSubject(const QString &subject);
|
||||
void setOrganizerName(const QString &organizer);
|
||||
void setOrganizerAddress(const QString &organizer);
|
||||
void setUri(const QString &uri);
|
||||
void setTimeZoneModel(TimeZoneModel *model);
|
||||
void setDescription(const QString &description);
|
||||
void setInviteMode(const int &mode);
|
||||
void setConferenceInfoState(LinphoneEnums::ConferenceInfoState state);
|
||||
|
||||
Q_INVOKABLE void addParticipant(const QString &address);
|
||||
Q_INVOKABLE void removeParticipant(const QString &address);
|
||||
Q_INVOKABLE void removeParticipant(const int &index);
|
||||
Q_INVOKABLE QString getParticipantAddressAt(const int &index);
|
||||
Q_INVOKABLE void clearParticipants();
|
||||
void resetParticipants(QVariantList participants);
|
||||
Q_INVOKABLE void resetParticipants(const QStringList &adresses);
|
||||
Q_INVOKABLE int getParticipantIndex(const QString &address);
|
||||
|
||||
void writeFromModel(const std::shared_ptr<ConferenceInfoModel> &model);
|
||||
void writeIntoModel(std::shared_ptr<ConferenceInfoModel> model);
|
||||
|
||||
Q_INVOKABLE void save();
|
||||
Q_INVOKABLE void cancelConference();
|
||||
Q_INVOKABLE void undo();
|
||||
|
||||
// Tools
|
||||
// Q_INVOKABLE void resetConferenceInfo(); // Recreate a new conference info from factory
|
||||
|
||||
// SCHEDULER
|
||||
|
||||
// virtual void onConferenceSchedulerStateChanged(linphone::ConferenceScheduler::State state);
|
||||
virtual void onInvitationsSent(const std::list<std::shared_ptr<linphone::Address>> &failedInvitations);
|
||||
|
||||
signals:
|
||||
void dateTimeChanged();
|
||||
void endDateTimeChanged();
|
||||
void durationChanged();
|
||||
void organizerAddressChanged();
|
||||
void organizerNameChanged();
|
||||
void subjectChanged();
|
||||
void descriptionChanged();
|
||||
void participantsChanged();
|
||||
void uriChanged();
|
||||
void isScheduledChanged();
|
||||
void isEndedChanged();
|
||||
void inviteModeChanged();
|
||||
void conferenceInfoStateChanged();
|
||||
void timeZoneModelChanged();
|
||||
// void conferenceSchedulerStateChanged();
|
||||
|
||||
void invitationsSent();
|
||||
void removed();
|
||||
|
||||
// void lCreateConference(const int &securityLevel);
|
||||
// void lCancelConference();
|
||||
void lDeleteConferenceInfo(); // Remove completly this conference info from DB
|
||||
|
||||
private:
|
||||
std::shared_ptr<ConferenceInfoModel> mConferenceInfoModel = nullptr;
|
||||
QSharedPointer<SafeConnection<ConferenceInfoCore, ConferenceInfoModel>> mConfInfoModelConnection;
|
||||
QSharedPointer<SafeConnection<ConferenceInfoCore, ConferenceSchedulerModel>> mConfSchedulerModelConnection;
|
||||
QSharedPointer<SafeConnection<ConferenceInfoCore, CoreModel>> mCoreModelConnection;
|
||||
|
||||
QDateTime mDateTime;
|
||||
QDateTime mEndDateTime;
|
||||
int mDuration;
|
||||
QString mOrganizerAddress;
|
||||
QString mOrganizerName;
|
||||
QString mSubject;
|
||||
QString mDescription;
|
||||
QString mUri;
|
||||
QVariantList mParticipants;
|
||||
QSharedPointer<TimeZoneModel> mTimeZoneModel;
|
||||
LinphoneEnums::ConferenceInfoState mConferenceInfoState =
|
||||
LinphoneEnums::ConferenceInfoState::ConferenceInfoStateNew;
|
||||
bool mIsScheduled = true;
|
||||
bool mIsEnded = false;
|
||||
QTimer mCheckEndTimer;
|
||||
int mInviteMode = 0;
|
||||
// bool mRemoveRequested = false; // true if user has request its deletion from DB
|
||||
// linphone::ConferenceScheduler::State mLastConferenceSchedulerState =
|
||||
// linphone::ConferenceScheduler::State::Idle; // Workaround for missing getter in scheduler.
|
||||
DECLARE_ABSTRACT_OBJECT
|
||||
};
|
||||
|
||||
Q_DECLARE_METATYPE(ConferenceInfoCore *)
|
||||
|
||||
#endif
|
||||
47
Linphone/core/conference/ConferenceInfoGui.cpp
Normal file
47
Linphone/core/conference/ConferenceInfoGui.cpp
Normal file
|
|
@ -0,0 +1,47 @@
|
|||
/*
|
||||
* Copyright (c) 2010-2024 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 <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "ConferenceInfoGui.hpp"
|
||||
#include "ConferenceInfoCore.hpp"
|
||||
#include "core/App.hpp"
|
||||
|
||||
DEFINE_ABSTRACT_OBJECT(ConferenceInfoGui)
|
||||
|
||||
ConferenceInfoGui::ConferenceInfoGui() {
|
||||
qDebug() << "[ConferenceInfoGui] new" << this;
|
||||
mCore = ConferenceInfoCore::create(nullptr);
|
||||
App::getInstance()->mEngine->setObjectOwnership(this, QQmlEngine::JavaScriptOwnership);
|
||||
if (isInLinphoneThread()) moveToThread(App::getInstance()->thread());
|
||||
}
|
||||
ConferenceInfoGui::ConferenceInfoGui(QSharedPointer<ConferenceInfoCore> core) {
|
||||
qDebug() << "[ConferenceInfoGui] new" << this;
|
||||
App::getInstance()->mEngine->setObjectOwnership(this, QQmlEngine::JavaScriptOwnership);
|
||||
mCore = core;
|
||||
if (isInLinphoneThread()) moveToThread(App::getInstance()->thread());
|
||||
}
|
||||
|
||||
ConferenceInfoGui::~ConferenceInfoGui() {
|
||||
mustBeInMainThread("~" + getClassName());
|
||||
qDebug() << "[ConferenceInfoGui] delete" << this;
|
||||
}
|
||||
|
||||
ConferenceInfoCore *ConferenceInfoGui::getCore() const {
|
||||
return mCore.get();
|
||||
}
|
||||
44
Linphone/core/conference/ConferenceInfoGui.hpp
Normal file
44
Linphone/core/conference/ConferenceInfoGui.hpp
Normal file
|
|
@ -0,0 +1,44 @@
|
|||
/*
|
||||
* Copyright (c) 2010-2024 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 <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef CONFERENCE_INFO_GUI_H_
|
||||
#define CONFERENCE_INFO_GUI_H_
|
||||
|
||||
#include "tool/AbstractObject.hpp"
|
||||
#include <QObject>
|
||||
#include <QSharedPointer>
|
||||
|
||||
class ConferenceInfoCore;
|
||||
|
||||
class ConferenceInfoGui : public QObject, public AbstractObject {
|
||||
Q_OBJECT
|
||||
|
||||
Q_PROPERTY(ConferenceInfoCore *core READ getCore CONSTANT)
|
||||
|
||||
public:
|
||||
ConferenceInfoGui();
|
||||
ConferenceInfoGui(QSharedPointer<ConferenceInfoCore> core);
|
||||
~ConferenceInfoGui();
|
||||
ConferenceInfoCore *getCore() const;
|
||||
QSharedPointer<ConferenceInfoCore> mCore;
|
||||
DECLARE_ABSTRACT_OBJECT
|
||||
};
|
||||
|
||||
#endif
|
||||
162
Linphone/core/conference/ConferenceInfoList.cpp
Normal file
162
Linphone/core/conference/ConferenceInfoList.cpp
Normal file
|
|
@ -0,0 +1,162 @@
|
|||
/*
|
||||
* Copyright (c) 2010-2024 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 <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "ConferenceInfoList.hpp"
|
||||
#include "ConferenceInfoCore.hpp"
|
||||
#include "ConferenceInfoGui.hpp"
|
||||
#include "core/App.hpp"
|
||||
#include "model/object/VariantObject.hpp"
|
||||
#include "tool/Utils.hpp"
|
||||
#include <QSharedPointer>
|
||||
#include <linphone++/linphone.hh>
|
||||
|
||||
// =============================================================================
|
||||
|
||||
DEFINE_ABSTRACT_OBJECT(ConferenceInfoList)
|
||||
|
||||
QSharedPointer<ConferenceInfoList> ConferenceInfoList::create() {
|
||||
auto model = QSharedPointer<ConferenceInfoList>(new ConferenceInfoList(), &QObject::deleteLater);
|
||||
model->moveToThread(App::getInstance()->thread());
|
||||
model->setSelf(model);
|
||||
return model;
|
||||
}
|
||||
|
||||
ConferenceInfoList::ConferenceInfoList(QObject *parent) : ListProxy(parent) {
|
||||
mustBeInMainThread(getClassName());
|
||||
}
|
||||
|
||||
ConferenceInfoList::~ConferenceInfoList() {
|
||||
mustBeInMainThread("~" + getClassName());
|
||||
mCoreModelConnection = nullptr;
|
||||
}
|
||||
|
||||
void ConferenceInfoList::setSelf(QSharedPointer<ConferenceInfoList> me) {
|
||||
mCoreModelConnection = QSharedPointer<SafeConnection<ConferenceInfoList, CoreModel>>(
|
||||
new SafeConnection<ConferenceInfoList, CoreModel>(me, CoreModel::getInstance()), &QObject::deleteLater);
|
||||
|
||||
mCoreModelConnection->makeConnectToCore(&ConferenceInfoList::lUpdate, [this]() {
|
||||
mCoreModelConnection->invokeToModel([this]() {
|
||||
QList<QSharedPointer<ConferenceInfoCore>> *items = new QList<QSharedPointer<ConferenceInfoCore>>();
|
||||
mustBeInLinphoneThread(getClassName());
|
||||
std::list<std::shared_ptr<linphone::ConferenceInfo>> conferenceInfos =
|
||||
CoreModel::getInstance()->getCore()->getDefaultAccount()->getConferenceInformationList();
|
||||
for (auto conferenceInfo : conferenceInfos) {
|
||||
auto confInfoCore = build(conferenceInfo);
|
||||
if (confInfoCore) items->push_back(confInfoCore);
|
||||
}
|
||||
mCoreModelConnection->invokeToCore([this, items]() {
|
||||
mustBeInMainThread(getClassName());
|
||||
resetData();
|
||||
add(*items);
|
||||
delete items;
|
||||
});
|
||||
});
|
||||
});
|
||||
// mCoreModelConnection->makeConnectToModel(
|
||||
// &CoreModel::conferenceInfoReceived,
|
||||
// [this](const std::shared_ptr<linphone::Core> core,
|
||||
// const std::shared_ptr<const linphone::ConferenceInfo> &conferenceInfo) {
|
||||
// auto realConferenceInfo = CoreModel::getInstance()->getCore()->findConferenceInformationFromUri(
|
||||
// conferenceInfo->getUri()->clone());
|
||||
// // auto realConferenceInfo = ConferenceInfoModel::findConferenceInfo(conferenceInfo);
|
||||
// if (realConferenceInfo) {
|
||||
// auto model = get(realConferenceInfo);
|
||||
// if (model) {
|
||||
// // model->setConferenceInfo(realConferenceInfo);
|
||||
// } else {
|
||||
// auto confInfo = build(realConferenceInfo);
|
||||
// if (confInfo) add(confInfo);
|
||||
// }
|
||||
// } else
|
||||
// qWarning() << "No ConferenceInfo have beend found for " << conferenceInfo->getUri()->asString().c_str();
|
||||
// });
|
||||
|
||||
mCoreModelConnection->makeConnectToModel(&CoreModel::conferenceInfoReceived, &ConferenceInfoList::lUpdate);
|
||||
mCoreModelConnection->makeConnectToModel(&CoreModel::conferenceStateChanged, [this] {
|
||||
qDebug() << "list: conf state changed";
|
||||
lUpdate();
|
||||
});
|
||||
mCoreModelConnection->makeConnectToModel(
|
||||
&CoreModel::conferenceInfoReceived,
|
||||
[this](const std::shared_ptr<linphone::Core> &core,
|
||||
const std::shared_ptr<const linphone::ConferenceInfo> &conferenceInfo) {
|
||||
qDebug() << "info received" << conferenceInfo->getOrganizer()->asStringUriOnly()
|
||||
<< conferenceInfo->getSubject();
|
||||
});
|
||||
emit lUpdate();
|
||||
}
|
||||
|
||||
QSharedPointer<ConferenceInfoCore>
|
||||
ConferenceInfoList::get(std::shared_ptr<linphone::ConferenceInfo> conferenceInfo) const {
|
||||
auto uri = Utils::coreStringToAppString(conferenceInfo->getUri()->asStringUriOnly());
|
||||
for (auto item : mList) {
|
||||
auto model = item.objectCast<ConferenceInfoCore>();
|
||||
auto confUri = model->getUri();
|
||||
if (confUri == uri) {
|
||||
return model;
|
||||
}
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
QSharedPointer<ConferenceInfoCore>
|
||||
ConferenceInfoList::build(const std::shared_ptr<linphone::ConferenceInfo> &conferenceInfo) const {
|
||||
auto me = CoreModel::getInstance()->getCore()->getDefaultAccount()->getParams()->getIdentityAddress();
|
||||
qDebug() << "[CONFERENCEINFOLIST] looking for me " << me->asStringUriOnly();
|
||||
std::list<std::shared_ptr<linphone::ParticipantInfo>> participants = conferenceInfo->getParticipantInfos();
|
||||
bool haveMe = conferenceInfo->getOrganizer()->weakEqual(me);
|
||||
if (!haveMe)
|
||||
haveMe = (std::find_if(participants.begin(), participants.end(),
|
||||
[me](const std::shared_ptr<linphone::ParticipantInfo> &p) {
|
||||
// qDebug()
|
||||
// << "[CONFERENCEINFOLIST] participant " << p->getAddress()->asStringUriOnly();
|
||||
return me->weakEqual(p->getAddress());
|
||||
}) != participants.end());
|
||||
if (haveMe) {
|
||||
auto conferenceModel = ConferenceInfoCore::create(conferenceInfo);
|
||||
connect(conferenceModel.get(), &ConferenceInfoCore::removed, this, &ConferenceInfoList::lUpdate);
|
||||
return conferenceModel;
|
||||
} else return nullptr;
|
||||
}
|
||||
|
||||
void ConferenceInfoList::remove(const int &row) {
|
||||
// beginRemoveRows(QModelIndex(), row, row);
|
||||
auto item = mList[row].objectCast<ConferenceInfoCore>();
|
||||
emit item->lDeleteConferenceInfo();
|
||||
// endRemoveRows();
|
||||
}
|
||||
|
||||
QHash<int, QByteArray> ConferenceInfoList::roleNames() const {
|
||||
QHash<int, QByteArray> roles;
|
||||
roles[Qt::DisplayRole] = "$modelData";
|
||||
roles[Qt::DisplayRole + 1] = "$sectionMonth";
|
||||
return roles;
|
||||
}
|
||||
|
||||
QVariant ConferenceInfoList::data(const QModelIndex &index, int role) const {
|
||||
int row = index.row();
|
||||
if (!index.isValid() || row < 0 || row >= mList.count()) return QVariant();
|
||||
if (role == Qt::DisplayRole) {
|
||||
return QVariant::fromValue(new ConferenceInfoGui(mList[row].objectCast<ConferenceInfoCore>()));
|
||||
} else if (role == Qt::DisplayRole + 1) {
|
||||
return Utils::toDateMonthString(mList[row].objectCast<ConferenceInfoCore>()->getDateTimeUtc());
|
||||
}
|
||||
return QVariant();
|
||||
}
|
||||
58
Linphone/core/conference/ConferenceInfoList.hpp
Normal file
58
Linphone/core/conference/ConferenceInfoList.hpp
Normal file
|
|
@ -0,0 +1,58 @@
|
|||
/*
|
||||
* 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 <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef CONFERENCE_INFO_LIST_H_
|
||||
#define CONFERENCE_INFO_LIST_H_
|
||||
|
||||
#include "../proxy/ListProxy.hpp"
|
||||
#include "tool/AbstractObject.hpp"
|
||||
#include "tool/thread/SafeConnection.hpp"
|
||||
#include <linphone++/linphone.hh>
|
||||
|
||||
class CoreModel;
|
||||
class ConferenceInfoCore;
|
||||
|
||||
class ConferenceInfoList : public ListProxy, public AbstractObject {
|
||||
Q_OBJECT
|
||||
public:
|
||||
static QSharedPointer<ConferenceInfoList> create();
|
||||
// Create a ConferenceInfoCore and make connections to List.
|
||||
ConferenceInfoList(QObject *parent = Q_NULLPTR);
|
||||
~ConferenceInfoList();
|
||||
|
||||
void setSelf(QSharedPointer<ConferenceInfoList> me);
|
||||
|
||||
QSharedPointer<ConferenceInfoCore> get(std::shared_ptr<linphone::ConferenceInfo> conferenceInfo) const;
|
||||
QSharedPointer<ConferenceInfoCore> build(const std::shared_ptr<linphone::ConferenceInfo> &conferenceInfo) const;
|
||||
|
||||
void remove(const int &row);
|
||||
|
||||
QHash<int, QByteArray> roleNames() const override;
|
||||
|
||||
virtual QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const override;
|
||||
|
||||
signals:
|
||||
void lUpdate();
|
||||
|
||||
private:
|
||||
QSharedPointer<SafeConnection<ConferenceInfoList, CoreModel>> mCoreModelConnection;
|
||||
DECLARE_ABSTRACT_OBJECT
|
||||
};
|
||||
#endif // CONFERENCE_INFO_LIST_H_
|
||||
74
Linphone/core/conference/ConferenceInfoProxy.cpp
Normal file
74
Linphone/core/conference/ConferenceInfoProxy.cpp
Normal file
|
|
@ -0,0 +1,74 @@
|
|||
/*
|
||||
* 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 <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "ConferenceInfoProxy.hpp"
|
||||
#include "ConferenceInfoCore.hpp"
|
||||
#include "ConferenceInfoGui.hpp"
|
||||
#include "ConferenceInfoList.hpp"
|
||||
|
||||
DEFINE_ABSTRACT_OBJECT(ConferenceInfoProxy)
|
||||
|
||||
ConferenceInfoProxy::ConferenceInfoProxy(QObject *parent) : SortFilterProxy(parent) {
|
||||
mList = ConferenceInfoList::create();
|
||||
setSourceModel(mList.get());
|
||||
connect(this, &ConferenceInfoProxy::searchTextChanged, [this] { invalidate(); });
|
||||
}
|
||||
|
||||
ConferenceInfoProxy::~ConferenceInfoProxy() {
|
||||
setSourceModel(nullptr);
|
||||
}
|
||||
|
||||
QString ConferenceInfoProxy::getSearchText() const {
|
||||
return mSearchText;
|
||||
}
|
||||
|
||||
void ConferenceInfoProxy::setSearchText(const QString &search) {
|
||||
mSearchText = search;
|
||||
emit searchTextChanged();
|
||||
}
|
||||
|
||||
bool ConferenceInfoProxy::filterAcceptsRow(int sourceRow, const QModelIndex &sourceParent) const {
|
||||
const ConferenceInfoGui *gui =
|
||||
sourceModel()->data(sourceModel()->index(sourceRow, 0, sourceParent)).value<ConferenceInfoGui *>();
|
||||
if (gui) {
|
||||
auto ciCore = gui->getCore();
|
||||
assert(ciCore);
|
||||
if (!ciCore->getSubject().contains(mSearchText)) return false;
|
||||
if (ciCore->getDuration() == 0) return false;
|
||||
QDateTime currentDateTime = QDateTime::currentDateTimeUtc();
|
||||
if (mFilterType == 0) {
|
||||
// auto res = ciCore->getEndDateTimeUtc() < currentDateTime;
|
||||
return true;
|
||||
} else if (mFilterType == 1) {
|
||||
auto res = ciCore->getEndDateTimeUtc() >= currentDateTime;
|
||||
return res;
|
||||
// } else if (mFilterType == 2) {
|
||||
// return !Utils::isMe(ciCore->getOrganizer());
|
||||
} else return mFilterType == -1;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool ConferenceInfoProxy::lessThan(const QModelIndex &left, const QModelIndex &right) const {
|
||||
auto l = getItemAt<ConferenceInfoList, ConferenceInfoGui>(left.row())->getCore();
|
||||
auto r = getItemAt<ConferenceInfoList, ConferenceInfoGui>(right.row())->getCore();
|
||||
|
||||
return l->getDateTimeUtc() < r->getDateTimeUtc();
|
||||
}
|
||||
54
Linphone/core/conference/ConferenceInfoProxy.hpp
Normal file
54
Linphone/core/conference/ConferenceInfoProxy.hpp
Normal file
|
|
@ -0,0 +1,54 @@
|
|||
/*
|
||||
* Copyright (c) 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 <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef CONFERENCE_INFO_PROXY_H_
|
||||
#define CONFERENCE_INFO_PROXY_H_
|
||||
|
||||
#include "../proxy/SortFilterProxy.hpp"
|
||||
#include "tool/AbstractObject.hpp"
|
||||
|
||||
class ConferenceInfoList;
|
||||
|
||||
class ConferenceInfoProxy : public SortFilterProxy, public AbstractObject {
|
||||
|
||||
Q_OBJECT
|
||||
Q_PROPERTY(QString searchText READ getSearchText WRITE setSearchText NOTIFY searchTextChanged)
|
||||
|
||||
public:
|
||||
ConferenceInfoProxy(QObject *parent = Q_NULLPTR);
|
||||
~ConferenceInfoProxy();
|
||||
|
||||
QString getSearchText() const;
|
||||
void setSearchText(const QString &search);
|
||||
|
||||
protected:
|
||||
bool filterAcceptsRow(int sourceRow, const QModelIndex &sourceParent) const override;
|
||||
bool lessThan(const QModelIndex &left, const QModelIndex &right) const override;
|
||||
|
||||
signals:
|
||||
void searchTextChanged();
|
||||
|
||||
private:
|
||||
QString mSearchText;
|
||||
QSharedPointer<ConferenceInfoList> mList;
|
||||
DECLARE_ABSTRACT_OBJECT
|
||||
};
|
||||
|
||||
#endif // CONFERENCE_INFO_PROXY_H_
|
||||
|
|
@ -459,6 +459,7 @@ void FriendCore::remove() {
|
|||
}
|
||||
|
||||
void FriendCore::save() { // Save Values to model
|
||||
mustBeInMainThread(getClassName() + "::save()");
|
||||
if (mAddressList.size() > 0) {
|
||||
auto it = std::find_if(mAddressList.begin(), mAddressList.end(), [this](const QVariant &a) {
|
||||
return a.toMap()["address"].toString() == mDefaultAddress;
|
||||
|
|
@ -472,9 +473,9 @@ void FriendCore::save() { // Save Values to model
|
|||
emit defaultAddressChanged();
|
||||
}
|
||||
FriendCore *thisCopy = new FriendCore(*this); // Pointer to avoid multiple copies in lambdas
|
||||
|
||||
if (mFriendModel) {
|
||||
mFriendModelConnection->invokeToModel([this, thisCopy]() { // Copy values to avoid concurrency
|
||||
mustBeInLinphoneThread(getClassName() + "::save()");
|
||||
thisCopy->writeIntoModel(mFriendModel);
|
||||
thisCopy->deleteLater();
|
||||
mFriendModelConnection->invokeToCore([this]() { saved(); });
|
||||
|
|
@ -491,18 +492,17 @@ void FriendCore::save() { // Save Values to model
|
|||
if (contact) break;
|
||||
}
|
||||
if (contact != nullptr) {
|
||||
auto friendModel = Utils::makeQObject_ptr<FriendModel>(contact);
|
||||
friendModel->setSelf(friendModel);
|
||||
thisCopy->writeIntoModel(friendModel);
|
||||
mFriendModel = Utils::makeQObject_ptr<FriendModel>(contact);
|
||||
mFriendModel->setSelf(mFriendModel);
|
||||
thisCopy->writeIntoModel(mFriendModel);
|
||||
thisCopy->deleteLater();
|
||||
if (mFriendModelConnection) mFriendModelConnection->invokeToCore([this] { saved(); });
|
||||
else mCoreModelConnection->invokeToCore([this] { saved(); });
|
||||
} else {
|
||||
auto contact = core->createFriend();
|
||||
std::shared_ptr<FriendModel> friendModel;
|
||||
friendModel = Utils::makeQObject_ptr<FriendModel>(contact);
|
||||
friendModel->setSelf(friendModel);
|
||||
thisCopy->writeIntoModel(friendModel);
|
||||
mFriendModel = Utils::makeQObject_ptr<FriendModel>(contact);
|
||||
mFriendModel->setSelf(mFriendModel);
|
||||
thisCopy->writeIntoModel(mFriendModel);
|
||||
thisCopy->deleteLater();
|
||||
bool created = (core->getDefaultFriendList()->addFriend(contact) == linphone::FriendList::Status::OK);
|
||||
if (created) {
|
||||
|
|
|
|||
|
|
@ -24,6 +24,7 @@
|
|||
DEFINE_ABSTRACT_OBJECT(FriendGui)
|
||||
|
||||
FriendGui::FriendGui(QObject *parent) : QObject(parent) {
|
||||
mustBeInMainThread(getClassName());
|
||||
mCore = FriendCore::create(nullptr);
|
||||
}
|
||||
FriendGui::FriendGui(QSharedPointer<FriendCore> core) {
|
||||
|
|
|
|||
|
|
@ -21,7 +21,6 @@
|
|||
#include "FriendInitialProxy.hpp"
|
||||
#include "FriendCore.hpp"
|
||||
#include "FriendGui.hpp"
|
||||
#include "tool/Utils.hpp"
|
||||
|
||||
DEFINE_ABSTRACT_OBJECT(FriendInitialProxy)
|
||||
|
||||
|
|
|
|||
172
Linphone/core/participant/ParticipantCore.cpp
Normal file
172
Linphone/core/participant/ParticipantCore.cpp
Normal file
|
|
@ -0,0 +1,172 @@
|
|||
/*
|
||||
* 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 <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include <QQmlApplicationEngine>
|
||||
|
||||
#include "core/App.hpp"
|
||||
|
||||
#include "ParticipantCore.hpp"
|
||||
// #include "ParticipantDeviceList.hpp"
|
||||
#include "model/participant/ParticipantModel.hpp"
|
||||
#include "tool/Utils.hpp"
|
||||
|
||||
// =============================================================================
|
||||
|
||||
DEFINE_ABSTRACT_OBJECT(ParticipantCore)
|
||||
|
||||
QSharedPointer<ParticipantCore> ParticipantCore::create(const std::shared_ptr<linphone::Participant> &participant) {
|
||||
auto sharedPointer = QSharedPointer<ParticipantCore>(new ParticipantCore(participant), &QObject::deleteLater);
|
||||
sharedPointer->setSelf(sharedPointer);
|
||||
sharedPointer->moveToThread(App::getInstance()->thread());
|
||||
return sharedPointer;
|
||||
}
|
||||
|
||||
ParticipantCore::ParticipantCore(const std::shared_ptr<linphone::Participant> &participant) : QObject(nullptr) {
|
||||
App::getInstance()->mEngine->setObjectOwnership(this, QQmlEngine::CppOwnership);
|
||||
mParticipantModel = Utils::makeQObject_ptr<ParticipantModel>(participant);
|
||||
mAdminStatus = participant->isAdmin();
|
||||
mSipAddress = Utils::coreStringToAppString(participant->getAddress()->asStringUriOnly());
|
||||
mCreationTime = QDateTime::fromSecsSinceEpoch(participant->getCreationTime());
|
||||
mDisplayName = Utils::coreStringToAppString(participant->getAddress()->getDisplayName());
|
||||
if (mDisplayName.isEmpty()) mDisplayName = Utils::coreStringToAppString(participant->getAddress()->getUsername());
|
||||
for (auto &device : participant->getDevices()) {
|
||||
auto name = Utils::coreStringToAppString(device->getName());
|
||||
auto address = Utils::coreStringToAppString(device->getAddress()->asStringUriOnly());
|
||||
QVariantMap map;
|
||||
map.insert("name", name);
|
||||
map.insert("address", address);
|
||||
mParticipantDevices.append(map);
|
||||
}
|
||||
// App::getInstance()->mEngine->setObjectOwnership(mParticipantDevices.get(),
|
||||
// QQmlEngine::CppOwnership); // Managed by QSharedPointer
|
||||
// connect(this, &ParticipantCore::deviceSecurityLevelChanged, mParticipantDevices.get(),
|
||||
// &ParticipantDeviceListModel::securityLevelChanged);
|
||||
}
|
||||
|
||||
ParticipantCore::~ParticipantCore() {
|
||||
mustBeInMainThread("~" + getClassName());
|
||||
}
|
||||
|
||||
void ParticipantCore::setSelf(QSharedPointer<ParticipantCore> me) {
|
||||
mParticipantConnection = QSharedPointer<SafeConnection<ParticipantCore, ParticipantModel>>(
|
||||
new SafeConnection<ParticipantCore, ParticipantModel>(me, mParticipantModel), &QObject::deleteLater);
|
||||
mParticipantConnection->makeConnectToCore(&ParticipantCore::lStartInvitation, [this](const int &secs) {
|
||||
QTimer::singleShot(secs * 1000, this, &ParticipantCore::onEndOfInvitation);
|
||||
});
|
||||
// mParticipantConnection->makeConnectToModel(&ParticipantModel::)
|
||||
}
|
||||
|
||||
// FriendCore *ParticipantCore::getFriendCore() const {
|
||||
// return nullptr;
|
||||
// // return CoreModel::getInstance()->getContactsListModel()->findContactModelFromSipAddress(getSipAddress()).get();
|
||||
// }
|
||||
|
||||
int ParticipantCore::getSecurityLevel() const {
|
||||
return mSecurityLevel;
|
||||
}
|
||||
|
||||
int ParticipantCore::getDeviceCount() const {
|
||||
return mParticipantDevices.size();
|
||||
}
|
||||
|
||||
bool ParticipantCore::isMe() const {
|
||||
return true; // Utils::isMe(getSipAddress());
|
||||
}
|
||||
|
||||
QString ParticipantCore::getSipAddress() const {
|
||||
return mSipAddress;
|
||||
}
|
||||
void ParticipantCore::setSipAddress(const QString &address) {
|
||||
if (mSipAddress != address) {
|
||||
mSipAddress = address;
|
||||
emit sipAddressChanged();
|
||||
}
|
||||
}
|
||||
|
||||
void ParticipantCore::setDisplayName(const QString &name) {
|
||||
if (mDisplayName != name) {
|
||||
mDisplayName = name;
|
||||
emit displayNameChanged();
|
||||
}
|
||||
}
|
||||
|
||||
QString ParticipantCore::getDisplayName() const {
|
||||
return mDisplayName;
|
||||
}
|
||||
|
||||
QDateTime ParticipantCore::getCreationTime() const {
|
||||
return mCreationTime;
|
||||
}
|
||||
void ParticipantCore::setCreationTime(const QDateTime &date) {
|
||||
if (date != mCreationTime) {
|
||||
mCreationTime = date;
|
||||
emit creationTimeChanged();
|
||||
}
|
||||
}
|
||||
|
||||
bool ParticipantCore::getAdminStatus() const {
|
||||
return mAdminStatus;
|
||||
}
|
||||
|
||||
bool ParticipantCore::isFocus() const {
|
||||
return mIsFocus;
|
||||
}
|
||||
|
||||
void ParticipantCore::setAdminStatus(const bool &status) {
|
||||
if (status != mAdminStatus) {
|
||||
mAdminStatus = status;
|
||||
emit adminStatusChanged();
|
||||
}
|
||||
}
|
||||
|
||||
void ParticipantCore::setIsFocus(const bool &focus) {
|
||||
if (focus != mIsFocus) {
|
||||
mIsFocus = focus;
|
||||
emit isFocusChanged();
|
||||
}
|
||||
}
|
||||
|
||||
void ParticipantCore::setSecurityLevel(int level) {
|
||||
if (level != mSecurityLevel) {
|
||||
mSecurityLevel = level;
|
||||
emit securityLevelChanged();
|
||||
}
|
||||
}
|
||||
|
||||
void ParticipantCore::onSecurityLevelChanged() {
|
||||
emit securityLevelChanged();
|
||||
}
|
||||
void ParticipantCore::onDeviceSecurityLevelChanged(std::shared_ptr<const linphone::Address> device) {
|
||||
emit deviceSecurityLevelChanged(device);
|
||||
}
|
||||
|
||||
// ParticipantDeviceProxyModel *ParticipantCore::getProxyDevices() {
|
||||
// ParticipantDeviceProxyModel *devices = new ParticipantDeviceProxyModel();
|
||||
// devices->setParticipant(this);
|
||||
// return devices;
|
||||
// }
|
||||
|
||||
QList<QVariant> ParticipantCore::getParticipantDevices() {
|
||||
return mParticipantDevices;
|
||||
}
|
||||
|
||||
void ParticipantCore::onEndOfInvitation() {
|
||||
emit invitationTimeout(this);
|
||||
}
|
||||
126
Linphone/core/participant/ParticipantCore.hpp
Normal file
126
Linphone/core/participant/ParticipantCore.hpp
Normal file
|
|
@ -0,0 +1,126 @@
|
|||
/*
|
||||
* 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 <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef PARTICIPANT_CORE_H_
|
||||
#define PARTICIPANT_CORE_H_
|
||||
|
||||
#include "tool/thread/SafeConnection.hpp"
|
||||
#include <linphone++/linphone.hh>
|
||||
|
||||
#include <QDateTime>
|
||||
#include <QMap>
|
||||
#include <QObject>
|
||||
#include <QSharedPointer>
|
||||
#include <QString>
|
||||
|
||||
class FriendCore;
|
||||
class ParticipantDeviceProxy;
|
||||
class ParticipantDeviceList;
|
||||
class ParticipantModel;
|
||||
|
||||
class ParticipantCore : public QObject, public AbstractObject {
|
||||
Q_OBJECT
|
||||
|
||||
// Q_PROPERTY(FriendCore *friendCore READ getFriendCore CONSTANT)
|
||||
Q_PROPERTY(QString sipAddress READ getSipAddress WRITE setSipAddress NOTIFY sipAddressChanged)
|
||||
Q_PROPERTY(QString displayName READ getDisplayName WRITE setDisplayName NOTIFY displayNameChanged)
|
||||
Q_PROPERTY(bool adminStatus READ getAdminStatus WRITE setAdminStatus NOTIFY adminStatusChanged)
|
||||
Q_PROPERTY(bool isMe READ isMe CONSTANT)
|
||||
Q_PROPERTY(QDateTime creationTime READ getCreationTime CONSTANT)
|
||||
Q_PROPERTY(bool focus READ isFocus CONSTANT)
|
||||
Q_PROPERTY(int securityLevel READ getSecurityLevel NOTIFY securityLevelChanged)
|
||||
Q_PROPERTY(int deviceCount READ getDeviceCount NOTIFY deviceCountChanged)
|
||||
Q_PROPERTY(QList<QVariant> devices READ getParticipantDevices NOTIFY deviceChanged)
|
||||
|
||||
// Q_PROPERTY(bool inviting READ getInviting NOTIFY invitingChanged)
|
||||
|
||||
public:
|
||||
static QSharedPointer<ParticipantCore> create(const std::shared_ptr<linphone::Participant> &participant);
|
||||
ParticipantCore(const std::shared_ptr<linphone::Participant> &participant);
|
||||
~ParticipantCore();
|
||||
|
||||
void setSelf(QSharedPointer<ParticipantCore> me);
|
||||
|
||||
// FriendCore *getFriendCore() const;
|
||||
QString getDisplayName() const;
|
||||
QString getSipAddress() const;
|
||||
QDateTime getCreationTime() const;
|
||||
bool getAdminStatus() const;
|
||||
bool isFocus() const;
|
||||
int getSecurityLevel() const;
|
||||
int getDeviceCount() const;
|
||||
|
||||
bool isMe() const;
|
||||
|
||||
void setSipAddress(const QString &address);
|
||||
void setDisplayName(const QString &name);
|
||||
void setCreationTime(const QDateTime &date);
|
||||
void setAdminStatus(const bool &status);
|
||||
void setIsFocus(const bool &focus);
|
||||
void setSecurityLevel(int level);
|
||||
|
||||
// Q_INVOKABLE ParticipantDeviceProxy *getProxyDevices();
|
||||
QList<QVariant> getParticipantDevices();
|
||||
|
||||
public slots:
|
||||
void onSecurityLevelChanged();
|
||||
void onDeviceSecurityLevelChanged(std::shared_ptr<const linphone::Address> device);
|
||||
void onEndOfInvitation();
|
||||
|
||||
signals:
|
||||
void securityLevelChanged();
|
||||
void deviceSecurityLevelChanged(std::shared_ptr<const linphone::Address> device);
|
||||
void sipAddressChanged();
|
||||
void updateAdminStatus(
|
||||
const std::shared_ptr<linphone::Participant> participant,
|
||||
const bool &isAdmin); // Split in two signals in order to sequancialize execution between SDK and GUI
|
||||
void adminStatusChanged();
|
||||
void isFocusChanged();
|
||||
void deviceCountChanged();
|
||||
void invitingChanged();
|
||||
void creationTimeChanged();
|
||||
void displayNameChanged();
|
||||
|
||||
void lStartInvitation(const int &secs);
|
||||
|
||||
void invitationTimeout(ParticipantCore *model);
|
||||
|
||||
void deviceChanged();
|
||||
|
||||
private:
|
||||
std::shared_ptr<ParticipantModel> mParticipantModel;
|
||||
QSharedPointer<SafeConnection<ParticipantCore, ParticipantModel>> mParticipantConnection;
|
||||
|
||||
// QSharedPointer<ParticipantDeviceList> mParticipantDevices;
|
||||
QList<QVariant> mParticipantDevices;
|
||||
|
||||
QString mDisplayName;
|
||||
QString mSipAddress;
|
||||
QDateTime mCreationTime;
|
||||
bool mAdminStatus;
|
||||
bool mIsFocus;
|
||||
int mSecurityLevel;
|
||||
|
||||
DECLARE_ABSTRACT_OBJECT
|
||||
};
|
||||
|
||||
Q_DECLARE_METATYPE(QSharedPointer<ParticipantCore>);
|
||||
|
||||
#endif // PARTICIPANT_CORE_H_
|
||||
250
Linphone/core/participant/ParticipantDeviceCore.cpp
Normal file
250
Linphone/core/participant/ParticipantDeviceCore.cpp
Normal file
|
|
@ -0,0 +1,250 @@
|
|||
/*
|
||||
* 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 <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "ParticipantDeviceCore.hpp"
|
||||
#include "core/App.hpp"
|
||||
#include "tool/Utils.hpp"
|
||||
#include <QQmlApplicationEngine>
|
||||
|
||||
DEFINE_ABSTRACT_OBJECT(ParticipantDeviceCore)
|
||||
|
||||
QSharedPointer<ParticipantDeviceCore>
|
||||
ParticipantDeviceCore::create(std::shared_ptr<linphone::ParticipantDevice> device, const bool &isMe, QObject *parent) {
|
||||
auto sharedPointer =
|
||||
QSharedPointer<ParticipantDeviceCore>(new ParticipantDeviceCore(device, isMe, parent), &QObject::deleteLater);
|
||||
sharedPointer->setSelf(sharedPointer);
|
||||
sharedPointer->moveToThread(App::getInstance()->thread());
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
ParticipantDeviceCore::ParticipantDeviceCore(const std::shared_ptr<linphone::ParticipantDevice> &device,
|
||||
const bool &isMe,
|
||||
QObject *parent)
|
||||
: QObject(parent) {
|
||||
App::getInstance()->mEngine->setObjectOwnership(this, QQmlEngine::CppOwnership);
|
||||
mustBeInLinphoneThread(getClassName());
|
||||
mName = Utils::coreStringToAppString(device->getName());
|
||||
mDisplayName = Utils::coreStringToAppString(device->getAddress()->getDisplayName());
|
||||
mAddress = Utils::coreStringToAppString(device->getAddress()->asStringUriOnly());
|
||||
mIsMuted = device->getIsMuted();
|
||||
mIsMe = isMe;
|
||||
mParticipantDeviceModel = Utils::makeQObject_ptr<ParticipantDeviceModel>(device);
|
||||
mParticipantDeviceModel->setSelf(mParticipantDeviceModel);
|
||||
mState = LinphoneEnums::fromLinphone(device->getState());
|
||||
// mCall = callModel;
|
||||
// if (mCall) connect(mCall, &CallModel::statusChanged, this, &ParticipantDeviceCore::onCallStatusChanged);
|
||||
mIsVideoEnabled = mParticipantDeviceModel->isVideoEnabled();
|
||||
// if (mCall && mParticipantDeviceModel) updateIsLocal();
|
||||
}
|
||||
|
||||
ParticipantDeviceCore::~ParticipantDeviceCore() {
|
||||
mParticipantDeviceModel->removeListener();
|
||||
}
|
||||
|
||||
void ParticipantDeviceCore::setSelf(QSharedPointer<ParticipantDeviceCore> me) {
|
||||
mParticipantDeviceModelConnection = QSharedPointer<SafeConnection<ParticipantDeviceCore, ParticipantDeviceModel>>(
|
||||
new SafeConnection<ParticipantDeviceCore, ParticipantDeviceModel>(me, mParticipantDeviceModel),
|
||||
&QObject::deleteLater);
|
||||
mParticipantDeviceModelConnection->makeConnectToModel(
|
||||
&ParticipantDeviceModel::isPausedChanged, [this](bool paused) {
|
||||
mParticipantDeviceModelConnection->invokeToCore([this, paused] { setPaused(paused); });
|
||||
});
|
||||
mParticipantDeviceModelConnection->makeConnectToModel(
|
||||
&ParticipantDeviceModel::isSpeakingChanged, [this](bool speaking) {
|
||||
mParticipantDeviceModelConnection->invokeToCore([this, speaking] { setIsSpeaking(speaking); });
|
||||
});
|
||||
mParticipantDeviceModelConnection->makeConnectToModel(&ParticipantDeviceModel::isMutedChanged, [this](bool muted) {
|
||||
mParticipantDeviceModelConnection->invokeToCore([this, muted] { setIsMuted(muted); });
|
||||
});
|
||||
mParticipantDeviceModelConnection->makeConnectToModel(
|
||||
&ParticipantDeviceModel::stateChanged, [this](LinphoneEnums::ParticipantDeviceState state) {
|
||||
mParticipantDeviceModelConnection->invokeToCore([this, state] { setState(state); });
|
||||
});
|
||||
mParticipantDeviceModelConnection->makeConnectToModel(
|
||||
&ParticipantDeviceModel::streamCapabilityChanged, [this](linphone::StreamType) {
|
||||
auto videoEnabled = mParticipantDeviceModel->isVideoEnabled();
|
||||
mParticipantDeviceModelConnection->invokeToCore([this, videoEnabled] { setIsVideoEnabled(videoEnabled); });
|
||||
});
|
||||
mParticipantDeviceModelConnection->makeConnectToModel(
|
||||
&ParticipantDeviceModel::streamAvailabilityChanged, [this](linphone::StreamType) {
|
||||
auto videoEnabled = mParticipantDeviceModel->isVideoEnabled();
|
||||
mParticipantDeviceModelConnection->invokeToCore([this, videoEnabled] { setIsVideoEnabled(videoEnabled); });
|
||||
});
|
||||
}
|
||||
|
||||
QString ParticipantDeviceCore::getName() const {
|
||||
return mName;
|
||||
}
|
||||
|
||||
QString ParticipantDeviceCore::getDisplayName() const {
|
||||
return mDisplayName;
|
||||
}
|
||||
|
||||
int ParticipantDeviceCore::getSecurityLevel() const {
|
||||
if (mParticipantDeviceModel) {
|
||||
int security = (int)mParticipantDeviceModel->getSecurityLevel();
|
||||
return security;
|
||||
} else return 0;
|
||||
}
|
||||
|
||||
time_t ParticipantDeviceCore::getTimeOfJoining() const {
|
||||
return mParticipantDeviceModel ? mParticipantDeviceModel->getTimeOfJoining() : 0;
|
||||
}
|
||||
|
||||
QString ParticipantDeviceCore::getAddress() const {
|
||||
return mAddress;
|
||||
}
|
||||
|
||||
bool ParticipantDeviceCore::getPaused() const {
|
||||
return mIsPaused;
|
||||
}
|
||||
|
||||
bool ParticipantDeviceCore::getIsSpeaking() const {
|
||||
return mIsSpeaking;
|
||||
}
|
||||
|
||||
bool ParticipantDeviceCore::getIsMuted() const {
|
||||
return mIsMuted;
|
||||
}
|
||||
|
||||
LinphoneEnums::ParticipantDeviceState ParticipantDeviceCore::getState() const {
|
||||
return mState;
|
||||
}
|
||||
|
||||
bool ParticipantDeviceCore::isVideoEnabled() const {
|
||||
return mIsVideoEnabled;
|
||||
}
|
||||
|
||||
void ParticipantDeviceCore::setPaused(bool paused) {
|
||||
if (mIsPaused != paused) {
|
||||
mIsPaused = paused;
|
||||
emit isPausedChanged();
|
||||
}
|
||||
}
|
||||
|
||||
void ParticipantDeviceCore::setIsSpeaking(bool speaking) {
|
||||
if (mIsSpeaking != speaking) {
|
||||
mIsSpeaking = speaking;
|
||||
emit isSpeakingChanged();
|
||||
}
|
||||
}
|
||||
|
||||
void ParticipantDeviceCore::setIsMuted(bool muted) {
|
||||
if (mIsMuted != muted) {
|
||||
mIsMuted = muted;
|
||||
emit isMutedChanged();
|
||||
}
|
||||
}
|
||||
|
||||
void ParticipantDeviceCore::setIsLocal(bool local) {
|
||||
if (mIsLocal != local) {
|
||||
mIsLocal = local;
|
||||
emit isLocalChanged();
|
||||
}
|
||||
}
|
||||
|
||||
void ParticipantDeviceCore::setState(LinphoneEnums::ParticipantDeviceState state) {
|
||||
if (mState != state) {
|
||||
mState = state;
|
||||
emit stateChanged();
|
||||
}
|
||||
}
|
||||
|
||||
void ParticipantDeviceCore::setIsVideoEnabled(bool enabled) {
|
||||
if (mIsVideoEnabled != enabled) {
|
||||
mIsVideoEnabled = enabled;
|
||||
emit videoEnabledChanged();
|
||||
}
|
||||
}
|
||||
|
||||
bool ParticipantDeviceCore::isMe() const {
|
||||
return mIsMe;
|
||||
}
|
||||
|
||||
bool ParticipantDeviceCore::isLocal() const {
|
||||
return mIsLocal;
|
||||
}
|
||||
|
||||
// void ParticipantDeviceCore::updateIsLocal() {
|
||||
// auto deviceAddress = mParticipantDeviceModel->getAddress();
|
||||
// auto callAddress = mCall->getConferenceSharedModel()->getConference()->getMe()->getAddress();
|
||||
// auto gruuAddress =
|
||||
// CoreManager::getInstance()->getAccountSettingsModel()->findAccount(callAddress)->getContactAddress();
|
||||
// setIsLocal(deviceAddress->equal(gruuAddress));
|
||||
// }
|
||||
|
||||
// void ParticipantDeviceCore::onSecurityLevelChanged(std::shared_ptr<const linphone::Address> device) {
|
||||
// if (!device || mParticipantDeviceModel && mParticipantDeviceModel->getAddress()->weakEqual(device))
|
||||
// emit securityLevelChanged();
|
||||
// }
|
||||
|
||||
// void ParticipantDeviceCore::onCallStatusChanged() {
|
||||
// if (mCall->getCall()->getState() == linphone::Call::State::StreamsRunning) {
|
||||
// updateVideoEnabled();
|
||||
// }
|
||||
// }
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
void ParticipantDeviceCore::onIsSpeakingChanged(const std::shared_ptr<linphone::ParticipantDevice> &participantDevice,
|
||||
bool isSpeaking) {
|
||||
setIsSpeaking(isSpeaking);
|
||||
}
|
||||
void ParticipantDeviceCore::onIsMuted(const std::shared_ptr<linphone::ParticipantDevice> &participantDevice,
|
||||
bool isMuted) {
|
||||
emit isMutedChanged();
|
||||
}
|
||||
void ParticipantDeviceCore::onStateChanged(const std::shared_ptr<linphone::ParticipantDevice> &participantDevice,
|
||||
linphone::ParticipantDevice::State state) {
|
||||
switch (state) {
|
||||
case linphone::ParticipantDevice::State::Joining:
|
||||
break;
|
||||
case linphone::ParticipantDevice::State::Present:
|
||||
setPaused(false);
|
||||
break;
|
||||
case linphone::ParticipantDevice::State::Leaving:
|
||||
break;
|
||||
case linphone::ParticipantDevice::State::Left:
|
||||
break;
|
||||
case linphone::ParticipantDevice::State::ScheduledForJoining:
|
||||
break;
|
||||
case linphone::ParticipantDevice::State::ScheduledForLeaving:
|
||||
break;
|
||||
case linphone::ParticipantDevice::State::OnHold:
|
||||
setPaused(true);
|
||||
break;
|
||||
case linphone::ParticipantDevice::State::Alerting:
|
||||
break;
|
||||
case linphone::ParticipantDevice::State::MutedByFocus:
|
||||
break;
|
||||
default: {
|
||||
}
|
||||
}
|
||||
setState(LinphoneEnums::fromLinphone(state));
|
||||
}
|
||||
void ParticipantDeviceCore::onStreamCapabilityChanged(
|
||||
const std::shared_ptr<linphone::ParticipantDevice> &participantDevice,
|
||||
linphone::MediaDirection direction,
|
||||
linphone::StreamType streamType) {
|
||||
}
|
||||
void ParticipantDeviceCore::onStreamAvailabilityChanged(
|
||||
const std::shared_ptr<linphone::ParticipantDevice> &participantDevice,
|
||||
bool available,
|
||||
linphone::StreamType streamType) {
|
||||
}
|
||||
130
Linphone/core/participant/ParticipantDeviceCore.hpp
Normal file
130
Linphone/core/participant/ParticipantDeviceCore.hpp
Normal file
|
|
@ -0,0 +1,130 @@
|
|||
/*
|
||||
* 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 <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef PARTICIPANT_DEVICE_CORE_H_
|
||||
#define PARTICIPANT_DEVICE_CORE_H_
|
||||
|
||||
#include "model/participant/ParticipantDeviceModel.hpp"
|
||||
#include "tool/LinphoneEnums.hpp"
|
||||
#include "tool/thread/SafeConnection.hpp"
|
||||
#include <linphone++/linphone.hh>
|
||||
|
||||
#include <QDateTime>
|
||||
#include <QObject>
|
||||
#include <QSharedPointer>
|
||||
#include <QString>
|
||||
|
||||
class ParticipantDeviceCore : public QObject, public AbstractObject {
|
||||
Q_OBJECT
|
||||
|
||||
Q_PROPERTY(QString displayName READ getDisplayName CONSTANT)
|
||||
Q_PROPERTY(QString name READ getName CONSTANT)
|
||||
Q_PROPERTY(QString address READ getAddress CONSTANT)
|
||||
Q_PROPERTY(int securityLevel READ getSecurityLevel NOTIFY securityLevelChanged)
|
||||
Q_PROPERTY(time_t timeOfJoining READ getTimeOfJoining CONSTANT)
|
||||
Q_PROPERTY(bool videoEnabled READ isVideoEnabled NOTIFY videoEnabledChanged)
|
||||
Q_PROPERTY(bool isMe READ isMe CONSTANT)
|
||||
Q_PROPERTY(bool isLocal READ isLocal WRITE setIsLocal NOTIFY
|
||||
isLocalChanged) // Can change on call update. Not really used but it just in case as Object can be
|
||||
// initialized with empty call/device.
|
||||
Q_PROPERTY(bool isPaused READ getPaused WRITE setPaused NOTIFY isPausedChanged)
|
||||
Q_PROPERTY(bool isSpeaking READ getIsSpeaking WRITE setIsSpeaking NOTIFY isSpeakingChanged)
|
||||
Q_PROPERTY(bool isMuted READ getIsMuted NOTIFY isMutedChanged)
|
||||
Q_PROPERTY(LinphoneEnums::ParticipantDeviceState state READ getState WRITE setState NOTIFY stateChanged)
|
||||
|
||||
public:
|
||||
// static QSharedPointer<ParticipantDeviceCore> create(const std::shared_ptr<linphone::ParticipantDevice> &device);
|
||||
static QSharedPointer<ParticipantDeviceCore>
|
||||
create(std::shared_ptr<linphone::ParticipantDevice> device, const bool &isMe = false, QObject *parent = nullptr);
|
||||
|
||||
ParticipantDeviceCore(const std::shared_ptr<linphone::ParticipantDevice> &device,
|
||||
const bool &isMe = false,
|
||||
QObject *parent = nullptr);
|
||||
virtual ~ParticipantDeviceCore();
|
||||
void setSelf(QSharedPointer<ParticipantDeviceCore> me);
|
||||
|
||||
QString getName() const;
|
||||
QString getDisplayName() const;
|
||||
QString getAddress() const;
|
||||
int getSecurityLevel() const;
|
||||
time_t getTimeOfJoining() const;
|
||||
bool isVideoEnabled() const;
|
||||
bool isMe() const;
|
||||
bool isLocal() const;
|
||||
bool getPaused() const;
|
||||
bool getIsSpeaking() const;
|
||||
bool getIsMuted() const;
|
||||
LinphoneEnums::ParticipantDeviceState getState() const;
|
||||
|
||||
std::shared_ptr<linphone::ParticipantDevice> getDevice();
|
||||
|
||||
void setPaused(bool paused);
|
||||
void setIsSpeaking(bool speaking);
|
||||
void setIsMuted(bool muted);
|
||||
void setIsLocal(bool local);
|
||||
void setIsVideoEnabled(bool enabled);
|
||||
void setState(LinphoneEnums::ParticipantDeviceState state);
|
||||
|
||||
virtual void onIsSpeakingChanged(const std::shared_ptr<linphone::ParticipantDevice> &participantDevice,
|
||||
bool isSpeaking);
|
||||
virtual void onIsMuted(const std::shared_ptr<linphone::ParticipantDevice> &participantDevice, bool isMuted);
|
||||
virtual void onStateChanged(const std::shared_ptr<linphone::ParticipantDevice> &participantDevice,
|
||||
linphone::ParticipantDevice::State state);
|
||||
virtual void onStreamCapabilityChanged(const std::shared_ptr<linphone::ParticipantDevice> &participantDevice,
|
||||
linphone::MediaDirection direction,
|
||||
linphone::StreamType streamType);
|
||||
virtual void onStreamAvailabilityChanged(const std::shared_ptr<linphone::ParticipantDevice> &participantDevice,
|
||||
bool available,
|
||||
linphone::StreamType streamType);
|
||||
|
||||
// void updateIsLocal();
|
||||
|
||||
// public slots:
|
||||
// void onSecurityLevelChanged(std::shared_ptr<const linphone::Address> device);
|
||||
// void onCallStatusChanged();
|
||||
signals:
|
||||
void securityLevelChanged();
|
||||
void videoEnabledChanged();
|
||||
void isPausedChanged();
|
||||
void isSpeakingChanged();
|
||||
void isMutedChanged();
|
||||
void isLocalChanged();
|
||||
void stateChanged();
|
||||
|
||||
private:
|
||||
QString mName;
|
||||
QString mDisplayName;
|
||||
QString mAddress;
|
||||
bool mIsMe = false;
|
||||
bool mIsLocal = false;
|
||||
bool mIsVideoEnabled;
|
||||
bool mIsMuted = false;
|
||||
bool mIsPaused = false;
|
||||
bool mIsSpeaking = false;
|
||||
LinphoneEnums::ParticipantDeviceState mState;
|
||||
|
||||
std::shared_ptr<ParticipantDeviceModel> mParticipantDeviceModel;
|
||||
QSharedPointer<SafeConnection<ParticipantDeviceCore, ParticipantDeviceModel>> mParticipantDeviceModelConnection;
|
||||
|
||||
DECLARE_ABSTRACT_OBJECT
|
||||
};
|
||||
Q_DECLARE_METATYPE(QSharedPointer<ParticipantDeviceCore>)
|
||||
|
||||
#endif // PARTICIPANT_CORE_H_
|
||||
343
Linphone/core/participant/ParticipantDeviceList.cpp
Normal file
343
Linphone/core/participant/ParticipantDeviceList.cpp
Normal file
|
|
@ -0,0 +1,343 @@
|
|||
/*
|
||||
* 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 <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "ParticipantDeviceList.hpp"
|
||||
#include "core/App.hpp"
|
||||
#include "core/participant/ParticipantCore.hpp"
|
||||
|
||||
#include <QQmlApplicationEngine>
|
||||
#include <algorithm>
|
||||
|
||||
DEFINE_ABSTRACT_OBJECT(ParticipantDeviceList)
|
||||
|
||||
QSharedPointer<ParticipantDeviceList>
|
||||
ParticipantDeviceList::create(const std::shared_ptr<linphone::Participant> &participant) {
|
||||
auto model = QSharedPointer<ParticipantDeviceList>(new ParticipantDeviceList(participant), &QObject::deleteLater);
|
||||
model->moveToThread(App::getInstance()->thread());
|
||||
model->setSelf(model);
|
||||
return model;
|
||||
}
|
||||
|
||||
QSharedPointer<ParticipantDeviceList> ParticipantDeviceList::create() {
|
||||
auto model = QSharedPointer<ParticipantDeviceList>(new ParticipantDeviceList(), &QObject::deleteLater);
|
||||
model->moveToThread(App::getInstance()->thread());
|
||||
model->setSelf(model);
|
||||
return model;
|
||||
}
|
||||
|
||||
ParticipantDeviceList::ParticipantDeviceList(const std::shared_ptr<linphone::Participant> &participant, QObject *parent)
|
||||
: ListProxy(parent) {
|
||||
std::list<std::shared_ptr<linphone::ParticipantDevice>> devices = participant->getDevices();
|
||||
for (auto device : devices) {
|
||||
auto deviceModel = ParticipantDeviceCore::create(device, isMe(device));
|
||||
// connect(this, &ParticipantDeviceList::securityLevelChanged, deviceModel.get(),
|
||||
// &ParticipantDeviceCore::onSecurityLevelChanged);
|
||||
connect(deviceModel.get(), &ParticipantDeviceCore::isSpeakingChanged, this,
|
||||
&ParticipantDeviceList::onParticipantDeviceSpeaking);
|
||||
mList << deviceModel;
|
||||
}
|
||||
mInitialized = true;
|
||||
}
|
||||
|
||||
ParticipantDeviceList::ParticipantDeviceList(QObject *parent) {
|
||||
mustBeInMainThread(getClassName());
|
||||
}
|
||||
|
||||
// ParticipantDeviceList::ParticipantDeviceList(CallModel *callModel, QObject *parent) : ProxyListModel(parent) {
|
||||
// if (callModel && callModel->isConference()) {
|
||||
// mCallModel = callModel;
|
||||
// connect(mCallModel, &CallModel::conferenceModelChanged, this, &ParticipantDeviceList::onConferenceModelChanged);
|
||||
// initConferenceModel();
|
||||
// }
|
||||
// }
|
||||
|
||||
ParticipantDeviceList::~ParticipantDeviceList() {
|
||||
mustBeInMainThread(getClassName());
|
||||
}
|
||||
|
||||
void ParticipantDeviceList::setSelf(QSharedPointer<ParticipantDeviceList> me) {
|
||||
}
|
||||
|
||||
void ParticipantDeviceList::initConferenceModel() {
|
||||
// if (!mInitialized && mCallModel) {
|
||||
// auto conferenceModel = mCallModel->getConferenceSharedModel();
|
||||
// if (conferenceModel) {
|
||||
// updateDevices(conferenceModel->getConference()->getMe()->getDevices(), true);
|
||||
// updateDevices(conferenceModel->getConference()->getParticipantDeviceList(), false);
|
||||
|
||||
// qDebug() << "Conference have " << mList.size() << " devices";
|
||||
// connect(conferenceModel.get(), &ConferenceModel::activeSpeakerParticipantDevice, this,
|
||||
// &ParticipantDeviceList::onActiveSpeakerParticipantDevice);
|
||||
// connect(conferenceModel.get(), &ConferenceModel::participantAdded, this,
|
||||
// &ParticipantDeviceList::onParticipantAdded);
|
||||
// connect(conferenceModel.get(), &ConferenceModel::participantRemoved, this,
|
||||
// &ParticipantDeviceList::onParticipantRemoved);
|
||||
// connect(conferenceModel.get(), &ConferenceModel::participantDeviceAdded, this,
|
||||
// &ParticipantDeviceList::onParticipantDeviceAdded);
|
||||
// connect(conferenceModel.get(), &ConferenceModel::participantDeviceRemoved, this,
|
||||
// &ParticipantDeviceList::onParticipantDeviceRemoved);
|
||||
// connect(conferenceModel.get(), &ConferenceModel::conferenceStateChanged, this,
|
||||
// &ParticipantDeviceList::onConferenceStateChanged);
|
||||
// connect(conferenceModel.get(), &ConferenceModel::participantDeviceMediaCapabilityChanged, this,
|
||||
// &ParticipantDeviceList::onParticipantDeviceMediaCapabilityChanged);
|
||||
// connect(conferenceModel.get(), &ConferenceModel::participantDeviceMediaAvailabilityChanged, this,
|
||||
// &ParticipantDeviceList::onParticipantDeviceMediaAvailabilityChanged);
|
||||
// connect(conferenceModel.get(), &ConferenceModel::participantDeviceIsSpeakingChanged, this,
|
||||
// &ParticipantDeviceList::onParticipantDeviceIsSpeakingChanged);
|
||||
// mActiveSpeaker = get(conferenceModel->getConference()->getActiveSpeakerParticipantDevice());
|
||||
// mInitialized = true;
|
||||
// }
|
||||
// }
|
||||
}
|
||||
|
||||
void ParticipantDeviceList::updateDevices(std::shared_ptr<linphone::Participant> participant) {
|
||||
std::list<std::shared_ptr<linphone::ParticipantDevice>> devices = participant->getDevices();
|
||||
bool meAdded = false;
|
||||
beginResetModel();
|
||||
qDebug() << "Update devices from participant";
|
||||
mList.clear();
|
||||
for (auto device : devices) {
|
||||
bool addMe = isMe(device);
|
||||
auto deviceModel = ParticipantDeviceCore::create(device, addMe);
|
||||
// connect(this, &ParticipantDeviceList::securityLevelChanged, deviceModel.get(),
|
||||
// &ParticipantDeviceCore::onSecurityLevelChanged);
|
||||
connect(deviceModel.get(), &ParticipantDeviceCore::isSpeakingChanged, this,
|
||||
&ParticipantDeviceList::onParticipantDeviceSpeaking);
|
||||
mList << deviceModel;
|
||||
if (addMe) meAdded = true;
|
||||
}
|
||||
endResetModel();
|
||||
if (meAdded) emit meChanged();
|
||||
}
|
||||
|
||||
void ParticipantDeviceList::updateDevices(const std::list<QSharedPointer<ParticipantDeviceCore>> &devices,
|
||||
const bool &isMe) {
|
||||
for (auto device : devices) {
|
||||
add(device);
|
||||
}
|
||||
}
|
||||
|
||||
bool ParticipantDeviceList::add(const QSharedPointer<ParticipantDeviceCore> &deviceToAdd) {
|
||||
auto deviceToAddAddr = deviceToAdd->getAddress();
|
||||
int row = 0;
|
||||
qDebug() << "Adding device " << deviceToAdd->getAddress();
|
||||
for (auto item : mList) {
|
||||
auto deviceCore = item.objectCast<ParticipantDeviceCore>();
|
||||
if (deviceCore == deviceToAdd) {
|
||||
qDebug() << "Device already exist. Send video update event";
|
||||
// deviceCore->updateVideoEnabled();
|
||||
return false;
|
||||
} else if (deviceToAddAddr == deviceCore->getAddress()) { // Address is the same (same device) but the model
|
||||
// is using another linphone object. Replace it.
|
||||
qDebug() << "Replacing device : Device exists but the model is using another linphone object.";
|
||||
// deviceCore->updateVideoEnabled();
|
||||
removeRow(row);
|
||||
break;
|
||||
}
|
||||
++row;
|
||||
}
|
||||
bool addMe = isMe(deviceToAdd);
|
||||
auto deviceModel = ParticipantDeviceCore::create(deviceToAdd, addMe);
|
||||
// connect(this, &ParticipantDeviceList::securityLevelChanged, deviceModel.get(),
|
||||
// &ParticipantDeviceCore::onSecurityLevelChanged);
|
||||
connect(deviceModel.get(), &ParticipantDeviceCore::isSpeakingChanged, this,
|
||||
&ParticipantDeviceList::onParticipantDeviceSpeaking);
|
||||
ListProxy::add<ParticipantDeviceCore>(deviceModel);
|
||||
qDebug() << "Device added. Count=" << mList.count();
|
||||
QStringList debugDevices;
|
||||
for (auto i : mList) {
|
||||
auto item = i.objectCast<ParticipantDeviceCore>();
|
||||
debugDevices.push_back(item->getAddress());
|
||||
}
|
||||
qDebug() << debugDevices.join("\n");
|
||||
if (addMe) {
|
||||
qDebug() << "Added a me device";
|
||||
emit meChanged();
|
||||
} else if (mList.size() == 1 ||
|
||||
(mList.size() == 2 && isMe(mList.front().objectCast<ParticipantDeviceCore>()->getDevice()))) {
|
||||
mActiveSpeaker = mList.back().objectCast<ParticipantDeviceCore>();
|
||||
emit activeSpeakerChanged();
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool ParticipantDeviceList::remove(std::shared_ptr<const linphone::ParticipantDevice> deviceToRemove) {
|
||||
int row = 0;
|
||||
for (auto item : mList) {
|
||||
auto device = item.objectCast<ParticipantDeviceCore>();
|
||||
if (device->getDevice() == deviceToRemove) {
|
||||
// device->updateVideoEnabled();
|
||||
removeRow(row);
|
||||
return true;
|
||||
} else ++row;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
QSharedPointer<ParticipantDeviceCore>
|
||||
ParticipantDeviceList::get(std::shared_ptr<const linphone::ParticipantDevice> deviceToGet, int *index) {
|
||||
int row = 0;
|
||||
for (auto item : mList) {
|
||||
auto device = item.objectCast<ParticipantDeviceCore>();
|
||||
if (device->getDevice() == deviceToGet) {
|
||||
if (index) *index = row;
|
||||
return device;
|
||||
} else ++row;
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
QSharedPointer<ParticipantDeviceCore> ParticipantDeviceList::getMe(int *index) const {
|
||||
int row = 0;
|
||||
for (auto item : mList) {
|
||||
auto device = item.objectCast<ParticipantDeviceCore>();
|
||||
if (device->isMe() && device->isLocal()) {
|
||||
if (index) *index = row;
|
||||
return device;
|
||||
} else ++row;
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
ParticipantDeviceCore *ParticipantDeviceList::getActiveSpeakerModel() const {
|
||||
return mActiveSpeaker.get();
|
||||
}
|
||||
|
||||
bool ParticipantDeviceList::isMe(std::shared_ptr<linphone::ParticipantDevice> deviceToCheck) const {
|
||||
// if (mCallModel) {
|
||||
// auto devices = mCallModel->getConferenceSharedModel()->getConference()->getMe()->getDevices();
|
||||
// auto deviceToCheckAddress = deviceToCheck->getAddress();
|
||||
// for (auto device : devices) {
|
||||
// if (deviceToCheckAddress == device->getAddress()) return true;
|
||||
// }
|
||||
// }
|
||||
return false;
|
||||
}
|
||||
|
||||
bool ParticipantDeviceList::isMeAlone() const {
|
||||
for (auto item : mList) {
|
||||
auto device = item.objectCast<ParticipantDeviceCore>();
|
||||
if (!isMe(device->getDevice())) return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
void ParticipantDeviceList::onConferenceModelChanged() {
|
||||
if (!mInitialized) {
|
||||
initConferenceModel();
|
||||
}
|
||||
}
|
||||
|
||||
void ParticipantDeviceList::onSecurityLevelChanged(std::shared_ptr<const linphone::Address> device) {
|
||||
emit securityLevelChanged(device);
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------------------------------------
|
||||
void ParticipantDeviceList::onParticipantAdded(const std::shared_ptr<const linphone::Participant> &participant) {
|
||||
std::list<std::shared_ptr<linphone::ParticipantDevice>> devices = participant->getDevices();
|
||||
if (devices.size() == 0)
|
||||
qDebug() << "Participant has no device. It will not be added : "
|
||||
<< participant->getAddress()->asString().c_str();
|
||||
else
|
||||
for (auto device : devices)
|
||||
add(device);
|
||||
}
|
||||
|
||||
void ParticipantDeviceList::onParticipantRemoved(const std::shared_ptr<const linphone::Participant> &participant) {
|
||||
std::list<std::shared_ptr<linphone::ParticipantDevice>> devices = participant->getDevices();
|
||||
for (auto device : devices)
|
||||
remove(device);
|
||||
}
|
||||
|
||||
void ParticipantDeviceList::onParticipantDeviceAdded(
|
||||
const std::shared_ptr<const linphone::ParticipantDevice> &participantDevice) {
|
||||
qDebug() << "Adding new device : " << mList.count();
|
||||
// auto conferenceModel = mCallModel->getConferenceSharedModel();
|
||||
std::list<std::shared_ptr<linphone::ParticipantDevice>> devices;
|
||||
for (int i = 0; i < 2; ++i) {
|
||||
// if (i == 0) devices = conferenceModel->getConference()->getParticipantDeviceList(); // Active devices.
|
||||
// else devices = conferenceModel->getConference()->getMe()->getDevices();
|
||||
for (auto realParticipantDevice : devices) {
|
||||
if (realParticipantDevice == participantDevice) {
|
||||
add(realParticipantDevice);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
qDebug() << "No participant device found from linphone::ParticipantDevice at onParticipantDeviceAdded";
|
||||
}
|
||||
|
||||
void ParticipantDeviceList::onParticipantDeviceRemoved(
|
||||
const std::shared_ptr<const linphone::ParticipantDevice> &participantDevice) {
|
||||
qDebug() << "Removing participant device : " << mList.count();
|
||||
if (!remove(participantDevice))
|
||||
qDebug() << "No participant device found from linphone::ParticipantDevice at onParticipantDeviceRemoved";
|
||||
}
|
||||
|
||||
void ParticipantDeviceList::onConferenceStateChanged(linphone::Conference::State newState) {
|
||||
// if (newState == linphone::Conference::State::Created) {
|
||||
// if (mCallModel && mCallModel->isConference()) {
|
||||
// auto conferenceModel = mCallModel->getConferenceSharedModel();
|
||||
// updateDevices(conferenceModel->getConference()->getMe()->getDevices(), true);
|
||||
// updateDevices(conferenceModel->getConference()->getParticipantDeviceList(), false);
|
||||
// }
|
||||
// emit conferenceCreated();
|
||||
// }
|
||||
}
|
||||
|
||||
void ParticipantDeviceList::onParticipantDeviceMediaCapabilityChanged(
|
||||
const std::shared_ptr<const linphone::ParticipantDevice> &participantDevice) {
|
||||
// auto device = get(participantDevice);
|
||||
// if (device) device->updateVideoEnabled();
|
||||
// else onParticipantDeviceAdded(participantDevice);
|
||||
|
||||
// device = get(participantDevice);
|
||||
// if (device && device->isMe()) { // Capability change for me. Update all videos.
|
||||
// for (auto item : mList) {
|
||||
// auto device = item.objectCast<ParticipantDeviceCore>();
|
||||
// device->updateVideoEnabled();
|
||||
// }
|
||||
// }
|
||||
}
|
||||
|
||||
void ParticipantDeviceList::onParticipantDeviceMediaAvailabilityChanged(
|
||||
const std::shared_ptr<const linphone::ParticipantDevice> &participantDevice) {
|
||||
// auto device = get(participantDevice);
|
||||
// if (device) device->updateVideoEnabled();
|
||||
// else onParticipantDeviceAdded(participantDevice);
|
||||
}
|
||||
void ParticipantDeviceList::onActiveSpeakerParticipantDevice(
|
||||
const std::shared_ptr<const linphone::ParticipantDevice> &participantDevice) {
|
||||
// auto device = get(participantDevice);
|
||||
// if (device) {
|
||||
// mActiveSpeaker = device;
|
||||
// emit activeSpeakerChanged();
|
||||
// }
|
||||
}
|
||||
|
||||
void ParticipantDeviceList::onParticipantDeviceIsSpeakingChanged(
|
||||
const std::shared_ptr<const linphone::ParticipantDevice> &participantDevice, bool isSpeaking) {
|
||||
auto device = get(participantDevice);
|
||||
if (device) emit participantSpeaking(device.get());
|
||||
}
|
||||
|
||||
void ParticipantDeviceList::onParticipantDeviceSpeaking() {
|
||||
}
|
||||
94
Linphone/core/participant/ParticipantDeviceList.hpp
Normal file
94
Linphone/core/participant/ParticipantDeviceList.hpp
Normal file
|
|
@ -0,0 +1,94 @@
|
|||
/*
|
||||
* 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 <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef PARTICIPANT_DEVICE_LIST_H_
|
||||
#define PARTICIPANT_DEVICE_LIST_H_
|
||||
|
||||
#include "../proxy/ListProxy.hpp"
|
||||
#include "core/call/CallCore.hpp"
|
||||
#include "core/participant/ParticipantDeviceCore.hpp"
|
||||
#include <QDateTime>
|
||||
#include <QObject>
|
||||
#include <QString>
|
||||
|
||||
class ParticipantDeviceList : public ListProxy, public AbstractObject {
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
static QSharedPointer<ParticipantDeviceList> create(const std::shared_ptr<linphone::Participant> &participant);
|
||||
static QSharedPointer<ParticipantDeviceList> create();
|
||||
|
||||
ParticipantDeviceList(const std::shared_ptr<linphone::Participant> &participant, QObject *parent = nullptr);
|
||||
// ParticipantDeviceList(CallCore *callCore, QObject *parent = nullptr);
|
||||
ParticipantDeviceList(QObject *parent = Q_NULLPTR);
|
||||
~ParticipantDeviceList();
|
||||
|
||||
void setSelf(QSharedPointer<ParticipantDeviceList> me);
|
||||
|
||||
void initConferenceModel();
|
||||
void updateDevices(std::shared_ptr<linphone::Participant> participant);
|
||||
void updateDevices(const std::list<QSharedPointer<ParticipantDeviceCore>> &devices, const bool &isMe);
|
||||
|
||||
bool add(const QSharedPointer<ParticipantDeviceCore> &deviceToAdd);
|
||||
bool remove(std::shared_ptr<const linphone::ParticipantDevice> deviceToAdd);
|
||||
QSharedPointer<ParticipantDeviceCore> get(std::shared_ptr<const linphone::ParticipantDevice> deviceToGet,
|
||||
int *index = nullptr);
|
||||
QSharedPointer<ParticipantDeviceCore> getMe(int *index = nullptr) const;
|
||||
ParticipantDeviceCore *getActiveSpeakerModel() const;
|
||||
|
||||
bool isMe(std::shared_ptr<linphone::ParticipantDevice> device) const;
|
||||
bool isMeAlone() const;
|
||||
|
||||
public slots:
|
||||
void onActiveSpeakerParticipantDevice(const std::shared_ptr<const linphone::ParticipantDevice> &participantDevice);
|
||||
void onConferenceModelChanged();
|
||||
void onSecurityLevelChanged(std::shared_ptr<const linphone::Address> device);
|
||||
void onParticipantAdded(const std::shared_ptr<const linphone::Participant> &participant);
|
||||
void onParticipantRemoved(const std::shared_ptr<const linphone::Participant> &participant);
|
||||
void onParticipantDeviceAdded(const std::shared_ptr<const linphone::ParticipantDevice> &participantDevice);
|
||||
void onParticipantDeviceRemoved(const std::shared_ptr<const linphone::ParticipantDevice> &participantDevice);
|
||||
void onConferenceStateChanged(linphone::Conference::State newState);
|
||||
void onParticipantDeviceMediaCapabilityChanged(
|
||||
const std::shared_ptr<const linphone::ParticipantDevice> &participantDevice);
|
||||
void onParticipantDeviceMediaAvailabilityChanged(
|
||||
const std::shared_ptr<const linphone::ParticipantDevice> &participantDevice);
|
||||
void onParticipantDeviceIsSpeakingChanged(const std::shared_ptr<const linphone::ParticipantDevice> &device,
|
||||
bool isSpeaking);
|
||||
void onParticipantDeviceSpeaking();
|
||||
|
||||
signals:
|
||||
void activeSpeakerChanged();
|
||||
void securityLevelChanged(std::shared_ptr<const linphone::Address> device);
|
||||
void participantSpeaking(ParticipantDeviceCore *speakingDevice);
|
||||
void conferenceCreated();
|
||||
void meChanged();
|
||||
|
||||
private:
|
||||
CallCore *mCallCore = nullptr;
|
||||
QSharedPointer<ParticipantDeviceCore> mActiveSpeaker;
|
||||
// QList<ParticipantDeviceCore*> mActiveSpeakers;// First item is last speaker
|
||||
bool mInitialized = false;
|
||||
QSharedPointer<SafeConnection<ParticipantDeviceList, CallModel>> mModelConnection;
|
||||
|
||||
DECLARE_ABSTRACT_OBJECT
|
||||
};
|
||||
Q_DECLARE_METATYPE(QSharedPointer<ParticipantDeviceList>);
|
||||
|
||||
#endif // PARTICIPANT_DEVICE_LIST_H_
|
||||
121
Linphone/core/participant/ParticipantDeviceProxy.cpp
Normal file
121
Linphone/core/participant/ParticipantDeviceProxy.cpp
Normal file
|
|
@ -0,0 +1,121 @@
|
|||
/*
|
||||
* 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 <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "ParticipantDeviceProxy.hpp"
|
||||
#include "ParticipantDeviceList.hpp"
|
||||
#include "core/App.hpp"
|
||||
|
||||
#include <QQmlApplicationEngine>
|
||||
|
||||
// =============================================================================
|
||||
|
||||
ParticipantDeviceProxy::ParticipantDeviceProxy(QObject *parent) : SortFilterProxy(parent) {
|
||||
mDeleteSourceModel = true;
|
||||
mList = ParticipantDeviceList::create();
|
||||
setSourceModel(mList.get());
|
||||
}
|
||||
|
||||
ParticipantDeviceProxy::~ParticipantDeviceProxy() {
|
||||
}
|
||||
|
||||
bool ParticipantDeviceProxy::filterAcceptsRow(int sourceRow, const QModelIndex &sourceParent) const {
|
||||
const QModelIndex index = mList->index(sourceRow, 0, sourceParent);
|
||||
const ParticipantDeviceCore *device = index.data().value<ParticipantDeviceCore *>();
|
||||
return device && (isShowMe() /*|| !(device->isMe() && device->isLocal())*/);
|
||||
}
|
||||
|
||||
bool ParticipantDeviceProxy::lessThan(const QModelIndex &left, const QModelIndex &right) const {
|
||||
const ParticipantDeviceCore *deviceA = sourceModel()->data(left).value<ParticipantDeviceCore *>();
|
||||
const ParticipantDeviceCore *deviceB = sourceModel()->data(right).value<ParticipantDeviceCore *>();
|
||||
// 'me' at end (for grid).
|
||||
return /*deviceB->isLocal() || !deviceA->isLocal() && deviceB->isMe() ||*/ left.row() < right.row();
|
||||
}
|
||||
//---------------------------------------------------------------------------------
|
||||
|
||||
ParticipantDeviceCore *ParticipantDeviceProxy::getAt(int row) {
|
||||
if (row >= 0) {
|
||||
QModelIndex sourceIndex = mapToSource(this->index(row, 0));
|
||||
return sourceModel()->data(sourceIndex).value<ParticipantDeviceCore *>();
|
||||
} else return nullptr;
|
||||
}
|
||||
|
||||
ParticipantDeviceCore *ParticipantDeviceProxy::getActiveSpeakerModel() {
|
||||
return mList->getActiveSpeakerModel();
|
||||
}
|
||||
|
||||
CallModel *ParticipantDeviceProxy::getCallModel() const {
|
||||
return mCallModel;
|
||||
}
|
||||
|
||||
ParticipantDeviceCore *ParticipantDeviceProxy::getMe() const {
|
||||
return mList->getMe().get();
|
||||
}
|
||||
|
||||
bool ParticipantDeviceProxy::isShowMe() const {
|
||||
return mShowMe;
|
||||
}
|
||||
|
||||
void ParticipantDeviceProxy::connectTo(ParticipantDeviceList *model) {
|
||||
connect(model, &ParticipantDeviceList::countChanged, this, &ParticipantDeviceProxy::onCountChanged);
|
||||
connect(model, &ParticipantDeviceList::participantSpeaking, this, &ParticipantDeviceProxy::onParticipantSpeaking);
|
||||
connect(model, &ParticipantDeviceList::conferenceCreated, this, &ParticipantDeviceProxy::conferenceCreated);
|
||||
connect(model, &ParticipantDeviceList::meChanged, this, &ParticipantDeviceProxy::meChanged);
|
||||
connect(model, &ParticipantDeviceList::activeSpeakerChanged, this, &ParticipantDeviceProxy::activeSpeakerChanged);
|
||||
}
|
||||
void ParticipantDeviceProxy::setCallModel(CallModel *callModel) {
|
||||
setFilterType(1);
|
||||
mCallModel = callModel;
|
||||
deleteSourceModel();
|
||||
auto newSourceModel = new ParticipantDeviceList(mCallModel);
|
||||
connectTo(newSourceModel);
|
||||
setSourceModel(newSourceModel);
|
||||
mDeleteSourceModel = true;
|
||||
sort(0);
|
||||
emit countChanged();
|
||||
emit meChanged();
|
||||
}
|
||||
|
||||
// void ParticipantDeviceProxy::setParticipant(ParticipantCore *participantCore) {
|
||||
// setFilterType(0);
|
||||
// deleteSourceModel();
|
||||
// auto newSourceModel = participant->getParticipantDevices().get();
|
||||
// connectTo(newSourceModel);
|
||||
// setSourceModel(newSourceModel);
|
||||
// mDeleteSourceModel = false;
|
||||
// sort(0);
|
||||
// emit countChanged();
|
||||
// emit meChanged();
|
||||
// }
|
||||
|
||||
void ParticipantDeviceProxy::setShowMe(const bool &show) {
|
||||
if (mShowMe != show) {
|
||||
mShowMe = show;
|
||||
emit showMeChanged();
|
||||
invalidate();
|
||||
}
|
||||
}
|
||||
|
||||
void ParticipantDeviceProxy::onCountChanged() {
|
||||
qDebug() << "Count changed : " << getCount();
|
||||
}
|
||||
|
||||
void ParticipantDeviceProxy::onParticipantSpeaking(ParticipantDeviceCore *speakingDevice) {
|
||||
emit participantSpeaking(speakingDevice);
|
||||
}
|
||||
84
Linphone/core/participant/ParticipantDeviceProxy.hpp
Normal file
84
Linphone/core/participant/ParticipantDeviceProxy.hpp
Normal file
|
|
@ -0,0 +1,84 @@
|
|||
/*
|
||||
* 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 <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef PARTICIPANT_DEVICE_PROXY_MODEL_H_
|
||||
#define PARTICIPANT_DEVICE_PROXY_MODEL_H_
|
||||
|
||||
#include <linphone++/linphone.hh>
|
||||
// =============================================================================
|
||||
#include "../proxy/SortFilterProxy.hpp"
|
||||
#include <QDateTime>
|
||||
#include <QObject>
|
||||
#include <QSharedPointer>
|
||||
#include <QString>
|
||||
|
||||
class ParticipantDeviceList;
|
||||
class ParticipantDeviceCore;
|
||||
class ParticipantCore;
|
||||
class CallModel;
|
||||
|
||||
class ParticipantDeviceProxy : public SortFilterProxy {
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
Q_PROPERTY(CallModel *callModel READ getCallModel WRITE setCallModel NOTIFY callModelChanged)
|
||||
Q_PROPERTY(bool showMe READ isShowMe WRITE setShowMe NOTIFY showMeChanged)
|
||||
Q_PROPERTY(ParticipantDeviceCore *me READ getMe NOTIFY meChanged)
|
||||
Q_PROPERTY(ParticipantDeviceCore *activeSpeaker READ getActiveSpeakerModel NOTIFY activeSpeakerChanged)
|
||||
|
||||
ParticipantDeviceProxy(QObject *parent = nullptr);
|
||||
~ParticipantDeviceProxy();
|
||||
|
||||
Q_INVOKABLE ParticipantDeviceCore *getAt(int row);
|
||||
ParticipantDeviceCore *getActiveSpeakerModel();
|
||||
ParticipantDeviceCore *getMe() const;
|
||||
|
||||
CallModel *getCallModel() const;
|
||||
bool isShowMe() const;
|
||||
|
||||
void setCallModel(CallModel *callModel);
|
||||
// void setParticipant(ParticipantCore *participantCore);
|
||||
void setShowMe(const bool &show);
|
||||
|
||||
void connectTo(ParticipantDeviceList *model);
|
||||
|
||||
public slots:
|
||||
void onCountChanged();
|
||||
void onParticipantSpeaking(ParticipantDeviceCore *speakingDevice);
|
||||
|
||||
signals:
|
||||
void activeSpeakerChanged();
|
||||
void callModelChanged();
|
||||
void showMeChanged();
|
||||
void meChanged();
|
||||
void participantSpeaking(ParticipantDeviceCore *speakingDevice);
|
||||
void conferenceCreated();
|
||||
|
||||
protected:
|
||||
virtual bool filterAcceptsRow(int sourceRow, const QModelIndex &sourceParent) const override;
|
||||
virtual bool lessThan(const QModelIndex &left, const QModelIndex &right) const override;
|
||||
|
||||
CallModel *mCallModel;
|
||||
bool mShowMe = true;
|
||||
|
||||
QSharedPointer<ParticipantDeviceList> mList;
|
||||
};
|
||||
|
||||
#endif
|
||||
41
Linphone/core/participant/ParticipantGui.cpp
Normal file
41
Linphone/core/participant/ParticipantGui.cpp
Normal file
|
|
@ -0,0 +1,41 @@
|
|||
/*
|
||||
* Copyright (c) 2010-2024 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 <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "ParticipantGui.hpp"
|
||||
#include "core/App.hpp"
|
||||
|
||||
DEFINE_ABSTRACT_OBJECT(ParticipantGui)
|
||||
|
||||
ParticipantGui::ParticipantGui(QObject *parent) : QObject(parent) {
|
||||
mCore = ParticipantCore::create(nullptr);
|
||||
}
|
||||
ParticipantGui::ParticipantGui(QSharedPointer<ParticipantCore> core) {
|
||||
App::getInstance()->mEngine->setObjectOwnership(this, QQmlEngine::JavaScriptOwnership);
|
||||
mCore = core;
|
||||
if (isInLinphoneThread()) moveToThread(App::getInstance()->thread());
|
||||
}
|
||||
|
||||
ParticipantGui::~ParticipantGui() {
|
||||
mustBeInMainThread("~" + getClassName());
|
||||
}
|
||||
|
||||
ParticipantCore *ParticipantGui::getCore() const {
|
||||
return mCore.get();
|
||||
}
|
||||
42
Linphone/core/participant/ParticipantGui.hpp
Normal file
42
Linphone/core/participant/ParticipantGui.hpp
Normal file
|
|
@ -0,0 +1,42 @@
|
|||
/*
|
||||
* Copyright (c) 2010-2024 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 <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef PARTICIPANT_GUI_H_
|
||||
#define PARTICIPANT_GUI_H_
|
||||
|
||||
#include "ParticipantCore.hpp"
|
||||
#include <QObject>
|
||||
#include <QSharedPointer>
|
||||
|
||||
class ParticipantGui : public QObject, public AbstractObject {
|
||||
Q_OBJECT
|
||||
|
||||
Q_PROPERTY(ParticipantCore *core READ getCore CONSTANT)
|
||||
|
||||
public:
|
||||
ParticipantGui(QSharedPointer<ParticipantCore> core);
|
||||
ParticipantGui(QObject *parent = nullptr);
|
||||
~ParticipantGui();
|
||||
ParticipantCore *getCore() const;
|
||||
QSharedPointer<ParticipantCore> mCore;
|
||||
DECLARE_ABSTRACT_OBJECT
|
||||
};
|
||||
|
||||
#endif
|
||||
406
Linphone/core/participant/ParticipantList.cpp
Normal file
406
Linphone/core/participant/ParticipantList.cpp
Normal file
|
|
@ -0,0 +1,406 @@
|
|||
/*
|
||||
* 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 <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "ParticipantList.hpp"
|
||||
#include "core/App.hpp"
|
||||
#include "core/participant/ParticipantGui.hpp"
|
||||
#include "model/core/CoreModel.hpp"
|
||||
#include "model/tool/ToolModel.hpp"
|
||||
#include "tool/Utils.hpp"
|
||||
|
||||
#include <QDebug>
|
||||
|
||||
DEFINE_ABSTRACT_OBJECT(ParticipantList)
|
||||
|
||||
QSharedPointer<ParticipantList> ParticipantList::create() {
|
||||
auto model = QSharedPointer<ParticipantList>(new ParticipantList(), &QObject::deleteLater);
|
||||
model->moveToThread(App::getInstance()->thread());
|
||||
model->setSelf(model);
|
||||
return model;
|
||||
}
|
||||
|
||||
// ParticipantList::ParticipantList(ChatRoomModel *chatRoomModel, QObject *parent) : ProxyListModel(parent) {
|
||||
// if (chatRoomModel) {
|
||||
// mChatRoomModel = chatRoomModel;
|
||||
|
||||
// connect(mChatRoomModel, &ChatRoomModel::securityEvent, this, &ParticipantList::onSecurityEvent);
|
||||
// connect(mChatRoomModel, &ChatRoomModel::conferenceJoined, this, &ParticipantList::onConferenceJoined);
|
||||
// connect(mChatRoomModel, &ChatRoomModel::participantAdded, this,
|
||||
// QOverload<const std::shared_ptr<const linphone::EventLog> &>::of(
|
||||
// &ParticipantList::onParticipantAdded));
|
||||
// connect(mChatRoomModel, &ChatRoomModel::participantRemoved, this,
|
||||
// QOverload<const std::shared_ptr<const linphone::EventLog> &>::of(
|
||||
// &ParticipantList::onParticipantRemoved));
|
||||
// connect(mChatRoomModel, &ChatRoomModel::participantAdminStatusChanged, this,
|
||||
// QOverload<const std::shared_ptr<const linphone::EventLog> &>::of(
|
||||
// &ParticipantList::onParticipantAdminStatusChanged));
|
||||
// connect(mChatRoomModel, &ChatRoomModel::participantDeviceAdded, this,
|
||||
// &ParticipantList::onParticipantDeviceAdded);
|
||||
// connect(mChatRoomModel, &ChatRoomModel::participantDeviceRemoved, this,
|
||||
// &ParticipantList::onParticipantDeviceRemoved);
|
||||
// connect(mChatRoomModel, &ChatRoomModel::participantRegistrationSubscriptionRequested, this,
|
||||
// &ParticipantList::onParticipantRegistrationSubscriptionRequested);
|
||||
// connect(mChatRoomModel, &ChatRoomModel::participantRegistrationUnsubscriptionRequested, this,
|
||||
// &ParticipantList::onParticipantRegistrationUnsubscriptionRequested);
|
||||
|
||||
// updateParticipants();
|
||||
// }
|
||||
// }
|
||||
|
||||
// ParticipantList::ParticipantList(ConferenceModel *conferenceModel, QObject *parent) : ListProxy(parent) {
|
||||
// if (conferenceModel) {
|
||||
// mConferenceModel = conferenceModel;
|
||||
|
||||
// connect(mConferenceModel, &ConferenceModel::participantAdded, this,
|
||||
// QOverload<const std::shared_ptr<const linphone::Participant> &>::of(
|
||||
// &ParticipantList::onParticipantAdded));
|
||||
// connect(mConferenceModel, &ConferenceModel::participantRemoved, this,
|
||||
// QOverload<const std::shared_ptr<const linphone::Participant> &>::of(
|
||||
// &ParticipantList::onParticipantRemoved));
|
||||
// connect(mConferenceModel, &ConferenceModel::participantAdminStatusChanged, this,
|
||||
// QOverload<const std::shared_ptr<const linphone::Participant> &>::of(
|
||||
// &ParticipantList::onParticipantAdminStatusChanged));
|
||||
// connect(mConferenceModel, &ConferenceModel::conferenceStateChanged, this,
|
||||
// &ParticipantList::onStateChanged);
|
||||
|
||||
// updateParticipants();
|
||||
// }
|
||||
// }
|
||||
|
||||
ParticipantList::ParticipantList(QObject *parent) : ListProxy(parent) {
|
||||
}
|
||||
|
||||
ParticipantList::~ParticipantList() {
|
||||
mList.clear();
|
||||
// mChatRoomModel = nullptr;
|
||||
// mConferenceModel = nullptr;
|
||||
}
|
||||
|
||||
void ParticipantList::setSelf(QSharedPointer<ParticipantList> me) {
|
||||
mModelConnection = QSharedPointer<SafeConnection<ParticipantList, ConferenceModel>>(
|
||||
new SafeConnection<ParticipantList, ConferenceModel>(me, mConferenceModel), &QObject::deleteLater);
|
||||
|
||||
mModelConnection->makeConnectToCore(&ParticipantList::lUpdateParticipants, [this] {
|
||||
mModelConnection->invokeToModel([this]() {
|
||||
QList<QSharedPointer<ParticipantCore>> *participantList = new QList<QSharedPointer<ParticipantCore>>();
|
||||
mustBeInLinphoneThread(getClassName());
|
||||
std::list<std::shared_ptr<linphone::Participant>> participants;
|
||||
participants = mConferenceModel->getMonitor()->getParticipantList();
|
||||
for (auto it : participants) {
|
||||
auto model = ParticipantCore::create(it);
|
||||
participantList->push_back(model);
|
||||
}
|
||||
mModelConnection->invokeToCore([this, participantList]() {
|
||||
mustBeInMainThread(getClassName());
|
||||
resetData();
|
||||
add(*participantList);
|
||||
delete participantList;
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
mModelConnection->makeConnectToModel(&ConferenceModel::participantAdded, &ParticipantList::lUpdateParticipants);
|
||||
mModelConnection->makeConnectToModel(&ConferenceModel::participantRemoved, &ParticipantList::lUpdateParticipants);
|
||||
emit lUpdateParticipants();
|
||||
}
|
||||
|
||||
QVariant ParticipantList::data(const QModelIndex &index, int role) const {
|
||||
int row = index.row();
|
||||
if (!index.isValid() || row < 0 || row >= mList.count()) return QVariant();
|
||||
if (role == Qt::DisplayRole) {
|
||||
return QVariant::fromValue(new ParticipantGui(mList[row].objectCast<ParticipantCore>()));
|
||||
}
|
||||
return QVariant();
|
||||
}
|
||||
|
||||
std::list<std::shared_ptr<linphone::Address>> ParticipantList::getParticipants() const {
|
||||
std::list<std::shared_ptr<linphone::Address>> participants;
|
||||
for (auto participant : mList) {
|
||||
participants.push_back(ToolModel::interpretUrl(participant.objectCast<ParticipantCore>()->getSipAddress()));
|
||||
}
|
||||
return participants;
|
||||
}
|
||||
|
||||
QString ParticipantList::addressesToString() const {
|
||||
QStringList txt;
|
||||
for (auto item : mList) {
|
||||
auto participant = item.objectCast<ParticipantCore>();
|
||||
if (participant) {
|
||||
|
||||
// chat room yet.
|
||||
txt << participant->getSipAddress();
|
||||
// txt << Utils::toDisplayString(Utils::coreStringToAppString(address->asStringUriOnly()),
|
||||
// CoreModel::getInstance()->getSettingsModel()->getSipDisplayMode());
|
||||
}
|
||||
}
|
||||
if (txt.size() > 0) txt.removeFirst(); // Remove me
|
||||
return txt.join(", ");
|
||||
}
|
||||
|
||||
QString ParticipantList::displayNamesToString() const {
|
||||
QStringList txt;
|
||||
for (auto item : mList) {
|
||||
auto participant = item.objectCast<ParticipantCore>();
|
||||
if (participant) {
|
||||
QString displayName = participant->getSipAddress();
|
||||
if (displayName != "") txt << displayName;
|
||||
}
|
||||
}
|
||||
if (txt.size() > 0) txt.removeFirst(); // Remove me
|
||||
return txt.join(", ");
|
||||
}
|
||||
|
||||
QString ParticipantList::usernamesToString() const {
|
||||
QStringList txt;
|
||||
for (auto item : mList) {
|
||||
auto participant = item.objectCast<ParticipantCore>();
|
||||
if (participant) {
|
||||
auto username = participant->getDisplayName();
|
||||
txt << username;
|
||||
}
|
||||
}
|
||||
if (txt.size() > 0) txt.removeFirst(); // Remove me
|
||||
return txt.join(", ");
|
||||
}
|
||||
|
||||
bool ParticipantList::contains(const QString &address) const {
|
||||
auto testAddress = ToolModel::interpretUrl(address);
|
||||
bool exists = false;
|
||||
for (auto itParticipant = mList.begin(); !exists && itParticipant != mList.end(); ++itParticipant)
|
||||
exists = testAddress->weakEqual(
|
||||
ToolModel::interpretUrl(itParticipant->objectCast<ParticipantCore>()->getSipAddress()));
|
||||
return exists;
|
||||
}
|
||||
|
||||
// void ParticipantList::updateParticipants() {
|
||||
// if (/*mChatRoomModel ||*/ mConferenceModel) {
|
||||
// bool changed = false;
|
||||
// mConferenceModel->getMonitor()->getParticipantList();
|
||||
// // auto dbParticipants = (/*mChatRoomModel ? mChatRoomModel->getParticipants() :*/ mConferenceModel->get());
|
||||
// // Remove left participants
|
||||
// auto itParticipant = mList.begin();
|
||||
// while (itParticipant != mList.end()) {
|
||||
// auto itDbParticipant = dbParticipants.begin();
|
||||
// while (
|
||||
// itDbParticipant != dbParticipants.end() &&
|
||||
// (itParticipant->objectCast<ParticipantCore>()->getParticipant() &&
|
||||
// !(*itDbParticipant)
|
||||
// ->getAddress()
|
||||
// ->weakEqual(itParticipant->objectCast<ParticipantCore>()->getParticipant()->getAddress()) ||
|
||||
// !itParticipant->objectCast<ParticipantCore>()->getParticipant() &&
|
||||
// !(*itDbParticipant)
|
||||
// ->getAddress()
|
||||
// ->weakEqual(
|
||||
// Utils::interpretUrl(itParticipant->objectCast<ParticipantCore>()->getSipAddress())))) {
|
||||
// ++itDbParticipant;
|
||||
// }
|
||||
// if (itDbParticipant == dbParticipants.end()) {
|
||||
// int row = itParticipant - mList.begin();
|
||||
// if (!changed) emit layoutAboutToBeChanged();
|
||||
// beginRemoveRows(QModelIndex(), row, row);
|
||||
// itParticipant = mList.erase(itParticipant);
|
||||
// endRemoveRows();
|
||||
// changed = true;
|
||||
// } else ++itParticipant;
|
||||
// }
|
||||
// // Add new
|
||||
// for (auto dbParticipant : dbParticipants) {
|
||||
// auto itParticipant = mList.begin();
|
||||
// while (itParticipant != mList.end() &&
|
||||
// ((itParticipant->objectCast<ParticipantCore>()->getParticipant() &&
|
||||
// !dbParticipant->getAddress()->weakEqual(
|
||||
// itParticipant->objectCast<ParticipantCore>()->getParticipant()->getAddress()))
|
||||
|
||||
// || (!itParticipant->objectCast<ParticipantCore>()->getParticipant() &&
|
||||
// !dbParticipant->getAddress()->weakEqual(
|
||||
// Utils::interpretUrl(itParticipant->objectCast<ParticipantCore>()->getSipAddress()))))) {
|
||||
// ++itParticipant;
|
||||
// }
|
||||
// if (itParticipant == mList.end()) {
|
||||
// auto participant = QSharedPointer<ParticipantCore>::create(dbParticipant);
|
||||
// add(participant);
|
||||
// changed = true;
|
||||
// } else if (!itParticipant->objectCast<ParticipantCore>()->getParticipant() ||
|
||||
// itParticipant->objectCast<ParticipantCore>()->getParticipant() != dbParticipant) {
|
||||
// itParticipant->objectCast<ParticipantCore>()->setParticipant(dbParticipant);
|
||||
// changed = true;
|
||||
// }
|
||||
// }
|
||||
// if (changed) {
|
||||
// emit layoutChanged();
|
||||
// emit participantsChanged();
|
||||
// emit countChanged();
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
|
||||
// void ParticipantList::add(QSharedPointer<ParticipantCore> participant) {
|
||||
// int row = mList.count();
|
||||
// connect(this, &ParticipantList::deviceSecurityLevelChanged, participant.get(),
|
||||
// &ParticipantCore::onDeviceSecurityLevelChanged);
|
||||
// connect(this, &ParticipantList::securityLevelChanged, participant.get(), &ParticipantCore::onSecurityLevelChanged);
|
||||
// connect(participant.get(), &ParticipantCore::updateAdminStatus, this, &ParticipantList::setAdminStatus);
|
||||
// ProxyListModel::add(participant);
|
||||
// emit participantsChanged();
|
||||
// }
|
||||
|
||||
// void ParticipantList::add(const std::shared_ptr<const linphone::Participant> &participant) {
|
||||
// updateParticipants();
|
||||
// }
|
||||
|
||||
// void ParticipantList::add(const std::shared_ptr<const linphone::Address> &participantAddress) {
|
||||
// add((mChatRoomModel ? mChatRoomModel->getChatRoom()->findParticipant(participantAddress->clone())
|
||||
// : mConferenceModel->getConference()->findParticipant(participantAddress)));
|
||||
// }
|
||||
|
||||
void ParticipantList::remove(ParticipantCore *participant) {
|
||||
QString address = participant->getSipAddress();
|
||||
int index = 0;
|
||||
bool found = false;
|
||||
auto itParticipant = mList.begin();
|
||||
while (!found && itParticipant != mList.end()) {
|
||||
if (itParticipant->objectCast<ParticipantCore>()->getSipAddress() == address) found = true;
|
||||
else {
|
||||
++itParticipant;
|
||||
++index;
|
||||
}
|
||||
}
|
||||
if (found) {
|
||||
mConferenceModel->removeParticipant(ToolModel::interpretUrl(address));
|
||||
}
|
||||
}
|
||||
|
||||
// const QSharedPointer<ParticipantCore>
|
||||
// ParticipantList::getParticipant(const std::shared_ptr<const linphone::Address> &address) const {
|
||||
// if (address) {
|
||||
// auto itParticipant =
|
||||
// std::find_if(mList.begin(), mList.end(), [address](const QSharedPointer<QObject> &participant) {
|
||||
// return
|
||||
// participant.objectCast<ParticipantCore>()->getParticipant()->getAddress()->weakEqual(address);
|
||||
// });
|
||||
// if (itParticipant == mList.end()) return nullptr;
|
||||
// else return itParticipant->objectCast<ParticipantCore>();
|
||||
// } else return nullptr;
|
||||
// }
|
||||
// const QSharedPointer<ParticipantCore>
|
||||
// ParticipantList::getParticipant(const std::shared_ptr<const linphone::Participant> &pParticipant) const {
|
||||
// if (pParticipant) {
|
||||
// auto itParticipant =
|
||||
// std::find_if(mList.begin(), mList.end(), [pParticipant](const QSharedPointer<QObject> &participant) {
|
||||
// return participant.objectCast<ParticipantCore>()->getParticipant() == pParticipant;
|
||||
// });
|
||||
// if (itParticipant == mList.end()) return nullptr;
|
||||
// else return itParticipant->objectCast<ParticipantCore>();
|
||||
// } else return nullptr;
|
||||
// }
|
||||
|
||||
//-------------------------------------------------------------
|
||||
|
||||
void ParticipantList::setAdminStatus(const std::shared_ptr<linphone::Participant> participant, const bool &isAdmin) {
|
||||
// if (mChatRoomModel) mChatRoomModel->getChatRoom()->setParticipantAdminStatus(participant, isAdmin);
|
||||
// if (mConferenceModel) mConferenceModel->getConference()->setParticipantAdminStatus(participant, isAdmin);
|
||||
}
|
||||
|
||||
void ParticipantList::onSecurityEvent(const std::shared_ptr<const linphone::EventLog> &eventLog) {
|
||||
auto address = eventLog->getParticipantAddress();
|
||||
if (address) {
|
||||
// auto participant = getParticipant(address);
|
||||
// if (participant) {
|
||||
// emit participant->securityLevelChanged();
|
||||
// }
|
||||
} else {
|
||||
address = eventLog->getDeviceAddress();
|
||||
// Looping on all participant ensure to get all devices. Can be optimized if Device address is unique : Gain
|
||||
// 2n operations.
|
||||
if (address) emit deviceSecurityLevelChanged(address);
|
||||
}
|
||||
}
|
||||
|
||||
void ParticipantList::onConferenceJoined() {
|
||||
// updateParticipants();
|
||||
}
|
||||
|
||||
void ParticipantList::onParticipantAdded(const std::shared_ptr<const linphone::EventLog> &eventLog) {
|
||||
qDebug() << "onParticipantAdded event: " << eventLog->getParticipantAddress()->asString().c_str();
|
||||
// add(eventLog->getParticipantAddress());
|
||||
}
|
||||
|
||||
void ParticipantList::onParticipantAdded(const std::shared_ptr<const linphone::Participant> &participant) {
|
||||
qDebug() << "onParticipantAdded part: " << participant->getAddress()->asString().c_str();
|
||||
// add(participant);
|
||||
}
|
||||
|
||||
void ParticipantList::onParticipantAdded(const std::shared_ptr<const linphone::Address> &address) {
|
||||
qDebug() << "onParticipantAdded addr: " << address->asString().c_str();
|
||||
// add(address);
|
||||
}
|
||||
|
||||
void ParticipantList::onParticipantRemoved(const std::shared_ptr<const linphone::EventLog> &eventLog) {
|
||||
onParticipantRemoved(eventLog->getParticipantAddress());
|
||||
}
|
||||
|
||||
void ParticipantList::onParticipantRemoved(const std::shared_ptr<const linphone::Participant> &participant) {
|
||||
// auto p = getParticipant(participant);
|
||||
// if (p) remove(p.get());
|
||||
}
|
||||
|
||||
void ParticipantList::onParticipantRemoved(const std::shared_ptr<const linphone::Address> &address) {
|
||||
// auto participant = getParticipant(address);
|
||||
// if (participant) remove(participant.get());
|
||||
}
|
||||
|
||||
void ParticipantList::onParticipantAdminStatusChanged(const std::shared_ptr<const linphone::EventLog> &eventLog) {
|
||||
onParticipantAdminStatusChanged(eventLog->getParticipantAddress());
|
||||
}
|
||||
void ParticipantList::onParticipantAdminStatusChanged(const std::shared_ptr<const linphone::Participant> &participant) {
|
||||
// auto p = getParticipant(participant);
|
||||
// if (participant) emit p->adminStatusChanged(); // Request to participant to update its status from its data
|
||||
}
|
||||
void ParticipantList::onParticipantAdminStatusChanged(const std::shared_ptr<const linphone::Address> &address) {
|
||||
// auto participant = getParticipant(address);
|
||||
// if (participant)
|
||||
// emit participant->adminStatusChanged(); // Request to participant to update its status from its data
|
||||
}
|
||||
void ParticipantList::onParticipantDeviceAdded(const std::shared_ptr<const linphone::EventLog> &eventLog) {
|
||||
// auto participant = getParticipant(eventLog->getParticipantAddress());
|
||||
// if (participant) {
|
||||
// emit participant->deviceCountChanged();
|
||||
// }
|
||||
}
|
||||
void ParticipantList::onParticipantDeviceRemoved(const std::shared_ptr<const linphone::EventLog> &eventLog) {
|
||||
// auto participant = getParticipant(eventLog->getParticipantAddress());
|
||||
// if (participant) {
|
||||
// emit participant->deviceCountChanged();
|
||||
// }
|
||||
}
|
||||
void ParticipantList::onParticipantRegistrationSubscriptionRequested(
|
||||
const std::shared_ptr<const linphone::Address> &participantAddress) {
|
||||
}
|
||||
void ParticipantList::onParticipantRegistrationUnsubscriptionRequested(
|
||||
const std::shared_ptr<const linphone::Address> &participantAddress) {
|
||||
}
|
||||
|
||||
void ParticipantList::onStateChanged() {
|
||||
// if (mConferenceModel) {
|
||||
// if (mConferenceModel->getConference()->getState() == linphone::Conference::State::Created) {
|
||||
// updateParticipants();
|
||||
// }
|
||||
// }
|
||||
}
|
||||
106
Linphone/core/participant/ParticipantList.hpp
Normal file
106
Linphone/core/participant/ParticipantList.hpp
Normal file
|
|
@ -0,0 +1,106 @@
|
|||
/*
|
||||
* 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 <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef PARTICIPANT_LIST_H_
|
||||
#define PARTICIPANT_LIST_H_
|
||||
|
||||
#include "../proxy/ListProxy.hpp"
|
||||
#include "core/participant/ParticipantCore.hpp"
|
||||
#include "model/conference/ConferenceModel.hpp"
|
||||
|
||||
class ConferenceModel;
|
||||
|
||||
// =============================================================================
|
||||
|
||||
class ParticipantList : public ListProxy, public AbstractObject {
|
||||
Q_OBJECT
|
||||
public:
|
||||
static QSharedPointer<ParticipantList> create();
|
||||
|
||||
// ParticipantList(ChatRoomModel *chatRoomModel, QObject *parent = Q_NULLPTR);
|
||||
// ParticipantList(ConferenceModel *conferenceModel, QObject *parent = Q_NULLPTR);
|
||||
ParticipantList(QObject *parent = Q_NULLPTR);
|
||||
virtual ~ParticipantList();
|
||||
|
||||
void setSelf(QSharedPointer<ParticipantList> me);
|
||||
|
||||
// Q_PROPERTY(ChatRoomModel *chatRoomModel READ getChatRoomModel CONSTANT)
|
||||
Q_PROPERTY(QString addressesToString READ addressesToString NOTIFY participantsChanged)
|
||||
Q_PROPERTY(QString displayNamesToString READ displayNamesToString NOTIFY participantsChanged)
|
||||
Q_PROPERTY(QString usernamesToString READ usernamesToString NOTIFY participantsChanged)
|
||||
|
||||
void reset();
|
||||
// void updateParticipants(); // Update list from Chat Room
|
||||
// const QSharedPointer<ParticipantCore>
|
||||
// getParticipant(const std::shared_ptr<const linphone::Address> &address) const;
|
||||
// const QSharedPointer<ParticipantCore> const QSharedPointer<ParticipantCore>
|
||||
// getParticipant(const std::shared_ptr<const linphone::Participant> &participant) const;
|
||||
|
||||
Q_INVOKABLE void remove(ParticipantCore *participant);
|
||||
std::list<std::shared_ptr<linphone::Address>> getParticipants() const;
|
||||
|
||||
Q_INVOKABLE QString addressesToString() const;
|
||||
Q_INVOKABLE QString displayNamesToString() const;
|
||||
Q_INVOKABLE QString usernamesToString() const;
|
||||
|
||||
bool contains(const QString &address) const;
|
||||
|
||||
virtual QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const override;
|
||||
|
||||
public slots:
|
||||
void setAdminStatus(const std::shared_ptr<linphone::Participant> participant, const bool &isAdmin);
|
||||
|
||||
void onSecurityEvent(const std::shared_ptr<const linphone::EventLog> &eventLog);
|
||||
void onConferenceJoined();
|
||||
void onParticipantAdded(const std::shared_ptr<const linphone::Participant> &participant);
|
||||
void onParticipantAdded(const std::shared_ptr<const linphone::EventLog> &eventLog);
|
||||
void onParticipantAdded(const std::shared_ptr<const linphone::Address> &address);
|
||||
void onParticipantRemoved(const std::shared_ptr<const linphone::Participant> &participant);
|
||||
void onParticipantRemoved(const std::shared_ptr<const linphone::EventLog> &eventLog);
|
||||
void onParticipantRemoved(const std::shared_ptr<const linphone::Address> &address);
|
||||
void onParticipantAdminStatusChanged(const std::shared_ptr<const linphone::Participant> &participant);
|
||||
void onParticipantAdminStatusChanged(const std::shared_ptr<const linphone::EventLog> &eventLog);
|
||||
void onParticipantAdminStatusChanged(const std::shared_ptr<const linphone::Address> &address);
|
||||
void onParticipantDeviceAdded(const std::shared_ptr<const linphone::EventLog> &eventLog);
|
||||
void onParticipantDeviceRemoved(const std::shared_ptr<const linphone::EventLog> &eventLog);
|
||||
void
|
||||
onParticipantRegistrationSubscriptionRequested(const std::shared_ptr<const linphone::Address> &participantAddress);
|
||||
void onParticipantRegistrationUnsubscriptionRequested(
|
||||
const std::shared_ptr<const linphone::Address> &participantAddress);
|
||||
void onStateChanged();
|
||||
|
||||
signals:
|
||||
void securityLevelChanged();
|
||||
void deviceSecurityLevelChanged(std::shared_ptr<const linphone::Address> device);
|
||||
void participantsChanged();
|
||||
|
||||
void lUpdateParticipants();
|
||||
|
||||
private:
|
||||
std::shared_ptr<ConferenceModel> mConferenceModel;
|
||||
QSharedPointer<SafeConnection<ParticipantList, ConferenceModel>> mModelConnection;
|
||||
|
||||
// ChatRoomModel *mChatRoomModel = nullptr;
|
||||
// ConferenceCore *mConferenceCore = nullptr;
|
||||
|
||||
DECLARE_ABSTRACT_OBJECT
|
||||
};
|
||||
Q_DECLARE_METATYPE(QSharedPointer<ParticipantList>);
|
||||
#endif // PARTICIPANT_LIST_H_
|
||||
196
Linphone/core/participant/ParticipantProxy.cpp
Normal file
196
Linphone/core/participant/ParticipantProxy.cpp
Normal file
|
|
@ -0,0 +1,196 @@
|
|||
/*
|
||||
* 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 <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "ParticipantProxy.hpp"
|
||||
|
||||
// #include "core/conference/ConferenceCore.hpp"
|
||||
#include "model/core/CoreModel.hpp"
|
||||
#include "tool/Utils.hpp"
|
||||
|
||||
#include "ParticipantList.hpp"
|
||||
#include "core/participant/ParticipantCore.hpp"
|
||||
|
||||
#include <QDebug>
|
||||
|
||||
// =============================================================================
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
ParticipantProxy::ParticipantProxy(QObject *parent) : SortFilterProxy(parent) {
|
||||
mList = ParticipantList::create();
|
||||
setSourceModel(mList.get());
|
||||
connect(this, &ParticipantProxy::chatRoomModelChanged, this, &ParticipantProxy::countChanged);
|
||||
connect(this, &ParticipantProxy::conferenceModelChanged, this, &ParticipantProxy::countChanged);
|
||||
}
|
||||
|
||||
ParticipantProxy::~ParticipantProxy() {
|
||||
setSourceModel(nullptr);
|
||||
}
|
||||
|
||||
// ChatRoomModel *ParticipantProxy::getChatRoomModel() const {
|
||||
// return mChatRoomModel;
|
||||
// }
|
||||
|
||||
// ConferenceModel *ParticipantProxy::getConferenceModel() const {
|
||||
// return mConferenceModel;
|
||||
// }
|
||||
|
||||
QStringList ParticipantProxy::getSipAddresses() const {
|
||||
QStringList participants;
|
||||
for (int i = 0; i < mList->rowCount(); ++i)
|
||||
participants << mList->getAt<ParticipantCore>(i)->getSipAddress();
|
||||
return participants;
|
||||
}
|
||||
|
||||
QVariantList ParticipantProxy::getParticipants() const {
|
||||
QVariantList participants;
|
||||
ParticipantList *list = qobject_cast<ParticipantList *>(sourceModel());
|
||||
for (int i = 0; i < list->rowCount(); ++i)
|
||||
participants << QVariant::fromValue(list->getAt<ParticipantCore>(i).get());
|
||||
return participants;
|
||||
}
|
||||
|
||||
bool ParticipantProxy::getShowMe() const {
|
||||
return mShowMe;
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
// void ParticipantProxy::setChatRoomModel(ChatRoomModel *chatRoomModel) {
|
||||
// if (!mChatRoomModel || mChatRoomModel != chatRoomModel) {
|
||||
// mChatRoomModel = chatRoomModel;
|
||||
// if (mChatRoomModel) {
|
||||
// auto participants = mChatRoomModel->getParticipantList();
|
||||
// connect(participants, &ParticipantList::countChanged, this, &ParticipantProxy::countChanged);
|
||||
// setSourceModel(participants);
|
||||
// emit participantListChanged();
|
||||
// for (int i = 0; i < participants->getCount(); ++i) {
|
||||
// auto participant = participants->getAt<ParticipantCore>(i);
|
||||
// connect(participant.get(), &ParticipantCore::invitationTimeout, this, &ParticipantProxy::removeModel);
|
||||
// emit addressAdded(participant->getSipAddress());
|
||||
// }
|
||||
// } else if (!sourceModel()) {
|
||||
// auto model = new ParticipantList((ChatRoomModel *)nullptr, this);
|
||||
// connect(model, &ParticipantList::countChanged, this, &ParticipantProxy::countChanged);
|
||||
// setSourceModel(model);
|
||||
// emit participantListChanged();
|
||||
// }
|
||||
// sort(0);
|
||||
// emit chatRoomModelChanged();
|
||||
// }
|
||||
// }
|
||||
|
||||
void ParticipantProxy::setConferenceModel(ConferenceModel *conferenceModel) {
|
||||
// if (!mConferenceModel || mConferenceModel != conferenceModel) {
|
||||
// mConferenceModel = conferenceModel;
|
||||
// if (mConferenceModel) {
|
||||
// auto participants = mConferenceModel->getParticipantList();
|
||||
// connect(participants, &ParticipantList::countChanged, this, &ParticipantProxy::countChanged);
|
||||
// setSourceModel(participants);
|
||||
// emit participantListChanged();
|
||||
// for (int i = 0; i < participants->getCount(); ++i) {
|
||||
// auto participant = participants->getAt<ParticipantCore>(i);
|
||||
// connect(participant.get(), &ParticipantCore::invitationTimeout, this, &ParticipantProxy::removeModel);
|
||||
// emit addressAdded(participant->getSipAddress());
|
||||
// }
|
||||
// } else if (!sourceModel()) {
|
||||
// auto model = new ParticipantList((ConferenceModel *)nullptr, this);
|
||||
// connect(model, &ParticipantList::countChanged, this, &ParticipantProxy::countChanged);
|
||||
// setSourceModel(model);
|
||||
// emit participantListChanged();
|
||||
// }
|
||||
// sort(0);
|
||||
// emit conferenceModelChanged();
|
||||
// }
|
||||
}
|
||||
|
||||
void ParticipantProxy::setAddresses(ConferenceInfoModel *conferenceInfoModel) {
|
||||
// if (conferenceInfoModel && conferenceInfoModel->getConferenceInfo())
|
||||
// for (auto address : conferenceInfoModel->getConferenceInfo()->getParticipants())
|
||||
// addAddress(QString::fromStdString(address->asString()));
|
||||
}
|
||||
|
||||
void ParticipantProxy::setShowMe(const bool &show) {
|
||||
if (mShowMe != show) {
|
||||
mShowMe = show;
|
||||
emit showMeChanged();
|
||||
invalidate();
|
||||
}
|
||||
}
|
||||
|
||||
// void ParticipantProxy::addAddress(const QString &address) {
|
||||
// if (!participantsModel->contains(address)) {
|
||||
// QSharedPointer<ParticipantCore> participant = QSharedPointer<ParticipantCore>::create(nullptr);
|
||||
// connect(participant.get(), &ParticipantCore::invitationTimeout, this, &ParticipantProxy::removeModel);
|
||||
// participant->setSipAddress(address);
|
||||
// participantsModel->add(participant);
|
||||
// if (mChatRoomModel && mChatRoomModel->getChatRoom()) { // Invite and wait for its creation
|
||||
// participant->startInvitation();
|
||||
// mChatRoomModel->getChatRoom()->addParticipant(Utils::interpretUrl(address));
|
||||
// }
|
||||
// if (mConferenceModel && mConferenceModel->getConference()) {
|
||||
// auto addressToInvite = Utils::interpretUrl(address);
|
||||
// std::list<std::shared_ptr<linphone::Call>> runningCallsToAdd;
|
||||
// auto currentCalls = CoreManager::getInstance()->getCore()->getCalls();
|
||||
// auto haveCall = std::find_if(currentCalls.begin(), currentCalls.end(),
|
||||
// [addressToInvite](const std::shared_ptr<linphone::Call> &call) {
|
||||
// return call->getRemoteAddress()->weakEqual(addressToInvite);
|
||||
// });
|
||||
// participant->startInvitation();
|
||||
// if (haveCall == currentCalls.end()) mConferenceModel->getConference()->addParticipant(addressToInvite);
|
||||
// else {
|
||||
// runningCallsToAdd.push_back(*haveCall);
|
||||
// mConferenceModel->getConference()->addParticipants(runningCallsToAdd);
|
||||
// }
|
||||
// /*
|
||||
// std::list<std::shared_ptr<linphone::Address>> addressesToInvite;
|
||||
// addressesToInvite.push_back(addressToInvite);
|
||||
// auto callParameters =
|
||||
// CoreManager::getInstance()->getCore()->createCallParams(mConferenceModel->getConference()->getCall());
|
||||
// mConferenceModel->getConference()->inviteParticipants(addressesToInvite, callParameters);*/
|
||||
// }
|
||||
// emit countChanged();
|
||||
// emit addressAdded(address);
|
||||
// }
|
||||
// }
|
||||
|
||||
void ParticipantProxy::removeParticipant(ParticipantCore *participant) {
|
||||
if (participant) {
|
||||
mList->remove(participant);
|
||||
}
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
bool ParticipantProxy::filterAcceptsRow(int sourceRow, const QModelIndex &sourceParent) const {
|
||||
if (mShowMe) return true;
|
||||
else {
|
||||
const ParticipantCore *a =
|
||||
sourceModel()->data(sourceModel()->index(sourceRow, 0, sourceParent)).value<ParticipantCore *>();
|
||||
return !a->isMe();
|
||||
}
|
||||
}
|
||||
|
||||
bool ParticipantProxy::lessThan(const QModelIndex &left, const QModelIndex &right) const {
|
||||
const ParticipantCore *a = sourceModel()->data(left).value<ParticipantCore *>();
|
||||
const ParticipantCore *b = sourceModel()->data(right).value<ParticipantCore *>();
|
||||
|
||||
return a->getCreationTime() > b->getCreationTime() || b->isMe();
|
||||
}
|
||||
79
Linphone/core/participant/ParticipantProxy.hpp
Normal file
79
Linphone/core/participant/ParticipantProxy.hpp
Normal file
|
|
@ -0,0 +1,79 @@
|
|||
/*
|
||||
* Copyright (c) 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 <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef PARTICIPANT_PROXY_H_
|
||||
#define PARTICIPANT_PROXY_H_
|
||||
|
||||
#include "../proxy/SortFilterProxy.hpp"
|
||||
#include <memory>
|
||||
|
||||
class ParticipantCore;
|
||||
class ChatRoomModel;
|
||||
class ParticipantList;
|
||||
class ConferenceModel;
|
||||
class ConferenceInfoModel;
|
||||
// =============================================================================
|
||||
|
||||
class QWindow;
|
||||
|
||||
class ParticipantProxy : public SortFilterProxy {
|
||||
|
||||
Q_OBJECT
|
||||
|
||||
Q_PROPERTY(bool showMe READ getShowMe WRITE setShowMe NOTIFY showMeChanged)
|
||||
|
||||
public:
|
||||
ParticipantProxy(QObject *parent = Q_NULLPTR);
|
||||
~ParticipantProxy();
|
||||
|
||||
bool filterAcceptsRow(int sourceRow, const QModelIndex &sourceParent) const override;
|
||||
bool lessThan(const QModelIndex &left, const QModelIndex &right) const override;
|
||||
|
||||
// ChatRoomModel *getChatRoomModel() const;
|
||||
// ConferenceModel *getConferenceModel() const;
|
||||
Q_INVOKABLE QStringList getSipAddresses() const;
|
||||
Q_INVOKABLE QVariantList getParticipants() const;
|
||||
bool getShowMe() const;
|
||||
|
||||
// void setChatRoomModel(ChatRoomModel *chatRoomModel);
|
||||
void setConferenceModel(ConferenceModel *conferenceModel);
|
||||
void setShowMe(const bool &show);
|
||||
|
||||
// Q_INVOKABLE void addAddress(const QString &address);
|
||||
Q_INVOKABLE void removeParticipant(ParticipantCore *participant);
|
||||
Q_INVOKABLE void setAddresses(ConferenceInfoModel *conferenceInfoModel);
|
||||
|
||||
signals:
|
||||
void chatRoomModelChanged();
|
||||
void conferenceModelChanged();
|
||||
void participantListChanged();
|
||||
void countChanged();
|
||||
void showMeChanged();
|
||||
void addressAdded(QString sipAddress);
|
||||
void addressRemoved(QString sipAddress);
|
||||
|
||||
private:
|
||||
// ChatRoomModel *mChatRoomModel = nullptr;
|
||||
// ConferenceModel *mConferenceModel = nullptr;
|
||||
bool mShowMe = true;
|
||||
QSharedPointer<ParticipantList> mList;
|
||||
};
|
||||
|
||||
#endif // PARTICIPANT_PROXY_H_
|
||||
56
Linphone/core/timezone/TimeZone.cpp
Normal file
56
Linphone/core/timezone/TimeZone.cpp
Normal file
|
|
@ -0,0 +1,56 @@
|
|||
/*
|
||||
* 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 <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "TimeZone.hpp"
|
||||
|
||||
#include "core/App.hpp"
|
||||
|
||||
#include <QQmlApplicationEngine>
|
||||
|
||||
// =============================================================================
|
||||
|
||||
TimeZoneModel::TimeZoneModel(const QTimeZone &timeZone, QObject *parent) : QObject(parent) {
|
||||
App::getInstance()->mEngine->setObjectOwnership(
|
||||
this, QQmlEngine::CppOwnership); // Avoid QML to destroy it when passing by Q_INVOKABLE
|
||||
mTimeZone = timeZone;
|
||||
}
|
||||
|
||||
TimeZoneModel::~TimeZoneModel() {
|
||||
}
|
||||
|
||||
QTimeZone TimeZoneModel::getTimeZone() const {
|
||||
return mTimeZone;
|
||||
}
|
||||
|
||||
int TimeZoneModel::getOffsetFromUtc() const {
|
||||
return mTimeZone.offsetFromUtc(QDateTime::currentDateTime());
|
||||
}
|
||||
|
||||
int TimeZoneModel::getStandardTimeOffset() const {
|
||||
return mTimeZone.standardTimeOffset(QDateTime::currentDateTime());
|
||||
}
|
||||
|
||||
QString TimeZoneModel::getCountryName() const {
|
||||
return QLocale::countryToString(mTimeZone.country());
|
||||
}
|
||||
|
||||
QString TimeZoneModel::getDisplayName() const {
|
||||
return mTimeZone.displayName(QTimeZone::TimeType::GenericTime, QTimeZone::NameType::LongName);
|
||||
}
|
||||
53
Linphone/core/timezone/TimeZone.hpp
Normal file
53
Linphone/core/timezone/TimeZone.hpp
Normal file
|
|
@ -0,0 +1,53 @@
|
|||
/*
|
||||
* 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 <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef TIME_ZONE_MODEL_H_
|
||||
#define TIME_ZONE_MODEL_H_
|
||||
|
||||
#include <QObject>
|
||||
#include <QTimeZone>
|
||||
|
||||
#include <linphone++/linphone.hh>
|
||||
|
||||
// =============================================================================
|
||||
|
||||
class TimeZoneModel : public QObject {
|
||||
Q_OBJECT
|
||||
Q_PROPERTY(QTimeZone timezone MEMBER mTimeZone CONSTANT)
|
||||
Q_PROPERTY(int offsetFromUtc READ getOffsetFromUtc CONSTANT)
|
||||
Q_PROPERTY(int standardTimeOffset READ getStandardTimeOffset CONSTANT)
|
||||
Q_PROPERTY(QString countryName READ getCountryName CONSTANT)
|
||||
Q_PROPERTY(QString displayName READ getDisplayName CONSTANT)
|
||||
|
||||
public:
|
||||
TimeZoneModel(const QTimeZone &timeZone, QObject *parent = nullptr);
|
||||
virtual ~TimeZoneModel();
|
||||
|
||||
QTimeZone getTimeZone() const;
|
||||
int getOffsetFromUtc() const;
|
||||
int getStandardTimeOffset() const;
|
||||
QString getCountryName() const;
|
||||
QString getDisplayName() const;
|
||||
|
||||
private:
|
||||
QTimeZone mTimeZone;
|
||||
};
|
||||
Q_DECLARE_METATYPE(TimeZoneModel *);
|
||||
#endif
|
||||
105
Linphone/core/timezone/TimeZoneList.cpp
Normal file
105
Linphone/core/timezone/TimeZoneList.cpp
Normal file
|
|
@ -0,0 +1,105 @@
|
|||
/*
|
||||
* 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 <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "TimeZoneList.hpp"
|
||||
#include "core/App.hpp"
|
||||
|
||||
#include <QTimeZone>
|
||||
|
||||
// =============================================================================
|
||||
|
||||
DEFINE_ABSTRACT_OBJECT(TimeZoneList)
|
||||
|
||||
using namespace std;
|
||||
|
||||
QSharedPointer<TimeZoneList> TimeZoneList::create() {
|
||||
auto model = QSharedPointer<TimeZoneList>(new TimeZoneList(), &QObject::deleteLater);
|
||||
model->moveToThread(App::getInstance()->thread());
|
||||
return model;
|
||||
}
|
||||
|
||||
TimeZoneList::TimeZoneList(QObject *parent) : ListProxy(parent) {
|
||||
initTimeZones();
|
||||
}
|
||||
|
||||
TimeZoneList::~TimeZoneList() {
|
||||
mustBeInMainThread("~" + getClassName());
|
||||
}
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
void TimeZoneList::initTimeZones() {
|
||||
resetData();
|
||||
for (auto id : QTimeZone::availableTimeZoneIds()) {
|
||||
auto model = QSharedPointer<TimeZoneModel>::create(QTimeZone(id));
|
||||
if (std::find_if(mList.begin(), mList.end(), [id](const QSharedPointer<QObject> &a) {
|
||||
return a.objectCast<TimeZoneModel>()->getTimeZone() == QTimeZone(id);
|
||||
}) == mList.end()) {
|
||||
if (model->getCountryName().toUpper() != "DEFAULT") {
|
||||
add(model);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
QHash<int, QByteArray> TimeZoneList::roleNames() const {
|
||||
QHash<int, QByteArray> roles;
|
||||
roles[Qt::DisplayRole] = "modelData";
|
||||
roles[Qt::DisplayRole + 1] = "timeZoneModel";
|
||||
return roles;
|
||||
}
|
||||
|
||||
QVariant TimeZoneList::data(const QModelIndex &index, int role) const {
|
||||
int row = index.row();
|
||||
|
||||
if (!index.isValid() || row < 0 || row >= mList.count()) return QVariant();
|
||||
auto timeZoneModel = getAt<TimeZoneModel>(row);
|
||||
if (!timeZoneModel) return QVariant();
|
||||
if (role == Qt::DisplayRole) {
|
||||
int offset = timeZoneModel->getStandardTimeOffset() / 3600;
|
||||
int absOffset = std::abs(offset);
|
||||
|
||||
return QStringLiteral("(GMT%1%2%3:00) %4 %5")
|
||||
.arg(offset >= 0 ? "+" : "-")
|
||||
.arg(absOffset < 10 ? "0" : "")
|
||||
.arg(absOffset)
|
||||
.arg(timeZoneModel->getCountryName())
|
||||
.arg(timeZoneModel->getTimeZone().comment().isEmpty() ? ""
|
||||
: (" - " + timeZoneModel->getTimeZone().comment()));
|
||||
} else {
|
||||
return QVariant::fromValue(timeZoneModel.get());
|
||||
}
|
||||
|
||||
return QVariant();
|
||||
}
|
||||
|
||||
int TimeZoneList::get(const QTimeZone &timeZone) const {
|
||||
auto it = find_if(mList.cbegin(), mList.cend(), [&timeZone](QSharedPointer<QObject> item) {
|
||||
return item.objectCast<TimeZoneModel>()->getTimeZone() == timeZone;
|
||||
});
|
||||
if (it == mList.cend()) {
|
||||
auto today = QDateTime::currentDateTime();
|
||||
it = find_if(mList.cbegin(), mList.cend(), [&timeZone, today](QSharedPointer<QObject> item) {
|
||||
auto tz = item.objectCast<TimeZoneModel>()->getTimeZone();
|
||||
return (timeZone.country() == QLocale::AnyCountry || tz.country() == timeZone.country()) &&
|
||||
tz.standardTimeOffset(today) == timeZone.standardTimeOffset(today);
|
||||
});
|
||||
}
|
||||
return it != mList.cend() ? int(distance(mList.cbegin(), it)) : 0;
|
||||
}
|
||||
48
Linphone/core/timezone/TimeZoneList.hpp
Normal file
48
Linphone/core/timezone/TimeZoneList.hpp
Normal file
|
|
@ -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 <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef TIME_ZONE_LIST_MODEL_H_
|
||||
#define TIME_ZONE_LIST_MODEL_H_
|
||||
|
||||
#include "../proxy/ListProxy.hpp"
|
||||
#include "core/timezone/TimeZone.hpp"
|
||||
#include "tool/AbstractObject.hpp"
|
||||
// =============================================================================
|
||||
|
||||
class TimeZoneList : public ListProxy, public AbstractObject {
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
static QSharedPointer<TimeZoneList> create();
|
||||
|
||||
TimeZoneList(QObject *parent = Q_NULLPTR);
|
||||
~TimeZoneList();
|
||||
|
||||
void initTimeZones();
|
||||
int get(const QTimeZone &timeZone = QTimeZone::systemTimeZone()) const;
|
||||
|
||||
QHash<int, QByteArray> roleNames() const override;
|
||||
QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const override;
|
||||
|
||||
private:
|
||||
DECLARE_ABSTRACT_OBJECT
|
||||
};
|
||||
|
||||
#endif
|
||||
51
Linphone/core/timezone/TimeZoneProxy.cpp
Normal file
51
Linphone/core/timezone/TimeZoneProxy.cpp
Normal file
|
|
@ -0,0 +1,51 @@
|
|||
/*
|
||||
* 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 <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "TimeZoneProxy.hpp"
|
||||
#include "TimeZoneList.hpp"
|
||||
#include "core/timezone/TimeZone.hpp"
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
TimeZoneProxy::TimeZoneProxy(QObject *parent) : SortFilterProxy(parent) {
|
||||
mDeleteSourceModel = true;
|
||||
mList = TimeZoneList::create();
|
||||
setSourceModel(mList.get());
|
||||
sort(0);
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
bool TimeZoneProxy::lessThan(const QModelIndex &left, const QModelIndex &right) const {
|
||||
auto test = sourceModel()->data(left);
|
||||
auto l = getItemAt<TimeZoneList, TimeZoneModel>(left.row());
|
||||
auto r = getItemAt<TimeZoneList, TimeZoneModel>(right.row());
|
||||
if (!l || !r) return true;
|
||||
auto timeA = l->getStandardTimeOffset() / 3600;
|
||||
auto timeB = r->getStandardTimeOffset() / 3600;
|
||||
|
||||
return timeA < timeB || (timeA == timeB && l->getCountryName() < r->getCountryName());
|
||||
}
|
||||
|
||||
int TimeZoneProxy::getIndex(TimeZoneModel *model) const {
|
||||
int index = 0;
|
||||
index = mList->get(model ? model->getTimeZone() : QTimeZone::systemTimeZone());
|
||||
return mapFromSource(mList->index(index, 0)).row();
|
||||
}
|
||||
44
Linphone/core/timezone/TimeZoneProxy.hpp
Normal file
44
Linphone/core/timezone/TimeZoneProxy.hpp
Normal file
|
|
@ -0,0 +1,44 @@
|
|||
/*
|
||||
* 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 <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef TIME_ZONE_PROXY_MODEL_H_
|
||||
#define TIME_ZONE_PROXY_MODEL_H_
|
||||
|
||||
#include "../proxy/SortFilterProxy.hpp"
|
||||
|
||||
// =============================================================================
|
||||
|
||||
class TimeZoneModel;
|
||||
class TimeZoneList;
|
||||
|
||||
class TimeZoneProxy : public SortFilterProxy {
|
||||
Q_OBJECT
|
||||
public:
|
||||
TimeZoneProxy(QObject *parent = Q_NULLPTR);
|
||||
Q_PROPERTY(int defaultIndex READ getIndex CONSTANT)
|
||||
|
||||
Q_INVOKABLE int getIndex(TimeZoneModel *model = nullptr) const;
|
||||
|
||||
protected:
|
||||
QSharedPointer<TimeZoneList> mList;
|
||||
bool lessThan(const QModelIndex &left, const QModelIndex &right) const override;
|
||||
};
|
||||
|
||||
#endif
|
||||
3
Linphone/data/image/note.svg
Normal file
3
Linphone/data/image/note.svg
Normal file
|
|
@ -0,0 +1,3 @@
|
|||
<svg width="32" height="32" viewBox="0 0 32 32" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path d="M11 12C11 11.7348 11.1054 11.4804 11.2929 11.2929C11.4804 11.1054 11.7348 11 12 11H20C20.2652 11 20.5196 11.1054 20.7071 11.2929C20.8946 11.4804 21 11.7348 21 12C21 12.2652 20.8946 12.5196 20.7071 12.7071C20.5196 12.8946 20.2652 13 20 13H12C11.7348 13 11.4804 12.8946 11.2929 12.7071C11.1054 12.5196 11 12.2652 11 12ZM12 17H20C20.2652 17 20.5196 16.8946 20.7071 16.7071C20.8946 16.5196 21 16.2652 21 16C21 15.7348 20.8946 15.4804 20.7071 15.2929C20.5196 15.1054 20.2652 15 20 15H12C11.7348 15 11.4804 15.1054 11.2929 15.2929C11.1054 15.4804 11 15.7348 11 16C11 16.2652 11.1054 16.5196 11.2929 16.7071C11.4804 16.8946 11.7348 17 12 17ZM16 19H12C11.7348 19 11.4804 19.1054 11.2929 19.2929C11.1054 19.4804 11 19.7348 11 20C11 20.2652 11.1054 20.5196 11.2929 20.7071C11.4804 20.8946 11.7348 21 12 21H16C16.2652 21 16.5196 20.8946 16.7071 20.7071C16.8946 20.5196 17 20.2652 17 20C17 19.7348 16.8946 19.4804 16.7071 19.2929C16.5196 19.1054 16.2652 19 16 19ZM28 6V19.5863C28.0008 19.849 27.9494 20.1093 27.8488 20.352C27.7482 20.5947 27.6003 20.815 27.4137 21L21 27.4137C20.815 27.6003 20.5947 27.7482 20.352 27.8488C20.1093 27.9494 19.849 28.0008 19.5863 28H6C5.46957 28 4.96086 27.7893 4.58579 27.4142C4.21071 27.0391 4 26.5304 4 26V6C4 5.46957 4.21071 4.96086 4.58579 4.58579C4.96086 4.21071 5.46957 4 6 4H26C26.5304 4 27.0391 4.21071 27.4142 4.58579C27.7893 4.96086 28 5.46957 28 6ZM6 26H19V20C19 19.7348 19.1054 19.4804 19.2929 19.2929C19.4804 19.1054 19.7348 19 20 19H26V6H6V26ZM21 21V24.5875L24.5863 21H21Z" fill="#343330"/>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 1.6 KiB |
3
Linphone/data/image/smiley-sad.svg
Normal file
3
Linphone/data/image/smiley-sad.svg
Normal file
|
|
@ -0,0 +1,3 @@
|
|||
<svg width="32" height="32" viewBox="0 0 32 32" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path d="M16 3C13.4288 3 10.9154 3.76244 8.77759 5.1909C6.63975 6.61935 4.97351 8.64968 3.98957 11.0251C3.00563 13.4006 2.74819 16.0144 3.2498 18.5362C3.75141 21.0579 4.98953 23.3743 6.80762 25.1924C8.6257 27.0105 10.9421 28.2486 13.4638 28.7502C15.9856 29.2518 18.5995 28.9944 20.9749 28.0104C23.3503 27.0265 25.3807 25.3603 26.8091 23.2224C28.2376 21.0846 29 18.5712 29 16C28.9964 12.5533 27.6256 9.24882 25.1884 6.81163C22.7512 4.37445 19.4467 3.00364 16 3ZM16 27C13.8244 27 11.6977 26.3549 9.88873 25.1462C8.07979 23.9375 6.66989 22.2195 5.83733 20.2095C5.00477 18.1995 4.78693 15.9878 5.21137 13.854C5.63581 11.7202 6.68345 9.7602 8.22183 8.22183C9.76021 6.68345 11.7202 5.6358 13.854 5.21136C15.9878 4.78692 18.1995 5.00476 20.2095 5.83733C22.2195 6.66989 23.9375 8.07979 25.1462 9.88873C26.3549 11.6977 27 13.8244 27 16C26.9967 18.9164 25.8367 21.7123 23.7745 23.7745C21.7123 25.8367 18.9164 26.9967 16 27ZM10 13.5C10 13.2033 10.088 12.9133 10.2528 12.6666C10.4176 12.42 10.6519 12.2277 10.926 12.1142C11.2001 12.0006 11.5017 11.9709 11.7926 12.0288C12.0836 12.0867 12.3509 12.2296 12.5607 12.4393C12.7704 12.6491 12.9133 12.9164 12.9712 13.2074C13.0291 13.4983 12.9994 13.7999 12.8858 14.074C12.7723 14.3481 12.58 14.5824 12.3334 14.7472C12.0867 14.912 11.7967 15 11.5 15C11.1022 15 10.7206 14.842 10.4393 14.5607C10.158 14.2794 10 13.8978 10 13.5ZM22 13.5C22 13.7967 21.912 14.0867 21.7472 14.3334C21.5824 14.58 21.3481 14.7723 21.074 14.8858C20.7999 14.9994 20.4983 15.0291 20.2074 14.9712C19.9164 14.9133 19.6491 14.7704 19.4393 14.5607C19.2296 14.3509 19.0867 14.0836 19.0288 13.7926C18.971 13.5017 19.0007 13.2001 19.1142 12.926C19.2277 12.6519 19.42 12.4176 19.6667 12.2528C19.9133 12.088 20.2033 12 20.5 12C20.8978 12 21.2794 12.158 21.5607 12.4393C21.842 12.7206 22 13.1022 22 13.5ZM21.865 21.5C21.9374 21.6138 21.9859 21.7411 22.0078 21.8742C22.0297 22.0073 22.0245 22.1434 21.9924 22.2744C21.9603 22.4054 21.902 22.5285 21.8211 22.6364C21.7402 22.7443 21.6383 22.8348 21.5215 22.9022C21.4048 22.9697 21.2756 23.0129 21.1417 23.0292C21.0078 23.0454 20.872 23.0345 20.7425 22.9969C20.6129 22.9593 20.4924 22.8959 20.388 22.8105C20.2836 22.7251 20.1975 22.6195 20.135 22.5C19.2013 20.8862 17.7338 20 16 20C14.2663 20 12.7988 20.8875 11.865 22.5C11.8025 22.6195 11.7164 22.7251 11.6121 22.8105C11.5077 22.8959 11.3871 22.9593 11.2575 22.9969C11.128 23.0345 10.9922 23.0454 10.8583 23.0292C10.7245 23.0129 10.5952 22.9697 10.4785 22.9022C10.3617 22.8348 10.2598 22.7443 10.1789 22.6364C10.098 22.5285 10.0397 22.4054 10.0076 22.2744C9.97555 22.1434 9.97029 22.0073 9.99218 21.8742C10.0141 21.7411 10.0627 21.6138 10.135 21.5C11.4213 19.2762 13.5588 18 16 18C18.4413 18 20.5788 19.275 21.865 21.5Z" fill="#343330"/>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 2.8 KiB |
|
|
@ -1 +1,3 @@
|
|||
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" fill="#4e6074" viewBox="0 0 256 256"><path d="M128,24A104,104,0,1,0,232,128,104.11,104.11,0,0,0,128,24Zm0,192a88,88,0,1,1,88-88A88.1,88.1,0,0,1,128,216ZM80,108a12,12,0,1,1,12,12A12,12,0,0,1,80,108Zm96,0a12,12,0,1,1-12-12A12,12,0,0,1,176,108Zm-1.07,48c-10.29,17.79-27.4,28-46.93,28s-36.63-10.2-46.92-28a8,8,0,1,1,13.84-8c7.47,12.91,19.21,20,33.08,20s25.61-7.1,33.07-20a8,8,0,0,1,13.86,8Z"></path></svg>
|
||||
<svg width="32" height="32" viewBox="0 0 32 32" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path d="M16 3C13.4288 3 10.9154 3.76244 8.77759 5.1909C6.63975 6.61935 4.97351 8.64968 3.98957 11.0251C3.00563 13.4006 2.74819 16.0144 3.2498 18.5362C3.75141 21.0579 4.98953 23.3743 6.80762 25.1924C8.6257 27.0105 10.9421 28.2486 13.4638 28.7502C15.9856 29.2518 18.5995 28.9944 20.9749 28.0104C23.3503 27.0265 25.3807 25.3603 26.8091 23.2224C28.2376 21.0846 29 18.5712 29 16C28.9964 12.5533 27.6256 9.24882 25.1884 6.81163C22.7512 4.37445 19.4467 3.00364 16 3ZM16 27C13.8244 27 11.6977 26.3549 9.88873 25.1462C8.07979 23.9375 6.66989 22.2195 5.83733 20.2095C5.00477 18.1995 4.78693 15.9878 5.21137 13.854C5.63581 11.7202 6.68345 9.7602 8.22183 8.22183C9.76021 6.68345 11.7202 5.6358 13.854 5.21136C15.9878 4.78692 18.1995 5.00476 20.2095 5.83733C22.2195 6.66989 23.9375 8.07979 25.1462 9.88873C26.3549 11.6977 27 13.8244 27 16C26.9967 18.9164 25.8367 21.7123 23.7745 23.7745C21.7123 25.8367 18.9164 26.9967 16 27ZM10 13.5C10 13.2033 10.088 12.9133 10.2528 12.6666C10.4176 12.42 10.6519 12.2277 10.926 12.1142C11.2001 12.0006 11.5017 11.9709 11.7926 12.0288C12.0836 12.0867 12.3509 12.2296 12.5607 12.4393C12.7704 12.6491 12.9133 12.9164 12.9712 13.2074C13.0291 13.4983 12.9994 13.7999 12.8858 14.074C12.7723 14.3481 12.58 14.5824 12.3334 14.7472C12.0867 14.912 11.7967 15 11.5 15C11.1022 15 10.7206 14.842 10.4393 14.5607C10.158 14.2794 10 13.8978 10 13.5ZM22 13.5C22 13.7967 21.912 14.0867 21.7472 14.3334C21.5824 14.58 21.3481 14.7723 21.074 14.8858C20.7999 14.9994 20.4983 15.0291 20.2074 14.9712C19.9164 14.9133 19.6491 14.7704 19.4393 14.5607C19.2296 14.3509 19.0867 14.0836 19.0288 13.7926C18.971 13.5017 19.0007 13.2001 19.1142 12.926C19.2277 12.6519 19.42 12.4176 19.6667 12.2528C19.9133 12.088 20.2033 12 20.5 12C20.8978 12 21.2794 12.158 21.5607 12.4393C21.842 12.7206 22 13.1022 22 13.5ZM21.8663 19.5C20.58 21.7238 18.4413 23 16 23C13.5588 23 11.4213 21.725 10.135 19.5C10.0627 19.3862 10.0141 19.2589 9.99218 19.1258C9.97029 18.9927 9.97555 18.8566 10.0076 18.7256C10.0397 18.5946 10.098 18.4715 10.1789 18.3636C10.2598 18.2557 10.3617 18.1652 10.4785 18.0978C10.5952 18.0303 10.7245 17.9871 10.8583 17.9708C10.9922 17.9546 11.128 17.9655 11.2575 18.0031C11.3871 18.0407 11.5077 18.1041 11.6121 18.1895C11.7164 18.2749 11.8025 18.3805 11.865 18.5C12.7988 20.1138 14.2663 21 16 21C17.7338 21 19.2013 20.1125 20.1338 18.5C20.2664 18.2703 20.4848 18.1026 20.741 18.0339C20.9972 17.9652 21.2703 18.0011 21.5 18.1338C21.7297 18.2664 21.8974 18.4848 21.9661 18.741C22.0348 18.9972 21.9989 19.2703 21.8663 19.5Z" fill="#343330"/>
|
||||
</svg>
|
||||
|
|
|
|||
|
Before Width: | Height: | Size: 464 B After Width: | Height: | Size: 2.6 KiB |
3
Linphone/data/image/user-rectangle.svg
Normal file
3
Linphone/data/image/user-rectangle.svg
Normal file
|
|
@ -0,0 +1,3 @@
|
|||
<svg width="32" height="32" viewBox="0 0 32 32" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path d="M27 5H5C4.46957 5 3.96086 5.21071 3.58579 5.58579C3.21071 5.96086 3 6.46957 3 7V25C3 25.5304 3.21071 26.0391 3.58579 26.4142C3.96086 26.7893 4.46957 27 5 27H27C27.5304 27 28.0391 26.7893 28.4142 26.4142C28.7893 26.0391 29 25.5304 29 25V7C29 6.46957 28.7893 5.96086 28.4142 5.58579C28.0391 5.21071 27.5304 5 27 5ZM12 15C12 14.2089 12.2346 13.4355 12.6741 12.7777C13.1136 12.1199 13.7384 11.6072 14.4693 11.3045C15.2002 11.0017 16.0044 10.9225 16.7804 11.0769C17.5563 11.2312 18.269 11.6122 18.8284 12.1716C19.3878 12.731 19.7688 13.4437 19.9231 14.2196C20.0775 14.9956 19.9983 15.7998 19.6955 16.5307C19.3928 17.2616 18.8801 17.8864 18.2223 18.3259C17.5645 18.7654 16.7911 19 16 19C14.9391 19 13.9217 18.5786 13.1716 17.8284C12.4214 17.0783 12 16.0609 12 15ZM9.07125 25C9.77332 23.7836 10.7833 22.7734 11.9995 22.0711C13.2158 21.3688 14.5955 20.9991 16 20.9991C17.4045 20.9991 18.7842 21.3688 20.0005 22.0711C21.2167 22.7734 22.2267 23.7836 22.9287 25H9.07125ZM27 25H25.1663C24.1107 22.5894 22.1489 20.6909 19.705 19.715C20.6866 18.9444 21.4035 17.8868 21.7559 16.6896C22.1082 15.4924 22.0785 14.2151 21.6708 13.0355C21.2631 11.856 20.4978 10.833 19.4814 10.1088C18.4649 9.38473 17.248 8.99557 16 8.99557C14.752 8.99557 13.5351 9.38473 12.5186 10.1088C11.5022 10.833 10.7369 11.856 10.3292 13.0355C9.92149 14.2151 9.89175 15.4924 10.2441 16.6896C10.5965 17.8868 11.3134 18.9444 12.295 19.715C9.85107 20.6909 7.88932 22.5894 6.83375 25H5V7H27V25Z" fill="#343330"/>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 1.5 KiB |
|
|
@ -5,6 +5,13 @@ list(APPEND _LINPHONEAPP_SOURCES
|
|||
model/call/CallModel.cpp
|
||||
|
||||
model/call-history/CallHistoryModel.cpp
|
||||
|
||||
model/conference/ConferenceInfoModel.cpp
|
||||
model/conference/ConferenceModel.cpp
|
||||
model/conference/ConferenceSchedulerModel.cpp
|
||||
|
||||
model/participant/ParticipantDeviceModel.cpp
|
||||
model/participant/ParticipantModel.cpp
|
||||
|
||||
model/core/CoreModel.cpp
|
||||
|
||||
|
|
|
|||
|
|
@ -23,7 +23,6 @@
|
|||
#include <QDebug>
|
||||
|
||||
#include "model/core/CoreModel.hpp"
|
||||
#include "tool/Utils.hpp"
|
||||
|
||||
DEFINE_ABSTRACT_OBJECT(CallHistoryModel)
|
||||
|
||||
|
|
@ -37,5 +36,6 @@ CallHistoryModel::~CallHistoryModel() {
|
|||
}
|
||||
|
||||
void CallHistoryModel::removeCallHistory() {
|
||||
mustBeInLinphoneThread(getClassName() + "::removeCallHistory");
|
||||
CoreModel::getInstance()->getCore()->removeCallLog(callLog);
|
||||
}
|
||||
145
Linphone/model/conference/ConferenceInfoModel.cpp
Normal file
145
Linphone/model/conference/ConferenceInfoModel.cpp
Normal file
|
|
@ -0,0 +1,145 @@
|
|||
/*
|
||||
* Copyright (c) 2010-2024 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 <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "ConferenceInfoModel.hpp"
|
||||
|
||||
#include <QDebug>
|
||||
|
||||
#include "core/participant/ParticipantList.hpp"
|
||||
#include "core/path/Paths.hpp"
|
||||
#include "model/core/CoreModel.hpp"
|
||||
#include "model/tool/ToolModel.hpp"
|
||||
#include "tool/Utils.hpp"
|
||||
|
||||
DEFINE_ABSTRACT_OBJECT(ConferenceInfoModel)
|
||||
|
||||
ConferenceInfoModel::ConferenceInfoModel(const std::shared_ptr<linphone::ConferenceInfo> &conferenceInfo,
|
||||
QObject *parent)
|
||||
: mConferenceInfo(conferenceInfo) {
|
||||
mustBeInLinphoneThread(getClassName());
|
||||
}
|
||||
|
||||
ConferenceInfoModel::~ConferenceInfoModel() {
|
||||
mustBeInLinphoneThread("~" + getClassName());
|
||||
if (mConferenceSchedulerModel) mConferenceSchedulerModel->removeListener();
|
||||
}
|
||||
|
||||
void ConferenceInfoModel::createConferenceScheduler() {
|
||||
mustBeInLinphoneThread(getClassName() + "::createConferenceScheduler()");
|
||||
}
|
||||
|
||||
std::shared_ptr<ConferenceSchedulerModel> ConferenceInfoModel::getConferenceScheduler() const {
|
||||
return mConferenceSchedulerModel;
|
||||
}
|
||||
|
||||
void ConferenceInfoModel::setConferenceScheduler(const std::shared_ptr<ConferenceSchedulerModel> &model) {
|
||||
if (mConferenceSchedulerModel != model) {
|
||||
if (mConferenceSchedulerModel) {
|
||||
disconnect(mConferenceSchedulerModel.get(), &ConferenceSchedulerModel::stateChanged, this, nullptr);
|
||||
disconnect(mConferenceSchedulerModel.get(), &ConferenceSchedulerModel::invitationsSent, this, nullptr);
|
||||
mConferenceSchedulerModel->removeListener();
|
||||
}
|
||||
mConferenceSchedulerModel = model;
|
||||
connect(mConferenceSchedulerModel.get(), &ConferenceSchedulerModel::stateChanged, this,
|
||||
&ConferenceInfoModel::stateChanged);
|
||||
connect(mConferenceSchedulerModel.get(), &ConferenceSchedulerModel::invitationsSent, this,
|
||||
&ConferenceInfoModel::invitationsSent);
|
||||
mConferenceSchedulerModel->setSelf(mConferenceSchedulerModel);
|
||||
}
|
||||
}
|
||||
|
||||
QDateTime ConferenceInfoModel::getDateTime() const {
|
||||
return QDateTime::fromMSecsSinceEpoch(mConferenceInfo->getDateTime() * 1000, Qt::LocalTime);
|
||||
}
|
||||
|
||||
int ConferenceInfoModel::getDuration() const {
|
||||
return mConferenceInfo->getDuration();
|
||||
}
|
||||
|
||||
QDateTime ConferenceInfoModel::getEndTime() const {
|
||||
return getDateTime().addSecs(mConferenceInfo->getDuration());
|
||||
}
|
||||
|
||||
QString ConferenceInfoModel::getSubject() const {
|
||||
return Utils::coreStringToAppString(mConferenceInfo->getSubject());
|
||||
}
|
||||
|
||||
QString ConferenceInfoModel::getOrganizerName() const {
|
||||
auto organizer = mConferenceInfo->getOrganizer();
|
||||
auto name = Utils::coreStringToAppString(organizer->getDisplayName());
|
||||
if (name.isEmpty()) name = ToolModel::getDisplayName(Utils::coreStringToAppString(organizer->asStringUriOnly()));
|
||||
return name;
|
||||
}
|
||||
|
||||
QString ConferenceInfoModel::getOrganizerAddress() const {
|
||||
return Utils::coreStringToAppString(mConferenceInfo->getOrganizer()->asStringUriOnly());
|
||||
}
|
||||
|
||||
QString ConferenceInfoModel::getDescription() const {
|
||||
return Utils::coreStringToAppString(mConferenceInfo->getSubject());
|
||||
}
|
||||
|
||||
std::list<std::shared_ptr<linphone::ParticipantInfo>> ConferenceInfoModel::getParticipantInfos() const {
|
||||
return mConferenceInfo->getParticipantInfos();
|
||||
}
|
||||
|
||||
void ConferenceInfoModel::setDateTime(const QDateTime &date) {
|
||||
mConferenceInfo->setDateTime(date.toMSecsSinceEpoch() / 1000); // toMSecsSinceEpoch() is UTC
|
||||
emit dateTimeChanged(date);
|
||||
}
|
||||
|
||||
void ConferenceInfoModel::setDuration(int duration) {
|
||||
mConferenceInfo->setDuration(duration);
|
||||
emit durationChanged(duration);
|
||||
}
|
||||
|
||||
void ConferenceInfoModel::setSubject(const QString &subject) {
|
||||
mConferenceInfo->setSubject(Utils::appStringToCoreString(subject));
|
||||
emit subjectChanged(subject);
|
||||
}
|
||||
|
||||
void ConferenceInfoModel::setOrganizer(const QString &organizerAddress) {
|
||||
auto linAddr = ToolModel::interpretUrl(organizerAddress);
|
||||
if (linAddr) {
|
||||
mConferenceInfo->setOrganizer(linAddr);
|
||||
emit organizerChanged(organizerAddress);
|
||||
}
|
||||
}
|
||||
|
||||
void ConferenceInfoModel::setDescription(const QString &description) {
|
||||
mConferenceInfo->setDescription(Utils::appStringToCoreString(description));
|
||||
emit descriptionChanged(description);
|
||||
}
|
||||
|
||||
void ConferenceInfoModel::setParticipantInfos(
|
||||
const std::list<std::shared_ptr<linphone::ParticipantInfo>> &participantInfos) {
|
||||
mConferenceInfo->setParticipantInfos(participantInfos);
|
||||
emit participantsChanged();
|
||||
}
|
||||
|
||||
void ConferenceInfoModel::deleteConferenceInfo() {
|
||||
CoreModel::getInstance()->getCore()->deleteConferenceInformation(mConferenceInfo);
|
||||
emit conferenceInfoDeleted();
|
||||
}
|
||||
|
||||
void ConferenceInfoModel::cancelConference() {
|
||||
if (!mConferenceSchedulerModel) return;
|
||||
mConferenceSchedulerModel->cancelConference(mConferenceInfo);
|
||||
}
|
||||
79
Linphone/model/conference/ConferenceInfoModel.hpp
Normal file
79
Linphone/model/conference/ConferenceInfoModel.hpp
Normal file
|
|
@ -0,0 +1,79 @@
|
|||
/*
|
||||
* Copyright (c) 2010-2024 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 <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef CONFERENCE_INFO_MODEL_H_
|
||||
#define CONFERENCE_INFO_MODEL_H_
|
||||
|
||||
#include "model/conference/ConferenceSchedulerModel.hpp"
|
||||
#include "tool/AbstractObject.hpp"
|
||||
|
||||
#include <QObject>
|
||||
#include <QTimer>
|
||||
#include <linphone++/linphone.hh>
|
||||
|
||||
class ConferenceInfoModel : public QObject, public AbstractObject {
|
||||
Q_OBJECT
|
||||
public:
|
||||
ConferenceInfoModel(const std::shared_ptr<linphone::ConferenceInfo> &conferenceInfo, QObject *parent = nullptr);
|
||||
~ConferenceInfoModel();
|
||||
|
||||
void createConferenceScheduler();
|
||||
|
||||
std::shared_ptr<ConferenceSchedulerModel> getConferenceScheduler() const;
|
||||
void setConferenceScheduler(const std::shared_ptr<ConferenceSchedulerModel> &model);
|
||||
QDateTime getDateTime() const;
|
||||
int getDuration() const;
|
||||
QDateTime getEndTime() const;
|
||||
QString getSubject() const;
|
||||
QString getOrganizerName() const;
|
||||
QString getOrganizerAddress() const;
|
||||
QString getDescription() const;
|
||||
std::list<std::shared_ptr<linphone::ParticipantInfo>> getParticipantInfos() const;
|
||||
|
||||
void setDateTime(const QDateTime &date);
|
||||
void setDuration(int duration);
|
||||
void setSubject(const QString &subject);
|
||||
void setOrganizer(const QString &organizerAddress);
|
||||
void setDescription(const QString &description);
|
||||
void setParticipantInfos(const std::list<std::shared_ptr<linphone::ParticipantInfo>> &participantInfos);
|
||||
void deleteConferenceInfo();
|
||||
void cancelConference();
|
||||
|
||||
signals:
|
||||
void dateTimeChanged(const QDateTime &date);
|
||||
void durationChanged(int duration);
|
||||
void organizerChanged(const QString &organizer);
|
||||
void subjectChanged(const QString &subject);
|
||||
void descriptionChanged(const QString &description);
|
||||
void participantsChanged();
|
||||
void conferenceInfoDeleted();
|
||||
void stateChanged(linphone::ConferenceScheduler::State state);
|
||||
void invitationsSent(const std::list<std::shared_ptr<linphone::Address>> &failedInvitations);
|
||||
|
||||
private:
|
||||
std::shared_ptr<linphone::ConferenceInfo> mConferenceInfo;
|
||||
std::shared_ptr<ConferenceSchedulerModel> mConferenceSchedulerModel = nullptr;
|
||||
DECLARE_ABSTRACT_OBJECT
|
||||
|
||||
// LINPHONE
|
||||
//--------------------------------------------------------------------------------
|
||||
};
|
||||
|
||||
#endif
|
||||
218
Linphone/model/conference/ConferenceModel.cpp
Normal file
218
Linphone/model/conference/ConferenceModel.cpp
Normal file
|
|
@ -0,0 +1,218 @@
|
|||
/*
|
||||
* Copyright (c) 2010-2024 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 <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "ConferenceModel.hpp"
|
||||
|
||||
#include <QDebug>
|
||||
|
||||
#include "core/path/Paths.hpp"
|
||||
#include "model/core/CoreModel.hpp"
|
||||
|
||||
DEFINE_ABSTRACT_OBJECT(ConferenceModel)
|
||||
|
||||
ConferenceModel::ConferenceModel(const std::shared_ptr<linphone::Conference> &conference, QObject *parent)
|
||||
: ::Listener<linphone::Conference, linphone::ConferenceListener>(conference, parent) {
|
||||
mustBeInLinphoneThread(getClassName());
|
||||
}
|
||||
|
||||
ConferenceModel::~ConferenceModel() {
|
||||
mustBeInLinphoneThread("~" + getClassName());
|
||||
}
|
||||
|
||||
void ConferenceModel::terminate() {
|
||||
mustBeInLinphoneThread(log().arg(Q_FUNC_INFO));
|
||||
mMonitor->terminate();
|
||||
}
|
||||
void ConferenceModel::setPaused(bool paused) {
|
||||
mustBeInLinphoneThread(log().arg(Q_FUNC_INFO));
|
||||
}
|
||||
|
||||
void ConferenceModel::removeParticipant(std::shared_ptr<linphone::Participant> p) {
|
||||
mMonitor->removeParticipant(p);
|
||||
}
|
||||
|
||||
void ConferenceModel::removeParticipant(std::shared_ptr<linphone::Address> address) {
|
||||
for (auto &p : mMonitor->getParticipantList()) {
|
||||
if (address->asStringUriOnly() == p->getAddress()->asStringUriOnly()) {
|
||||
mMonitor->removeParticipant(p);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void ConferenceModel::setMicrophoneMuted(bool isMuted) {
|
||||
mustBeInLinphoneThread(log().arg(Q_FUNC_INFO));
|
||||
mMonitor->setMicrophoneMuted(isMuted);
|
||||
emit microphoneMutedChanged(isMuted);
|
||||
}
|
||||
|
||||
void ConferenceModel::startRecording() {
|
||||
mustBeInLinphoneThread(log().arg(Q_FUNC_INFO));
|
||||
// mMonitor->startRecording(mMonitor->getCurrentParams()->getRecordFile());
|
||||
// emit recordingChanged(mMonitor->getParams()->isRecording());
|
||||
}
|
||||
|
||||
void ConferenceModel::stopRecording() {
|
||||
mustBeInLinphoneThread(log().arg(Q_FUNC_INFO));
|
||||
mMonitor->stopRecording();
|
||||
// emit recordingChanged(mMonitor->getParams()->isRecording());
|
||||
// TODO : display notification
|
||||
}
|
||||
|
||||
void ConferenceModel::setRecordFile(const std::string &path) {
|
||||
mustBeInLinphoneThread(log().arg(Q_FUNC_INFO));
|
||||
auto core = CoreModel::getInstance()->getCore();
|
||||
// auto params = core->createCallParams(mMonitor);
|
||||
// params->setRecordFile(path);
|
||||
// mMonitor->update(params);
|
||||
}
|
||||
|
||||
// void ConferenceModel::setSpeakerVolumeGain(float gain) {
|
||||
// mMonitor->setSpeakerVolumeGain(gain);
|
||||
// emit speakerVolumeGainChanged(gain);
|
||||
// }
|
||||
|
||||
// float ConferenceModel::getSpeakerVolumeGain() const {
|
||||
// auto gain = mMonitor->getSpeakerVolumeGain();
|
||||
// if (gain < 0) gain = CoreModel::getInstance()->getCore()->getPlaybackGainDb();
|
||||
// return gain;
|
||||
// }
|
||||
|
||||
// void ConferenceModel::setMicrophoneVolumeGain(float gain) {
|
||||
// mMonitor->setMicrophoneVolumeGain(gain);
|
||||
// emit microphoneVolumeGainChanged(gain);
|
||||
// }
|
||||
|
||||
// float ConferenceModel::getMicrophoneVolumeGain() const {
|
||||
// auto gain = mMonitor->getMicrophoneVolumeGain();
|
||||
// return gain;
|
||||
// }
|
||||
|
||||
// float ConferenceModel::getMicrophoneVolume() const {
|
||||
// auto volume = mMonitor->getRecordVolume();
|
||||
// return volume;
|
||||
// }
|
||||
|
||||
void ConferenceModel::setInputAudioDevice(const std::shared_ptr<linphone::AudioDevice> &device) {
|
||||
mMonitor->setInputAudioDevice(device);
|
||||
std::string deviceName;
|
||||
if (device) deviceName = device->getDeviceName();
|
||||
emit inputAudioDeviceChanged(deviceName);
|
||||
}
|
||||
|
||||
std::shared_ptr<const linphone::AudioDevice> ConferenceModel::getInputAudioDevice() const {
|
||||
return mMonitor->getInputAudioDevice();
|
||||
}
|
||||
|
||||
void ConferenceModel::setOutputAudioDevice(const std::shared_ptr<linphone::AudioDevice> &device) {
|
||||
mMonitor->setOutputAudioDevice(device);
|
||||
std::string deviceName;
|
||||
if (device) deviceName = device->getDeviceName();
|
||||
emit outputAudioDeviceChanged(deviceName);
|
||||
}
|
||||
|
||||
std::shared_ptr<const linphone::AudioDevice> ConferenceModel::getOutputAudioDevice() const {
|
||||
return mMonitor->getOutputAudioDevice();
|
||||
}
|
||||
|
||||
void ConferenceModel::onActiveSpeakerParticipantDevice(
|
||||
const std::shared_ptr<linphone::Conference> &conference,
|
||||
const std::shared_ptr<const linphone::ParticipantDevice> &participantDevice) {
|
||||
qDebug() << "onActiveSpeakerParticipantDevice: " << participantDevice->getAddress()->asString().c_str();
|
||||
emit activeSpeakerParticipantDevice(participantDevice);
|
||||
}
|
||||
|
||||
void ConferenceModel::onParticipantAdded(const std::shared_ptr<linphone::Conference> &conference,
|
||||
const std::shared_ptr<const linphone::Participant> &participant) {
|
||||
qDebug() << "onParticipantAdded: " << participant->getAddress()->asString().c_str();
|
||||
emit participantAdded(participant);
|
||||
}
|
||||
void ConferenceModel::onParticipantRemoved(const std::shared_ptr<linphone::Conference> &conference,
|
||||
const std::shared_ptr<const linphone::Participant> &participant) {
|
||||
qDebug() << "onParticipantRemoved";
|
||||
emit participantRemoved(participant);
|
||||
}
|
||||
void ConferenceModel::onParticipantDeviceAdded(
|
||||
const std::shared_ptr<linphone::Conference> &conference,
|
||||
const std::shared_ptr<const linphone::ParticipantDevice> &participantDevice) {
|
||||
qDebug() << "onParticipantDeviceAdded";
|
||||
qDebug() << "Me devices : " << conference->getMe()->getDevices().size();
|
||||
if (conference->getMe()->getDevices().size() > 1)
|
||||
for (auto d : conference->getMe()->getDevices())
|
||||
qDebug() << "\t--> " << d->getAddress()->asString().c_str();
|
||||
emit participantDeviceAdded(participantDevice);
|
||||
}
|
||||
void ConferenceModel::onParticipantDeviceRemoved(
|
||||
const std::shared_ptr<linphone::Conference> &conference,
|
||||
const std::shared_ptr<const linphone::ParticipantDevice> &participantDevice) {
|
||||
qDebug() << "onParticipantDeviceRemoved: " << participantDevice->getAddress()->asString().c_str() << " isInConf?["
|
||||
<< participantDevice->isInConference() << "]";
|
||||
qDebug() << "Me devices : " << conference->getMe()->getDevices().size();
|
||||
emit participantDeviceRemoved(participantDevice);
|
||||
}
|
||||
void ConferenceModel::onParticipantDeviceStateChanged(const std::shared_ptr<linphone::Conference> &conference,
|
||||
const std::shared_ptr<const linphone::ParticipantDevice> &device,
|
||||
linphone::ParticipantDevice::State state) {
|
||||
qDebug() << "onParticipantDeviceStateChanged: " << device->getAddress()->asString().c_str() << " isInConf?["
|
||||
<< device->isInConference() << "] " << (int)state;
|
||||
emit participantDeviceStateChanged(conference, device, state);
|
||||
}
|
||||
void ConferenceModel::onParticipantAdminStatusChanged(const std::shared_ptr<linphone::Conference> &conference,
|
||||
const std::shared_ptr<const linphone::Participant> &participant) {
|
||||
qDebug() << "onParticipantAdminStatusChanged";
|
||||
emit participantAdminStatusChanged(participant);
|
||||
}
|
||||
void ConferenceModel::onParticipantDeviceMediaCapabilityChanged(
|
||||
const std::shared_ptr<linphone::Conference> &conference,
|
||||
const std::shared_ptr<const linphone::ParticipantDevice> &participantDevice) {
|
||||
qDebug() << "onParticipantDeviceMediaCapabilityChanged: "
|
||||
<< (int)participantDevice->getStreamCapability(linphone::StreamType::Video)
|
||||
<< ". Device: " << participantDevice->getAddress()->asString().c_str();
|
||||
emit participantDeviceMediaCapabilityChanged(participantDevice);
|
||||
}
|
||||
void ConferenceModel::onParticipantDeviceMediaAvailabilityChanged(
|
||||
const std::shared_ptr<linphone::Conference> &conference,
|
||||
const std::shared_ptr<const linphone::ParticipantDevice> &participantDevice) {
|
||||
qDebug() << "onParticipantDeviceMediaAvailabilityChanged: "
|
||||
<< (int)participantDevice->getStreamAvailability(linphone::StreamType::Video)
|
||||
<< ". Device: " << participantDevice->getAddress()->asString().c_str();
|
||||
emit participantDeviceMediaAvailabilityChanged(participantDevice);
|
||||
}
|
||||
void ConferenceModel::onParticipantDeviceIsSpeakingChanged(
|
||||
const std::shared_ptr<linphone::Conference> &conference,
|
||||
const std::shared_ptr<const linphone::ParticipantDevice> &participantDevice,
|
||||
bool isSpeaking) {
|
||||
// qDebug() << "onParticipantDeviceIsSpeakingChanged: " << participantDevice->getAddress()->asString().c_str() <<
|
||||
// ". Speaking:" << isSpeaking;
|
||||
emit participantDeviceIsSpeakingChanged(participantDevice, isSpeaking);
|
||||
}
|
||||
void ConferenceModel::onStateChanged(const std::shared_ptr<linphone::Conference> &conference,
|
||||
linphone::Conference::State newState) {
|
||||
qDebug() << "onStateChanged:" << (int)newState;
|
||||
emit conferenceStateChanged(newState);
|
||||
}
|
||||
void ConferenceModel::onSubjectChanged(const std::shared_ptr<linphone::Conference> &conference,
|
||||
const std::string &subject) {
|
||||
qDebug() << "onSubjectChanged";
|
||||
emit subjectChanged(subject);
|
||||
}
|
||||
void ConferenceModel::onAudioDeviceChanged(const std::shared_ptr<linphone::Conference> &conference,
|
||||
const std::shared_ptr<const linphone::AudioDevice> &audioDevice) {
|
||||
qDebug() << "onAudioDeviceChanged is not yet implemented.";
|
||||
}
|
||||
135
Linphone/model/conference/ConferenceModel.hpp
Normal file
135
Linphone/model/conference/ConferenceModel.hpp
Normal file
|
|
@ -0,0 +1,135 @@
|
|||
/*
|
||||
* Copyright (c) 2010-2024 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 <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef CONFERENCE_MODEL_H_
|
||||
#define CONFERENCE_MODEL_H_
|
||||
|
||||
#include "model/listener/Listener.hpp"
|
||||
#include "tool/AbstractObject.hpp"
|
||||
|
||||
#include <QObject>
|
||||
#include <QTimer>
|
||||
#include <linphone++/linphone.hh>
|
||||
|
||||
class ConferenceModel : public ::Listener<linphone::Conference, linphone::ConferenceListener>,
|
||||
public linphone::ConferenceListener,
|
||||
public AbstractObject {
|
||||
Q_OBJECT
|
||||
public:
|
||||
ConferenceModel(const std::shared_ptr<linphone::Conference> &conference, QObject *parent = nullptr);
|
||||
~ConferenceModel();
|
||||
|
||||
void terminate();
|
||||
|
||||
void setMicrophoneMuted(bool isMuted);
|
||||
void startRecording();
|
||||
void stopRecording();
|
||||
void setRecordFile(const std::string &path);
|
||||
void setInputAudioDevice(const std::shared_ptr<linphone::AudioDevice> &id);
|
||||
std::shared_ptr<const linphone::AudioDevice> getInputAudioDevice() const;
|
||||
void setOutputAudioDevice(const std::shared_ptr<linphone::AudioDevice> &id);
|
||||
std::shared_ptr<const linphone::AudioDevice> getOutputAudioDevice() const;
|
||||
|
||||
void setPaused(bool paused);
|
||||
|
||||
void removeParticipant(std::shared_ptr<linphone::Participant> p);
|
||||
void removeParticipant(std::shared_ptr<linphone::Address> address);
|
||||
|
||||
signals:
|
||||
void microphoneMutedChanged(bool isMuted);
|
||||
void speakerMutedChanged(bool isMuted);
|
||||
void cameraEnabledChanged(bool enabled);
|
||||
void durationChanged(int);
|
||||
void microphoneVolumeChanged(float);
|
||||
void pausedChanged(bool paused);
|
||||
void remoteVideoEnabledChanged(bool remoteVideoEnabled);
|
||||
void recordingChanged(bool recording);
|
||||
void speakerVolumeGainChanged(float volume);
|
||||
void microphoneVolumeGainChanged(float volume);
|
||||
void inputAudioDeviceChanged(const std::string &id);
|
||||
void outputAudioDeviceChanged(const std::string &id);
|
||||
|
||||
private:
|
||||
// LINPHONE LISTENERS
|
||||
virtual void onActiveSpeakerParticipantDevice(
|
||||
const std::shared_ptr<linphone::Conference> &conference,
|
||||
const std::shared_ptr<const linphone::ParticipantDevice> &participantDevice) override;
|
||||
virtual void onParticipantAdded(const std::shared_ptr<linphone::Conference> &conference,
|
||||
const std::shared_ptr<const linphone::Participant> &participant) override;
|
||||
virtual void onParticipantRemoved(const std::shared_ptr<linphone::Conference> &conference,
|
||||
const std::shared_ptr<const linphone::Participant> &participant) override;
|
||||
virtual void
|
||||
onParticipantAdminStatusChanged(const std::shared_ptr<linphone::Conference> &conference,
|
||||
const std::shared_ptr<const linphone::Participant> &participant) override;
|
||||
virtual void
|
||||
onParticipantDeviceAdded(const std::shared_ptr<linphone::Conference> &conference,
|
||||
const std::shared_ptr<const linphone::ParticipantDevice> &participantDevice) override;
|
||||
virtual void
|
||||
onParticipantDeviceRemoved(const std::shared_ptr<linphone::Conference> &conference,
|
||||
const std::shared_ptr<const linphone::ParticipantDevice> &participantDevice) override;
|
||||
virtual void onParticipantDeviceStateChanged(const std::shared_ptr<linphone::Conference> &conference,
|
||||
const std::shared_ptr<const linphone::ParticipantDevice> &device,
|
||||
linphone::ParticipantDevice::State state) override;
|
||||
virtual void onParticipantDeviceMediaCapabilityChanged(
|
||||
const std::shared_ptr<linphone::Conference> &conference,
|
||||
const std::shared_ptr<const linphone::ParticipantDevice> &device) override;
|
||||
virtual void onParticipantDeviceMediaAvailabilityChanged(
|
||||
const std::shared_ptr<linphone::Conference> &conference,
|
||||
const std::shared_ptr<const linphone::ParticipantDevice> &device) override;
|
||||
virtual void
|
||||
onParticipantDeviceIsSpeakingChanged(const std::shared_ptr<linphone::Conference> &conference,
|
||||
const std::shared_ptr<const linphone::ParticipantDevice> &participantDevice,
|
||||
bool isSpeaking) override;
|
||||
virtual void onStateChanged(const std::shared_ptr<linphone::Conference> &conference,
|
||||
linphone::Conference::State newState) override;
|
||||
virtual void onSubjectChanged(const std::shared_ptr<linphone::Conference> &conference,
|
||||
const std::string &subject) override;
|
||||
virtual void onAudioDeviceChanged(const std::shared_ptr<linphone::Conference> &conference,
|
||||
const std::shared_ptr<const linphone::AudioDevice> &audioDevice) override;
|
||||
|
||||
signals:
|
||||
void activeSpeakerParticipantDevice(const std::shared_ptr<const linphone::ParticipantDevice> &participantDevice);
|
||||
void participantAdded(const std::shared_ptr<const linphone::Participant> &participant);
|
||||
void participantRemoved(const std::shared_ptr<const linphone::Participant> &participant);
|
||||
void participantAdminStatusChanged(const std::shared_ptr<const linphone::Participant> &participant);
|
||||
void participantDeviceAdded(const std::shared_ptr<const linphone::ParticipantDevice> &participantDevice);
|
||||
void participantDeviceRemoved(const std::shared_ptr<const linphone::ParticipantDevice> &participantDevice);
|
||||
void participantDeviceStateChanged(const std::shared_ptr<linphone::Conference> &conference,
|
||||
const std::shared_ptr<const linphone::ParticipantDevice> &device,
|
||||
linphone::ParticipantDevice::State state);
|
||||
void participantDeviceMediaCapabilityChanged(
|
||||
const std::shared_ptr<const linphone::ParticipantDevice> &participantDevice);
|
||||
void participantDeviceMediaAvailabilityChanged(
|
||||
const std::shared_ptr<const linphone::ParticipantDevice> &participantDevice);
|
||||
void participantDeviceIsSpeakingChanged(const std::shared_ptr<const linphone::ParticipantDevice> &participantDevice,
|
||||
bool isSpeaking);
|
||||
void conferenceStateChanged(linphone::Conference::State newState);
|
||||
void subjectChanged(const std::string &subject);
|
||||
|
||||
private:
|
||||
QTimer mDurationTimer;
|
||||
QTimer mMicroVolumeTimer;
|
||||
DECLARE_ABSTRACT_OBJECT
|
||||
|
||||
// LINPHONE
|
||||
//--------------------------------------------------------------------------------
|
||||
};
|
||||
|
||||
#endif
|
||||
59
Linphone/model/conference/ConferenceSchedulerModel.cpp
Normal file
59
Linphone/model/conference/ConferenceSchedulerModel.cpp
Normal file
|
|
@ -0,0 +1,59 @@
|
|||
/*
|
||||
* Copyright (c) 2010-2024 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 <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "ConferenceSchedulerModel.hpp"
|
||||
|
||||
#include <QDebug>
|
||||
|
||||
#include "model/core/CoreModel.hpp"
|
||||
|
||||
DEFINE_ABSTRACT_OBJECT(ConferenceSchedulerModel)
|
||||
|
||||
ConferenceSchedulerModel::ConferenceSchedulerModel(
|
||||
const std::shared_ptr<linphone::ConferenceScheduler> &conferenceScheduler, QObject *parent)
|
||||
: ::Listener<linphone::ConferenceScheduler, linphone::ConferenceSchedulerListener>(conferenceScheduler, parent) {
|
||||
mustBeInLinphoneThread(getClassName());
|
||||
auto defaultAccount = CoreModel::getInstance()->getCore()->getDefaultAccount();
|
||||
assert(defaultAccount);
|
||||
mMonitor->setAccount(CoreModel::getInstance()->getCore()->getDefaultAccount());
|
||||
}
|
||||
|
||||
ConferenceSchedulerModel::~ConferenceSchedulerModel() {
|
||||
mustBeInLinphoneThread("~" + getClassName());
|
||||
}
|
||||
|
||||
void ConferenceSchedulerModel::setInfo(const std::shared_ptr<linphone::ConferenceInfo> &confInfo) {
|
||||
mMonitor->setInfo(confInfo);
|
||||
}
|
||||
|
||||
void ConferenceSchedulerModel::cancelConference(const std::shared_ptr<linphone::ConferenceInfo> &confInfo) {
|
||||
mMonitor->cancelConference(confInfo);
|
||||
}
|
||||
|
||||
void ConferenceSchedulerModel::onStateChanged(const std::shared_ptr<linphone::ConferenceScheduler> &conferenceScheduler,
|
||||
linphone::ConferenceScheduler::State state) {
|
||||
emit stateChanged(state);
|
||||
}
|
||||
|
||||
void ConferenceSchedulerModel::onInvitationsSent(
|
||||
const std::shared_ptr<linphone::ConferenceScheduler> &conferenceScheduler,
|
||||
const std::list<std::shared_ptr<linphone::Address>> &failedInvitations) {
|
||||
emit invitationsSent(failedInvitations);
|
||||
}
|
||||
60
Linphone/model/conference/ConferenceSchedulerModel.hpp
Normal file
60
Linphone/model/conference/ConferenceSchedulerModel.hpp
Normal file
|
|
@ -0,0 +1,60 @@
|
|||
/*
|
||||
* Copyright (c) 2010-2024 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 <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef CONFERENCE_SCHEDULER_MODEL_H_
|
||||
#define CONFERENCE_SCHEDULER_MODEL_H_
|
||||
|
||||
#include "model/listener/Listener.hpp"
|
||||
#include "tool/AbstractObject.hpp"
|
||||
|
||||
#include <QObject>
|
||||
#include <QTimer>
|
||||
#include <linphone++/linphone.hh>
|
||||
|
||||
class ConferenceSchedulerModel
|
||||
: public ::Listener<linphone::ConferenceScheduler, linphone::ConferenceSchedulerListener>,
|
||||
public linphone::ConferenceSchedulerListener,
|
||||
public AbstractObject {
|
||||
Q_OBJECT
|
||||
public:
|
||||
ConferenceSchedulerModel(const std::shared_ptr<linphone::ConferenceScheduler> &conferenceScheduler,
|
||||
QObject *parent = nullptr);
|
||||
~ConferenceSchedulerModel();
|
||||
|
||||
void setInfo(const std::shared_ptr<linphone::ConferenceInfo> &confInfo);
|
||||
void cancelConference(const std::shared_ptr<linphone::ConferenceInfo> &confInfo);
|
||||
|
||||
signals:
|
||||
void stateChanged(linphone::ConferenceScheduler::State state);
|
||||
void invitationsSent(const std::list<std::shared_ptr<linphone::Address>> &failedInvitations);
|
||||
|
||||
private:
|
||||
DECLARE_ABSTRACT_OBJECT
|
||||
|
||||
//--------------------------------------------------------------------------------
|
||||
// LINPHONE
|
||||
//--------------------------------------------------------------------------------
|
||||
virtual void onStateChanged(const std::shared_ptr<linphone::ConferenceScheduler> &conferenceScheduler,
|
||||
linphone::ConferenceScheduler::State state) override;
|
||||
virtual void onInvitationsSent(const std::shared_ptr<linphone::ConferenceScheduler> &conferenceScheduler,
|
||||
const std::list<std::shared_ptr<linphone::Address>> &failedInvitations) override;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
@ -220,8 +220,13 @@ void CoreModel::onConferenceInfoReceived(const std::shared_ptr<linphone::Core> &
|
|||
const std::shared_ptr<const linphone::ConferenceInfo> &conferenceInfo) {
|
||||
emit conferenceInfoReceived(core, conferenceInfo);
|
||||
}
|
||||
void CoreModel::onConferenceStateChanged(const std::shared_ptr<linphone::Core> &core,
|
||||
const std::shared_ptr<linphone::Conference> &conference,
|
||||
linphone::Conference::State state) {
|
||||
emit conferenceStateChanged(core, conference, state);
|
||||
}
|
||||
void CoreModel::onConfiguringStatus(const std::shared_ptr<linphone::Core> &core,
|
||||
linphone::ConfiguringState status,
|
||||
linphone::Config::ConfiguringState status,
|
||||
const std::string &message) {
|
||||
emit configuringStatus(core, status, message);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -108,8 +108,12 @@ private:
|
|||
virtual void
|
||||
onConferenceInfoReceived(const std::shared_ptr<linphone::Core> &core,
|
||||
const std::shared_ptr<const linphone::ConferenceInfo> &conferenceInfo) override;
|
||||
virtual void onConferenceStateChanged(const std::shared_ptr<linphone::Core> &core,
|
||||
const std::shared_ptr<linphone::Conference> &conference,
|
||||
linphone::Conference::State state) override;
|
||||
|
||||
virtual void onConfiguringStatus(const std::shared_ptr<linphone::Core> &core,
|
||||
linphone::ConfiguringState status,
|
||||
linphone::Config::ConfiguringState status,
|
||||
const std::string &message) override;
|
||||
virtual void onDefaultAccountChanged(const std::shared_ptr<linphone::Core> &core,
|
||||
const std::shared_ptr<linphone::Account> &account) override;
|
||||
|
|
@ -192,8 +196,11 @@ signals:
|
|||
linphone::ChatRoom::State state);
|
||||
void conferenceInfoReceived(const std::shared_ptr<linphone::Core> &core,
|
||||
const std::shared_ptr<const linphone::ConferenceInfo> &conferenceInfo);
|
||||
void conferenceStateChanged(const std::shared_ptr<linphone::Core> &core,
|
||||
const std::shared_ptr<linphone::Conference> &conference,
|
||||
linphone::Conference::State state);
|
||||
void configuringStatus(const std::shared_ptr<linphone::Core> &core,
|
||||
linphone::ConfiguringState status,
|
||||
linphone::Config::ConfiguringState status,
|
||||
const std::string &message);
|
||||
void defaultAccountChanged(const std::shared_ptr<linphone::Core> &core,
|
||||
const std::shared_ptr<linphone::Account> &account);
|
||||
|
|
|
|||
122
Linphone/model/participant/ParticipantDeviceModel.cpp
Normal file
122
Linphone/model/participant/ParticipantDeviceModel.cpp
Normal file
|
|
@ -0,0 +1,122 @@
|
|||
/*
|
||||
* 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 <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "ParticipantDeviceModel.hpp"
|
||||
|
||||
#include "core/App.hpp"
|
||||
#include "tool/Utils.hpp"
|
||||
#include <QQmlApplicationEngine>
|
||||
|
||||
DEFINE_ABSTRACT_OBJECT(ParticipantDeviceModel)
|
||||
|
||||
ParticipantDeviceModel::ParticipantDeviceModel(const std::shared_ptr<linphone::ParticipantDevice> &device,
|
||||
QObject *parent)
|
||||
: ::Listener<linphone::ParticipantDevice, linphone::ParticipantDeviceListener>(device, parent) {
|
||||
mustBeInLinphoneThread(getClassName());
|
||||
}
|
||||
|
||||
ParticipantDeviceModel::~ParticipantDeviceModel() {
|
||||
}
|
||||
|
||||
QString ParticipantDeviceModel::getName() const {
|
||||
return Utils::coreStringToAppString(mMonitor->getName());
|
||||
}
|
||||
|
||||
QString ParticipantDeviceModel::getDisplayName() const {
|
||||
return Utils::coreStringToAppString(mMonitor->getAddress()->getDisplayName());
|
||||
}
|
||||
|
||||
int ParticipantDeviceModel::getSecurityLevel() const {
|
||||
return (int)mMonitor->getSecurityLevel();
|
||||
}
|
||||
|
||||
time_t ParticipantDeviceModel::getTimeOfJoining() const {
|
||||
return mMonitor->getTimeOfJoining();
|
||||
}
|
||||
|
||||
QString ParticipantDeviceModel::getAddress() const {
|
||||
return Utils::coreStringToAppString(mMonitor->getAddress()->asStringUriOnly());
|
||||
}
|
||||
|
||||
bool ParticipantDeviceModel::getPaused() const {
|
||||
return !mMonitor->isInConference() || mMonitor->getState() == linphone::ParticipantDevice::State::OnHold;
|
||||
}
|
||||
|
||||
bool ParticipantDeviceModel::getIsSpeaking() const {
|
||||
return mMonitor->getIsSpeaking();
|
||||
}
|
||||
|
||||
bool ParticipantDeviceModel::getIsMuted() const {
|
||||
return mMonitor->getIsMuted();
|
||||
}
|
||||
|
||||
LinphoneEnums::ParticipantDeviceState ParticipantDeviceModel::getState() const {
|
||||
return LinphoneEnums::fromLinphone(mMonitor->getState());
|
||||
}
|
||||
|
||||
bool ParticipantDeviceModel::isVideoEnabled() const {
|
||||
return mMonitor->isInConference() && mMonitor->getStreamAvailability(linphone::StreamType::Video) &&
|
||||
(mMonitor->getStreamCapability(linphone::StreamType::Video) == linphone::MediaDirection::SendRecv ||
|
||||
mMonitor->getStreamCapability(linphone::StreamType::Video) == linphone::MediaDirection::SendOnly);
|
||||
}
|
||||
|
||||
// void ParticipantDeviceModel::updateIsLocal() {
|
||||
// auto deviceAddress = mMonitor->getAddress();
|
||||
// auto callAddress = mCall->getConferenceSharedModel()->getConference()->getMe()->getAddress();
|
||||
// auto gruuAddress =
|
||||
// CoreManager::getInstance()->getAccountSettingsModel()->findAccount(callAddress)->getContactAddress();
|
||||
// setIsLocal(deviceAddress->equal(gruuAddress));
|
||||
// }
|
||||
|
||||
// void ParticipantDeviceModel::onSecurityLevelChanged(std::shared_ptr<const linphone::Address> device) {
|
||||
// if (!device || mMonitor && mMonitor->getAddress()->weakEqual(device)) emit securityLevelChanged();
|
||||
// }
|
||||
|
||||
// void ParticipantDeviceModel::onCallStatusChanged() {
|
||||
// if (mCall->getCall()->getState() == linphone::Call::State::StreamsRunning) {
|
||||
// updateVideoEnabled();
|
||||
// }
|
||||
// }
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
void ParticipantDeviceModel::onIsSpeakingChanged(const std::shared_ptr<linphone::ParticipantDevice> &participantDevice,
|
||||
bool isSpeaking) {
|
||||
emit isSpeakingChanged(isSpeaking);
|
||||
}
|
||||
void ParticipantDeviceModel::onIsMuted(const std::shared_ptr<linphone::ParticipantDevice> &participantDevice,
|
||||
bool isMuted) {
|
||||
emit isMutedChanged(isMuted);
|
||||
}
|
||||
void ParticipantDeviceModel::onStateChanged(const std::shared_ptr<linphone::ParticipantDevice> &participantDevice,
|
||||
linphone::ParticipantDevice::State state) {
|
||||
emit stateChanged(LinphoneEnums::fromLinphone(state));
|
||||
}
|
||||
void ParticipantDeviceModel::onStreamCapabilityChanged(
|
||||
const std::shared_ptr<linphone::ParticipantDevice> &participantDevice,
|
||||
linphone::MediaDirection direction,
|
||||
linphone::StreamType streamType) {
|
||||
emit streamCapabilityChanged(streamType);
|
||||
}
|
||||
void ParticipantDeviceModel::onStreamAvailabilityChanged(
|
||||
const std::shared_ptr<linphone::ParticipantDevice> &participantDevice,
|
||||
bool available,
|
||||
linphone::StreamType streamType) {
|
||||
emit streamAvailabilityChanged(streamType);
|
||||
}
|
||||
85
Linphone/model/participant/ParticipantDeviceModel.hpp
Normal file
85
Linphone/model/participant/ParticipantDeviceModel.hpp
Normal file
|
|
@ -0,0 +1,85 @@
|
|||
/*
|
||||
* Copyright (c) 2024 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 <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef PARTICIPANT_DEVICE_MODEL_H_
|
||||
#define PARTICIPANT_DEVICE_MODEL_H_
|
||||
|
||||
#include "model/listener/Listener.hpp"
|
||||
#include "tool/AbstractObject.hpp"
|
||||
#include "tool/LinphoneEnums.hpp"
|
||||
#include <linphone++/linphone.hh>
|
||||
|
||||
#include <QDateTime>
|
||||
#include <QObject>
|
||||
#include <QSharedPointer>
|
||||
#include <QString>
|
||||
|
||||
class ParticipantDeviceModel : public ::Listener<linphone::ParticipantDevice, linphone::ParticipantDeviceListener>,
|
||||
public linphone::ParticipantDeviceListener,
|
||||
public AbstractObject {
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
ParticipantDeviceModel(const std::shared_ptr<linphone::ParticipantDevice> &device, QObject *parent = nullptr);
|
||||
virtual ~ParticipantDeviceModel();
|
||||
|
||||
QString getName() const;
|
||||
QString getDisplayName() const;
|
||||
QString getAddress() const;
|
||||
int getSecurityLevel() const;
|
||||
time_t getTimeOfJoining() const;
|
||||
bool isVideoEnabled() const;
|
||||
// bool isLocal() const;
|
||||
bool getPaused() const;
|
||||
bool getIsSpeaking() const;
|
||||
bool getIsMuted() const;
|
||||
LinphoneEnums::ParticipantDeviceState getState() const;
|
||||
|
||||
virtual void onIsSpeakingChanged(const std::shared_ptr<linphone::ParticipantDevice> &participantDevice,
|
||||
bool isSpeaking) override;
|
||||
virtual void onIsMuted(const std::shared_ptr<linphone::ParticipantDevice> &participantDevice,
|
||||
bool isMuted) override;
|
||||
virtual void onStateChanged(const std::shared_ptr<linphone::ParticipantDevice> &participantDevice,
|
||||
linphone::ParticipantDevice::State state) override;
|
||||
virtual void onStreamCapabilityChanged(const std::shared_ptr<linphone::ParticipantDevice> &participantDevice,
|
||||
linphone::MediaDirection direction,
|
||||
linphone::StreamType streamType) override;
|
||||
virtual void onStreamAvailabilityChanged(const std::shared_ptr<linphone::ParticipantDevice> &participantDevice,
|
||||
bool available,
|
||||
linphone::StreamType streamType) override;
|
||||
|
||||
// void updateVideoEnabled();
|
||||
// void updateIsLocal();
|
||||
|
||||
signals:
|
||||
// void securityLevelChanged();
|
||||
// void videoEnabledChanged();
|
||||
void isPausedChanged(bool paused);
|
||||
void isSpeakingChanged(bool speaking);
|
||||
void isMutedChanged(bool muted);
|
||||
void stateChanged(LinphoneEnums::ParticipantDeviceState state);
|
||||
void streamCapabilityChanged(linphone::StreamType streamType);
|
||||
void streamAvailabilityChanged(linphone::StreamType streamType);
|
||||
|
||||
private:
|
||||
DECLARE_ABSTRACT_OBJECT
|
||||
};
|
||||
|
||||
#endif // PARTICIPANT_DEVICE_MODEL_H_
|
||||
65
Linphone/model/participant/ParticipantModel.cpp
Normal file
65
Linphone/model/participant/ParticipantModel.cpp
Normal file
|
|
@ -0,0 +1,65 @@
|
|||
/*
|
||||
* 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 <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "ParticipantModel.hpp"
|
||||
|
||||
#include "tool/Utils.hpp"
|
||||
|
||||
#include <QTimer>
|
||||
|
||||
DEFINE_ABSTRACT_OBJECT(ParticipantModel)
|
||||
|
||||
ParticipantModel::ParticipantModel(std::shared_ptr<linphone::Participant> linphoneParticipant, QObject *parent)
|
||||
: QObject(parent) {
|
||||
assert(mParticipant);
|
||||
mParticipant = linphoneParticipant;
|
||||
}
|
||||
|
||||
ParticipantModel::~ParticipantModel() {
|
||||
mustBeInLinphoneThread("~" + getClassName());
|
||||
}
|
||||
|
||||
int ParticipantModel::getSecurityLevel() const {
|
||||
return (int)mParticipant->getSecurityLevel();
|
||||
}
|
||||
|
||||
std::list<std::shared_ptr<linphone::ParticipantDevice>> ParticipantModel::getDevices() const {
|
||||
return mParticipant->getDevices();
|
||||
}
|
||||
|
||||
int ParticipantModel::getDeviceCount() {
|
||||
return mParticipant->getDevices().size();
|
||||
}
|
||||
|
||||
QString ParticipantModel::getSipAddress() const {
|
||||
return Utils::coreStringToAppString(mParticipant->getAddress()->asString());
|
||||
}
|
||||
|
||||
QDateTime ParticipantModel::getCreationTime() const {
|
||||
return QDateTime::fromSecsSinceEpoch(mParticipant->getCreationTime());
|
||||
}
|
||||
|
||||
bool ParticipantModel::getAdminStatus() const {
|
||||
return mParticipant->isAdmin();
|
||||
}
|
||||
|
||||
bool ParticipantModel::isFocus() const {
|
||||
return mParticipant->isFocus();
|
||||
}
|
||||
56
Linphone/model/participant/ParticipantModel.hpp
Normal file
56
Linphone/model/participant/ParticipantModel.hpp
Normal file
|
|
@ -0,0 +1,56 @@
|
|||
/*
|
||||
* 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 <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef PARTICIPANT_MODEL_H_
|
||||
#define PARTICIPANT_MODEL_H_
|
||||
|
||||
#include "tool/AbstractObject.hpp"
|
||||
#include <linphone++/linphone.hh>
|
||||
|
||||
#include <QDateTime>
|
||||
#include <QObject>
|
||||
#include <QSharedPointer>
|
||||
#include <QString>
|
||||
|
||||
class ParticipantDeviceProxyModel;
|
||||
class ParticipantDeviceListModel;
|
||||
|
||||
class ParticipantModel : public QObject, public AbstractObject {
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
ParticipantModel(std::shared_ptr<linphone::Participant> linphoneParticipant, QObject *parent = nullptr);
|
||||
~ParticipantModel();
|
||||
|
||||
QString getSipAddress() const;
|
||||
QDateTime getCreationTime() const;
|
||||
bool getAdminStatus() const;
|
||||
bool isFocus() const;
|
||||
int getSecurityLevel() const;
|
||||
int getDeviceCount();
|
||||
std::list<std::shared_ptr<linphone::ParticipantDevice>> getDevices() const;
|
||||
|
||||
private:
|
||||
std::shared_ptr<linphone::Participant> mParticipant;
|
||||
|
||||
DECLARE_ABSTRACT_OBJECT
|
||||
};
|
||||
|
||||
#endif // PARTICIPANT_MODEL_H_
|
||||
|
|
@ -37,7 +37,7 @@ public:
|
|||
|
||||
//----------------------------------------------------------------------------------
|
||||
|
||||
static constexpr char DefaultLocale[] = "en";
|
||||
static constexpr char DefaultLocale[] = "en_EN";
|
||||
static constexpr char DefaultFont[] = "Noto Sans";
|
||||
static constexpr int DefaultFontPointSize = 10;
|
||||
|
||||
|
|
|
|||
|
|
@ -221,6 +221,14 @@ LinphoneEnums::ParticipantDeviceState LinphoneEnums::fromLinphone(const linphone
|
|||
return static_cast<LinphoneEnums::ParticipantDeviceState>(state);
|
||||
}
|
||||
|
||||
linphone::Participant::Role LinphoneEnums::toLinphone(const LinphoneEnums::ParticipantRole &role) {
|
||||
return static_cast<linphone::Participant::Role>(role);
|
||||
}
|
||||
|
||||
LinphoneEnums::ParticipantRole LinphoneEnums::fromLinphone(const linphone::Participant::Role &role) {
|
||||
return static_cast<LinphoneEnums::ParticipantRole>(role);
|
||||
}
|
||||
|
||||
linphone::Tunnel::Mode LinphoneEnums::toLinphone(const LinphoneEnums::TunnelMode &data) {
|
||||
return static_cast<linphone::Tunnel::Mode>(data);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -256,6 +256,15 @@ Q_ENUM_NS(ParticipantDeviceState)
|
|||
linphone::ParticipantDevice::State toLinphone(const LinphoneEnums::ParticipantDeviceState &state);
|
||||
LinphoneEnums::ParticipantDeviceState fromLinphone(const linphone::ParticipantDevice::State &state);
|
||||
|
||||
enum class ParticipantRole {
|
||||
Speaker = int(linphone::Participant::Role::Speaker),
|
||||
Listener = int(linphone::Participant::Role::Listener),
|
||||
Unknown = int(linphone::Participant::Role::Unknown)
|
||||
};
|
||||
Q_ENUM_NS(ParticipantRole)
|
||||
linphone::Participant::Role toLinphone(const LinphoneEnums::ParticipantRole &role);
|
||||
LinphoneEnums::ParticipantRole fromLinphone(const linphone::Participant::Role &role);
|
||||
|
||||
enum class RegistrationState {
|
||||
None = int(linphone::RegistrationState::None),
|
||||
Progress = int(linphone::RegistrationState::Progress),
|
||||
|
|
|
|||
|
|
@ -141,6 +141,12 @@ QQuickWindow *Utils::getMainWindow() {
|
|||
return win;
|
||||
}
|
||||
|
||||
void Utils::showInformationPopup(const QString &title, const QString &description, bool isSuccess) {
|
||||
auto win = App::getInstance()->getMainWindow();
|
||||
QMetaObject::invokeMethod(win, "showInformationPopup", Q_ARG(QVariant, title), Q_ARG(QVariant, description),
|
||||
Q_ARG(QVariant, isSuccess));
|
||||
}
|
||||
|
||||
VariantObject *Utils::haveAccount() {
|
||||
VariantObject *result = new VariantObject();
|
||||
if (!result) return nullptr;
|
||||
|
|
@ -274,6 +280,15 @@ QString Utils::generateLinphoneSipAddress(const QString &uri) {
|
|||
return ret;
|
||||
}
|
||||
|
||||
QString Utils::findAvatarByAddress(const QString &address) {
|
||||
auto defaultFriendList = CoreModel::getInstance()->getCore()->getDefaultFriendList();
|
||||
if (!defaultFriendList) return QString();
|
||||
auto linphoneAddr = ToolModel::interpretUrl(address);
|
||||
auto linFriend = CoreModel::getInstance()->getCore()->findFriend(linphoneAddr);
|
||||
if (linFriend) return Utils::coreStringToAppString(linFriend->getPhoto());
|
||||
return QString();
|
||||
}
|
||||
|
||||
QString Utils::generateSavedFilename(const QString &from, const QString &to) {
|
||||
auto escape = [](const QString &str) {
|
||||
constexpr char ReservedCharacters[] = "[<|>|:|\"|/|\\\\|\\?|\\*|\\+|\\||_|-]+";
|
||||
|
|
@ -340,3 +355,842 @@ QString Utils::computeUserAgent() {
|
|||
.arg(qVersion());
|
||||
*/
|
||||
}
|
||||
QString Utils::getCountryName(const QLocale::Country &p_country) {
|
||||
QString countryName;
|
||||
switch (p_country) {
|
||||
case QLocale::Afghanistan:
|
||||
if ((countryName = QCoreApplication::translate("country", "Afghanistan")) == "Afghanistan")
|
||||
countryName = "";
|
||||
break;
|
||||
case QLocale::Albania:
|
||||
if ((countryName = QCoreApplication::translate("country", "Albania")) == "Albania") countryName = "";
|
||||
break;
|
||||
case QLocale::Algeria:
|
||||
if ((countryName = QCoreApplication::translate("country", "Algeria")) == "Algeria") countryName = "";
|
||||
break;
|
||||
case QLocale::AmericanSamoa:
|
||||
if ((countryName = QCoreApplication::translate("country", "AmericanSamoa")) == "AmericanSamoa")
|
||||
countryName = "";
|
||||
break;
|
||||
case QLocale::Andorra:
|
||||
if ((countryName = QCoreApplication::translate("country", "Andorra")) == "Andorra") countryName = "";
|
||||
break;
|
||||
case QLocale::Angola:
|
||||
if ((countryName = QCoreApplication::translate("country", "Angola")) == "Angola") countryName = "";
|
||||
break;
|
||||
case QLocale::Anguilla:
|
||||
if ((countryName = QCoreApplication::translate("country", "Anguilla")) == "Anguilla") countryName = "";
|
||||
break;
|
||||
case QLocale::AntiguaAndBarbuda:
|
||||
if ((countryName = QCoreApplication::translate("country", "AntiguaAndBarbuda")) == "AntiguaAndBarbuda")
|
||||
countryName = "";
|
||||
break;
|
||||
case QLocale::Argentina:
|
||||
if ((countryName = QCoreApplication::translate("country", "Argentina")) == "Argentina") countryName = "";
|
||||
break;
|
||||
case QLocale::Armenia:
|
||||
if ((countryName = QCoreApplication::translate("country", "Armenia")) == "Armenia") countryName = "";
|
||||
break;
|
||||
case QLocale::Aruba:
|
||||
if ((countryName = QCoreApplication::translate("country", "Aruba")) == "Aruba") countryName = "";
|
||||
break;
|
||||
case QLocale::Australia:
|
||||
if ((countryName = QCoreApplication::translate("country", "Australia")) == "Australia") countryName = "";
|
||||
break;
|
||||
case QLocale::Austria:
|
||||
if ((countryName = QCoreApplication::translate("country", "Austria")) == "Austria") countryName = "";
|
||||
break;
|
||||
case QLocale::Azerbaijan:
|
||||
if ((countryName = QCoreApplication::translate("country", "Azerbaijan")) == "Azerbaijan") countryName = "";
|
||||
break;
|
||||
case QLocale::Bahamas:
|
||||
if ((countryName = QCoreApplication::translate("country", "Bahamas")) == "Bahamas") countryName = "";
|
||||
break;
|
||||
case QLocale::Bahrain:
|
||||
if ((countryName = QCoreApplication::translate("country", "Bahrain")) == "Bahrain") countryName = "";
|
||||
break;
|
||||
case QLocale::Bangladesh:
|
||||
if ((countryName = QCoreApplication::translate("country", "Bangladesh")) == "Bangladesh") countryName = "";
|
||||
break;
|
||||
case QLocale::Barbados:
|
||||
if ((countryName = QCoreApplication::translate("country", "Barbados")) == "Barbados") countryName = "";
|
||||
break;
|
||||
case QLocale::Belarus:
|
||||
if ((countryName = QCoreApplication::translate("country", "Belarus")) == "Belarus") countryName = "";
|
||||
break;
|
||||
case QLocale::Belgium:
|
||||
if ((countryName = QCoreApplication::translate("country", "Belgium")) == "Belgium") countryName = "";
|
||||
break;
|
||||
case QLocale::Belize:
|
||||
if ((countryName = QCoreApplication::translate("country", "Belize")) == "Belize") countryName = "";
|
||||
break;
|
||||
case QLocale::Benin:
|
||||
if ((countryName = QCoreApplication::translate("country", "Benin")) == "Benin") countryName = "";
|
||||
break;
|
||||
case QLocale::Bermuda:
|
||||
if ((countryName = QCoreApplication::translate("country", "Bermuda")) == "Bermuda") countryName = "";
|
||||
break;
|
||||
case QLocale::Bhutan:
|
||||
if ((countryName = QCoreApplication::translate("country", "Bhutan")) == "Bhutan") countryName = "";
|
||||
break;
|
||||
case QLocale::Bolivia:
|
||||
if ((countryName = QCoreApplication::translate("country", "Bolivia")) == "Bolivia") countryName = "";
|
||||
break;
|
||||
case QLocale::BosniaAndHerzegowina:
|
||||
if ((countryName = QCoreApplication::translate("country", "BosniaAndHerzegowina")) ==
|
||||
"BosniaAndHerzegowina")
|
||||
countryName = "";
|
||||
break;
|
||||
case QLocale::Botswana:
|
||||
if ((countryName = QCoreApplication::translate("country", "Botswana")) == "Botswana") countryName = "";
|
||||
break;
|
||||
case QLocale::Brazil:
|
||||
if ((countryName = QCoreApplication::translate("country", "Brazil")) == "Brazil") countryName = "";
|
||||
break;
|
||||
case QLocale::Brunei:
|
||||
if ((countryName = QCoreApplication::translate("country", "Brunei")) == "Brunei") countryName = "";
|
||||
break;
|
||||
case QLocale::Bulgaria:
|
||||
if ((countryName = QCoreApplication::translate("country", "Bulgaria")) == "Bulgaria") countryName = "";
|
||||
break;
|
||||
case QLocale::BurkinaFaso:
|
||||
if ((countryName = QCoreApplication::translate("country", "BurkinaFaso")) == "BurkinaFaso")
|
||||
countryName = "";
|
||||
break;
|
||||
case QLocale::Burundi:
|
||||
if ((countryName = QCoreApplication::translate("country", "Burundi")) == "Burundi") countryName = "";
|
||||
break;
|
||||
case QLocale::Cambodia:
|
||||
if ((countryName = QCoreApplication::translate("country", "Cambodia")) == "Cambodia") countryName = "";
|
||||
break;
|
||||
case QLocale::Cameroon:
|
||||
if ((countryName = QCoreApplication::translate("country", "Cameroon")) == "Cameroon") countryName = "";
|
||||
break;
|
||||
case QLocale::Canada:
|
||||
if ((countryName = QCoreApplication::translate("country", "Canada")) == "Canada") countryName = "";
|
||||
break;
|
||||
case QLocale::CapeVerde:
|
||||
if ((countryName = QCoreApplication::translate("country", "CapeVerde")) == "CapeVerde") countryName = "";
|
||||
break;
|
||||
case QLocale::CaymanIslands:
|
||||
if ((countryName = QCoreApplication::translate("country", "CaymanIslands")) == "CaymanIslands")
|
||||
countryName = "";
|
||||
break;
|
||||
case QLocale::CentralAfricanRepublic:
|
||||
if ((countryName = QCoreApplication::translate("country", "CentralAfricanRepublic")) ==
|
||||
"CentralAfricanRepublic")
|
||||
countryName = "";
|
||||
break;
|
||||
case QLocale::Chad:
|
||||
if ((countryName = QCoreApplication::translate("country", "Chad")) == "Chad") countryName = "";
|
||||
break;
|
||||
case QLocale::Chile:
|
||||
if ((countryName = QCoreApplication::translate("country", "Chile")) == "Chile") countryName = "";
|
||||
break;
|
||||
case QLocale::China:
|
||||
if ((countryName = QCoreApplication::translate("country", "China")) == "China") countryName = "";
|
||||
break;
|
||||
case QLocale::Colombia:
|
||||
if ((countryName = QCoreApplication::translate("country", "Colombia")) == "Colombia") countryName = "";
|
||||
break;
|
||||
case QLocale::Comoros:
|
||||
if ((countryName = QCoreApplication::translate("country", "Comoros")) == "Comoros") countryName = "";
|
||||
break;
|
||||
case QLocale::PeoplesRepublicOfCongo:
|
||||
if ((countryName = QCoreApplication::translate("country", "PeoplesRepublicOfCongo")) ==
|
||||
"PeoplesRepublicOfCongo")
|
||||
countryName = "";
|
||||
break;
|
||||
case QLocale::DemocraticRepublicOfCongo:
|
||||
if ((countryName = QCoreApplication::translate("country", "DemocraticRepublicOfCongo")) ==
|
||||
"DemocraticRepublicOfCongo")
|
||||
countryName = "";
|
||||
break;
|
||||
case QLocale::CookIslands:
|
||||
if ((countryName = QCoreApplication::translate("country", "CookIslands")) == "CookIslands")
|
||||
countryName = "";
|
||||
break;
|
||||
case QLocale::CostaRica:
|
||||
if ((countryName = QCoreApplication::translate("country", "CostaRica")) == "CostaRica") countryName = "";
|
||||
break;
|
||||
case QLocale::IvoryCoast:
|
||||
if ((countryName = QCoreApplication::translate("country", "IvoryCoast")) == "IvoryCoast") countryName = "";
|
||||
break;
|
||||
case QLocale::Croatia:
|
||||
if ((countryName = QCoreApplication::translate("country", "Croatia")) == "Croatia") countryName = "";
|
||||
break;
|
||||
case QLocale::Cuba:
|
||||
if ((countryName = QCoreApplication::translate("country", "Cuba")) == "Cuba") countryName = "";
|
||||
break;
|
||||
case QLocale::Cyprus:
|
||||
if ((countryName = QCoreApplication::translate("country", "Cyprus")) == "Cyprus") countryName = "";
|
||||
break;
|
||||
case QLocale::CzechRepublic:
|
||||
if ((countryName = QCoreApplication::translate("country", "CzechRepublic")) == "CzechRepublic")
|
||||
countryName = "";
|
||||
break;
|
||||
case QLocale::Denmark:
|
||||
if ((countryName = QCoreApplication::translate("country", "Denmark")) == "Denmark") countryName = "";
|
||||
break;
|
||||
case QLocale::Djibouti:
|
||||
if ((countryName = QCoreApplication::translate("country", "Djibouti")) == "Djibouti") countryName = "";
|
||||
break;
|
||||
case QLocale::Dominica:
|
||||
if ((countryName = QCoreApplication::translate("country", "Dominica")) == "Dominica") countryName = "";
|
||||
break;
|
||||
case QLocale::DominicanRepublic:
|
||||
if ((countryName = QCoreApplication::translate("country", "DominicanRepublic")) == "DominicanRepublic")
|
||||
countryName = "";
|
||||
break;
|
||||
case QLocale::Ecuador:
|
||||
if ((countryName = QCoreApplication::translate("country", "Ecuador")) == "Ecuador") countryName = "";
|
||||
break;
|
||||
case QLocale::Egypt:
|
||||
if ((countryName = QCoreApplication::translate("country", "Egypt")) == "Egypt") countryName = "";
|
||||
break;
|
||||
case QLocale::ElSalvador:
|
||||
if ((countryName = QCoreApplication::translate("country", "ElSalvador")) == "ElSalvador") countryName = "";
|
||||
break;
|
||||
case QLocale::EquatorialGuinea:
|
||||
if ((countryName = QCoreApplication::translate("country", "EquatorialGuinea")) == "EquatorialGuinea")
|
||||
countryName = "";
|
||||
break;
|
||||
case QLocale::Eritrea:
|
||||
if ((countryName = QCoreApplication::translate("country", "Eritrea")) == "Eritrea") countryName = "";
|
||||
break;
|
||||
case QLocale::Estonia:
|
||||
if ((countryName = QCoreApplication::translate("country", "Estonia")) == "Estonia") countryName = "";
|
||||
break;
|
||||
case QLocale::Ethiopia:
|
||||
if ((countryName = QCoreApplication::translate("country", "Ethiopia")) == "Ethiopia") countryName = "";
|
||||
break;
|
||||
case QLocale::FalklandIslands:
|
||||
if ((countryName = QCoreApplication::translate("country", "FalklandIslands")) == "FalklandIslands")
|
||||
countryName = "";
|
||||
break;
|
||||
case QLocale::FaroeIslands:
|
||||
if ((countryName = QCoreApplication::translate("country", "FaroeIslands")) == "FaroeIslands")
|
||||
countryName = "";
|
||||
break;
|
||||
case QLocale::Fiji:
|
||||
if ((countryName = QCoreApplication::translate("country", "Fiji")) == "Fiji") countryName = "";
|
||||
break;
|
||||
case QLocale::Finland:
|
||||
if ((countryName = QCoreApplication::translate("country", "Finland")) == "Finland") countryName = "";
|
||||
break;
|
||||
case QLocale::France:
|
||||
if ((countryName = QCoreApplication::translate("country", "France")) == "France") countryName = "";
|
||||
break;
|
||||
case QLocale::FrenchGuiana:
|
||||
if ((countryName = QCoreApplication::translate("country", "FrenchGuiana")) == "FrenchGuiana")
|
||||
countryName = "";
|
||||
break;
|
||||
case QLocale::FrenchPolynesia:
|
||||
if ((countryName = QCoreApplication::translate("country", "FrenchPolynesia")) == "FrenchPolynesia")
|
||||
countryName = "";
|
||||
break;
|
||||
case QLocale::Gabon:
|
||||
if ((countryName = QCoreApplication::translate("country", "Gabon")) == "Gabon") countryName = "";
|
||||
break;
|
||||
case QLocale::Gambia:
|
||||
if ((countryName = QCoreApplication::translate("country", "Gambia")) == "Gambia") countryName = "";
|
||||
break;
|
||||
case QLocale::Georgia:
|
||||
if ((countryName = QCoreApplication::translate("country", "Georgia")) == "Georgia") countryName = "";
|
||||
break;
|
||||
case QLocale::Germany:
|
||||
if ((countryName = QCoreApplication::translate("country", "Germany")) == "Germany") countryName = "";
|
||||
break;
|
||||
case QLocale::Ghana:
|
||||
if ((countryName = QCoreApplication::translate("country", "Ghana")) == "Ghana") countryName = "";
|
||||
break;
|
||||
case QLocale::Gibraltar:
|
||||
if ((countryName = QCoreApplication::translate("country", "Gibraltar")) == "Gibraltar") countryName = "";
|
||||
break;
|
||||
case QLocale::Greece:
|
||||
if ((countryName = QCoreApplication::translate("country", "Greece")) == "Greece") countryName = "";
|
||||
break;
|
||||
case QLocale::Greenland:
|
||||
if ((countryName = QCoreApplication::translate("country", "Greenland")) == "Greenland") countryName = "";
|
||||
break;
|
||||
case QLocale::Grenada:
|
||||
if ((countryName = QCoreApplication::translate("country", "Grenada")) == "Grenada") countryName = "";
|
||||
break;
|
||||
case QLocale::Guadeloupe:
|
||||
if ((countryName = QCoreApplication::translate("country", "Guadeloupe")) == "Guadeloupe") countryName = "";
|
||||
break;
|
||||
case QLocale::Guam:
|
||||
if ((countryName = QCoreApplication::translate("country", "Guam")) == "Guam") countryName = "";
|
||||
break;
|
||||
case QLocale::Guatemala:
|
||||
if ((countryName = QCoreApplication::translate("country", "Guatemala")) == "Guatemala") countryName = "";
|
||||
break;
|
||||
case QLocale::Guinea:
|
||||
if ((countryName = QCoreApplication::translate("country", "Guinea")) == "Guinea") countryName = "";
|
||||
break;
|
||||
case QLocale::GuineaBissau:
|
||||
if ((countryName = QCoreApplication::translate("country", "GuineaBissau")) == "GuineaBissau")
|
||||
countryName = "";
|
||||
break;
|
||||
case QLocale::Guyana:
|
||||
if ((countryName = QCoreApplication::translate("country", "Guyana")) == "Guyana") countryName = "";
|
||||
break;
|
||||
case QLocale::Haiti:
|
||||
if ((countryName = QCoreApplication::translate("country", "Haiti")) == "Haiti") countryName = "";
|
||||
break;
|
||||
case QLocale::Honduras:
|
||||
if ((countryName = QCoreApplication::translate("country", "Honduras")) == "Honduras") countryName = "";
|
||||
break;
|
||||
case QLocale::HongKong:
|
||||
if ((countryName = QCoreApplication::translate("country", "HongKong")) == "HongKong") countryName = "";
|
||||
break;
|
||||
case QLocale::Hungary:
|
||||
if ((countryName = QCoreApplication::translate("country", "Hungary")) == "Hungary") countryName = "";
|
||||
break;
|
||||
case QLocale::Iceland:
|
||||
if ((countryName = QCoreApplication::translate("country", "Iceland")) == "Iceland") countryName = "";
|
||||
break;
|
||||
case QLocale::India:
|
||||
if ((countryName = QCoreApplication::translate("country", "India")) == "India") countryName = "";
|
||||
break;
|
||||
case QLocale::Indonesia:
|
||||
if ((countryName = QCoreApplication::translate("country", "Indonesia")) == "Indonesia") countryName = "";
|
||||
break;
|
||||
case QLocale::Iran:
|
||||
if ((countryName = QCoreApplication::translate("country", "Iran")) == "Iran") countryName = "";
|
||||
break;
|
||||
case QLocale::Iraq:
|
||||
if ((countryName = QCoreApplication::translate("country", "Iraq")) == "Iraq") countryName = "";
|
||||
break;
|
||||
case QLocale::Ireland:
|
||||
if ((countryName = QCoreApplication::translate("country", "Ireland")) == "Ireland") countryName = "";
|
||||
break;
|
||||
case QLocale::Israel:
|
||||
if ((countryName = QCoreApplication::translate("country", "Israel")) == "Israel") countryName = "";
|
||||
break;
|
||||
case QLocale::Italy:
|
||||
if ((countryName = QCoreApplication::translate("country", "Italy")) == "Italy") countryName = "";
|
||||
break;
|
||||
case QLocale::Jamaica:
|
||||
if ((countryName = QCoreApplication::translate("country", "Jamaica")) == "Jamaica") countryName = "";
|
||||
break;
|
||||
case QLocale::Japan:
|
||||
if ((countryName = QCoreApplication::translate("country", "Japan")) == "Japan") countryName = "";
|
||||
break;
|
||||
case QLocale::Jordan:
|
||||
if ((countryName = QCoreApplication::translate("country", "Jordan")) == "Jordan") countryName = "";
|
||||
break;
|
||||
case QLocale::Kazakhstan:
|
||||
if ((countryName = QCoreApplication::translate("country", "Kazakhstan")) == "Kazakhstan") countryName = "";
|
||||
break;
|
||||
case QLocale::Kenya:
|
||||
if ((countryName = QCoreApplication::translate("country", "Kenya")) == "Kenya") countryName = "";
|
||||
break;
|
||||
case QLocale::Kiribati:
|
||||
if ((countryName = QCoreApplication::translate("country", "Kiribati")) == "Kiribati") countryName = "";
|
||||
break;
|
||||
case QLocale::DemocraticRepublicOfKorea:
|
||||
if ((countryName = QCoreApplication::translate("country", "DemocraticRepublicOfKorea")) ==
|
||||
"DemocraticRepublicOfKorea")
|
||||
countryName = "";
|
||||
break;
|
||||
case QLocale::RepublicOfKorea:
|
||||
if ((countryName = QCoreApplication::translate("country", "RepublicOfKorea")) == "RepublicOfKorea")
|
||||
countryName = "";
|
||||
break;
|
||||
case QLocale::Kuwait:
|
||||
if ((countryName = QCoreApplication::translate("country", "Kuwait")) == "Kuwait") countryName = "";
|
||||
break;
|
||||
case QLocale::Kyrgyzstan:
|
||||
if ((countryName = QCoreApplication::translate("country", "Kyrgyzstan")) == "Kyrgyzstan") countryName = "";
|
||||
break;
|
||||
case QLocale::Laos:
|
||||
if ((countryName = QCoreApplication::translate("country", "Laos")) == "Laos") countryName = "";
|
||||
break;
|
||||
case QLocale::Latvia:
|
||||
if ((countryName = QCoreApplication::translate("country", "Latvia")) == "Latvia") countryName = "";
|
||||
break;
|
||||
case QLocale::Lebanon:
|
||||
if ((countryName = QCoreApplication::translate("country", "Lebanon")) == "Lebanon") countryName = "";
|
||||
break;
|
||||
case QLocale::Lesotho:
|
||||
if ((countryName = QCoreApplication::translate("country", "Lesotho")) == "Lesotho") countryName = "";
|
||||
break;
|
||||
case QLocale::Liberia:
|
||||
if ((countryName = QCoreApplication::translate("country", "Liberia")) == "Liberia") countryName = "";
|
||||
break;
|
||||
case QLocale::Libya:
|
||||
if ((countryName = QCoreApplication::translate("country", "Libya")) == "Libya") countryName = "";
|
||||
break;
|
||||
case QLocale::Liechtenstein:
|
||||
if ((countryName = QCoreApplication::translate("country", "Liechtenstein")) == "Liechtenstein")
|
||||
countryName = "";
|
||||
break;
|
||||
case QLocale::Lithuania:
|
||||
if ((countryName = QCoreApplication::translate("country", "Lithuania")) == "Lithuania") countryName = "";
|
||||
break;
|
||||
case QLocale::Luxembourg:
|
||||
if ((countryName = QCoreApplication::translate("country", "Luxembourg")) == "Luxembourg") countryName = "";
|
||||
break;
|
||||
case QLocale::Macau:
|
||||
if ((countryName = QCoreApplication::translate("country", "Macau")) == "Macau") countryName = "";
|
||||
break;
|
||||
case QLocale::Macedonia:
|
||||
if ((countryName = QCoreApplication::translate("country", "Macedonia")) == "Macedonia") countryName = "";
|
||||
break;
|
||||
case QLocale::Madagascar:
|
||||
if ((countryName = QCoreApplication::translate("country", "Madagascar")) == "Madagascar") countryName = "";
|
||||
break;
|
||||
case QLocale::Malawi:
|
||||
if ((countryName = QCoreApplication::translate("country", "Malawi")) == "Malawi") countryName = "";
|
||||
break;
|
||||
case QLocale::Malaysia:
|
||||
if ((countryName = QCoreApplication::translate("country", "Malaysia")) == "Malaysia") countryName = "";
|
||||
break;
|
||||
case QLocale::Maldives:
|
||||
if ((countryName = QCoreApplication::translate("country", "Maldives")) == "Maldives") countryName = "";
|
||||
break;
|
||||
case QLocale::Mali:
|
||||
if ((countryName = QCoreApplication::translate("country", "Mali")) == "Mali") countryName = "";
|
||||
break;
|
||||
case QLocale::Malta:
|
||||
if ((countryName = QCoreApplication::translate("country", "Malta")) == "Malta") countryName = "";
|
||||
break;
|
||||
case QLocale::MarshallIslands:
|
||||
if ((countryName = QCoreApplication::translate("country", "MarshallIslands")) == "MarshallIslands")
|
||||
countryName = "";
|
||||
break;
|
||||
case QLocale::Martinique:
|
||||
if ((countryName = QCoreApplication::translate("country", "Martinique")) == "Martinique") countryName = "";
|
||||
break;
|
||||
case QLocale::Mauritania:
|
||||
if ((countryName = QCoreApplication::translate("country", "Mauritania")) == "Mauritania") countryName = "";
|
||||
break;
|
||||
case QLocale::Mauritius:
|
||||
if ((countryName = QCoreApplication::translate("country", "Mauritius")) == "Mauritius") countryName = "";
|
||||
break;
|
||||
case QLocale::Mayotte:
|
||||
if ((countryName = QCoreApplication::translate("country", "Mayotte")) == "Mayotte") countryName = "";
|
||||
break;
|
||||
case QLocale::Mexico:
|
||||
if ((countryName = QCoreApplication::translate("country", "Mexico")) == "Mexico") countryName = "";
|
||||
break;
|
||||
case QLocale::Micronesia:
|
||||
if ((countryName = QCoreApplication::translate("country", "Micronesia")) == "Micronesia") countryName = "";
|
||||
break;
|
||||
case QLocale::Moldova:
|
||||
if ((countryName = QCoreApplication::translate("country", "Moldova")) == "Moldova") countryName = "";
|
||||
break;
|
||||
case QLocale::Monaco:
|
||||
if ((countryName = QCoreApplication::translate("country", "Monaco")) == "Monaco") countryName = "";
|
||||
break;
|
||||
case QLocale::Mongolia:
|
||||
if ((countryName = QCoreApplication::translate("country", "Mongolia")) == "Mongolia") countryName = "";
|
||||
break;
|
||||
case QLocale::Montenegro:
|
||||
if ((countryName = QCoreApplication::translate("country", "Montenegro")) == "Montenegro") countryName = "";
|
||||
break;
|
||||
case QLocale::Montserrat:
|
||||
if ((countryName = QCoreApplication::translate("country", "Montserrat")) == "Montserrat") countryName = "";
|
||||
break;
|
||||
case QLocale::Morocco:
|
||||
if ((countryName = QCoreApplication::translate("country", "Morocco")) == "Morocco") countryName = "";
|
||||
break;
|
||||
case QLocale::Mozambique:
|
||||
if ((countryName = QCoreApplication::translate("country", "Mozambique")) == "Mozambique") countryName = "";
|
||||
break;
|
||||
case QLocale::Myanmar:
|
||||
if ((countryName = QCoreApplication::translate("country", "Myanmar")) == "Myanmar") countryName = "";
|
||||
break;
|
||||
case QLocale::Namibia:
|
||||
if ((countryName = QCoreApplication::translate("country", "Namibia")) == "Namibia") countryName = "";
|
||||
break;
|
||||
case QLocale::NauruCountry:
|
||||
if ((countryName = QCoreApplication::translate("country", "NauruCountry")) == "NauruCountry")
|
||||
countryName = "";
|
||||
break;
|
||||
case QLocale::Nepal:
|
||||
if ((countryName = QCoreApplication::translate("country", "Nepal")) == "Nepal") countryName = "";
|
||||
break;
|
||||
case QLocale::Netherlands:
|
||||
if ((countryName = QCoreApplication::translate("country", "Netherlands")) == "Netherlands")
|
||||
countryName = "";
|
||||
break;
|
||||
case QLocale::NewCaledonia:
|
||||
if ((countryName = QCoreApplication::translate("country", "NewCaledonia")) == "NewCaledonia")
|
||||
countryName = "";
|
||||
break;
|
||||
case QLocale::NewZealand:
|
||||
if ((countryName = QCoreApplication::translate("country", "NewZealand")) == "NewZealand") countryName = "";
|
||||
break;
|
||||
case QLocale::Nicaragua:
|
||||
if ((countryName = QCoreApplication::translate("country", "Nicaragua")) == "Nicaragua") countryName = "";
|
||||
break;
|
||||
case QLocale::Niger:
|
||||
if ((countryName = QCoreApplication::translate("country", "Niger")) == "Niger") countryName = "";
|
||||
break;
|
||||
case QLocale::Nigeria:
|
||||
if ((countryName = QCoreApplication::translate("country", "Nigeria")) == "Nigeria") countryName = "";
|
||||
break;
|
||||
case QLocale::Niue:
|
||||
if ((countryName = QCoreApplication::translate("country", "Niue")) == "Niue") countryName = "";
|
||||
break;
|
||||
case QLocale::NorfolkIsland:
|
||||
if ((countryName = QCoreApplication::translate("country", "NorfolkIsland")) == "NorfolkIsland")
|
||||
countryName = "";
|
||||
break;
|
||||
case QLocale::NorthernMarianaIslands:
|
||||
if ((countryName = QCoreApplication::translate("country", "NorthernMarianaIslands")) ==
|
||||
"NorthernMarianaIslands")
|
||||
countryName = "";
|
||||
break;
|
||||
case QLocale::Norway:
|
||||
if ((countryName = QCoreApplication::translate("country", "Norway")) == "Norway") countryName = "";
|
||||
break;
|
||||
case QLocale::Oman:
|
||||
if ((countryName = QCoreApplication::translate("country", "Oman")) == "Oman") countryName = "";
|
||||
break;
|
||||
case QLocale::Pakistan:
|
||||
if ((countryName = QCoreApplication::translate("country", "Pakistan")) == "Pakistan") countryName = "";
|
||||
break;
|
||||
case QLocale::Palau:
|
||||
if ((countryName = QCoreApplication::translate("country", "Palau")) == "Palau") countryName = "";
|
||||
break;
|
||||
case QLocale::PalestinianTerritories:
|
||||
if ((countryName = QCoreApplication::translate("country", "PalestinianTerritories")) ==
|
||||
"PalestinianTerritories")
|
||||
countryName = "";
|
||||
break;
|
||||
case QLocale::Panama:
|
||||
if ((countryName = QCoreApplication::translate("country", "Panama")) == "Panama") countryName = "";
|
||||
break;
|
||||
case QLocale::PapuaNewGuinea:
|
||||
if ((countryName = QCoreApplication::translate("country", "PapuaNewGuinea")) == "PapuaNewGuinea")
|
||||
countryName = "";
|
||||
break;
|
||||
case QLocale::Paraguay:
|
||||
if ((countryName = QCoreApplication::translate("country", "Paraguay")) == "Paraguay") countryName = "";
|
||||
break;
|
||||
case QLocale::Peru:
|
||||
if ((countryName = QCoreApplication::translate("country", "Peru")) == "Peru") countryName = "";
|
||||
break;
|
||||
case QLocale::Philippines:
|
||||
if ((countryName = QCoreApplication::translate("country", "Philippines")) == "Philippines")
|
||||
countryName = "";
|
||||
break;
|
||||
case QLocale::Poland:
|
||||
if ((countryName = QCoreApplication::translate("country", "Poland")) == "Poland") countryName = "";
|
||||
break;
|
||||
case QLocale::Portugal:
|
||||
if ((countryName = QCoreApplication::translate("country", "Portugal")) == "Portugal") countryName = "";
|
||||
break;
|
||||
case QLocale::PuertoRico:
|
||||
if ((countryName = QCoreApplication::translate("country", "PuertoRico")) == "PuertoRico") countryName = "";
|
||||
break;
|
||||
case QLocale::Qatar:
|
||||
if ((countryName = QCoreApplication::translate("country", "Qatar")) == "Qatar") countryName = "";
|
||||
break;
|
||||
case QLocale::Reunion:
|
||||
if ((countryName = QCoreApplication::translate("country", "Reunion")) == "Reunion") countryName = "";
|
||||
break;
|
||||
case QLocale::Romania:
|
||||
if ((countryName = QCoreApplication::translate("country", "Romania")) == "Romania") countryName = "";
|
||||
break;
|
||||
case QLocale::RussianFederation:
|
||||
if ((countryName = QCoreApplication::translate("country", "RussianFederation")) == "RussianFederation")
|
||||
countryName = "";
|
||||
break;
|
||||
case QLocale::Rwanda:
|
||||
if ((countryName = QCoreApplication::translate("country", "Rwanda")) == "Rwanda") countryName = "";
|
||||
break;
|
||||
case QLocale::SaintHelena:
|
||||
if ((countryName = QCoreApplication::translate("country", "SaintHelena")) == "SaintHelena")
|
||||
countryName = "";
|
||||
break;
|
||||
case QLocale::SaintKittsAndNevis:
|
||||
if ((countryName = QCoreApplication::translate("country", "SaintKittsAndNevis")) == "SaintKittsAndNevis")
|
||||
countryName = "";
|
||||
break;
|
||||
case QLocale::SaintLucia:
|
||||
if ((countryName = QCoreApplication::translate("country", "SaintLucia")) == "SaintLucia") countryName = "";
|
||||
break;
|
||||
case QLocale::SaintPierreAndMiquelon:
|
||||
if ((countryName = QCoreApplication::translate("country", "SaintPierreAndMiquelon")) ==
|
||||
"SaintPierreAndMiquelon")
|
||||
countryName = "";
|
||||
break;
|
||||
case QLocale::SaintVincentAndTheGrenadines:
|
||||
if ((countryName = QCoreApplication::translate("country", "SaintVincentAndTheGrenadines")) ==
|
||||
"SaintVincentAndTheGrenadines")
|
||||
countryName = "";
|
||||
break;
|
||||
case QLocale::Samoa:
|
||||
if ((countryName = QCoreApplication::translate("country", "Samoa")) == "Samoa") countryName = "";
|
||||
break;
|
||||
case QLocale::SanMarino:
|
||||
if ((countryName = QCoreApplication::translate("country", "SanMarino")) == "SanMarino") countryName = "";
|
||||
break;
|
||||
case QLocale::SaoTomeAndPrincipe:
|
||||
if ((countryName = QCoreApplication::translate("country", "SaoTomeAndPrincipe")) == "SaoTomeAndPrincipe")
|
||||
countryName = "";
|
||||
break;
|
||||
case QLocale::SaudiArabia:
|
||||
if ((countryName = QCoreApplication::translate("country", "SaudiArabia")) == "SaudiArabia")
|
||||
countryName = "";
|
||||
break;
|
||||
case QLocale::Senegal:
|
||||
if ((countryName = QCoreApplication::translate("country", "Senegal")) == "Senegal") countryName = "";
|
||||
break;
|
||||
case QLocale::Serbia:
|
||||
if ((countryName = QCoreApplication::translate("country", "Serbia")) == "Serbia") countryName = "";
|
||||
break;
|
||||
case QLocale::Seychelles:
|
||||
if ((countryName = QCoreApplication::translate("country", "Seychelles")) == "Seychelles") countryName = "";
|
||||
break;
|
||||
case QLocale::SierraLeone:
|
||||
if ((countryName = QCoreApplication::translate("country", "SierraLeone")) == "SierraLeone")
|
||||
countryName = "";
|
||||
break;
|
||||
case QLocale::Singapore:
|
||||
if ((countryName = QCoreApplication::translate("country", "Singapore")) == "Singapore") countryName = "";
|
||||
break;
|
||||
case QLocale::Slovakia:
|
||||
if ((countryName = QCoreApplication::translate("country", "Slovakia")) == "Slovakia") countryName = "";
|
||||
break;
|
||||
case QLocale::Slovenia:
|
||||
if ((countryName = QCoreApplication::translate("country", "Slovenia")) == "Slovenia") countryName = "";
|
||||
break;
|
||||
case QLocale::SolomonIslands:
|
||||
if ((countryName = QCoreApplication::translate("country", "SolomonIslands")) == "SolomonIslands")
|
||||
countryName = "";
|
||||
break;
|
||||
case QLocale::Somalia:
|
||||
if ((countryName = QCoreApplication::translate("country", "Somalia")) == "Somalia") countryName = "";
|
||||
break;
|
||||
case QLocale::SouthAfrica:
|
||||
if ((countryName = QCoreApplication::translate("country", "SouthAfrica")) == "SouthAfrica")
|
||||
countryName = "";
|
||||
break;
|
||||
case QLocale::Spain:
|
||||
if ((countryName = QCoreApplication::translate("country", "Spain")) == "Spain") countryName = "";
|
||||
break;
|
||||
case QLocale::SriLanka:
|
||||
if ((countryName = QCoreApplication::translate("country", "SriLanka")) == "SriLanka") countryName = "";
|
||||
break;
|
||||
case QLocale::Sudan:
|
||||
if ((countryName = QCoreApplication::translate("country", "Sudan")) == "Sudan") countryName = "";
|
||||
break;
|
||||
case QLocale::Suriname:
|
||||
if ((countryName = QCoreApplication::translate("country", "Suriname")) == "Suriname") countryName = "";
|
||||
break;
|
||||
case QLocale::Swaziland:
|
||||
if ((countryName = QCoreApplication::translate("country", "Swaziland")) == "Swaziland") countryName = "";
|
||||
break;
|
||||
case QLocale::Sweden:
|
||||
if ((countryName = QCoreApplication::translate("country", "Sweden")) == "Sweden") countryName = "";
|
||||
break;
|
||||
case QLocale::Switzerland:
|
||||
if ((countryName = QCoreApplication::translate("country", "Switzerland")) == "Switzerland")
|
||||
countryName = "";
|
||||
break;
|
||||
case QLocale::Syria:
|
||||
if ((countryName = QCoreApplication::translate("country", "Syria")) == "Syria") countryName = "";
|
||||
break;
|
||||
case QLocale::Taiwan:
|
||||
if ((countryName = QCoreApplication::translate("country", "Taiwan")) == "Taiwan") countryName = "";
|
||||
break;
|
||||
case QLocale::Tajikistan:
|
||||
if ((countryName = QCoreApplication::translate("country", "Tajikistan")) == "Tajikistan") countryName = "";
|
||||
break;
|
||||
case QLocale::Tanzania:
|
||||
if ((countryName = QCoreApplication::translate("country", "Tanzania")) == "Tanzania") countryName = "";
|
||||
break;
|
||||
case QLocale::Thailand:
|
||||
if ((countryName = QCoreApplication::translate("country", "Thailand")) == "Thailand") countryName = "";
|
||||
break;
|
||||
case QLocale::Togo:
|
||||
if ((countryName = QCoreApplication::translate("country", "Togo")) == "Togo") countryName = "";
|
||||
break;
|
||||
case QLocale::TokelauCountry:
|
||||
if ((countryName = QCoreApplication::translate("country", "Tokelau")) == "Tokelau") countryName = "";
|
||||
break;
|
||||
case QLocale::Tonga:
|
||||
if ((countryName = QCoreApplication::translate("country", "Tonga")) == "Tonga") countryName = "";
|
||||
break;
|
||||
case QLocale::TrinidadAndTobago:
|
||||
if ((countryName = QCoreApplication::translate("country", "TrinidadAndTobago")) == "TrinidadAndTobago")
|
||||
countryName = "";
|
||||
break;
|
||||
case QLocale::Tunisia:
|
||||
if ((countryName = QCoreApplication::translate("country", "Tunisia")) == "Tunisia") countryName = "";
|
||||
break;
|
||||
case QLocale::Turkey:
|
||||
if ((countryName = QCoreApplication::translate("country", "Turkey")) == "Turkey") countryName = "";
|
||||
break;
|
||||
case QLocale::Turkmenistan:
|
||||
if ((countryName = QCoreApplication::translate("country", "Turkmenistan")) == "Turkmenistan")
|
||||
countryName = "";
|
||||
break;
|
||||
case QLocale::TurksAndCaicosIslands:
|
||||
if ((countryName = QCoreApplication::translate("country", "TurksAndCaicosIslands")) ==
|
||||
"TurksAndCaicosIslands")
|
||||
countryName = "";
|
||||
break;
|
||||
case QLocale::TuvaluCountry:
|
||||
if ((countryName = QCoreApplication::translate("country", "Tuvalu")) == "Tuvalu") countryName = "";
|
||||
break;
|
||||
case QLocale::Uganda:
|
||||
if ((countryName = QCoreApplication::translate("country", "Uganda")) == "Uganda") countryName = "";
|
||||
break;
|
||||
case QLocale::Ukraine:
|
||||
if ((countryName = QCoreApplication::translate("country", "Ukraine")) == "Ukraine") countryName = "";
|
||||
break;
|
||||
case QLocale::UnitedArabEmirates:
|
||||
if ((countryName = QCoreApplication::translate("country", "UnitedArabEmirates")) == "UnitedArabEmirates")
|
||||
countryName = "";
|
||||
break;
|
||||
case QLocale::UnitedKingdom:
|
||||
if ((countryName = QCoreApplication::translate("country", "UnitedKingdom")) == "UnitedKingdom")
|
||||
countryName = "";
|
||||
break;
|
||||
case QLocale::UnitedStates:
|
||||
if ((countryName = QCoreApplication::translate("country", "UnitedStates")) == "UnitedStates")
|
||||
countryName = "";
|
||||
break;
|
||||
case QLocale::Uruguay:
|
||||
if ((countryName = QCoreApplication::translate("country", "Uruguay")) == "Uruguay") countryName = "";
|
||||
break;
|
||||
case QLocale::Uzbekistan:
|
||||
if ((countryName = QCoreApplication::translate("country", "Uzbekistan")) == "Uzbekistan") countryName = "";
|
||||
break;
|
||||
case QLocale::Vanuatu:
|
||||
if ((countryName = QCoreApplication::translate("country", "Vanuatu")) == "Vanuatu") countryName = "";
|
||||
break;
|
||||
case QLocale::Venezuela:
|
||||
if ((countryName = QCoreApplication::translate("country", "Venezuela")) == "Venezuela") countryName = "";
|
||||
break;
|
||||
case QLocale::Vietnam:
|
||||
if ((countryName = QCoreApplication::translate("country", "Vietnam")) == "Vietnam") countryName = "";
|
||||
break;
|
||||
case QLocale::WallisAndFutunaIslands:
|
||||
if ((countryName = QCoreApplication::translate("country", "WallisAndFutunaIslands")) ==
|
||||
"WallisAndFutunaIslands")
|
||||
countryName = "";
|
||||
break;
|
||||
case QLocale::Yemen:
|
||||
if ((countryName = QCoreApplication::translate("country", "Yemen")) == "Yemen") countryName = "";
|
||||
break;
|
||||
case QLocale::Zambia:
|
||||
if ((countryName = QCoreApplication::translate("country", "Zambia")) == "Zambia") countryName = "";
|
||||
break;
|
||||
case QLocale::Zimbabwe:
|
||||
if ((countryName = QCoreApplication::translate("country", "Zimbabwe")) == "Zimbabwe") countryName = "";
|
||||
break;
|
||||
default: {
|
||||
countryName = QLocale::countryToString(p_country);
|
||||
}
|
||||
}
|
||||
if (countryName == "") countryName = QLocale::countryToString(p_country);
|
||||
return countryName;
|
||||
}
|
||||
QString Utils::toDateString(QDateTime date, const QString &format) {
|
||||
return QLocale().toString(date, (!format.isEmpty() ? format : "ddd d MMMM yyyy"));
|
||||
}
|
||||
|
||||
QString Utils::toDateString(QDate date, const QString &format) {
|
||||
return QLocale().toString(date, (!format.isEmpty() ? format : "ddd d, MMMM"));
|
||||
}
|
||||
|
||||
QString Utils::toDateDayString(const QDateTime &date) {
|
||||
auto res = QLocale().toString(date, "d");
|
||||
return res;
|
||||
}
|
||||
|
||||
QString Utils::toDateHourString(const QDateTime &date) {
|
||||
return QLocale().toString(date, "hh:mm");
|
||||
}
|
||||
|
||||
QString Utils::toDateDayNameString(const QDateTime &date) {
|
||||
return QLocale().toString(date, "ddd");
|
||||
}
|
||||
|
||||
QString Utils::toDateMonthString(const QDateTime &date) {
|
||||
return QLocale().toString(date, "MMMM");
|
||||
}
|
||||
|
||||
bool Utils::isCurrentDay(QDateTime date) {
|
||||
auto dateDayNum = date.date().day();
|
||||
auto currentDate = QDateTime::currentDateTime();
|
||||
auto currentDayNum = currentDate.date().day();
|
||||
auto daysTo = date.daysTo(currentDate);
|
||||
return (dateDayNum == currentDayNum && daysTo == 0);
|
||||
}
|
||||
|
||||
bool Utils::isCurrentDay(QDate date) {
|
||||
auto currentDate = QDate::currentDate();
|
||||
return date.month() == currentDate.month() && date.year() == currentDate.year() && date.day() == currentDate.day();
|
||||
}
|
||||
|
||||
bool Utils::isCurrentMonth(QDate date) {
|
||||
auto currentDate = QDate::currentDate();
|
||||
return date.month() == currentDate.month() && date.year() == currentDate.year();
|
||||
}
|
||||
|
||||
bool Utils::isBeforeToday(QDate date) {
|
||||
auto currentDate = QDate::currentDate();
|
||||
auto res = date.daysTo(currentDate) > 0;
|
||||
return res;
|
||||
}
|
||||
|
||||
bool Utils::datesAreEqual(const QDate &a, const QDate &b) {
|
||||
return a.month() == b.month() && a.year() == b.year() && a.day() == b.day();
|
||||
}
|
||||
|
||||
QDateTime Utils::createDateTime(const QDate &date, int hour, int min) {
|
||||
QTime time(hour, min);
|
||||
return QDateTime(date, time);
|
||||
}
|
||||
|
||||
int Utils::secsTo(const QString &startTime, const QString &endTime) {
|
||||
QDateTime startDate(QDateTime::fromString(startTime, "hh:mm"));
|
||||
QDateTime endDate(QDateTime::fromString(endTime, "hh:mm"));
|
||||
auto res = startDate.secsTo(endDate);
|
||||
return res;
|
||||
}
|
||||
|
||||
QDateTime Utils::addSecs(QDateTime date, int secs) {
|
||||
date = date.addSecs(secs);
|
||||
return date;
|
||||
}
|
||||
|
||||
int Utils::getYear(const QDate &date) {
|
||||
return date.year();
|
||||
}
|
||||
|
||||
bool Utils::isMe(const QString &address) {
|
||||
auto linAddr = ToolModel::interpretUrl(address);
|
||||
if (!CoreModel::getInstance()->getCore()->getDefaultAccount()) {
|
||||
for (auto &account : CoreModel::getInstance()->getCore()->getAccountList()) {
|
||||
if (account->getContactAddress()->weakEqual(linAddr)) return true;
|
||||
}
|
||||
return false;
|
||||
} else {
|
||||
auto accountAddr = CoreModel::getInstance()->getCore()->getDefaultAccount()->getContactAddress();
|
||||
return linAddr && accountAddr ? accountAddr->weakEqual(linAddr) : false;
|
||||
}
|
||||
}
|
||||
// QDateTime dateTime(QDateTime::fromString(date, "yyyy-MM-dd hh:mm:ss"));
|
||||
|
||||
// bool Utils::isMe(const QString &address) {
|
||||
// return !address.isEmpty() ? isMe(Utils::interpretUrl(address)) : false;
|
||||
// }
|
||||
|
||||
// bool Utils::isMe(const std::shared_ptr<const linphone::Address> &address) {
|
||||
// if (!CoreModel::getInstance()
|
||||
// ->getCore()
|
||||
// ->getDefaultAccount()) { // Default account is selected : Me is all local accounts.
|
||||
// return CoreModel::getInstance()->getAccountSettingsModel()->findAccount(address) != nullptr;
|
||||
// } else
|
||||
// return address ? CoreModel::getInstance()->getAccountSettingsModel()->getUsedSipAddress()->weakEqual(address)
|
||||
// : false;
|
||||
// }
|
||||
|
|
|
|||
|
|
@ -62,6 +62,8 @@ public:
|
|||
const QHash<QString, QString> &headers = {});
|
||||
Q_INVOKABLE static void openCallsWindow(CallGui *call);
|
||||
Q_INVOKABLE static QQuickWindow *getMainWindow();
|
||||
Q_INVOKABLE static void
|
||||
showInformationPopup(const QString &title, const QString &description, bool isSuccess = true);
|
||||
Q_INVOKABLE static QQuickWindow *getCallsWindow(CallGui *callGui);
|
||||
Q_INVOKABLE static void closeCallsWindow();
|
||||
Q_INVOKABLE static VariantObject *haveAccount();
|
||||
|
|
@ -74,8 +76,26 @@ public:
|
|||
Q_INVOKABLE static QStringList generateSecurityLettersArray(int arraySize, int correctIndex, QString correctCode);
|
||||
Q_INVOKABLE static int getRandomIndex(int size);
|
||||
Q_INVOKABLE static void copyToClipboard(const QString &text);
|
||||
static QString generateSavedFilename(const QString &from, const QString &to);
|
||||
Q_INVOKABLE static QString toDateString(QDateTime date, const QString &format = "");
|
||||
Q_INVOKABLE static QString toDateString(QDate date, const QString &format = "");
|
||||
Q_INVOKABLE static QString toDateDayString(const QDateTime &date);
|
||||
Q_INVOKABLE static QString toDateHourString(const QDateTime &date);
|
||||
Q_INVOKABLE static QString toDateDayNameString(const QDateTime &date);
|
||||
Q_INVOKABLE static QString toDateMonthString(const QDateTime &date);
|
||||
Q_INVOKABLE static bool isCurrentDay(QDateTime date);
|
||||
Q_INVOKABLE static bool isCurrentDay(QDate date);
|
||||
Q_INVOKABLE static bool isCurrentMonth(QDate date);
|
||||
Q_INVOKABLE static bool isBeforeToday(QDate date);
|
||||
Q_INVOKABLE static bool datesAreEqual(const QDate &a, const QDate &b);
|
||||
Q_INVOKABLE static QDateTime createDateTime(const QDate &date, int hour, int min);
|
||||
Q_INVOKABLE static int getYear(const QDate &date);
|
||||
Q_INVOKABLE static int secsTo(const QString &start, const QString &end);
|
||||
Q_INVOKABLE static QDateTime addSecs(QDateTime date, int secs);
|
||||
Q_INVOKABLE static QString generateLinphoneSipAddress(const QString &uri);
|
||||
Q_INVOKABLE static QString findAvatarByAddress(const QString &address);
|
||||
static QString generateSavedFilename(const QString &from, const QString &to);
|
||||
Q_INVOKABLE static bool isMe(const QString &address);
|
||||
static QString getCountryName(const QLocale::Country &p_country);
|
||||
|
||||
static QString getApplicationProduct();
|
||||
static QString getOsProduct();
|
||||
|
|
|
|||
|
|
@ -345,8 +345,9 @@ Item {
|
|||
id: callPage
|
||||
}
|
||||
ContactPage{}
|
||||
Item{}
|
||||
//ConversationPage{}
|
||||
//MeetingPage{}
|
||||
MeetingPage{}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -24,6 +24,121 @@ Window {
|
|||
mainWindowStackView.currentItem.transferCallSucceed()
|
||||
}
|
||||
|
||||
function showInformationPopup(title, description, isSuccess) {
|
||||
var infoPopup = popupComp.createObject(popupLayout, {"title": title, "description": description, "isSuccess": isSuccess})
|
||||
// informationPopup.title = title
|
||||
// informationPopup.description = description
|
||||
// informationPopup.isSuccess = isSuccess
|
||||
// infoPopup.y = popupLayout.nextY - infoPopup.height
|
||||
infoPopup.index = popupLayout.popupList.length
|
||||
popupLayout.popupList.push(infoPopup)
|
||||
infoPopup.open()
|
||||
}
|
||||
|
||||
Component {
|
||||
id: popupComp
|
||||
Popup {
|
||||
id: informationPopup
|
||||
property bool isSuccess: true
|
||||
property string title
|
||||
property string description
|
||||
property int index
|
||||
onAboutToShow: {
|
||||
autoClosePopup.restart()
|
||||
}
|
||||
onAboutToHide: {
|
||||
popupLayout.popupList.splice(informationPopup.index, 1)
|
||||
}
|
||||
closePolicy: Popup.NoAutoClose
|
||||
x : parent.x + parent.width - width
|
||||
// y : parent.y + parent.height - height
|
||||
rightMargin: 20 * DefaultStyle.dp
|
||||
bottomMargin: 20 * DefaultStyle.dp
|
||||
padding: 20 * DefaultStyle.dp
|
||||
underlineColor: informationPopup.isSuccess ? DefaultStyle.success_500main : DefaultStyle.danger_500main
|
||||
radius: 0
|
||||
onHoveredChanged: {
|
||||
if (hovered) autoClosePopup.stop()
|
||||
else autoClosePopup.restart()
|
||||
}
|
||||
Timer {
|
||||
id: autoClosePopup
|
||||
interval: 5000
|
||||
onTriggered: {
|
||||
informationPopup.close()
|
||||
}
|
||||
}
|
||||
contentItem: RowLayout {
|
||||
spacing: 15 * DefaultStyle.dp
|
||||
EffectImage {
|
||||
imageSource: informationPopup.isSuccess ? AppIcons.smiley : AppIcons.smileySad
|
||||
colorizationColor: informationPopup.isSuccess ? DefaultStyle.success_500main : DefaultStyle.danger_500main
|
||||
Layout.preferredWidth: 32 * DefaultStyle.dp
|
||||
Layout.preferredHeight: 32 * DefaultStyle.dp
|
||||
width: 32 * DefaultStyle.dp
|
||||
height: 32 * DefaultStyle.dp
|
||||
}
|
||||
Rectangle {
|
||||
Layout.preferredWidth: 1 * DefaultStyle.dp
|
||||
Layout.preferredHeight: parent.height
|
||||
color: DefaultStyle.main2_200
|
||||
}
|
||||
ColumnLayout {
|
||||
RowLayout {
|
||||
Layout.fillWidth: true
|
||||
Text {
|
||||
Layout.fillWidth: true
|
||||
text: informationPopup.title
|
||||
color: informationPopup.isSuccess ? DefaultStyle.success_500main : DefaultStyle.danger_500main
|
||||
font {
|
||||
pixelSize: 16 * DefaultStyle.dp
|
||||
weight: 800 * DefaultStyle.dp
|
||||
}
|
||||
}
|
||||
Button {
|
||||
Layout.preferredWidth: 20 * DefaultStyle.dp
|
||||
Layout.preferredHeight: 20 * DefaultStyle.dp
|
||||
Layout.alignment: Qt.AlignTop | Qt.AlignRight
|
||||
visible: informationPopup.hovered || hovered
|
||||
background: Item{}
|
||||
icon.source: AppIcons.closeX
|
||||
onClicked: informationPopup.close()
|
||||
}
|
||||
}
|
||||
Text {
|
||||
Layout.alignment: Qt.AlignHCenter
|
||||
Layout.fillWidth: true
|
||||
Layout.maximumWidth: 300 * DefaultStyle.dp
|
||||
text: informationPopup.description
|
||||
wrapMode: Text.WordWrap
|
||||
color: DefaultStyle.main2_500main
|
||||
font {
|
||||
pixelSize: 12 * DefaultStyle.dp
|
||||
weight: 300 * DefaultStyle.dp
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
ColumnLayout {
|
||||
id: popupLayout
|
||||
anchors.fill: parent
|
||||
Layout.alignment: Qt.AlignBottom
|
||||
property int nextY: mainWindow.height
|
||||
property list<Popup> popupList
|
||||
property int popupCount: popupList.length
|
||||
spacing: 15
|
||||
onPopupCountChanged: {
|
||||
nextY = mainWindow.height
|
||||
for(var i = 0; i < popupCount; ++i) {
|
||||
popupList[i].y = nextY - popupList[i].height
|
||||
nextY = nextY - popupList[i].height - 15
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
AccountProxy {
|
||||
// TODO : change this so it does not display the main page for one second
|
||||
// when we fail trying to connect the first account (account is added and
|
||||
|
|
|
|||
|
|
@ -2,10 +2,17 @@
|
|||
list(APPEND _LINPHONEAPP_QML_FILES
|
||||
view/App/Main.qml
|
||||
view/App/CallsWindow.qml
|
||||
view/App/Layout/ContactLayout.qml
|
||||
view/App/Layout/LoginLayout.qml
|
||||
view/App/Layout/MainLayout.qml
|
||||
|
||||
view/Layout/Conference/IncallGrid.qml
|
||||
view/Layout/Contact/ContactLayout.qml
|
||||
view/Layout/Meeting/AddParticipantsLayout.qml
|
||||
|
||||
view/Layout/FormItemLayout.qml
|
||||
view/Layout/Mosaic.qml
|
||||
view/Layout/Section.qml
|
||||
|
||||
view/Item/Account/Accounts.qml
|
||||
|
||||
view/Item/Call/CallContactsLists.qml
|
||||
|
|
@ -22,9 +29,14 @@ list(APPEND _LINPHONEAPP_QML_FILES
|
|||
view/Item/Contact/ContactEdition.qml
|
||||
view/Item/Contact/ContactsList.qml
|
||||
view/Item/Contact/Sticker.qml
|
||||
|
||||
view/Item/Meeting/MeetingList.qml
|
||||
view/Item/Meeting/NewMeeting.qml
|
||||
|
||||
view/Item/BusyIndicator.qml
|
||||
view/Item/Button.qml
|
||||
view/Item/Calendar.qml
|
||||
view/Item/CalendarComboBox.qml
|
||||
view/Item/Carousel.qml
|
||||
view/Item/CheckBox.qml
|
||||
view/Item/ComboBox.qml
|
||||
|
|
@ -45,9 +57,12 @@ list(APPEND _LINPHONEAPP_QML_FILES
|
|||
view/Item/RoundedBackgroundControl.qml
|
||||
view/Item/SearchBar.qml
|
||||
view/Item/Slider.qml
|
||||
view/Item/Switch.qml
|
||||
view/Item/TabBar.qml
|
||||
view/Item/Text.qml
|
||||
view/Item/TextInput.qml
|
||||
view/Item/TextArea.qml
|
||||
view/Item/TextField.qml
|
||||
view/Item/TimeComboBox.qml
|
||||
view/Item/ToolTip.qml
|
||||
view/Item/VerticalTabBar.qml
|
||||
view/Item/ZrtpTokenAuthenticationDialog.qml
|
||||
|
|
@ -66,6 +81,7 @@ list(APPEND _LINPHONEAPP_QML_FILES
|
|||
view/Page/Main/AbstractMainPage.qml
|
||||
view/Page/Main/CallPage.qml
|
||||
view/Page/Main/ContactPage.qml
|
||||
view/Page/Main/MeetingPage.qml
|
||||
|
||||
view/Tool/utils.js
|
||||
# Prototypes
|
||||
|
|
|
|||
|
|
@ -15,6 +15,7 @@ Control.Button {
|
|||
property bool underline: false
|
||||
property bool shadowEnabled: false
|
||||
property var contentImageColor
|
||||
property alias contentText: contentText
|
||||
hoverEnabled: true
|
||||
icon.width: width
|
||||
icon.height: height
|
||||
|
|
@ -69,6 +70,7 @@ Control.Button {
|
|||
? 1
|
||||
: 2
|
||||
|
||||
width: mainItem.width
|
||||
Text {
|
||||
id: contentText
|
||||
horizontalAlignment: Text.AlignHCenter
|
||||
|
|
@ -76,10 +78,10 @@ Control.Button {
|
|||
Layout.alignment: Qt.AlignCenter
|
||||
Layout.fillWidth: true
|
||||
Layout.fillHeight: true
|
||||
width: implicitWidth
|
||||
height: implicitHeight
|
||||
wrapMode: Text.WordWrap
|
||||
wrapMode: Text.WrapAnywhere
|
||||
text: mainItem.text
|
||||
maximumLineCount: 1
|
||||
color: inversedColors ? mainItem.color : DefaultStyle.grey_0
|
||||
font {
|
||||
pixelSize: mainItem.textSize
|
||||
|
|
|
|||
117
Linphone/view/Item/Calendar.qml
Normal file
117
Linphone/view/Item/Calendar.qml
Normal file
|
|
@ -0,0 +1,117 @@
|
|||
import QtQuick 2.7
|
||||
import QtQuick.Layouts 1.3
|
||||
import QtQuick.Controls as Control
|
||||
import QtQuick.Effects
|
||||
|
||||
import Linphone
|
||||
import ConstantsCpp 1.0
|
||||
import UtilsCpp 1.0
|
||||
|
||||
ListView {
|
||||
id: mainItem
|
||||
// width: 400 * DefaultStyle.dp
|
||||
// height: 400 * DefaultStyle.dp
|
||||
snapMode: ListView.SnapOneItem
|
||||
orientation: Qt.Horizontal
|
||||
clip: true
|
||||
property int maxYears: 5
|
||||
readonly property var currentDate: new Date()
|
||||
Layout.fillWidth: true
|
||||
Layout.fillHeight: true
|
||||
highlightMoveDuration: 100
|
||||
|
||||
property var selectedDate: new Date()
|
||||
|
||||
model: Control.CalendarModel {
|
||||
id: calendarModel
|
||||
from: new Date()
|
||||
to: new Date(2025, 12, 31)
|
||||
}
|
||||
|
||||
delegate: ColumnLayout {
|
||||
width: mainItem.width
|
||||
height: mainItem.height
|
||||
RowLayout {
|
||||
Layout.fillWidth: true
|
||||
Text {
|
||||
text: new Date(model.year, model.month, 15).toLocaleString(Qt.locale(ConstantsCpp.DefaultLocale), 'MMMM yyyy')// 15 because of timezones that can change the date for localeString
|
||||
font {
|
||||
pixelSize: 14 * DefaultStyle.dp
|
||||
weight: 700 * DefaultStyle.dp
|
||||
capitalization: Font.Capitalize
|
||||
}
|
||||
}
|
||||
Item {
|
||||
Layout.fillWidth: true
|
||||
}
|
||||
Button {
|
||||
Layout.preferredWidth: 10 * DefaultStyle.dp
|
||||
Layout.preferredHeight: 20 * DefaultStyle.dp
|
||||
background: Item{}
|
||||
icon.source: AppIcons.leftArrow
|
||||
onClicked: if (mainItem.currentIndex > 0) --mainItem.currentIndex
|
||||
}
|
||||
Button {
|
||||
Layout.preferredWidth: 20 * DefaultStyle.dp
|
||||
Layout.preferredHeight: 20 * DefaultStyle.dp
|
||||
background: Item{}
|
||||
icon.source: AppIcons.rightArrow
|
||||
onClicked: if (mainItem.currentIndex < mainItem.count) ++mainItem.currentIndex
|
||||
}
|
||||
}
|
||||
Control.DayOfWeekRow {
|
||||
locale: monthGrid.locale
|
||||
Layout.column: 1
|
||||
Layout.fillWidth: true
|
||||
delegate: Text {
|
||||
text: model.shortName
|
||||
color: DefaultStyle.main2_400
|
||||
horizontalAlignment: Text.AlignHCenter
|
||||
verticalAlignment: Text.AlignVCenter
|
||||
font {
|
||||
pixelSize: 12 * DefaultStyle.dp
|
||||
weight: 300 * DefaultStyle.dp
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Control.MonthGrid {
|
||||
id: monthGrid
|
||||
Layout.fillWidth: true
|
||||
Layout.fillHeight: true
|
||||
|
||||
year: model.year
|
||||
month: model.month
|
||||
// locale: Qt.locale("en_US")
|
||||
delegate: Item {
|
||||
property bool isSelectedDay: UtilsCpp.datesAreEqual(mainItem.selectedDate, model.date)
|
||||
Rectangle {
|
||||
anchors.centerIn: parent
|
||||
width: 30 * DefaultStyle.dp
|
||||
height: 30 * DefaultStyle.dp
|
||||
radius: 50 * DefaultStyle.dp
|
||||
color: isSelectedDay ? DefaultStyle.main1_500_main : "transparent"
|
||||
}
|
||||
Text {
|
||||
anchors.centerIn: parent
|
||||
text: monthGrid.locale.toString(model.date, "d")
|
||||
color: isSelectedDay
|
||||
? DefaultStyle.grey_0
|
||||
: UtilsCpp.isCurrentDay(model.date)
|
||||
? DefaultStyle.main1_500_main
|
||||
: UtilsCpp.isCurrentMonth(model.date)
|
||||
? DefaultStyle.main2_700
|
||||
: DefaultStyle.main2_400
|
||||
font {
|
||||
pixelSize: 12 * DefaultStyle.dp
|
||||
weight: 300 * DefaultStyle.dp
|
||||
}
|
||||
}
|
||||
}
|
||||
onClicked: (date) => {
|
||||
if (UtilsCpp.isBeforeToday(date)) return;
|
||||
mainItem.selectedDate = date
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
45
Linphone/view/Item/CalendarComboBox.qml
Normal file
45
Linphone/view/Item/CalendarComboBox.qml
Normal file
|
|
@ -0,0 +1,45 @@
|
|||
import QtQuick
|
||||
import QtQuick.Controls as Control
|
||||
import QtQuick.Effects
|
||||
import Linphone
|
||||
|
||||
ComboBox {
|
||||
id: mainItem
|
||||
property var selectedDate: calendar.selectedDate
|
||||
property alias calendar: calendar
|
||||
contentItem: Text {
|
||||
text: Qt.formatDate(calendar.selectedDate, "ddd d, MMMM")
|
||||
anchors.fill: parent
|
||||
anchors.leftMargin: 15 * DefaultStyle.dp
|
||||
anchors.verticalCenter: parent.verticalCenter
|
||||
verticalAlignment: Text.AlignVCenter
|
||||
font {
|
||||
pixelSize: 14 * DefaultStyle.dp
|
||||
weight: 700 * DefaultStyle.dp
|
||||
}
|
||||
}
|
||||
popup: Control.Popup {
|
||||
y: mainItem.height
|
||||
width: 321 * DefaultStyle.dp
|
||||
height: 270 * DefaultStyle.dp
|
||||
closePolicy: Popup.NoAutoClose
|
||||
background: Item {
|
||||
Rectangle {
|
||||
id: calendarBg
|
||||
anchors.fill: parent
|
||||
color: DefaultStyle.grey_0
|
||||
radius: 16 * DefaultStyle.dp
|
||||
}
|
||||
MultiEffect {
|
||||
anchors.fill: calendarBg
|
||||
source: calendarBg
|
||||
shadowEnabled: true
|
||||
shadowBlur: 1
|
||||
shadowOpacity: 0.1
|
||||
}
|
||||
}
|
||||
contentItem: Calendar {
|
||||
id: calendar
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -235,12 +235,26 @@ Item {
|
|||
onContactSelected: (contact) => {
|
||||
if (contact.core.allAddresses.length > 1) {
|
||||
startCallPopup.contact = contact
|
||||
startCallPopup.open()
|
||||
onSelectedContactChanged: {
|
||||
if (selectedContact) {
|
||||
if (selectedContact.core.allAddresses.length > 1) {
|
||||
startCallPopup.selectedContact = selectedContact
|
||||
startCallPopup.open()
|
||||
|
||||
} else {
|
||||
mainItem.callButtonPressed(contact.core.defaultAddress)
|
||||
} else {
|
||||
mainItem.callButtonPressed(selectedContact.core.defaultAddress)
|
||||
}
|
||||
}
|
||||
}
|
||||
// onContactSelected: (contact) => {
|
||||
// if (contact.core.allAddresses.length > 1) {
|
||||
// startCallPopup.contact = contact
|
||||
// startCallPopup.open()
|
||||
|
||||
// } else {
|
||||
// mainItem.callButtonPressed(contact.core.defaultAddress)
|
||||
// }
|
||||
// }
|
||||
}
|
||||
}
|
||||
ColumnLayout {
|
||||
|
|
@ -264,20 +278,36 @@ Item {
|
|||
sourceFlags: LinphoneEnums.MagicSearchSource.All
|
||||
aggregationFlag: LinphoneEnums.MagicSearchAggregation.Friend
|
||||
}
|
||||
onContactSelected: (contact) => {
|
||||
if (contact.core.allAddresses.length > 1) {
|
||||
startCallPopup.contact = contact
|
||||
startCallPopup.open()
|
||||
onSelectedContactChanged: {
|
||||
if (selectedContact) {
|
||||
if (selectedContact.core.allAddresses.length > 1) {
|
||||
startCallPopup.selectedContact = selectedContact
|
||||
startCallPopup.open()
|
||||
|
||||
} else {
|
||||
var addressToCall = contact.core.defaultAddress.length === 0
|
||||
? contact.core.phoneNumbers.length === 0
|
||||
? ""
|
||||
: contact.core.phoneNumbers[0].address
|
||||
: contact.core.defaultAddress
|
||||
if (addressToCall.length != 0) mainItem.callButtonPressed(addressToCall)
|
||||
} else {
|
||||
var addressToCall = selectedContact.core.defaultAddress.length === 0
|
||||
? selectedContact.core.phoneNumbers.length === 0
|
||||
? ""
|
||||
: selectedContact.core.phoneNumbers[0].address
|
||||
: selectedContact.core.defaultAddress
|
||||
if (addressToCall.length != 0) mainItem.callButtonPressed(addressToCall)
|
||||
}
|
||||
}
|
||||
}
|
||||
// onContactSelected: (contact) => {
|
||||
// if (contact.core.allAddresses.length > 1) {
|
||||
// startCallPopup.contact = contact
|
||||
// startCallPopup.open()
|
||||
|
||||
// } else {
|
||||
// var addressToCall = contact.core.defaultAddress.length === 0
|
||||
// ? contact.core.phoneNumbers.length === 0
|
||||
// ? ""
|
||||
// : contact.core.phoneNumbers[0].address
|
||||
// : contact.core.defaultAddress
|
||||
// if (addressToCall.length != 0) mainItem.callButtonPressed(addressToCall)
|
||||
// }
|
||||
// }
|
||||
}
|
||||
}
|
||||
Item {
|
||||
|
|
|
|||
|
|
@ -4,196 +4,198 @@ import QtQuick.Layouts 1.0
|
|||
import QtQuick.Effects
|
||||
import Linphone
|
||||
|
||||
ColumnLayout {
|
||||
Control.ComboBox {
|
||||
id: mainItem
|
||||
property string label: ""
|
||||
// Usage : each item of the model list must be {text: ..., img: ...}
|
||||
// If string list, only text part of the delegate will be filled
|
||||
property var model: []
|
||||
property alias combobox: combobox
|
||||
readonly property string currentText: selectedItemText.text
|
||||
property bool enableBackgroundColors: true
|
||||
readonly property bool hasActiveFocus: combobox.activeFocus
|
||||
// readonly property string currentText: selectedItemText.text
|
||||
// Layout.preferredWidth: mainItem.width
|
||||
// Layout.preferredHeight: mainItem.height
|
||||
property alias listView: listView
|
||||
property string constantImageSource
|
||||
property int pixelSize: 14 * DefaultStyle.dp
|
||||
property int weight: 400 * DefaultStyle.dp
|
||||
property int leftMargin: 10 * DefaultStyle.dp
|
||||
|
||||
Text {
|
||||
visible: label.length > 0
|
||||
verticalAlignment: Text.AlignVCenter
|
||||
text: mainItem.label
|
||||
color: combobox.activeFocus ? DefaultStyle.main1_500_main : DefaultStyle.main2_600
|
||||
font {
|
||||
pixelSize: 13 * DefaultStyle.dp
|
||||
weight: 700 * DefaultStyle.dp
|
||||
}
|
||||
onConstantImageSourceChanged: if (constantImageSource) selectedItemImg.source = constantImageSource
|
||||
onCurrentIndexChanged: {
|
||||
var item = model[currentIndex]
|
||||
if (!item) item = model.getAt(currentIndex)
|
||||
selectedItemText.text = item.text
|
||||
? item.text
|
||||
: item
|
||||
? item
|
||||
: ""
|
||||
selectedItemImg.source = constantImageSource
|
||||
? constantImageSource
|
||||
: item.img
|
||||
? item.img
|
||||
: ""
|
||||
console.log("const", constantImageSource, item.img)
|
||||
}
|
||||
|
||||
Control.ComboBox {
|
||||
id: combobox
|
||||
model: mainItem.model
|
||||
Layout.preferredWidth: mainItem.width
|
||||
background: Rectangle {
|
||||
implicitWidth: mainItem.width
|
||||
implicitHeight: 49 * DefaultStyle.dp
|
||||
radius: 63 * DefaultStyle.dp
|
||||
color: combobox.enabled ? DefaultStyle.grey_100 : DefaultStyle.grey_200
|
||||
border.color: combobox.enabled ? DefaultStyle.grey_200 : DefaultStyle.grey_400
|
||||
}
|
||||
contentItem: Item {
|
||||
background: Rectangle {
|
||||
anchors.fill: mainItem
|
||||
radius: 63 * DefaultStyle.dp
|
||||
color: mainItem.enabled ? DefaultStyle.grey_100 : DefaultStyle.grey_200
|
||||
border.color: mainItem.enabled ? DefaultStyle.grey_200 : DefaultStyle.grey_400
|
||||
}
|
||||
contentItem: Item {
|
||||
Image {
|
||||
id: selectedItemImg
|
||||
source: mainItem.constantImageSource ? mainItem.constantImageSource : ""
|
||||
visible: source != ""
|
||||
sourceSize.width: 24 * DefaultStyle.dp
|
||||
width: visible ? 24 * DefaultStyle.dp : 0
|
||||
fillMode: Image.PreserveAspectFit
|
||||
anchors.verticalCenter: parent.verticalCenter
|
||||
anchors.left: parent.left
|
||||
anchors.right: indicImage.right
|
||||
Image {
|
||||
id: selectedItemImg
|
||||
visible: source != ""
|
||||
sourceSize.width: 20 * DefaultStyle.dp
|
||||
width: visible ? 20 * DefaultStyle.dp : 0
|
||||
fillMode: Image.PreserveAspectFit
|
||||
anchors.verticalCenter: parent.verticalCenter
|
||||
anchors.left: parent.left
|
||||
anchors.leftMargin: visible ? 10 * DefaultStyle.dp : 0
|
||||
}
|
||||
anchors.leftMargin: visible ? mainItem.leftMargin : 0
|
||||
}
|
||||
|
||||
Text {
|
||||
id: selectedItemText
|
||||
color: combobox.enabled ? DefaultStyle.main2_600 : DefaultStyle.grey_400
|
||||
elide: Text.ElideRight
|
||||
maximumLineCount: 1
|
||||
font {
|
||||
pixelSize: 14 * DefaultStyle.dp
|
||||
weight: 400 * DefaultStyle.dp
|
||||
}
|
||||
anchors.left: selectedItemImg.right
|
||||
anchors.leftMargin: selectedItemImg.visible ? 5 * DefaultStyle.dp : 10 * DefaultStyle.dp
|
||||
anchors.right: parent.right
|
||||
anchors.rightMargin: 20 * DefaultStyle.dp
|
||||
anchors.verticalCenter: parent.verticalCenter
|
||||
Text {
|
||||
id: selectedItemText
|
||||
color: mainItem.enabled ? DefaultStyle.main2_600 : DefaultStyle.grey_400
|
||||
elide: Text.ElideRight
|
||||
maximumLineCount: 2
|
||||
wrapMode: Text.WrapAnywhere
|
||||
font {
|
||||
pixelSize: mainItem.pixelSize
|
||||
weight: mainItem.weight
|
||||
}
|
||||
anchors.left: selectedItemImg.right
|
||||
anchors.leftMargin: selectedItemImg.visible ? 5 * DefaultStyle.dp : 10 * DefaultStyle.dp
|
||||
anchors.right: parent.right
|
||||
anchors.rightMargin: 20 * DefaultStyle.dp
|
||||
anchors.verticalCenter: parent.verticalCenter
|
||||
}
|
||||
|
||||
Component.onCompleted: {
|
||||
var index = combobox.currentIndex < 0 ? 0 : combobox.currentIndex
|
||||
Component.onCompleted: {
|
||||
var index = mainItem.currentIndex < 0 ? 0 : mainItem.currentIndex
|
||||
if (mainItem.model && mainItem.model[index]) {
|
||||
if (mainItem.model[index] && mainItem.model[index].img) {
|
||||
selectedItemImg.source = mainItem.model[index].img
|
||||
}
|
||||
if (mainItem.model[index] && mainItem.model[index].text)
|
||||
else if (mainItem.model[index] && mainItem.model[index].text)
|
||||
selectedItemText.text = mainItem.model[index].text
|
||||
else if (mainItem.model[index])
|
||||
else
|
||||
selectedItemText.text = mainItem.model[index]
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
indicator: Image {
|
||||
id: indicImage
|
||||
anchors.right: parent.right
|
||||
anchors.rightMargin: 10 * DefaultStyle.dp
|
||||
anchors.verticalCenter: parent.verticalCenter
|
||||
source: AppIcons.downArrow
|
||||
}
|
||||
indicator: Image {
|
||||
id: indicImage
|
||||
z: 1
|
||||
anchors.right: parent.right
|
||||
anchors.rightMargin: 10 * DefaultStyle.dp
|
||||
anchors.verticalCenter: parent.verticalCenter
|
||||
source: AppIcons.downArrow
|
||||
}
|
||||
|
||||
popup: Control.Popup {
|
||||
id: listPopup
|
||||
y: combobox.height - 1
|
||||
width: combobox.width
|
||||
implicitHeight: contentItem.implicitHeight
|
||||
padding: 1 * DefaultStyle.dp
|
||||
popup: Control.Popup {
|
||||
id: popup
|
||||
y: mainItem.height - 1
|
||||
width: mainItem.width
|
||||
implicitHeight: contentItem.implicitHeight
|
||||
padding: 1 * DefaultStyle.dp
|
||||
|
||||
contentItem: ListView {
|
||||
id: listView
|
||||
clip: true
|
||||
implicitHeight: contentHeight
|
||||
model: combobox.model
|
||||
currentIndex: combobox.highlightedIndex >= 0 ? combobox.highlightedIndex : 0
|
||||
highlightFollowsCurrentItem: true
|
||||
highlight: Rectangle {
|
||||
width: listView.width
|
||||
color: DefaultStyle.main2_300
|
||||
radius: 15 * DefaultStyle.dp
|
||||
y: listView.currentItem? listView.currentItem.y : 0
|
||||
}
|
||||
contentItem: ListView {
|
||||
id: listView
|
||||
clip: true
|
||||
implicitHeight: contentHeight
|
||||
height: contentHeight
|
||||
model: mainItem.model
|
||||
currentIndex: mainItem.highlightedIndex >= 0 ? mainItem.highlightedIndex : 0
|
||||
highlightFollowsCurrentItem: true
|
||||
highlightMoveDuration: -1
|
||||
highlightMoveVelocity: -1
|
||||
highlight: Rectangle {
|
||||
width: listView.width
|
||||
color: DefaultStyle.main2_200
|
||||
radius: 15 * DefaultStyle.dp
|
||||
y: listView.currentItem? listView.currentItem.y : 0
|
||||
}
|
||||
|
||||
delegate: Item {
|
||||
width:combobox.width
|
||||
height: combobox.height
|
||||
delegate: Item {
|
||||
width:mainItem.width
|
||||
height: mainItem.height
|
||||
// anchors.left: listView.left
|
||||
// anchors.right: listView.right
|
||||
|
||||
Image {
|
||||
id: delegateImg
|
||||
visible: source != ""
|
||||
width: visible ? 20 * DefaultStyle.dp : 0
|
||||
sourceSize.width: 20 * DefaultStyle.dp
|
||||
source: modelData.img ? modelData.img : ""
|
||||
fillMode: Image.PreserveAspectFit
|
||||
anchors.left: parent.left
|
||||
anchors.leftMargin: visible ? 10 * DefaultStyle.dp : 0
|
||||
anchors.verticalCenter: parent.verticalCenter
|
||||
}
|
||||
|
||||
Text {
|
||||
text: modelData.text
|
||||
? modelData.text
|
||||
: modelData
|
||||
? modelData
|
||||
: ""
|
||||
elide: Text.ElideRight
|
||||
maximumLineCount: 1
|
||||
wrapMode: Text.WrapAnywhere
|
||||
font {
|
||||
pixelSize: 14 * DefaultStyle.dp
|
||||
weight: 400 * DefaultStyle.dp
|
||||
}
|
||||
anchors.verticalCenter: parent.verticalCenter
|
||||
anchors.left: delegateImg.right
|
||||
anchors.leftMargin: delegateImg.visible ? 5 * DefaultStyle.dp : 10 * DefaultStyle.dp
|
||||
anchors.right: parent.right
|
||||
|
||||
Image {
|
||||
id: delegateImg
|
||||
visible: source != ""
|
||||
width: visible ? 20 * DefaultStyle.dp : 0
|
||||
sourceSize.width: 20 * DefaultStyle.dp
|
||||
source: modelData.img ? modelData.img : ""
|
||||
fillMode: Image.PreserveAspectFit
|
||||
anchors.left: parent.left
|
||||
anchors.leftMargin: visible ? 10 * DefaultStyle.dp : 0
|
||||
anchors.verticalCenter: parent.verticalCenter
|
||||
}
|
||||
|
||||
Text {
|
||||
text: modelData.text
|
||||
? modelData.text
|
||||
: modelData
|
||||
? modelData
|
||||
: ""
|
||||
elide: Text.ElideRight
|
||||
maximumLineCount: 1
|
||||
font {
|
||||
pixelSize: 14 * DefaultStyle.dp
|
||||
weight: 400 * DefaultStyle.dp
|
||||
}
|
||||
anchors.verticalCenter: parent.verticalCenter
|
||||
anchors.left: delegateImg.right
|
||||
anchors.leftMargin: delegateImg.visible ? 5 * DefaultStyle.dp : 10 * DefaultStyle.dp
|
||||
anchors.right: parent.right
|
||||
anchors.rightMargin: 20 * DefaultStyle.dp
|
||||
}
|
||||
|
||||
MouseArea {
|
||||
anchors.fill: parent
|
||||
hoverEnabled: true
|
||||
Rectangle {
|
||||
anchors.fill: parent
|
||||
opacity: 0.1
|
||||
radius: 15 * DefaultStyle.dp
|
||||
color: DefaultStyle.main2_500main
|
||||
visible: parent.containsMouse
|
||||
}
|
||||
onPressed: {
|
||||
combobox.state = ""
|
||||
selectedItemText.text = modelData.text
|
||||
? modelData.text
|
||||
: modelData
|
||||
? modelData
|
||||
: ""
|
||||
selectedItemImg.source = modelData.img ? modelData.img : ""
|
||||
combobox.currentIndex = index
|
||||
listPopup.close()
|
||||
}
|
||||
}
|
||||
anchors.rightMargin: 20 * DefaultStyle.dp
|
||||
}
|
||||
|
||||
Control.ScrollIndicator.vertical: Control.ScrollIndicator { }
|
||||
}
|
||||
|
||||
onOpened: {
|
||||
listView.positionViewAtIndex(listView.currentIndex, ListView.Center)
|
||||
}
|
||||
|
||||
background: Item {
|
||||
implicitWidth: mainItem.width
|
||||
implicitHeight: 30 * DefaultStyle.dp
|
||||
Rectangle {
|
||||
id: cboxBg
|
||||
MouseArea {
|
||||
anchors.fill: parent
|
||||
radius: 15 * DefaultStyle.dp
|
||||
hoverEnabled: true
|
||||
Rectangle {
|
||||
anchors.fill: parent
|
||||
opacity: 0.1
|
||||
radius: 15 * DefaultStyle.dp
|
||||
color: DefaultStyle.main2_500main
|
||||
visible: parent.containsMouse
|
||||
}
|
||||
onClicked: {
|
||||
mainItem.currentIndex = index
|
||||
popup.close()
|
||||
}
|
||||
}
|
||||
MultiEffect {
|
||||
anchors.fill: cboxBg
|
||||
source: cboxBg
|
||||
shadowEnabled: true
|
||||
shadowColor: DefaultStyle.grey_1000
|
||||
shadowBlur: 1
|
||||
shadowOpacity: 0.1
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Control.ScrollIndicator.vertical: Control.ScrollIndicator { }
|
||||
}
|
||||
|
||||
onOpened: {
|
||||
listView.positionViewAtIndex(listView.currentIndex, ListView.Center)
|
||||
}
|
||||
|
||||
background: Item {
|
||||
implicitWidth: mainItem.width
|
||||
implicitHeight: 30 * DefaultStyle.dp
|
||||
Rectangle {
|
||||
id: cboxBg
|
||||
anchors.fill: parent
|
||||
radius: 15 * DefaultStyle.dp
|
||||
}
|
||||
MultiEffect {
|
||||
anchors.fill: cboxBg
|
||||
source: cboxBg
|
||||
shadowEnabled: true
|
||||
shadowColor: DefaultStyle.grey_1000
|
||||
shadowBlur: 1
|
||||
shadowOpacity: 0.1
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -26,7 +26,9 @@ StackView {
|
|||
property string displayNameVal: displayNameObj ? displayNameObj.value : ""
|
||||
property bool haveAvatar: (account && account.core.pictureUri )
|
||||
|| (contact && contact.core.pictureUri)
|
||||
|
||||
|| computedAvatarUri.length != 0
|
||||
property string computedAvatarUri: UtilsCpp.findAvatarByAddress(address)
|
||||
|
||||
onHaveAvatarChanged: replace(haveAvatar ? avatar : initials, StackView.Immediate)
|
||||
|
||||
property bool secured: false
|
||||
|
|
@ -134,7 +136,7 @@ StackView {
|
|||
anchors.centerIn: parent
|
||||
source: mainItem.account && mainItem.account.core.pictureUri
|
||||
|| mainItem.contact && mainItem.contact.core.pictureUri
|
||||
|| ""
|
||||
|| computedAvatarUri
|
||||
mipmap: true
|
||||
}
|
||||
ShaderEffect {
|
||||
|
|
|
|||
|
|
@ -103,29 +103,37 @@ ColumnLayout {
|
|||
Layout.bottomMargin: 50 * DefaultStyle.dp
|
||||
ColumnLayout {
|
||||
spacing: 20 * DefaultStyle.dp
|
||||
TextInput {
|
||||
FormItemLayout {
|
||||
label: qsTr("Prénom")
|
||||
initialText: contact.core.givenName
|
||||
onEditingFinished: contact.core.givenName = text
|
||||
backgroundColor: DefaultStyle.grey_0
|
||||
contentItem: TextField {
|
||||
initialText: contact.core.givenName
|
||||
onEditingFinished: contact.core.givenName = text
|
||||
backgroundColor: DefaultStyle.grey_0
|
||||
}
|
||||
}
|
||||
TextInput {
|
||||
FormItemLayout {
|
||||
label: qsTr("Nom")
|
||||
initialText: contact.core.familyName
|
||||
onEditingFinished: contact.core.familyName = text
|
||||
backgroundColor: DefaultStyle.grey_0
|
||||
contentItem: TextField {
|
||||
initialText: contact.core.familyName
|
||||
onEditingFinished: contact.core.familyName = text
|
||||
backgroundColor: DefaultStyle.grey_0
|
||||
}
|
||||
}
|
||||
TextInput {
|
||||
FormItemLayout {
|
||||
label: qsTr("Entreprise")
|
||||
initialText: contact.core.organization
|
||||
onEditingFinished: contact.core.organization = text
|
||||
backgroundColor: DefaultStyle.grey_0
|
||||
contentItem: TextField {
|
||||
initialText: contact.core.organization
|
||||
onEditingFinished: contact.core.organization = text
|
||||
backgroundColor: DefaultStyle.grey_0
|
||||
}
|
||||
}
|
||||
TextInput {
|
||||
FormItemLayout {
|
||||
label: qsTr("Fonction")
|
||||
initialText: contact.core.job
|
||||
onEditingFinished: contact.core.job = text
|
||||
backgroundColor: DefaultStyle.grey_0
|
||||
contentItem: TextField {
|
||||
initialText: contact.core.job
|
||||
onEditingFinished: contact.core.job = text
|
||||
backgroundColor: DefaultStyle.grey_0
|
||||
}
|
||||
}
|
||||
Item{Layout.fillHeight: true}
|
||||
}
|
||||
|
|
@ -141,13 +149,15 @@ ColumnLayout {
|
|||
model: mainItem.contact && mainItem.contact.core.addresses || []
|
||||
}
|
||||
delegate: RowLayout {
|
||||
TextInput {
|
||||
FormItemLayout {
|
||||
label: modelData.label
|
||||
onEditingFinished: {
|
||||
if (text.length != 0) mainItem.contact.core.setAddressAt(index, qsTr("Address SIP"), text)
|
||||
contentItem: TextField {
|
||||
onEditingFinished: {
|
||||
if (text.length != 0) mainItem.contact.core.setAddressAt(index, qsTr("Address SIP"), text)
|
||||
}
|
||||
initialText: modelData.address
|
||||
backgroundColor: DefaultStyle.grey_0
|
||||
}
|
||||
initialText: modelData.address
|
||||
backgroundColor: DefaultStyle.grey_0
|
||||
}
|
||||
Button {
|
||||
Layout.preferredWidth: 24 * DefaultStyle.dp
|
||||
|
|
@ -161,12 +171,14 @@ ColumnLayout {
|
|||
}
|
||||
}
|
||||
RowLayout {
|
||||
TextInput {
|
||||
FormItemLayout {
|
||||
label: qsTr("Adresse SIP")
|
||||
backgroundColor: DefaultStyle.grey_0
|
||||
onEditingFinished: {
|
||||
if (text.length != 0) mainItem.contact.core.appendAddress(text)
|
||||
setText("")
|
||||
contentItem: TextField {
|
||||
backgroundColor: DefaultStyle.grey_0
|
||||
onEditingFinished: {
|
||||
if (text.length != 0) mainItem.contact.core.appendAddress(text)
|
||||
text = ""
|
||||
}
|
||||
}
|
||||
}
|
||||
Item {
|
||||
|
|
@ -180,13 +192,15 @@ ColumnLayout {
|
|||
model: mainItem.contact && mainItem.contact.core.phoneNumbers || []
|
||||
}
|
||||
delegate: RowLayout {
|
||||
TextInput {
|
||||
FormItemLayout {
|
||||
label: modelData.label
|
||||
initialText: modelData.address
|
||||
onEditingFinished: {
|
||||
if (text.length != 0) mainItem.contact.core.setPhoneNumberAt(index, qsTr("Téléphone"), text)
|
||||
contentItem: TextField {
|
||||
initialText: modelData.address
|
||||
onEditingFinished: {
|
||||
if (text.length != 0) mainItem.contact.core.setPhoneNumberAt(index, qsTr("Téléphone"), text)
|
||||
}
|
||||
backgroundColor: DefaultStyle.grey_0
|
||||
}
|
||||
backgroundColor: DefaultStyle.grey_0
|
||||
}
|
||||
Button {
|
||||
Layout.preferredWidth: 24 * DefaultStyle.dp
|
||||
|
|
@ -200,12 +214,14 @@ ColumnLayout {
|
|||
}
|
||||
}
|
||||
RowLayout {
|
||||
TextInput {
|
||||
FormItemLayout {
|
||||
label: qsTr("Phone")
|
||||
backgroundColor: DefaultStyle.grey_0
|
||||
onEditingFinished: {
|
||||
if (text.length != 0) mainItem.contact.core.appendPhoneNumber(label, text)
|
||||
setText("")
|
||||
contentItem: TextField {
|
||||
backgroundColor: DefaultStyle.grey_0
|
||||
onEditingFinished: {
|
||||
if (text.length != 0) mainItem.contact.core.appendPhoneNumber(label, text)
|
||||
setText("")
|
||||
}
|
||||
}
|
||||
}
|
||||
Item {
|
||||
|
|
|
|||
|
|
@ -18,6 +18,19 @@ ListView {
|
|||
property bool initialHeadersVisible: true
|
||||
property bool displayNameCapitalization: true
|
||||
property bool showOnlyFavourites: false
|
||||
|
||||
property ConferenceInfoGui confInfoGui
|
||||
|
||||
property bool multiSelectionEnabled: false
|
||||
property list<string> selectedContacts
|
||||
property int selectedContactCount: selectedContacts.length
|
||||
Component.onCompleted: {
|
||||
if (confInfoGui) {
|
||||
for(var i = 0; i < confInfoGui.core.participants.length; ++i) {
|
||||
selectedContacts.push(confInfoGui.core.getParticipantAddressAt(i));
|
||||
}
|
||||
}
|
||||
}
|
||||
property int delegateLeftMargin: 0
|
||||
currentIndex: -1
|
||||
|
||||
|
|
@ -30,10 +43,11 @@ ListView {
|
|||
selectedContact = model.getAt(currentIndex) || null
|
||||
}
|
||||
|
||||
signal contactSelected(var contact)
|
||||
// signal contactSelected(var contact)
|
||||
signal contactStarredChanged()
|
||||
signal contactDeletionRequested(FriendGui contact)
|
||||
|
||||
signal contactAddedToSelection()
|
||||
|
||||
model: MagicSearchProxy {
|
||||
searchText: searchBarText.length === 0 ? "*" : searchBarText
|
||||
}
|
||||
|
|
@ -89,13 +103,29 @@ ListView {
|
|||
maximumLineCount: 1
|
||||
Layout.fillWidth: true
|
||||
}
|
||||
RowLayout {
|
||||
id: buttonsLayout
|
||||
z: 1
|
||||
height: parent.height
|
||||
children: mainItem.delegateButtons || []
|
||||
EffectImage {
|
||||
id: isSelectedCheck
|
||||
// visible: mainItem.multiSelectionEnabled && (mainItem.confInfoGui.core.getParticipantIndex(modelData.core.defaultAddress) != -1)
|
||||
visible: mainItem.multiSelectionEnabled && (mainItem.selectedContacts.indexOf(modelData.core.defaultAddress) != -1)
|
||||
Layout.preferredWidth: 24 * DefaultStyle.dp
|
||||
Layout.preferredHeight: 24 * DefaultStyle.dp
|
||||
imageSource: AppIcons.check
|
||||
colorizationColor: DefaultStyle.main1_500_main
|
||||
Connections {
|
||||
target: mainItem
|
||||
// onParticipantsChanged: isSelectedCheck.visible = mainItem.confInfoGui.core.getParticipantIndex(modelData.core.defaultAddress) != -1
|
||||
onSelectedContactCountChanged: isSelectedCheck.visible = (mainItem.selectedContacts.indexOf(modelData.core.defaultAddress) != -1)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
RowLayout {
|
||||
z: 1
|
||||
height: parent.height
|
||||
anchors.right: parent.right
|
||||
anchors.rightMargin: 5 * DefaultStyle.dp
|
||||
anchors.verticalCenter: parent.verticalCenter
|
||||
children: mainItem.delegateButtons || []
|
||||
PopupButton {
|
||||
id: friendPopup
|
||||
z: 1
|
||||
|
|
@ -159,6 +189,7 @@ ListView {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
MouseArea {
|
||||
id: contactArea
|
||||
|
|
@ -169,11 +200,29 @@ ListView {
|
|||
anchors.fill: contactArea
|
||||
opacity: 0.7
|
||||
color: DefaultStyle.main2_100
|
||||
visible: contactArea.containsMouse || friendPopup.hovered || mainItem.currentIndex === index
|
||||
visible: contactArea.containsMouse || friendPopup.hovered || (!mainItem.multiSelectionEnabled && mainItem.currentIndex === index)
|
||||
}
|
||||
onClicked: {
|
||||
mainItem.currentIndex = index
|
||||
mainItem.contactSelected(modelData)
|
||||
// mainItem.contactSelected(modelData)
|
||||
// if (mainItem.multiSelectionEnabled && mainItem.confInfoGui) {
|
||||
// var indexInSelection = mainItem.confInfoGui.core.getParticipantIndex(modelData.core.defaultAddress)
|
||||
// if (indexInSelection == -1) {
|
||||
// mainItem.confInfoGui.core.addParticipant(modelData.core.defaultAddress)
|
||||
// } else {
|
||||
// mainItem.confInfoGui.core.removeParticipant(indexInSelection)
|
||||
// }
|
||||
// }
|
||||
if (mainItem.multiSelectionEnabled) {
|
||||
var indexInSelection = mainItem.selectedContacts.indexOf(modelData.core.defaultAddress)
|
||||
if (indexInSelection == -1) {
|
||||
mainItem.selectedContacts.push(modelData.core.defaultAddress)
|
||||
mainItem.contactAddedToSelection()
|
||||
}
|
||||
else {
|
||||
mainItem.selectedContacts.splice(indexInSelection, 1)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -9,43 +9,51 @@ ColumnLayout {
|
|||
spacing: 15 * DefaultStyle.dp
|
||||
signal connectionSucceed()
|
||||
|
||||
TextInput {
|
||||
FormItemLayout {
|
||||
id: username
|
||||
label: "Username"
|
||||
mandatory: true
|
||||
enableErrorText: true
|
||||
|
||||
Binding on background.border.color {
|
||||
when: errorText.opacity != 0
|
||||
value: DefaultStyle.danger_500main
|
||||
}
|
||||
Binding on textField.color {
|
||||
when: errorText.opacity != 0
|
||||
value: DefaultStyle.danger_500main
|
||||
}
|
||||
}
|
||||
|
||||
Item {
|
||||
Layout.preferredHeight: password.implicitHeight
|
||||
TextInput {
|
||||
id: password
|
||||
label: "Password"
|
||||
mandatory: true
|
||||
hidden: true
|
||||
enableErrorText: true
|
||||
|
||||
Binding on background.border.color {
|
||||
contentItem: TextField {
|
||||
id: usernameEdit
|
||||
Layout.preferredWidth: 360 * DefaultStyle.dp
|
||||
Layout.preferredHeight: 49 * DefaultStyle.dp
|
||||
Binding on backgroundBorderColor {
|
||||
when: errorText.opacity != 0
|
||||
value: DefaultStyle.danger_500main
|
||||
}
|
||||
Binding on textField.color {
|
||||
Binding on color {
|
||||
when: errorText.opacity != 0
|
||||
value: DefaultStyle.danger_500main
|
||||
}
|
||||
}
|
||||
}
|
||||
Item {
|
||||
Layout.preferredHeight: password.implicitHeight
|
||||
FormItemLayout {
|
||||
id: password
|
||||
label: "Password"
|
||||
mandatory: true
|
||||
enableErrorText: true
|
||||
contentItem: TextField {
|
||||
id: passwordEdit
|
||||
Layout.preferredWidth: 360 * DefaultStyle.dp
|
||||
Layout.preferredHeight: 49 * DefaultStyle.dp
|
||||
hidden: true
|
||||
Binding on backgroundBorderColor {
|
||||
when: errorText.opacity != 0
|
||||
value: DefaultStyle.danger_500main
|
||||
}
|
||||
Binding on color {
|
||||
when: errorText.opacity != 0
|
||||
value: DefaultStyle.danger_500main
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
ErrorText {
|
||||
anchors.bottom: password.bottom
|
||||
anchors.top: password.bottom
|
||||
anchors.topMargin: 15 * DefaultStyle.dp
|
||||
id: errorText
|
||||
Connections {
|
||||
target: LoginPageCpp
|
||||
|
|
@ -106,14 +114,14 @@ ColumnLayout {
|
|||
password.errorMessage = ""
|
||||
errorText.text = ""
|
||||
|
||||
if (username.text.length == 0 || password.text.length == 0) {
|
||||
if (username.text.length == 0)
|
||||
if (usernameEdit.text.length == 0 || passwordEdit.text.length == 0) {
|
||||
if (usernameEdit.text.length == 0)
|
||||
username.errorMessage = qsTr("You must enter a username")
|
||||
if (password.text.length == 0)
|
||||
if (passwordEdit.text.length == 0)
|
||||
password.errorMessage = qsTr("You must enter a password")
|
||||
return
|
||||
}
|
||||
LoginPageCpp.login(username.text, password.text)
|
||||
LoginPageCpp.login(usernameEdit.text, passwordEdit.text)
|
||||
connectionButton.currentIndex = 1
|
||||
}
|
||||
}
|
||||
|
|
|
|||
155
Linphone/view/Item/Meeting/MeetingList.qml
Normal file
155
Linphone/view/Item/Meeting/MeetingList.qml
Normal file
|
|
@ -0,0 +1,155 @@
|
|||
import QtQuick 2.7
|
||||
import QtQuick.Layouts 1.3
|
||||
import QtQuick.Effects
|
||||
|
||||
import Linphone
|
||||
import QtQml
|
||||
import UtilsCpp 1.0
|
||||
|
||||
ListView {
|
||||
id: mainItem
|
||||
height: contentHeight
|
||||
visible: count > 0
|
||||
clip: true
|
||||
|
||||
property string searchBarText
|
||||
|
||||
property bool hoverEnabled: true
|
||||
|
||||
property int delegateLeftMargin: 0
|
||||
currentIndex: -1
|
||||
|
||||
property var delegateButtons
|
||||
|
||||
property ConferenceInfoGui selectedConference: model.getAt(currentIndex) || null
|
||||
|
||||
onCountChanged: selectedConference = model.getAt(currentIndex) || null
|
||||
onCurrentIndexChanged: selectedConference = model.getAt(currentIndex) || null
|
||||
|
||||
signal conferenceSelected(var contact)
|
||||
|
||||
model: ConferenceInfoProxy {
|
||||
searchText: searchBarText.length === 0 ? "" : searchBarText
|
||||
}
|
||||
|
||||
section {
|
||||
criteria: ViewSection.FullString
|
||||
delegate: Text {
|
||||
text: section
|
||||
height: 29 * DefaultStyle.dp
|
||||
font {
|
||||
pixelSize: 20 * DefaultStyle.dp
|
||||
weight: 800 * DefaultStyle.dp
|
||||
capitalization: Font.Capitalize
|
||||
}
|
||||
}
|
||||
property: '$sectionMonth'
|
||||
}
|
||||
|
||||
delegate: Item {
|
||||
id: itemDelegate
|
||||
height: 80 * DefaultStyle.dp
|
||||
width: mainItem.width
|
||||
property var previousItem : mainItem.model.count > 0 && index > 0 ? mainItem.model.getAt(index-1) : null
|
||||
property var previousDateTime: previousItem ? previousItem.core.dateTimeUtc : null
|
||||
property var dateTime: $modelData.core.dateTime
|
||||
property var endDateTime: $modelData.core.endDateTime
|
||||
ColumnLayout {
|
||||
id: dateDay
|
||||
width: 32 * DefaultStyle.dp
|
||||
height: 51 * DefaultStyle.dp
|
||||
visible: !previousDateTime || previousDateTime != dateTime
|
||||
anchors.verticalCenter: parent.verticalCenter
|
||||
Text {
|
||||
verticalAlignment: Text.AlignVCenter
|
||||
Layout.preferredWidth: 32 * DefaultStyle.dp
|
||||
Layout.preferredHeight: 19 * DefaultStyle.dp
|
||||
// opacity: (!previousItem || !previousDateTime.startsWith(displayName[0])) ? 1 : 0
|
||||
text: UtilsCpp.toDateDayNameString(dateTime)
|
||||
color: DefaultStyle.main2_500main
|
||||
font {
|
||||
pixelSize: 14 * DefaultStyle.dp
|
||||
weight: 400 * DefaultStyle.dp
|
||||
capitalization: Font.Capitalize
|
||||
}
|
||||
}
|
||||
Rectangle {
|
||||
id: dayNum
|
||||
Layout.preferredWidth: 32 * DefaultStyle.dp
|
||||
Layout.preferredHeight: 32 * DefaultStyle.dp
|
||||
radius: 50 * DefaultStyle.dp
|
||||
property var isCurrentDay: UtilsCpp.isCurrentDay(dateTime)
|
||||
color: isCurrentDay ? DefaultStyle.main1_500_main : "transparent"
|
||||
Text {
|
||||
anchors.centerIn: parent
|
||||
text: UtilsCpp.toDateDayString(dateTime)
|
||||
color: dayNum.isCurrentDay ? DefaultStyle.grey_0 : DefaultStyle.main2_500main
|
||||
font {
|
||||
pixelSize: 20 * DefaultStyle.dp
|
||||
weight: 800 * DefaultStyle.dp
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
Rectangle {
|
||||
id: conferenceInfoDelegate
|
||||
anchors.left: dateDay.visible ? dateDay.right : parent.left
|
||||
anchors.leftMargin: 10 * DefaultStyle.dp + mainItem.delegateLeftMargin
|
||||
anchors.rightMargin: 10 * DefaultStyle.dp + mainItem.delegateLeftMargin
|
||||
anchors.right: parent.right
|
||||
anchors.verticalCenter: parent.verticalCenter
|
||||
radius: 10 * DefaultStyle.dp
|
||||
// width: 265 * DefaultStyle.dp
|
||||
height: 63 * DefaultStyle.dp
|
||||
color: mainItem.currentIndex === index ? DefaultStyle.main2_200 : DefaultStyle.grey_0
|
||||
ColumnLayout {
|
||||
anchors.fill: parent
|
||||
anchors.left: parent.left
|
||||
anchors.leftMargin: 15 * DefaultStyle.dp
|
||||
spacing: 2 * DefaultStyle.dp
|
||||
RowLayout {
|
||||
spacing: 8 * DefaultStyle.dp
|
||||
Image {
|
||||
source: AppIcons.usersThree
|
||||
Layout.preferredWidth: 24 * DefaultStyle.dp
|
||||
Layout.preferredHeight: 24 * DefaultStyle.dp
|
||||
}
|
||||
Text {
|
||||
text: $modelData.core.subject
|
||||
font {
|
||||
pixelSize: 13 * DefaultStyle.dp
|
||||
weight: 700 * DefaultStyle.dp
|
||||
}
|
||||
}
|
||||
}
|
||||
Text {
|
||||
text: UtilsCpp.toDateHourString(dateTime) + " - " + UtilsCpp.toDateHourString(endDateTime)
|
||||
color: DefaultStyle.main2_500main
|
||||
font {
|
||||
pixelSize: 14 * DefaultStyle.dp
|
||||
weight: 400 * DefaultStyle.dp
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
MultiEffect {
|
||||
source: conferenceInfoDelegate
|
||||
anchors.fill: conferenceInfoDelegate
|
||||
shadowEnabled: true
|
||||
shadowBlur: 1.0
|
||||
shadowOpacity: 0.1
|
||||
}
|
||||
|
||||
MouseArea {
|
||||
id: confArea
|
||||
hoverEnabled: mainItem.hoverEnabled
|
||||
anchors.fill: dateDay.visible ? conferenceInfoDelegate : parent
|
||||
cursorShape: Qt.PointingHandCursor
|
||||
onClicked: {
|
||||
mainItem.currentIndex = index
|
||||
mainItem.conferenceSelected($modelData)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
377
Linphone/view/Item/Meeting/NewMeeting.qml
Normal file
377
Linphone/view/Item/Meeting/NewMeeting.qml
Normal file
|
|
@ -0,0 +1,377 @@
|
|||
import QtQuick 2.15
|
||||
import QtQuick.Effects
|
||||
import QtQuick.Layouts
|
||||
import QtQuick.Controls as Control
|
||||
import Linphone
|
||||
import UtilsCpp 1.0
|
||||
|
||||
ColumnLayout {
|
||||
id: mainItem
|
||||
spacing: 8 * DefaultStyle.dp
|
||||
property ConferenceInfoGui conferenceInfoGui
|
||||
signal addParticipantsRequested()
|
||||
signal returnRequested()
|
||||
RowLayout {
|
||||
Button {
|
||||
background: Item{}
|
||||
icon.source: AppIcons.leftArrow
|
||||
Layout.preferredWidth: 24 * DefaultStyle.dp
|
||||
Layout.preferredHeight: 24 * DefaultStyle.dp
|
||||
onClicked: mainItem.returnRequested()
|
||||
}
|
||||
Text {
|
||||
text: qsTr("Nouvelle réunion")
|
||||
color: DefaultStyle.main2_700
|
||||
font {
|
||||
pixelSize: 22 * DefaultStyle.dp
|
||||
weight: 800 * DefaultStyle.dp
|
||||
}
|
||||
Layout.fillWidth: true
|
||||
}
|
||||
Button {
|
||||
topPadding: 6 * DefaultStyle.dp
|
||||
bottomPadding: 6 * DefaultStyle.dp
|
||||
leftPadding: 12 * DefaultStyle.dp
|
||||
rightPadding: 12 * DefaultStyle.dp
|
||||
text: qsTr("Créer")
|
||||
textSize: 13 * DefaultStyle.dp
|
||||
onClicked: {
|
||||
if (mainItem.conferenceInfoGui.core.subject.length === 0) {
|
||||
UtilsCpp.showInformationPopup(qsTr("Erreur lors de la création"), qsTr("La conférence doit contenir un sujet"), false)
|
||||
} else if (mainItem.conferenceInfoGui.core.duration <= 0) {
|
||||
UtilsCpp.showInformationPopup(qsTr("Erreur lors de la création"), qsTr("La fin de la conférence doit être plus récente que son début"), false)
|
||||
} else if (mainItem.conferenceInfoGui.core.participantCount === 0) {
|
||||
UtilsCpp.showInformationPopup(qsTr("Erreur lors de la création"), qsTr("La conférence doit contenir au moins un participant"), false)
|
||||
} else {
|
||||
mainItem.conferenceInfoGui.core.save()
|
||||
mainItem.returnRequested()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
component CheckableButton: Button {
|
||||
id: checkableButton
|
||||
checkable: true
|
||||
autoExclusive: true
|
||||
contentImageColor: checked ? DefaultStyle.grey_0 : DefaultStyle.main1_500_main
|
||||
inversedColors: !checked
|
||||
topPadding: 10 * DefaultStyle.dp
|
||||
bottomPadding: 10 * DefaultStyle.dp
|
||||
leftPadding: 16 * DefaultStyle.dp
|
||||
rightPadding: 16 * DefaultStyle.dp
|
||||
contentItem: RowLayout {
|
||||
EffectImage {
|
||||
imageSource: checkableButton.icon.source
|
||||
colorizationColor: checkableButton.checked ? DefaultStyle.grey_0 : DefaultStyle.main1_500_main
|
||||
width: 24 * DefaultStyle.dp
|
||||
height: 24 * DefaultStyle.dp
|
||||
}
|
||||
Text {
|
||||
text: checkableButton.text
|
||||
color: checkableButton.checked ? DefaultStyle.grey_0 : DefaultStyle.main1_500_main
|
||||
font {
|
||||
pixelSize: 16 * DefaultStyle.dp
|
||||
weight: 400 * DefaultStyle.dp
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
RowLayout {
|
||||
Layout.fillWidth: true
|
||||
Layout.topMargin: 20 * DefaultStyle.dp
|
||||
Layout.bottomMargin: 20 * DefaultStyle.dp
|
||||
Layout.alignment: Qt.AlignHCenter
|
||||
spacing: 20 * DefaultStyle.dp
|
||||
CheckableButton {
|
||||
Layout.preferredWidth: 151 * DefaultStyle.dp
|
||||
icon.source: AppIcons.usersThree
|
||||
text: qsTr("Réunion")
|
||||
checked: true
|
||||
}
|
||||
CheckableButton {
|
||||
Layout.preferredWidth: 151 * DefaultStyle.dp
|
||||
icon.source: AppIcons.slide
|
||||
text: qsTr("Broadcast")
|
||||
}
|
||||
}
|
||||
Section {
|
||||
content: RowLayout {
|
||||
EffectImage {
|
||||
imageSource: AppIcons.usersThree
|
||||
colorizationColor: DefaultStyle.main2_600
|
||||
Layout.preferredWidth: 24 * DefaultStyle.dp
|
||||
Layout.preferredHeight: 24 * DefaultStyle.dp
|
||||
}
|
||||
TextInput {
|
||||
id: confTitle
|
||||
text: qsTr("Ajouter un titre")
|
||||
color: DefaultStyle.main2_600
|
||||
font {
|
||||
pixelSize: 20 * DefaultStyle.dp
|
||||
weight: 800 * DefaultStyle.dp
|
||||
}
|
||||
onActiveFocusChanged: if(activeFocus==true) selectAll()
|
||||
onEditingFinished: mainItem.conferenceInfoGui.core.subject = text
|
||||
}
|
||||
}
|
||||
}
|
||||
Section {
|
||||
Layout.topMargin: 10 * DefaultStyle.dp
|
||||
content: ColumnLayout {
|
||||
spacing: 15 * DefaultStyle.dp
|
||||
anchors.left: parent.left
|
||||
anchors.right: parent.right
|
||||
RowLayout {
|
||||
Layout.fillWidth: true
|
||||
|
||||
EffectImage {
|
||||
imageSource: AppIcons.clock
|
||||
colorizationColor: DefaultStyle.main2_600
|
||||
Layout.preferredWidth: 24 * DefaultStyle.dp
|
||||
Layout.preferredHeight: 24 * DefaultStyle.dp
|
||||
}
|
||||
CalendarComboBox {
|
||||
id: startDate
|
||||
Layout.fillWidth: true
|
||||
Layout.preferredHeight: 30 * DefaultStyle.dp
|
||||
onSelectedDateChanged: {
|
||||
mainItem.conferenceInfoGui.core.dateTime = UtilsCpp.createDateTime(selectedDate, startHour.selectedHour, startHour.selectedMin)
|
||||
endDate.calendar.selectedDate = selectedDate
|
||||
}
|
||||
}
|
||||
}
|
||||
RowLayout {
|
||||
Item {
|
||||
Layout.preferredWidth: 24 * DefaultStyle.dp
|
||||
Layout.preferredHeight: 24 * DefaultStyle.dp
|
||||
}
|
||||
StackLayout {
|
||||
currentIndex: allDaySwitch.position
|
||||
RowLayout {
|
||||
TimeComboBox {
|
||||
id: startHour
|
||||
onSelectedHourChanged: {
|
||||
mainItem.conferenceInfoGui.core.dateTime = UtilsCpp.createDateTime(startDate.selectedDate, selectedHour, selectedMin)
|
||||
console.log("selected hour", selectedHour, selectedMin)
|
||||
endHour.selectedTimeString = Qt.formatDateTime(UtilsCpp.createDateTime(new Date(), selectedHour == 23 ? 0 : selectedHour + 1, selectedMin), "hh:mm")
|
||||
}
|
||||
onSelectedMinChanged: {
|
||||
mainItem.conferenceInfoGui.core.dateTime = UtilsCpp.createDateTime(startDate.selectedDate, selectedHour, selectedMin)
|
||||
console.log("selected min", selectedHour, selectedMin)
|
||||
endHour.selectedTimeString = Qt.formatDateTime(UtilsCpp.createDateTime(new Date(), selectedHour == 23 ? 0 : selectedHour + 1, selectedMin), "hh:mm")
|
||||
}
|
||||
Layout.preferredWidth: 94 * DefaultStyle.dp
|
||||
Layout.preferredHeight: 30 * DefaultStyle.dp
|
||||
}
|
||||
TimeComboBox {
|
||||
id: endHour
|
||||
property date startTime: new Date()
|
||||
onSelectedHourChanged: mainItem.conferenceInfoGui.core.endDateTime = UtilsCpp.createDateTime(endDate.selectedDate, selectedHour, selectedMin)
|
||||
onSelectedMinChanged: mainItem.conferenceInfoGui.core.endDateTime = UtilsCpp.createDateTime(endDate.selectedDate, selectedHour, selectedMin)
|
||||
Layout.preferredWidth: 94 * DefaultStyle.dp
|
||||
Layout.preferredHeight: 30 * DefaultStyle.dp
|
||||
Component.onCompleted: selectedTimeString = Qt.formatDateTime(UtilsCpp.addSecs(startTime, 3600), "hh:mm")
|
||||
}
|
||||
Item {
|
||||
Layout.fillWidth: true
|
||||
}
|
||||
Text {
|
||||
property int durationSec: UtilsCpp.secsTo(startHour.selectedTime, endHour.selectedTime)
|
||||
property int hour: durationSec/3600
|
||||
property int min: (durationSec - hour*3600)/60
|
||||
text: (hour > 0 ? hour + "h" : "") + (min > 0 ? min + "mn" : "")
|
||||
font {
|
||||
pixelSize: 14 * DefaultStyle.dp
|
||||
weight: 700 * DefaultStyle.dp
|
||||
}
|
||||
}
|
||||
}
|
||||
CalendarComboBox {
|
||||
id: endDate
|
||||
Layout.fillWidth: true
|
||||
Layout.preferredHeight: 30 * DefaultStyle.dp
|
||||
onSelectedDateChanged: mainItem.conferenceInfoGui.core.endDateTime = UtilsCpp.createDateTime(selectedDate, 23, 59)
|
||||
}
|
||||
}
|
||||
}
|
||||
RowLayout {
|
||||
Item {
|
||||
Layout.preferredWidth: 24 * DefaultStyle.dp
|
||||
Layout.preferredHeight: 24 * DefaultStyle.dp
|
||||
}
|
||||
RowLayout {
|
||||
Switch {
|
||||
id: allDaySwitch
|
||||
text: qsTr("Toute la journée")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
ComboBox {
|
||||
id: timeZoneCbox
|
||||
Layout.fillWidth: true
|
||||
Layout.preferredHeight: 30 * DefaultStyle.dp
|
||||
hoverEnabled: true
|
||||
listView.implicitHeight: 152 * DefaultStyle.dp
|
||||
constantImageSource: AppIcons.globe
|
||||
weight: 700 * DefaultStyle.dp
|
||||
leftMargin: 0
|
||||
currentIndex: mainItem.conferenceInfoGui ? model.getIndex(mainItem.conferenceInfoGui.core.timeZoneModel) : -1
|
||||
background: Rectangle {
|
||||
visible: parent.hovered || parent.down
|
||||
anchors.fill: parent
|
||||
color: DefaultStyle.grey_100
|
||||
}
|
||||
model: TimeZoneProxy{
|
||||
}
|
||||
onCurrentIndexChanged: {
|
||||
var modelIndex = timeZoneCbox.model.index(currentIndex, 0)
|
||||
mainItem.conferenceInfoGui.core.timeZoneModel = timeZoneCbox.model.data(modelIndex, Qt.DisplayRole + 1)
|
||||
}
|
||||
}
|
||||
|
||||
ComboBox {
|
||||
id: repeaterCbox
|
||||
enabled: false
|
||||
Component.onCompleted: console.log("TODO : handle conf repetition")
|
||||
constantImageSource: AppIcons.reloadArrow
|
||||
Layout.fillWidth: true
|
||||
Layout.preferredHeight: height
|
||||
height: 30 * DefaultStyle.dp
|
||||
width: 307 * DefaultStyle.dp
|
||||
weight: 700 * DefaultStyle.dp
|
||||
leftMargin: 0
|
||||
currentIndex: 0
|
||||
background: Rectangle {
|
||||
visible: parent.hovered || parent.down
|
||||
anchors.fill: parent
|
||||
color: DefaultStyle.grey_100
|
||||
}
|
||||
model: [
|
||||
{text: qsTr("Une fois")},
|
||||
{text: qsTr("Tous les jours")},
|
||||
{text: qsTr("Tous les jours de la semaine (Lun-Ven)")},
|
||||
{text: qsTr("Toutes les semaines")},
|
||||
{text: qsTr("Tous les mois")}
|
||||
]
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
Section {
|
||||
content: RowLayout {
|
||||
anchors.left: parent.left
|
||||
anchors.right: parent.right
|
||||
EffectImage {
|
||||
imageSource: AppIcons.note
|
||||
colorizationColor: DefaultStyle.main2_600
|
||||
Layout.preferredWidth: 24 * DefaultStyle.dp
|
||||
Layout.preferredHeight: 24 * DefaultStyle.dp
|
||||
}
|
||||
TextArea {
|
||||
id: descriptionEdit
|
||||
Layout.fillWidth: true
|
||||
Layout.preferredWidth: 275 * DefaultStyle.dp
|
||||
leftPadding: 8 * DefaultStyle.dp
|
||||
rightPadding: 8 * DefaultStyle.dp
|
||||
hoverEnabled: true
|
||||
placeholderText: qsTr("Ajouter une description")
|
||||
placeholderTextColor: DefaultStyle.main2_600
|
||||
placeholderWeight: 700 * DefaultStyle.dp
|
||||
color: DefaultStyle.main2_600
|
||||
font {
|
||||
pixelSize: 14 * DefaultStyle.dp
|
||||
weight: 400 * DefaultStyle.dp
|
||||
}
|
||||
background: Rectangle {
|
||||
anchors.fill: parent
|
||||
color: descriptionEdit.hovered || descriptionEdit.activeFocus ? DefaultStyle.grey_100 : "transparent"
|
||||
radius: 4 * DefaultStyle.dp
|
||||
}
|
||||
onEditingFinished: mainItem.conferenceInfoGui.core.description = text
|
||||
}
|
||||
}
|
||||
}
|
||||
Section {
|
||||
content: ColumnLayout {
|
||||
anchors.left: parent.left
|
||||
anchors.right: parent.right
|
||||
Button {
|
||||
id: addParticipantsButton
|
||||
Layout.fillWidth: true
|
||||
Layout.preferredHeight: 30 * DefaultStyle.dp
|
||||
background: Rectangle {
|
||||
anchors.fill: parent
|
||||
color: addParticipantsButton.hovered ? DefaultStyle.grey_100 : "transparent"
|
||||
radius: 4 * DefaultStyle.dp
|
||||
}
|
||||
contentItem: RowLayout {
|
||||
EffectImage {
|
||||
imageSource: AppIcons.usersThree
|
||||
colorizationColor: DefaultStyle.main2_600
|
||||
Layout.preferredWidth: 24 * DefaultStyle.dp
|
||||
Layout.preferredHeight: 24 * DefaultStyle.dp
|
||||
}
|
||||
Text {
|
||||
Layout.fillWidth: true
|
||||
text: qsTr("Ajouter des participants")
|
||||
font {
|
||||
pixelSize: 14 * DefaultStyle.dp
|
||||
weight: 700 * DefaultStyle.dp
|
||||
}
|
||||
}
|
||||
}
|
||||
onClicked: mainItem.addParticipantsRequested()
|
||||
}
|
||||
ListView {
|
||||
id: participantList
|
||||
Layout.fillWidth: true
|
||||
Layout.fillHeight: true
|
||||
Layout.preferredHeight: contentHeight
|
||||
Layout.maximumHeight: 250 * DefaultStyle.dp
|
||||
clip: true
|
||||
model: mainItem.conferenceInfoGui.core.participants
|
||||
delegate: Item {
|
||||
height: 56 * DefaultStyle.dp
|
||||
width: parent.width
|
||||
RowLayout {
|
||||
anchors.fill: parent
|
||||
Avatar {
|
||||
Layout.preferredWidth: 45 * DefaultStyle.dp
|
||||
Layout.preferredHeight: 45 * DefaultStyle.dp
|
||||
address: modelData.address
|
||||
}
|
||||
Text {
|
||||
text: modelData.displayName
|
||||
font.pixelSize: 14 * DefaultStyle.dp
|
||||
font.capitalization: Font.Capitalize
|
||||
}
|
||||
Item {
|
||||
Layout.fillWidth: true
|
||||
}
|
||||
Button {
|
||||
Layout.preferredWidth: 24 * DefaultStyle.dp
|
||||
Layout.preferredHeight: 24 * DefaultStyle.dp
|
||||
Layout.rightMargin: 10 * DefaultStyle.dp
|
||||
background: Item{}
|
||||
icon.source: AppIcons.closeX
|
||||
contentImageColor: DefaultStyle.main1_500_main
|
||||
onClicked: mainItem.conferenceInfoGui.core.removeParticipant(index)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
Switch {
|
||||
text: qsTr("Send invitation to participants")
|
||||
Component.onCompleted: {
|
||||
console.log("TODO : handle send invitation to participants")
|
||||
toggle()
|
||||
}
|
||||
}
|
||||
Item {
|
||||
Layout.fillHeight: true
|
||||
}
|
||||
}
|
||||
|
|
@ -49,12 +49,11 @@ ColumnLayout {
|
|||
Layout.bottomMargin: 10 * DefaultStyle.dp
|
||||
color: DefaultStyle.main2_600
|
||||
}
|
||||
TextInput {
|
||||
TextField {
|
||||
id: textField
|
||||
Layout.fillWidth: true
|
||||
placeholderText: mainItem.placeholderText
|
||||
enableBackgroundColors: false
|
||||
fillWidth: true
|
||||
background: Item{}
|
||||
initialText: initialPhoneNumber
|
||||
validator: IntValidator{}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -8,6 +8,7 @@ Control.Popup{
|
|||
padding: 0
|
||||
property color underlineColor
|
||||
property int radius: 16 * DefaultStyle.dp
|
||||
property bool hovered: mouseArea.containsMouse
|
||||
background: Item{
|
||||
Rectangle {
|
||||
visible: mainItem.underlineColor != undefined
|
||||
|
|
@ -32,5 +33,10 @@ Control.Popup{
|
|||
shadowBlur: 1.0
|
||||
shadowOpacity: 0.1
|
||||
}
|
||||
MouseArea {
|
||||
id: mouseArea
|
||||
anchors.fill: parent
|
||||
hoverEnabled: true
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -6,25 +6,35 @@ import Linphone
|
|||
Button {
|
||||
id: mainItem
|
||||
property alias popup: popup
|
||||
property var contentImageColor
|
||||
checked: popup.visible
|
||||
implicitWidth: 24 * DefaultStyle.dp
|
||||
implicitHeight: 24 * DefaultStyle.dp
|
||||
width: 24 * DefaultStyle.dp
|
||||
height: 24 * DefaultStyle.dp
|
||||
leftPadding: 0
|
||||
rightPadding: 0
|
||||
topPadding: 0
|
||||
bottomPadding: 0
|
||||
icon.source: AppIcons.more
|
||||
icon.width: width
|
||||
icon.height: height
|
||||
function close() {
|
||||
popup.close()
|
||||
}
|
||||
|
||||
background: Rectangle {
|
||||
anchors.fill: mainItem
|
||||
visible: mainItem.checked
|
||||
color: DefaultStyle.main2_300
|
||||
radius: 40 * DefaultStyle.dp
|
||||
}
|
||||
icon.source: AppIcons.more
|
||||
width: 24 * DefaultStyle.dp
|
||||
height: 24 * DefaultStyle.dp
|
||||
contentItem: EffectImage {
|
||||
imageSource: mainItem.icon.source
|
||||
imageWidth: mainItem.icon.width
|
||||
imageHeight: mainItem.icon.height
|
||||
colorizationColor: mainItem.contentImageColor
|
||||
}
|
||||
onPressed: {
|
||||
if (popup.visible) popup.close()
|
||||
else popup.open()
|
||||
|
|
@ -33,7 +43,7 @@ Button {
|
|||
id: popup
|
||||
x: - width
|
||||
y: mainItem.height
|
||||
closePolicy: Popup.CloseOnPressOutsideParent |Popup.CloseOnPressOutside
|
||||
closePolicy: Popup.CloseOnPressOutsideParent | Popup.CloseOnPressOutside
|
||||
parent: mainItem // Explicit define for coordinates references.
|
||||
|
||||
onAboutToShow: {
|
||||
|
|
@ -67,4 +77,4 @@ Button {
|
|||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
41
Linphone/view/Item/Switch.qml
Normal file
41
Linphone/view/Item/Switch.qml
Normal file
|
|
@ -0,0 +1,41 @@
|
|||
import QtQuick 2.12
|
||||
import QtQuick.Controls as Control
|
||||
|
||||
import Linphone
|
||||
|
||||
Control.Switch {
|
||||
id: mainItem
|
||||
font {
|
||||
pixelSize: 14 * DefaultStyle.dp
|
||||
weight: 400 * DefaultStyle.dp
|
||||
}
|
||||
indicator: Rectangle {
|
||||
implicitWidth: 32 * DefaultStyle.dp
|
||||
implicitHeight: 20 * DefaultStyle.dp
|
||||
x: mainItem.leftPadding
|
||||
y: parent.height / 2 - height / 2
|
||||
radius: 10 * DefaultStyle.dp
|
||||
color: mainItem.checked ? DefaultStyle.success_500main : DefaultStyle.main2_400
|
||||
|
||||
Rectangle {
|
||||
anchors.verticalCenter: parent.verticalCenter
|
||||
property int margin: 4 * DefaultStyle.dp
|
||||
x: mainItem.checked ? parent.width - width - margin : margin
|
||||
width: 12 * DefaultStyle.dp
|
||||
height: 12 * DefaultStyle.dp
|
||||
radius: 10 * DefaultStyle.dp
|
||||
color: DefaultStyle.grey_0
|
||||
Behavior on x {
|
||||
NumberAnimation{duration: 100}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
contentItem: Text {
|
||||
text: mainItem.text
|
||||
font: mainItem.font
|
||||
opacity: enabled ? 1.0 : 0.3
|
||||
verticalAlignment: Text.AlignVCenter
|
||||
leftPadding: mainItem.indicator.width + mainItem.spacing
|
||||
}
|
||||
}
|
||||
|
|
@ -102,22 +102,22 @@ Window {
|
|||
text: "scaled text"
|
||||
}
|
||||
RowLayout {
|
||||
TextInput {
|
||||
TextField {
|
||||
label: "mandatory text input"
|
||||
placeholderText: "default text"
|
||||
mandatory: true
|
||||
// mandatory: true
|
||||
}
|
||||
TextInput {
|
||||
TextField {
|
||||
label: "password text input"
|
||||
placeholderText: "default text"
|
||||
hidden: true
|
||||
}
|
||||
TextInput {
|
||||
TextField {
|
||||
id: next
|
||||
label: "text input with long long looooooooooooooooooooooooooooooooooooooooooooooooooooooooong label"
|
||||
placeholderText: "long long long default text"
|
||||
}
|
||||
TextInput {
|
||||
TextField {
|
||||
label: "number text input"
|
||||
validator: IntValidator{}
|
||||
}
|
||||
|
|
|
|||
46
Linphone/view/Item/TextArea.qml
Normal file
46
Linphone/view/Item/TextArea.qml
Normal file
|
|
@ -0,0 +1,46 @@
|
|||
import QtQuick
|
||||
import QtQuick.Controls as Control
|
||||
import QtQuick.Layouts 1.0
|
||||
import Linphone
|
||||
|
||||
TextEdit {
|
||||
id: mainItem
|
||||
|
||||
property string placeholderText
|
||||
property int placeholderPixelSize: 14 * DefaultStyle.dp
|
||||
property int placeholderWeight: 400 * DefaultStyle.dp
|
||||
property color placeholderTextColor: color
|
||||
property alias background: background.data
|
||||
property bool hoverEnabled: false
|
||||
property bool hovered: mouseArea.hoverEnabled && mouseArea.containsMouse
|
||||
topPadding: 5 * DefaultStyle.dp
|
||||
bottomPadding: 5 * DefaultStyle.dp
|
||||
|
||||
MouseArea {
|
||||
id: mouseArea
|
||||
anchors.fill: parent
|
||||
hoverEnabled: mainItem.hoverEnabled
|
||||
// onPressed: mainItem.forceActiveFocus()
|
||||
acceptedButtons: Qt.NoButton
|
||||
cursorShape: mainItem.hovered ? Qt.PointingHandCursor : Qt.ArrowCursor
|
||||
}
|
||||
|
||||
Item {
|
||||
id: background
|
||||
anchors.fill: parent
|
||||
z: -1
|
||||
}
|
||||
|
||||
Text {
|
||||
anchors.verticalCenter: mainItem.verticalCenter
|
||||
text: mainItem.placeholderText
|
||||
color: mainItem.placeholderTextColor
|
||||
visible: mainItem.text.length == 0 && !mainItem.activeFocus
|
||||
x: mainItem.leftPadding
|
||||
font {
|
||||
pixelSize: mainItem.placeholderPixelSize
|
||||
weight: mainItem.placeholderWeight
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
115
Linphone/view/Item/TextField.qml
Normal file
115
Linphone/view/Item/TextField.qml
Normal file
|
|
@ -0,0 +1,115 @@
|
|||
import QtQuick
|
||||
import QtQuick.Controls as Control
|
||||
import QtQuick.Layouts 1.0
|
||||
import Linphone
|
||||
|
||||
Control.TextField {
|
||||
id: mainItem
|
||||
width: 360 * DefaultStyle.dp
|
||||
height: 49 * DefaultStyle.dp
|
||||
leftPadding: 15 * DefaultStyle.dp
|
||||
rightPadding: eyeButton.visible ? 5 * DefaultStyle.dp + eyeButton.width + eyeButton.rightMargin : 15 * DefaultStyle.dp
|
||||
echoMode: (hidden && !eyeButton.checked) ? TextInput.Password : TextInput.Normal
|
||||
color: DefaultStyle.main2_600
|
||||
font {
|
||||
family: DefaultStyle.defaultFont
|
||||
pixelSize: 14 * DefaultStyle.dp
|
||||
weight: 400 * DefaultStyle.dp
|
||||
}
|
||||
selectByMouse: true
|
||||
|
||||
property bool controlIsDown: false
|
||||
property bool hidden: false
|
||||
property bool backgroundVisible: true
|
||||
property color backgroundColor: DefaultStyle.grey_100
|
||||
property color backgroundBorderColor: DefaultStyle.grey_200
|
||||
property string initialText
|
||||
property int pixelSize: 14 * DefaultStyle.dp
|
||||
property int weight: 400 * DefaultStyle.dp
|
||||
|
||||
Component.onCompleted: {
|
||||
text = initialText
|
||||
}
|
||||
|
||||
function resetText() {
|
||||
text = initialText
|
||||
}
|
||||
|
||||
signal enterPressed()
|
||||
|
||||
background: Rectangle {
|
||||
id: inputBackground
|
||||
visible: mainItem.backgroundVisible
|
||||
anchors.fill: parent
|
||||
radius: 79 * DefaultStyle.dp
|
||||
color: mainItem.backgroundColor
|
||||
border.color: activeFocus
|
||||
? DefaultStyle.main1_500_main
|
||||
: mainItem.backgroundBorderColor
|
||||
}
|
||||
cursorDelegate: Rectangle {
|
||||
id: cursor
|
||||
color: DefaultStyle.main1_500_main
|
||||
width: 1 * DefaultStyle.dp
|
||||
|
||||
SequentialAnimation {
|
||||
loops: Animation.Infinite
|
||||
running: mainItem.cursorVisible
|
||||
|
||||
PropertyAction {
|
||||
target: cursor
|
||||
property: 'visible'
|
||||
value: true
|
||||
}
|
||||
|
||||
PauseAnimation {
|
||||
duration: 600
|
||||
}
|
||||
|
||||
PropertyAction {
|
||||
target: cursor
|
||||
property: 'visible'
|
||||
value: false
|
||||
}
|
||||
|
||||
PauseAnimation {
|
||||
duration: 600
|
||||
}
|
||||
|
||||
onStopped: {
|
||||
cursor.visible = false
|
||||
}
|
||||
}
|
||||
}
|
||||
Keys.onPressed: (event) => {
|
||||
if (event.jey == Qt.Key_Control) mainItem.controlIsDown = true
|
||||
if (event.key === Qt.Key_Enter || event.key === Qt.Key_Return) {
|
||||
enterPressed()
|
||||
if (mainItem.controlIsDown) {
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
Keys.onReleased: (event) => {
|
||||
if (event.jey == Qt.Key_Control) mainItem.controlIsDown = false
|
||||
}
|
||||
|
||||
Button {
|
||||
id: eyeButton
|
||||
property int rightMargin: 15 * DefaultStyle.dp
|
||||
z: 1
|
||||
visible: mainItem.hidden
|
||||
checkable: true
|
||||
background: Rectangle {
|
||||
color: "transparent"
|
||||
}
|
||||
icon.source: eyeButton.checked ? AppIcons.eyeShow : AppIcons.eyeHide
|
||||
width: 20 * DefaultStyle.dp
|
||||
height: 20 * DefaultStyle.dp
|
||||
anchors.top: parent.top
|
||||
anchors.bottom: parent.bottom
|
||||
anchors.right: parent.right
|
||||
anchors.rightMargin: rightMargin
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -1,132 +0,0 @@
|
|||
import QtQuick
|
||||
import QtQuick.Controls as Control
|
||||
import QtQuick.Layouts
|
||||
import Linphone
|
||||
|
||||
ColumnLayout {
|
||||
id: mainItem
|
||||
|
||||
property string label: ""
|
||||
property string errorMessage: ""
|
||||
property string placeholderText: ""
|
||||
property bool mandatory: false
|
||||
property bool hidden: false
|
||||
property int textInputWidth: 346 * DefaultStyle.dp
|
||||
property var validator: RegularExpressionValidator{}
|
||||
property bool fillWidth: false
|
||||
property bool enableBackgroundColors: true
|
||||
property color backgroundColor: DefaultStyle.grey_100
|
||||
property color backgroundBorderColor: DefaultStyle.grey_200
|
||||
property string initialText
|
||||
|
||||
property bool enableErrorText: false
|
||||
property bool errorTextVisible: errorText.opacity > 0
|
||||
|
||||
property alias textField: textField
|
||||
property alias background: input
|
||||
|
||||
readonly property string text: textField.text
|
||||
readonly property bool hasActiveFocus: textField.activeFocus
|
||||
|
||||
signal editingFinished()
|
||||
|
||||
Component.onCompleted: {
|
||||
setText(initialText)
|
||||
}
|
||||
|
||||
function setText(text) {
|
||||
textField.text = text
|
||||
}
|
||||
function resetText() {
|
||||
setText(initialText)
|
||||
}
|
||||
|
||||
Text {
|
||||
visible: mainItem.label.length > 0
|
||||
verticalAlignment: Text.AlignVCenter
|
||||
text: mainItem.label + (mainItem.mandatory ? "*" : "")
|
||||
color: textField.activeFocus ? DefaultStyle.main1_500_main : DefaultStyle.main2_600
|
||||
elide: Text.ElideRight
|
||||
wrapMode: Text.Wrap
|
||||
maximumLineCount: 1
|
||||
font {
|
||||
pixelSize: 13 * DefaultStyle.dp
|
||||
family: DefaultStyle.defaultFont
|
||||
weight: 700 * DefaultStyle.dp
|
||||
}
|
||||
Layout.preferredWidth: mainItem.textInputWidth
|
||||
}
|
||||
|
||||
Rectangle {
|
||||
id: input
|
||||
Component.onCompleted: {
|
||||
if (mainItem.fillWidth)
|
||||
Layout.fillWidth = true
|
||||
}
|
||||
Layout.preferredWidth: mainItem.textInputWidth
|
||||
Layout.preferredHeight: 49 * DefaultStyle.dp
|
||||
radius: 79 * DefaultStyle.dp
|
||||
color: mainItem.backgroundColor
|
||||
border.color: mainItem.errorTextVisible
|
||||
? DefaultStyle.danger_500main
|
||||
: textField.activeFocus
|
||||
? DefaultStyle.main1_500_main
|
||||
: mainItem.backgroundBorderColor
|
||||
|
||||
Control.TextField {
|
||||
id: textField
|
||||
anchors.left: parent.left
|
||||
anchors.leftMargin: 10 * DefaultStyle.dp
|
||||
anchors.right: eyeButton.visible ? eyeButton.left : parent.right
|
||||
anchors.rightMargin: eyeButton.visible ? 0 : 10 * DefaultStyle.dp
|
||||
anchors.verticalCenter: parent.verticalCenter
|
||||
placeholderText: mainItem.placeholderText
|
||||
echoMode: (mainItem.hidden && !eyeButton.checked) ? TextInput.Password : TextInput.Normal
|
||||
font.family: DefaultStyle.defaultFont
|
||||
font {
|
||||
pixelSize: 14 * DefaultStyle.dp
|
||||
weight: 400 * DefaultStyle.dp
|
||||
}
|
||||
color: mainItem.errorTextVisible ? DefaultStyle.danger_500main : DefaultStyle.main2_600
|
||||
selectByMouse: true
|
||||
validator: mainItem.validator
|
||||
background: Item {
|
||||
opacity: 0.
|
||||
}
|
||||
cursorDelegate: Rectangle {
|
||||
visible: textField.activeFocus
|
||||
color: DefaultStyle.main1_500_main
|
||||
width: 2 * DefaultStyle.dp
|
||||
}
|
||||
onEditingFinished: {
|
||||
mainItem.editingFinished()
|
||||
}
|
||||
|
||||
Keys.onPressed: (event)=> {
|
||||
if (event.key === Qt.Key_Enter || event.key === Qt.Key_Return) {
|
||||
textField.focus = false
|
||||
}
|
||||
}
|
||||
}
|
||||
Button {
|
||||
id: eyeButton
|
||||
visible: mainItem.hidden
|
||||
checkable: true
|
||||
background: Rectangle {
|
||||
color: "transparent"
|
||||
}
|
||||
icon.source: eyeButton.checked ? AppIcons.eyeShow : AppIcons.eyeHide
|
||||
width: 20 * DefaultStyle.dp
|
||||
height: 20 * DefaultStyle.dp
|
||||
anchors.verticalCenter: parent.verticalCenter
|
||||
anchors.right: parent.right
|
||||
anchors.rightMargin: 15 * DefaultStyle.dp
|
||||
}
|
||||
}
|
||||
ErrorText {
|
||||
id: errorText
|
||||
visible: mainItem.enableErrorText
|
||||
text: mainItem.errorMessage
|
||||
Layout.preferredWidth: implicitWidth
|
||||
}
|
||||
}
|
||||
83
Linphone/view/Item/TimeComboBox.qml
Normal file
83
Linphone/view/Item/TimeComboBox.qml
Normal file
|
|
@ -0,0 +1,83 @@
|
|||
import QtQuick
|
||||
import Linphone
|
||||
import UtilsCpp 1.0
|
||||
|
||||
ComboBox {
|
||||
id: mainItem
|
||||
property string selectedTimeString: Qt.formatDateTime(new Date(), "hh:mm")
|
||||
property int selectedHour: input.hour*1
|
||||
property int selectedMin: input.min*1
|
||||
popup.width: 73 * DefaultStyle.dp
|
||||
listView.model: 48
|
||||
listView.implicitHeight: 204 * DefaultStyle.dp
|
||||
editable: true
|
||||
popup.closePolicy: Popup.PressOutsideParent | Popup.CloseOnPressOutside
|
||||
onCurrentTextChanged: input.text = currentText
|
||||
popup.onOpened: {
|
||||
input.forceActiveFocus()
|
||||
}
|
||||
contentItem: TextInput {
|
||||
id: input
|
||||
anchors.right: indicator.left
|
||||
validator: IntValidator{}
|
||||
// activeFocusOnPress: false
|
||||
inputMask: "00:00"
|
||||
verticalAlignment: TextInput.AlignVCenter
|
||||
horizontalAlignment: TextInput.AlignHCenter
|
||||
property string hour: text.split(":")[0]
|
||||
property string min: text.split(":")[1]
|
||||
color: DefaultStyle.main2_600
|
||||
onActiveFocusChanged: {
|
||||
if (activeFocus) {
|
||||
selectAll()
|
||||
mainItem.popup.open()
|
||||
} else {
|
||||
listView.currentIndex = -1
|
||||
mainItem.selectedTimeString = Qt.formatDateTime(UtilsCpp.createDateTime(new Date(), hour, min), "hh:mm")
|
||||
}
|
||||
}
|
||||
font {
|
||||
pixelSize: 14 * DefaultStyle.dp
|
||||
weight: 700 * DefaultStyle.dp
|
||||
}
|
||||
text: mainItem.selectedTimeString
|
||||
Keys.onPressed: (event) => {
|
||||
if (event.key == Qt.Key_Enter || event.key == Qt.Key_Return) {
|
||||
focus = false
|
||||
}
|
||||
}
|
||||
onEditingFinished: {
|
||||
console.log("set time", hour, min)
|
||||
mainItem.selectedTimeString = Qt.formatDateTime(UtilsCpp.createDateTime(new Date(), hour, min), "hh:mm")
|
||||
}
|
||||
}
|
||||
listView.delegate: Text {
|
||||
id: hourDelegate
|
||||
property int hour: modelData /2
|
||||
property int min: modelData%2 === 0 ? 0 : 30
|
||||
text: Qt.formatDateTime(UtilsCpp.createDateTime(new Date(), hour, min), "hh:mm")
|
||||
width: mainItem.width
|
||||
height: 25 * DefaultStyle.dp
|
||||
verticalAlignment: TextInput.AlignVCenter
|
||||
horizontalAlignment: TextInput.AlignHCenter
|
||||
font {
|
||||
pixelSize: 14 * DefaultStyle.dp
|
||||
weight: 400 * DefaultStyle.dp
|
||||
}
|
||||
MouseArea {
|
||||
anchors.fill: parent
|
||||
hoverEnabled: true
|
||||
cursorShape: containsMouse ? Qt.PointingHandCursor : Qt.ArrowCursor
|
||||
onClicked: {
|
||||
// mainItem.text = parent.text
|
||||
mainItem.listView.currentIndex = index
|
||||
mainItem.selectedTimeString = hourDelegate.text
|
||||
mainItem.popup.close()
|
||||
}
|
||||
Rectangle {
|
||||
visible: parent.containsMouse
|
||||
color: DefaultStyle.main2_200
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
67
Linphone/view/Layout/Conference/IncallGrid.qml
Normal file
67
Linphone/view/Layout/Conference/IncallGrid.qml
Normal file
|
|
@ -0,0 +1,67 @@
|
|||
import QtQuick 2.7
|
||||
import QtQuick.Layouts 1.3
|
||||
import QtQml.Models 2.12
|
||||
import QtGraphicalEffects 1.12
|
||||
|
||||
import Common 1.0
|
||||
import Common.Styles 1.0
|
||||
import Linphone 1.0
|
||||
import LinphoneEnums 1.0
|
||||
|
||||
import UtilsCpp 1.0
|
||||
|
||||
import App.Styles 1.0
|
||||
|
||||
import ConstantsCpp 1.0
|
||||
// Temp
|
||||
import 'Incall.js' as Logic
|
||||
import 'qrc:/ui/scripts/Utils/utils.js' as Utils
|
||||
|
||||
// =============================================================================
|
||||
|
||||
Mosaic {
|
||||
id: grid
|
||||
property alias callModel: participantDevices.callModel
|
||||
property bool cameraEnabled: true
|
||||
property int participantCount: gridModel.count
|
||||
|
||||
// On grid view, we limit the quality if there are enough participants// The vga mode has been activated from the factory rc
|
||||
//onParticipantCountChanged: participantCount > ConstantsCpp.maxMosaicParticipants ? SettingsModel.setLimitedMosaicQuality() : SettingsModel.setHighMosaicQuality()
|
||||
delegateModel: DelegateModel{
|
||||
id: gridModel
|
||||
property ParticipantDeviceProxyModel participantDevices : ParticipantDeviceProxyModel {
|
||||
id: participantDevices
|
||||
showMe: true
|
||||
}
|
||||
model: participantDevices
|
||||
delegate: Item{
|
||||
id: avatarCell
|
||||
property ParticipantDeviceModel currentDevice: gridModel.participantDevices.getAt(index)
|
||||
onCurrentDeviceChanged: {
|
||||
if(index < 0) cameraView.enabled = false // this is a delegate destruction. We need to stop camera before Qt change its currentDevice (and then, let CameraView to delete wrong renderer)
|
||||
}
|
||||
|
||||
height: grid.cellHeight - 10
|
||||
width: grid.cellWidth - 10
|
||||
|
||||
Sticker{
|
||||
id: cameraView
|
||||
anchors.fill: parent
|
||||
|
||||
cameraQmlName: 'G_'+index
|
||||
callModel: index >= 0 ? participantDevices.callModel : null // do this before to prioritize changing call on remove
|
||||
deactivateCamera: index <0 || !grid.cameraEnabled || grid.callModel.pausedByUser
|
||||
currentDevice: gridModel.participantDevices.getAt(index)
|
||||
|
||||
isCameraFromDevice: true
|
||||
isPaused: !isPreview && avatarCell.currentDevice && avatarCell.currentDevice.isPaused
|
||||
showCloseButton: false
|
||||
showCustomButton: false
|
||||
avatarStickerBackgroundColor: isPreview? IncallStyle.container.avatar.stickerPreviewBackgroundColor.color : IncallStyle.container.avatar.stickerBackgroundColor.color
|
||||
avatarBackgroundColor: IncallStyle.container.avatar.backgroundColor.color
|
||||
|
||||
//onCloseRequested: participantDevices.showMe = false
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
44
Linphone/view/Layout/FormItemLayout.qml
Normal file
44
Linphone/view/Layout/FormItemLayout.qml
Normal file
|
|
@ -0,0 +1,44 @@
|
|||
import QtQuick
|
||||
import QtQuick.Controls as Control
|
||||
import QtQuick.Layouts 1.0
|
||||
import QtQuick.Effects
|
||||
import Linphone
|
||||
|
||||
ColumnLayout {
|
||||
id: mainItem
|
||||
property alias contentItem: contentItem.data
|
||||
property string label: ""
|
||||
property bool mandatory: false
|
||||
|
||||
property string errorMessage: ""
|
||||
property bool enableErrorText: false
|
||||
property bool errorTextVisible: errorText.opacity > 0
|
||||
|
||||
Text {
|
||||
visible: label.length > 0
|
||||
verticalAlignment: Text.AlignVCenter
|
||||
text: mainItem.label + (mainItem.mandatory ? "*" : "")
|
||||
color: contentItem.activeFocus ? DefaultStyle.main1_500_main : DefaultStyle.main2_600
|
||||
elide: Text.ElideRight
|
||||
wrapMode: Text.Wrap
|
||||
maximumLineCount: 1
|
||||
|
||||
font {
|
||||
pixelSize: 13 * DefaultStyle.dp
|
||||
weight: 700 * DefaultStyle.dp
|
||||
}
|
||||
}
|
||||
|
||||
Item {
|
||||
id: contentItem
|
||||
Layout.preferredHeight: childrenRect.height
|
||||
Layout.preferredWidth: childrenRect.width
|
||||
}
|
||||
|
||||
ErrorText {
|
||||
id: errorText
|
||||
visible: mainItem.enableErrorText
|
||||
text: mainItem.errorMessage
|
||||
Layout.preferredWidth: implicitWidth
|
||||
}
|
||||
}
|
||||
114
Linphone/view/Layout/Meeting/AddParticipantsLayout.qml
Normal file
114
Linphone/view/Layout/Meeting/AddParticipantsLayout.qml
Normal file
|
|
@ -0,0 +1,114 @@
|
|||
import QtQuick 2.15
|
||||
import QtQuick.Effects
|
||||
import QtQuick.Layouts
|
||||
import QtQuick.Controls as Control
|
||||
import Linphone
|
||||
import UtilsCpp 1.0
|
||||
|
||||
ColumnLayout {
|
||||
id: mainItem
|
||||
property string title
|
||||
property string validateButtonText
|
||||
property string placeHolderText: qsTr("Rechercher des contacts")
|
||||
property color titleColor: DefaultStyle.main2_700
|
||||
property ConferenceInfoGui conferenceInfoGui
|
||||
signal returnRequested()
|
||||
Layout.preferredWidth: 362 * DefaultStyle.dp
|
||||
|
||||
RowLayout {
|
||||
Layout.preferredWidth: 362 * DefaultStyle.dp
|
||||
Button {
|
||||
background: Item{}
|
||||
icon.source: AppIcons.leftArrow
|
||||
contentImageColor: DefaultStyle.main1_500_main
|
||||
Layout.preferredWidth: 24 * DefaultStyle.dp
|
||||
Layout.preferredHeight: 24 * DefaultStyle.dp
|
||||
onClicked: mainItem.returnRequested()
|
||||
}
|
||||
Text {
|
||||
text: mainItem.title
|
||||
color: mainItem.titleColor
|
||||
maximumLineCount: 1
|
||||
font {
|
||||
pixelSize: 18 * DefaultStyle.dp
|
||||
weight: 800 * DefaultStyle.dp
|
||||
}
|
||||
Layout.fillWidth: true
|
||||
}
|
||||
Button {
|
||||
Layout.preferredWidth: 70 * DefaultStyle.dp
|
||||
topPadding: 6 * DefaultStyle.dp
|
||||
bottomPadding: 6 * DefaultStyle.dp
|
||||
// leftPadding: 12 * DefaultStyle.dp
|
||||
// rightPadding: 12 * DefaultStyle.dp
|
||||
text: mainItem.validateButtonText
|
||||
textSize: 13 * DefaultStyle.dp
|
||||
onClicked: {
|
||||
mainItem.conferenceInfoGui.core.resetParticipants(contactList.selectedContacts)
|
||||
mainItem.returnRequested()
|
||||
}
|
||||
}
|
||||
}
|
||||
ListView {
|
||||
id: participantList
|
||||
Layout.fillWidth: true
|
||||
// Layout.fillHeight: true
|
||||
Layout.preferredHeight: contentHeight
|
||||
Layout.maximumHeight: mainItem.height / 3
|
||||
width: mainItem.width
|
||||
model: contactList.selectedContacts
|
||||
clip: true
|
||||
delegate: Item {
|
||||
height: 56 * DefaultStyle.dp
|
||||
width: participantList.width
|
||||
RowLayout {
|
||||
anchors.fill: parent
|
||||
Avatar {
|
||||
Layout.preferredWidth: 45 * DefaultStyle.dp
|
||||
Layout.preferredHeight: 45 * DefaultStyle.dp
|
||||
address: modelData
|
||||
}
|
||||
Text {
|
||||
property var nameObj: UtilsCpp.getDisplayName(modelData)
|
||||
text: nameObj ? nameObj.value : ""
|
||||
font.pixelSize: 14 * DefaultStyle.dp
|
||||
font.capitalization: Font.Capitalize
|
||||
}
|
||||
Item {
|
||||
Layout.fillWidth: true
|
||||
}
|
||||
Button {
|
||||
Layout.preferredWidth: 24 * DefaultStyle.dp
|
||||
Layout.preferredHeight: 24 * DefaultStyle.dp
|
||||
background: Item{}
|
||||
icon.source: AppIcons.closeX
|
||||
contentImageColor: DefaultStyle.main1_500_main
|
||||
onClicked: contactList.selectedContacts.splice(index, 1)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
SearchBar {
|
||||
id: searchbar
|
||||
Layout.fillWidth: true
|
||||
placeholderText: mainItem.placeHolderText
|
||||
}
|
||||
Text {
|
||||
text: qsTr("Contacts")
|
||||
font {
|
||||
pixelSize: 16 * DefaultStyle.dp
|
||||
weight: 800 * DefaultStyle.dp
|
||||
}
|
||||
}
|
||||
ContactsList {
|
||||
id: contactList
|
||||
Layout.fillWidth: true
|
||||
Layout.fillHeight: true
|
||||
Layout.preferredHeight: contentHeight
|
||||
multiSelectionEnabled: true
|
||||
contactMenuVisible: false
|
||||
confInfoGui: mainItem.conferenceInfoGui
|
||||
searchBarText: searchbar.text
|
||||
onContactAddedToSelection: participantList.positionViewAtEnd()
|
||||
}
|
||||
}
|
||||
118
Linphone/view/Layout/Mosaic.qml
Normal file
118
Linphone/view/Layout/Mosaic.qml
Normal file
|
|
@ -0,0 +1,118 @@
|
|||
import QtQuick 2.12
|
||||
import QtQuick.Controls 2.2
|
||||
import QtQuick.Layouts 1.0
|
||||
import QtQml.Models 2.12
|
||||
|
||||
import Common 1.0
|
||||
import Common.Styles 1.0
|
||||
|
||||
// =============================================================================
|
||||
ColumnLayout{
|
||||
id: mainLayout
|
||||
property alias delegateModel: grid.model
|
||||
property alias cellHeight: grid.cellHeight
|
||||
property alias cellWidth: grid.cellWidth
|
||||
|
||||
function appendItem(item){
|
||||
mainLayout.delegateModel.model.append(item)
|
||||
}
|
||||
|
||||
function add(item){
|
||||
if( !grid.isLayoutWillChanged())
|
||||
appendItem(item)
|
||||
else
|
||||
bufferModels.append(item)
|
||||
}
|
||||
|
||||
function remove(index){
|
||||
if(mainLayout.delegateModel.model.count > index)
|
||||
mainLayout.delegateModel.model.remove( index, 1)
|
||||
}
|
||||
|
||||
function get(index){
|
||||
return mainLayout.delegateModel.model.get(index)
|
||||
}
|
||||
|
||||
function tryToAdd(item){
|
||||
if( !grid.isLayoutWillChanged()) {
|
||||
appendItem(item)
|
||||
return true
|
||||
}else
|
||||
return false
|
||||
}
|
||||
|
||||
function clear(){
|
||||
if(mainLayout.delegateModel.model.clear) {
|
||||
mainLayout.delegateModel.model.clear()
|
||||
bufferModels.clear()
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
property int transitionCount : 0
|
||||
property var bufferModels : ListModel{}
|
||||
|
||||
onWidthChanged: grid.updateLayout()
|
||||
onHeightChanged: grid.updateLayout()
|
||||
GridView{
|
||||
id: grid
|
||||
property int margin: 10
|
||||
property int itemCount: model.count ? model.count :( model.length ? model.length : 0)
|
||||
property int columns: 1
|
||||
property int rows: 1
|
||||
|
||||
function getBestLayout(itemCount){
|
||||
var availableW = mainLayout.width - grid.margin
|
||||
var availableH = mainLayout.height - grid.margin
|
||||
var bestSize = 0
|
||||
var bestC = 1, bestR = 1
|
||||
for(var R = 1 ; R <= itemCount ; ++R){
|
||||
for(var C = itemCount ; C >= 1 ; --C){
|
||||
if( R * C >= itemCount){// This is a good layout candidate
|
||||
var estimatedSize = Math.min(availableW / C, availableH / R)
|
||||
if(estimatedSize > bestSize // Size is better
|
||||
|| (estimatedSize == bestSize && Math.abs(bestR-bestC) > Math.abs(R - C) )){// Stickers are more homogenized
|
||||
bestSize = estimatedSize
|
||||
bestC = C
|
||||
bestR = R
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return [bestR, bestC]
|
||||
}
|
||||
|
||||
function updateLayout(){
|
||||
var bestLayout = getBestLayout(itemCount)
|
||||
if( rows != bestLayout[0])
|
||||
rows = bestLayout[0]
|
||||
if( columns != bestLayout[1])
|
||||
columns = bestLayout[1]
|
||||
}
|
||||
function updateCells(){
|
||||
cellWidth = Math.min(computedWidth, computedHeight)
|
||||
cellHeight = Math.min(computedWidth, computedHeight)
|
||||
}
|
||||
onItemCountChanged: updateLayout()
|
||||
property int computedWidth: (mainLayout.width - grid.margin ) / columns
|
||||
property int computedHeight: (mainLayout.height - grid.margin ) / rows
|
||||
onComputedHeightChanged: Qt.callLater(updateCells)
|
||||
onComputedWidthChanged: Qt.callLater(updateCells)
|
||||
cellWidth: Math.min(computedWidth, computedHeight)
|
||||
cellHeight: Math.min(computedWidth, computedHeight)
|
||||
|
||||
function isLayoutWillChanged(){
|
||||
var bestLayout = getBestLayout(itemCount+1)
|
||||
return rows !== bestLayout[0] || columns !== bestLayout[1]
|
||||
}
|
||||
|
||||
Layout.preferredWidth: cellWidth * columns
|
||||
Layout.preferredHeight: cellHeight * rows
|
||||
Layout.alignment: Qt.AlignCenter
|
||||
|
||||
interactive: false
|
||||
model: DelegateModel{}
|
||||
|
||||
onCountChanged: grid.updateLayout()
|
||||
}
|
||||
}
|
||||
26
Linphone/view/Layout/Section.qml
Normal file
26
Linphone/view/Layout/Section.qml
Normal file
|
|
@ -0,0 +1,26 @@
|
|||
import QtQuick 2.15
|
||||
import QtQuick.Layouts
|
||||
|
||||
import Linphone
|
||||
/*
|
||||
Layout with line separator used in several views
|
||||
*/
|
||||
|
||||
ColumnLayout {
|
||||
spacing: 15 * DefaultStyle.dp
|
||||
property alias content: contentItem.data
|
||||
implicitHeight: contentItem.implicitHeight + 1 * DefaultStyle.dp + spacing
|
||||
Item {
|
||||
id: contentItem
|
||||
Layout.fillWidth: true
|
||||
Layout.preferredHeight: childrenRect.height
|
||||
Layout.preferredWidth: childrenRect.width
|
||||
// Layout.leftMargin: 8 * DefaultStyle.dp
|
||||
}
|
||||
Rectangle {
|
||||
color: DefaultStyle.main2_200
|
||||
Layout.fillWidth: true
|
||||
Layout.preferredHeight: 1 * DefaultStyle.dp
|
||||
width: parent.width
|
||||
}
|
||||
}
|
||||
|
|
@ -17,7 +17,7 @@ LoginLayout {
|
|||
visible: mainItem.showBackButton
|
||||
Layout.preferredHeight: 27 * DefaultStyle.dp
|
||||
Layout.preferredWidth: 27 * DefaultStyle.dp
|
||||
icon.source: AppIcons.returnArrow
|
||||
icon.source: AppIcons.leftArrow
|
||||
background: Rectangle {
|
||||
color: "transparent"
|
||||
}
|
||||
|
|
|
|||
|
|
@ -13,7 +13,7 @@ LoginLayout {
|
|||
Button {
|
||||
Layout.preferredHeight: 24 * DefaultStyle.dp
|
||||
Layout.preferredWidth: 24 * DefaultStyle.dp
|
||||
icon.source: AppIcons.returnArrow
|
||||
icon.source: AppIcons.leftArrow
|
||||
background: Rectangle {
|
||||
color: "transparent"
|
||||
}
|
||||
|
|
|
|||
|
|
@ -68,16 +68,19 @@ LoginLayout {
|
|||
Layout.topMargin: 20 * DefaultStyle.dp
|
||||
spacing: 15 * DefaultStyle.dp
|
||||
RowLayout {
|
||||
TextInput {
|
||||
FormItemLayout {
|
||||
label: qsTr("Username")
|
||||
mandatory: true
|
||||
textInputWidth: 346 * DefaultStyle.dp
|
||||
contentItem: TextField {
|
||||
Layout.preferredWidth: 346 * DefaultStyle.dp
|
||||
}
|
||||
}
|
||||
ComboBox {
|
||||
label: " "
|
||||
Layout.alignment: Qt.AlignBottom
|
||||
enabled: false
|
||||
model: [{text:"@sip.linphone.org"}]
|
||||
Layout.preferredWidth: 210 * DefaultStyle.dp
|
||||
Layout.preferredHeight: 49 * DefaultStyle.dp
|
||||
}
|
||||
}
|
||||
PhoneNumberInput {
|
||||
|
|
@ -85,15 +88,17 @@ LoginLayout {
|
|||
label: qsTr("Phone number")
|
||||
mandatory: true
|
||||
placeholderText: "Phone number"
|
||||
textInputWidth: 346 * DefaultStyle.dp
|
||||
Layout.preferredWidth: 346 * DefaultStyle.dp
|
||||
}
|
||||
RowLayout {
|
||||
ColumnLayout {
|
||||
TextInput {
|
||||
FormItemLayout {
|
||||
label: qsTr("Password")
|
||||
mandatory: true
|
||||
hidden: true
|
||||
textInputWidth: 346 * DefaultStyle.dp
|
||||
contentItem: TextField {
|
||||
hidden: true
|
||||
Layout.preferredWidth: 346 * DefaultStyle.dp
|
||||
}
|
||||
}
|
||||
Text {
|
||||
text: qsTr("The password must contain 6 characters minimum")
|
||||
|
|
@ -104,11 +109,13 @@ LoginLayout {
|
|||
}
|
||||
}
|
||||
ColumnLayout {
|
||||
TextInput {
|
||||
FormItemLayout {
|
||||
label: qsTr("Confirm password")
|
||||
mandatory: true
|
||||
hidden: true
|
||||
textInputWidth: 346 * DefaultStyle.dp
|
||||
contentItem: TextField {
|
||||
hidden: true
|
||||
Layout.preferredWidth: 346 * DefaultStyle.dp
|
||||
}
|
||||
}
|
||||
Text {
|
||||
text: qsTr("The password must contain 6 characters minimum")
|
||||
|
|
@ -162,34 +169,40 @@ LoginLayout {
|
|||
Layout.fillHeight: true
|
||||
spacing: 15 * DefaultStyle.dp
|
||||
RowLayout {
|
||||
TextInput {
|
||||
FormItemLayout {
|
||||
label: qsTr("Username")
|
||||
mandatory: true
|
||||
textInputWidth: 346 * DefaultStyle.dp
|
||||
contentItem: TextField {
|
||||
Layout.preferredWidth: 346 * DefaultStyle.dp
|
||||
}
|
||||
}
|
||||
ComboBox {
|
||||
// if we don't set a label this item is offset
|
||||
// due to the invisibility of the upper label
|
||||
label: " "
|
||||
enabled: false
|
||||
model: [{text:"@sip.linphone.org"}]
|
||||
Layout.preferredWidth: 210 * DefaultStyle.dp
|
||||
Layout.alignment: Qt.AlignBottom
|
||||
}
|
||||
}
|
||||
TextInput {
|
||||
id: emailInput
|
||||
FormItemLayout {
|
||||
label: qsTr("Email")
|
||||
mandatory: true
|
||||
textInputWidth: 346 * DefaultStyle.dp
|
||||
contentItem: TextField {
|
||||
id: emailInput
|
||||
Layout.preferredWidth: 346 * DefaultStyle.dp
|
||||
}
|
||||
}
|
||||
RowLayout {
|
||||
ColumnLayout {
|
||||
TextInput {
|
||||
id: pwdInput
|
||||
FormItemLayout {
|
||||
label: qsTr("Password")
|
||||
mandatory: true
|
||||
hidden: true
|
||||
textInputWidth: 346 * DefaultStyle.dp
|
||||
contentItem: TextField {
|
||||
id: pwdInput
|
||||
hidden: true
|
||||
Layout.preferredWidth: 346 * DefaultStyle.dp
|
||||
}
|
||||
}
|
||||
Text {
|
||||
text: qsTr("The password must contain 6 characters minimum")
|
||||
|
|
@ -200,12 +213,14 @@ LoginLayout {
|
|||
}
|
||||
}
|
||||
ColumnLayout {
|
||||
TextInput {
|
||||
id: confirmPwdInput
|
||||
FormItemLayout {
|
||||
label: qsTr("Confirm password")
|
||||
mandatory: true
|
||||
hidden: true
|
||||
textInputWidth: 346 * DefaultStyle.dp
|
||||
contentItem: TextField {
|
||||
id: confirmPwdInput
|
||||
hidden: true
|
||||
Layout.preferredWidth: 346 * DefaultStyle.dp
|
||||
}
|
||||
}
|
||||
Text {
|
||||
text: qsTr("The password must contain 6 characters minimum")
|
||||
|
|
|
|||
|
|
@ -14,7 +14,7 @@ LoginLayout {
|
|||
Button {
|
||||
Layout.preferredHeight: 24 * DefaultStyle.dp
|
||||
Layout.preferredWidth: 24 * DefaultStyle.dp
|
||||
icon.source: AppIcons.returnArrow
|
||||
icon.source: AppIcons.leftArrow
|
||||
width: 24 * DefaultStyle.dp
|
||||
height: 24 * DefaultStyle.dp
|
||||
background: Item {
|
||||
|
|
@ -133,34 +133,45 @@ LoginLayout {
|
|||
id: secondItem
|
||||
ColumnLayout {
|
||||
spacing: 10 * DefaultStyle.dp
|
||||
TextInput {
|
||||
id: username
|
||||
FormItemLayout {
|
||||
label: qsTr("Username")
|
||||
mandatory: true
|
||||
textInputWidth: 360 * DefaultStyle.dp
|
||||
contentItem: TextField {
|
||||
id: username
|
||||
Layout.preferredWidth: 360 * DefaultStyle.dp
|
||||
}
|
||||
}
|
||||
TextInput {
|
||||
id: password
|
||||
FormItemLayout {
|
||||
label: qsTr("Password")
|
||||
mandatory: true
|
||||
hidden: true
|
||||
textInputWidth: 360 * DefaultStyle.dp
|
||||
contentItem: TextField {
|
||||
id: password
|
||||
hidden: true
|
||||
Layout.preferredWidth: 360 * DefaultStyle.dp
|
||||
}
|
||||
}
|
||||
TextInput {
|
||||
id: domain
|
||||
FormItemLayout {
|
||||
label: qsTr("Domain")
|
||||
mandatory: true
|
||||
textInputWidth: 360 * DefaultStyle.dp
|
||||
contentItem: TextField {
|
||||
id: domain
|
||||
Layout.preferredWidth: 360 * DefaultStyle.dp
|
||||
}
|
||||
}
|
||||
TextInput {
|
||||
id: displayName
|
||||
FormItemLayout {
|
||||
label: qsTr("Display Name")
|
||||
textInputWidth: 360 * DefaultStyle.dp
|
||||
contentItem: TextField {
|
||||
id: displayName
|
||||
Layout.preferredWidth: 360 * DefaultStyle.dp
|
||||
}
|
||||
}
|
||||
ComboBox {
|
||||
FormItemLayout {
|
||||
label: qsTr("Transport")
|
||||
model:[ "TCP", "UDP", "TLS", "DTLS"]
|
||||
Layout.preferredWidth: 360 * DefaultStyle.dp
|
||||
contentItem: ComboBox {
|
||||
height: 49 * DefaultStyle.dp
|
||||
width: 360 * DefaultStyle.dp
|
||||
model:[ "TCP", "UDP", "TLS", "DTLS"]
|
||||
}
|
||||
}
|
||||
|
||||
ErrorText {
|
||||
|
|
|
|||
|
|
@ -17,6 +17,7 @@ Item {
|
|||
property alias leftPanelContent: leftPanel.children
|
||||
property alias rightPanelStackView: rightPanelStackView
|
||||
property alias contactEditionComp: contactEditionComp
|
||||
property alias rightPanel: rightPanel
|
||||
property bool showDefaultItem: true
|
||||
signal noItemButtonPressed()
|
||||
signal contactEditionClosed()
|
||||
|
|
@ -231,6 +232,7 @@ Item {
|
|||
Layout.fillWidth: true
|
||||
Layout.fillHeight: true
|
||||
}
|
||||
// We need this component here as it is used in multiple subPages (Call and Contact pages)
|
||||
Component {
|
||||
id: contactEditionComp
|
||||
ContactEdition {
|
||||
|
|
|
|||
|
|
@ -317,7 +317,7 @@ AbstractMainPage {
|
|||
}
|
||||
Layout.preferredWidth: 24 * DefaultStyle.dp
|
||||
Layout.preferredHeight: 24 * DefaultStyle.dp
|
||||
icon.source: AppIcons.returnArrow
|
||||
icon.source: AppIcons.leftArrow
|
||||
onClicked: {
|
||||
console.debug("[CallPage]User: return to call history")
|
||||
listStackView.pop()
|
||||
|
|
|
|||
461
Linphone/view/Page/Main/MeetingPage.qml
Normal file
461
Linphone/view/Page/Main/MeetingPage.qml
Normal file
|
|
@ -0,0 +1,461 @@
|
|||
import QtQuick 2.15
|
||||
import QtQuick.Effects
|
||||
import QtQuick.Layouts
|
||||
import QtQuick.Controls as Control
|
||||
import Linphone
|
||||
import UtilsCpp 1.0
|
||||
|
||||
AbstractMainPage {
|
||||
id: mainItem
|
||||
noItemButtonText: qsTr("Créer une réunion")
|
||||
emptyListText: qsTr("Aucune réunion")
|
||||
newItemIconSource: AppIcons.plusCircle
|
||||
// rightPanel.color: DefaultStyle.grey_0
|
||||
|
||||
// disable left panel contact list interaction while a contact is being edited
|
||||
property bool leftPanelEnabled: true
|
||||
property ConferenceInfoGui selectedConference
|
||||
property int meetingListCount
|
||||
|
||||
onSelectedConferenceChanged: {
|
||||
if (selectedConference) {
|
||||
if (!rightPanelStackView.currentItem || rightPanelStackView.currentItem.objectName != "meetingDetail") rightPanelStackView.replace(meetingDetail, Control.StackView.Immediate)
|
||||
} else {
|
||||
if (rightPanelStackView.currentItem && rightPanelStackView.currentItem.objectName === "meetingDetail") rightPanelStackView.clear()
|
||||
}
|
||||
}
|
||||
|
||||
Connections {
|
||||
target: leftPanelStackView
|
||||
onCurrentItemChanged: {
|
||||
mainItem.showDefaultItem = leftPanelStackView.currentItem.objectName == "listLayout" && mainItem.meetingListCount === 0
|
||||
}
|
||||
}
|
||||
onMeetingListCountChanged: showDefaultItem = leftPanelStackView.currentItem.objectName == "listLayout" && meetingListCount === 0
|
||||
|
||||
function createConference(name, address) {
|
||||
var confInfoGui = Qt.createQmlObject('import Linphone
|
||||
ConferenceInfoGui{
|
||||
}', mainItem)
|
||||
leftPanelStackView.push(createConference, {"conferenceInfoGui": confInfoGui})
|
||||
}
|
||||
|
||||
leftPanelContent: ColumnLayout {
|
||||
id: leftPanel
|
||||
Layout.fillWidth: true
|
||||
Layout.fillHeight: true
|
||||
property int sideMargin: 25 * DefaultStyle.dp
|
||||
|
||||
ColumnLayout {
|
||||
Layout.topMargin: 30 * DefaultStyle.dp
|
||||
Layout.leftMargin: leftPanel.sideMargin
|
||||
Layout.rightMargin: leftPanel.sideMargin
|
||||
enabled: mainItem.leftPanelEnabled
|
||||
Item {
|
||||
Layout.fillWidth: true
|
||||
Layout.fillHeight: true
|
||||
|
||||
Control.ScrollBar {
|
||||
id: meetingsScrollbar
|
||||
active: true
|
||||
interactive: true
|
||||
policy: Control.ScrollBar.AsNeeded
|
||||
anchors.top: parent.top
|
||||
anchors.bottom: parent.bottom
|
||||
anchors.right: parent.right
|
||||
}
|
||||
Control.StackView {
|
||||
id: leftPanelStackView
|
||||
initialItem: listLayout
|
||||
anchors.fill: parent
|
||||
}
|
||||
Component {
|
||||
id: listLayout
|
||||
ColumnLayout {
|
||||
spacing: 19 * DefaultStyle.dp
|
||||
RowLayout {
|
||||
Layout.fillWidth: true
|
||||
Layout.leftMargin: leftPanel.sideMargin
|
||||
Layout.rightMargin: leftPanel.sideMargin
|
||||
Text {
|
||||
text: qsTr("Réunions")
|
||||
color: DefaultStyle.main2_700
|
||||
font.pixelSize: 29 * DefaultStyle.dp
|
||||
font.weight: 800 * DefaultStyle.dp
|
||||
}
|
||||
Item {
|
||||
Layout.fillWidth: true
|
||||
}
|
||||
Button {
|
||||
background: Item {
|
||||
}
|
||||
icon.source: AppIcons.plusCircle
|
||||
Layout.preferredWidth: 30 * DefaultStyle.dp
|
||||
Layout.preferredHeight: 30 * DefaultStyle.dp
|
||||
width: 30 * DefaultStyle.dp
|
||||
height: 30 * DefaultStyle.dp
|
||||
onClicked: {
|
||||
mainItem.createConference()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
SearchBar {
|
||||
id: searchBar
|
||||
Layout.rightMargin: leftPanel.sideMargin
|
||||
Layout.fillWidth: true
|
||||
placeholderText: qsTr("Rechercher une réunion")
|
||||
}
|
||||
Control.ScrollView {
|
||||
Layout.fillWidth: true
|
||||
Layout.fillHeight: true
|
||||
rightPadding: leftPanel.sideMargin
|
||||
contentWidth: width - leftPanel.sideMargin
|
||||
contentHeight: content.height
|
||||
clip: true
|
||||
Control.ScrollBar.vertical: meetingsScrollbar
|
||||
ColumnLayout {
|
||||
id: content
|
||||
width: parent.width
|
||||
anchors.topMargin: 5 * DefaultStyle.dp
|
||||
anchors.fill: parent
|
||||
spacing: 15 * DefaultStyle.dp
|
||||
Text {
|
||||
Layout.fillHeight: true
|
||||
Layout.alignment: Qt.AlignHCenter
|
||||
text: mainItem.emptyListText
|
||||
font {
|
||||
pixelSize: 16 * DefaultStyle.dp
|
||||
weight: 800 * DefaultStyle.dp
|
||||
}
|
||||
visible: mainItem.showDefaultItem
|
||||
}
|
||||
|
||||
MeetingList {
|
||||
id: conferenceList
|
||||
visible: count != 0
|
||||
hoverEnabled: mainItem.leftPanelEnabled
|
||||
Layout.preferredWidth: parent.width
|
||||
Layout.fillWidth: true
|
||||
Layout.fillHeight: true
|
||||
Layout.topMargin: 20 * DefaultStyle.dp
|
||||
searchBarText: searchBar.text
|
||||
onSelectedConferenceChanged: {
|
||||
mainItem.selectedConference = selectedConference
|
||||
}
|
||||
onCountChanged: {
|
||||
mainItem.meetingListCount = count
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
Component {
|
||||
id: createConference
|
||||
NewMeeting {
|
||||
onReturnRequested: leftPanelStackView.pop()
|
||||
onAddParticipantsRequested: {
|
||||
onClicked: leftPanelStackView.push(addParticipants, {"conferenceInfoGui": conferenceInfoGui})
|
||||
}
|
||||
}
|
||||
}
|
||||
Component {
|
||||
id: addParticipants
|
||||
AddParticipantsLayout {
|
||||
title: qsTr("Ajouter des participants")
|
||||
validateButtonText: qsTr("Ajouter")
|
||||
titleColor: DefaultStyle.main1_500_main
|
||||
onReturnRequested: {
|
||||
leftPanelStackView.pop()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Component {
|
||||
id: meetingDetail
|
||||
RowLayout {
|
||||
ColumnLayout {
|
||||
Layout.alignment: Qt.AlignTop
|
||||
Layout.preferredWidth: 393 * DefaultStyle.dp
|
||||
Layout.fillWidth: false
|
||||
Layout.fillHeight: true
|
||||
Layout.leftMargin: 39 * DefaultStyle.dp
|
||||
Layout.topMargin: 39 * DefaultStyle.dp
|
||||
spacing: 25 * DefaultStyle.dp
|
||||
Section {
|
||||
content: RowLayout {
|
||||
spacing: 8 * DefaultStyle.dp
|
||||
Image {
|
||||
source: AppIcons.usersThree
|
||||
Layout.preferredWidth: 24 * DefaultStyle.dp
|
||||
Layout.preferredHeight: 24 * DefaultStyle.dp
|
||||
}
|
||||
Text {
|
||||
text: mainItem.selectedConference.core.subject
|
||||
font {
|
||||
pixelSize: 20 * DefaultStyle.dp
|
||||
weight: 800 * DefaultStyle.dp
|
||||
}
|
||||
}
|
||||
Item {
|
||||
Layout.fillWidth: true
|
||||
}
|
||||
Button {
|
||||
Layout.preferredWidth: 24 * DefaultStyle.dp
|
||||
Layout.preferredHeight: 24 * DefaultStyle.dp
|
||||
icon.source: AppIcons.pencil
|
||||
contentImageColor: DefaultStyle.main1_500_main
|
||||
background: Item{}
|
||||
onClicked: mainItem.rightPanelStackView.replace()
|
||||
}
|
||||
PopupButton {
|
||||
id: deletePopup
|
||||
Layout.preferredWidth: 24 * DefaultStyle.dp
|
||||
Layout.preferredHeight: 24 * DefaultStyle.dp
|
||||
contentImageColor: DefaultStyle.main1_500_main
|
||||
popup.contentItem: RowLayout {
|
||||
Button {
|
||||
background: Item{}
|
||||
contentItem: RowLayout {
|
||||
EffectImage {
|
||||
imageSource: AppIcons.trashCan
|
||||
width: 24 * DefaultStyle.dp
|
||||
height: 24 * DefaultStyle.dp
|
||||
Layout.preferredWidth: 24 * DefaultStyle.dp
|
||||
Layout.preferredHeight: 24 * DefaultStyle.dp
|
||||
fillMode: Image.PreserveAspectFit
|
||||
colorizationColor: DefaultStyle.danger_500main
|
||||
}
|
||||
Text {
|
||||
text: qsTr("Delete this meeting")
|
||||
color: DefaultStyle.danger_500main
|
||||
font {
|
||||
pixelSize: 14 * DefaultStyle.dp
|
||||
weight: 400 * DefaultStyle.dp
|
||||
}
|
||||
}
|
||||
}
|
||||
onClicked: {
|
||||
if (UtilsCpp.isMe(mainItem.selectedConference.core.organizerAddress))
|
||||
mainItem.selectedConference.core.lDeleteConferenceInfo()
|
||||
else
|
||||
UtilsCpp.showInformationPopup(qsTr("Erreur"), qsTr("Vous pouvez supprimer une conférence seulement si vous en êtes l'organisateur"), false)
|
||||
// mainItem.contactDeletionRequested(mainItem.selectedConference)
|
||||
deletePopup.close()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
Section {
|
||||
content: ColumnLayout {
|
||||
spacing: 15 * DefaultStyle.dp
|
||||
width: parent.width
|
||||
RowLayout {
|
||||
spacing: 8 * DefaultStyle.dp
|
||||
Layout.fillWidth: true
|
||||
Image {
|
||||
Layout.preferredWidth: 24 * DefaultStyle.dp
|
||||
Layout.preferredHeight: 24 * DefaultStyle.dp
|
||||
source: AppIcons.videoCamera
|
||||
}
|
||||
Button {
|
||||
Layout.fillWidth: true
|
||||
text: mainItem.selectedConference.core.uri
|
||||
textSize: 14 * DefaultStyle.dp
|
||||
textWeight: 400 * DefaultStyle.dp
|
||||
underline: true
|
||||
inversedColors: true
|
||||
color: DefaultStyle.main2_600
|
||||
background: Item{}
|
||||
onClicked: {
|
||||
console.log("TODO: join conf", text)
|
||||
}
|
||||
}
|
||||
Button {
|
||||
Layout.preferredWidth: 24 * DefaultStyle.dp
|
||||
Layout.preferredHeight: 24 * DefaultStyle.dp
|
||||
background: Item{}
|
||||
icon.source: AppIcons.shareNetwork
|
||||
onClicked: UtilsCpp.copyToClipboard(confUri.text)
|
||||
}
|
||||
}
|
||||
RowLayout {
|
||||
spacing: 8 * DefaultStyle.dp
|
||||
Image {
|
||||
Layout.preferredWidth: 24 * DefaultStyle.dp
|
||||
Layout.preferredHeight: 24 * DefaultStyle.dp
|
||||
source: AppIcons.clock
|
||||
}
|
||||
Text {
|
||||
text: UtilsCpp.toDateString(mainItem.selectedConference.core.dateTimeUtc)
|
||||
+ " | " + UtilsCpp.toDateHourString(mainItem.selectedConference.core.dateTimeUtc)
|
||||
+ " - "
|
||||
+ UtilsCpp.toDateHourString(mainItem.selectedConference.core.endDateTime)
|
||||
font {
|
||||
pixelSize: 14 * DefaultStyle.dp
|
||||
capitalization: Font.Capitalize
|
||||
}
|
||||
}
|
||||
}
|
||||
RowLayout {
|
||||
spacing: 8 * DefaultStyle.dp
|
||||
Image {
|
||||
Layout.preferredWidth: 24 * DefaultStyle.dp
|
||||
Layout.preferredHeight: 24 * DefaultStyle.dp
|
||||
source: AppIcons.globe
|
||||
}
|
||||
Text {
|
||||
text: qsTr("Time zone: ") + mainItem.selectedConference.core.timeZoneModel.displayName + ", " + mainItem.selectedConference.core.timeZoneModel.countryName
|
||||
font {
|
||||
pixelSize: 14 * DefaultStyle.dp
|
||||
capitalization: Font.Capitalize
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
Section {
|
||||
visible: mainItem.selectedConference.core.description.length != 0
|
||||
content: RowLayout {
|
||||
spacing: 8 * DefaultStyle.dp
|
||||
EffectImage {
|
||||
Layout.preferredWidth: 24 * DefaultStyle.dp
|
||||
Layout.preferredHeight: 24 * DefaultStyle.dp
|
||||
imageSource: AppIcons.note
|
||||
colorizationColor: DefaultStyle.main2_600
|
||||
}
|
||||
Text {
|
||||
text: mainItem.selectedConference.core.description
|
||||
Layout.fillWidth: true
|
||||
font {
|
||||
pixelSize: 14 * DefaultStyle.dp
|
||||
capitalization: Font.Capitalize
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
Section {
|
||||
content: RowLayout {
|
||||
spacing: 8 * DefaultStyle.dp
|
||||
EffectImage {
|
||||
Layout.preferredWidth: 24 * DefaultStyle.dp
|
||||
Layout.preferredHeight: 24 * DefaultStyle.dp
|
||||
imageSource: AppIcons.userRectangle
|
||||
colorizationColor: DefaultStyle.main2_600
|
||||
}
|
||||
Avatar {
|
||||
Layout.preferredWidth: 45 * DefaultStyle.dp
|
||||
Layout.preferredHeight: 45 * DefaultStyle.dp
|
||||
address: mainItem.selectedConference.core.organizerAddress
|
||||
}
|
||||
Text {
|
||||
text: mainItem.selectedConference.core.organizerName
|
||||
font {
|
||||
pixelSize: 14 * DefaultStyle.dp
|
||||
capitalization: Font.Capitalize
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
Section {
|
||||
content: RowLayout {
|
||||
Layout.preferredHeight: participantList.height
|
||||
width: 393 * DefaultStyle.dp
|
||||
spacing: 8 * DefaultStyle.dp
|
||||
Image {
|
||||
Layout.preferredWidth: 24 * DefaultStyle.dp
|
||||
Layout.preferredHeight: 24 * DefaultStyle.dp
|
||||
Layout.alignment: Qt.AlignLeft | Qt.AlignTop
|
||||
Layout.topMargin: 20 * DefaultStyle.dp
|
||||
source: AppIcons.usersTwo
|
||||
}
|
||||
ListView {
|
||||
id: participantList
|
||||
Layout.preferredHeight: Math.min(184 * DefaultStyle.dp, contentHeight)
|
||||
Layout.fillWidth: true
|
||||
model: mainItem.selectedConference.core.participants
|
||||
clip: true
|
||||
delegate: RowLayout {
|
||||
height: 56 * DefaultStyle.dp
|
||||
width: participantList.width
|
||||
Avatar {
|
||||
Layout.preferredWidth: 45 * DefaultStyle.dp
|
||||
Layout.preferredHeight: 45 * DefaultStyle.dp
|
||||
address: modelData.address
|
||||
}
|
||||
Text {
|
||||
text: modelData.displayName
|
||||
Layout.fillWidth: true
|
||||
font {
|
||||
pixelSize: 14 * DefaultStyle.dp
|
||||
capitalization: Font.Capitalize
|
||||
}
|
||||
}
|
||||
Text {
|
||||
text: qsTr("Organizer")
|
||||
visible: mainItem.selectedConference.core.organizerAddress === modelData.address
|
||||
color: DefaultStyle.main2_400
|
||||
font {
|
||||
pixelSize: 12 * DefaultStyle.dp
|
||||
weight: 300 * DefaultStyle.dp
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
Button {
|
||||
Layout.fillWidth: true
|
||||
text: qsTr("Rejoindre la réunion")
|
||||
topPadding: 11 * DefaultStyle.dp
|
||||
bottomPadding: 11 * DefaultStyle.dp
|
||||
onClicked: console.log("TODO: join conf", mainItem.selectedConference.core.subject)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
Component {
|
||||
id: meetingEdition
|
||||
Section {
|
||||
content: RowLayout {
|
||||
spacing: 8 * DefaultStyle.dp
|
||||
Button {
|
||||
Layout.preferredWidth: 24 * DefaultStyle.dp
|
||||
Layout.preferredHeight: 24 * DefaultStyle.dp
|
||||
icon.source: AppIcons.leftArrow
|
||||
contentImageColor: DefaultStyle.main1_500_main
|
||||
background: Item{}
|
||||
onClicked: mainItem.rightPanelStackView.pop()
|
||||
}
|
||||
Image {
|
||||
source: AppIcons.usersThree
|
||||
Layout.preferredWidth: 24 * DefaultStyle.dp
|
||||
Layout.preferredHeight: 24 * DefaultStyle.dp
|
||||
}
|
||||
Text {
|
||||
text: mainItem.selectedConference.core.subject
|
||||
font {
|
||||
pixelSize: 20 * DefaultStyle.dp
|
||||
weight: 800 * DefaultStyle.dp
|
||||
}
|
||||
}
|
||||
Item {
|
||||
Layout.fillWidth: true
|
||||
}
|
||||
Button {
|
||||
text: qsTr("Save")
|
||||
onClicked: {
|
||||
console.log("TODO : save meeting infos")
|
||||
mainItem.rightPanelStackView.pop(meetingDetail, Control.StackView.Immediate)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -128,10 +128,10 @@ Window{
|
|||
}
|
||||
}
|
||||
}
|
||||
TextInput {
|
||||
TextField {
|
||||
id: usernameToCall
|
||||
label: "Username to call"
|
||||
textInputWidth: 250
|
||||
Layout.preferredWidth: 250 * DefaultStyle.dp
|
||||
}
|
||||
Button{
|
||||
text: 'Call'
|
||||
|
|
|
|||
|
|
@ -16,12 +16,12 @@ Window{
|
|||
FriendGui{
|
||||
id: contact
|
||||
}
|
||||
TextInput{
|
||||
TextField{
|
||||
placeholderText: 'Name'
|
||||
initialText: contact.core.givenName
|
||||
onTextChanged: contact.core.givenName = text
|
||||
}
|
||||
TextInput{
|
||||
TextField{
|
||||
placeholderText: 'Address'
|
||||
initialText: contact.core.address
|
||||
onTextChanged: contact.core.address = text
|
||||
|
|
@ -63,7 +63,7 @@ Window{
|
|||
Text{
|
||||
text: modelData.core.address
|
||||
}
|
||||
TextInput{
|
||||
TextField{
|
||||
initialText: modelData.core.address
|
||||
onTextChanged: if(modelData.core.address != text){
|
||||
modelData.core.address = text
|
||||
|
|
|
|||
|
|
@ -8,9 +8,10 @@ QtObject {
|
|||
property string eyeHide: "image://internal/eye.svg"
|
||||
property string eyeShow: "image://internal/eye-slash.svg"
|
||||
property string downArrow: "image://internal/caret-down.svg"
|
||||
property string returnArrow: "image://internal/caret-left.svg"
|
||||
property string leftArrow: "image://internal/caret-left.svg"
|
||||
property string rightArrow: "image://internal/caret-right.svg"
|
||||
property string upArrow: "image://internal/caret-up.svg"
|
||||
property string reloadArrow: "image://internal/arrow-clockwise.svg"
|
||||
property string info: "image://internal/info.svg"
|
||||
property string loginImage: "image://internal/login_image.svg"
|
||||
property string belledonne: "image://internal/belledonne.svg"
|
||||
|
|
@ -62,6 +63,7 @@ QtObject {
|
|||
property string pause: "image://internal/pause.svg"
|
||||
property string play: "image://internal/play.svg"
|
||||
property string smiley: "image://internal/smiley.svg"
|
||||
property string smileySad: "image://internal/smiley-sad.svg"
|
||||
property string trashCan: "image://internal/trash-simple.svg"
|
||||
property string copy: "image://internal/copy.svg"
|
||||
property string empty: "image://internal/empty.svg"
|
||||
|
|
@ -75,5 +77,11 @@ QtObject {
|
|||
property string bellSlash: "image://internal/bell-simple-slash.svg"
|
||||
property string question: "image://internal/question.svg"
|
||||
property string settings: "image://internal/settings.svg"
|
||||
property string clock: "image://internal/clock.svg"
|
||||
property string note: "image://internal/note.svg"
|
||||
property string userRectangle: "image://internal/user-rectangle.svg"
|
||||
property string usersTwo: "image://internal/users.svg"
|
||||
property string globe: "image://internal/globe-hemisphere-west.svg"
|
||||
property string slide: "image://internal/slideshow.svg"
|
||||
|
||||
}
|
||||
|
|
|
|||
Some files were not shown because too many files have changed in this diff Show more
Loading…
Add table
Reference in a new issue