mirror of
https://gitlab.linphone.org/BC/public/linphone-desktop.git
synced 2026-01-17 11:28:07 +00:00
Fix crash on logger (instance lost).
Add Call model. Start audio call from Utils. Simplify VariantObject to use only setValue(). Add notifications.
This commit is contained in:
parent
62a9d34e09
commit
7ff6989614
34 changed files with 1883 additions and 380 deletions
|
|
@ -35,6 +35,9 @@ if(NOT WIN32)
|
|||
add_compile_options(-Werror=deprecated-declarations)
|
||||
endif()
|
||||
set(CMAKE_CXX_STANDARD_REQUIRED ON)
|
||||
set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} -DNDEBUG -DQT_NO_DEBUG")
|
||||
set(CMAKE_CXX_FLAGS_RELWITHDEBINFO "${CMAKE_CXX_FLAGS_RELWITHDEBINFO} -DQT_QML_DEBUG -DQT_DECLARATIVE_DEBUG")
|
||||
set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} -DDEBUG -DQT_QML_DEBUG -DQT_DECLARATIVE_DEBUG" )
|
||||
set(CMAKE_INCLUDE_CURRENT_DIR ON)#useful for config.h
|
||||
include(application_info.cmake)
|
||||
|
||||
|
|
|
|||
|
|
@ -23,13 +23,18 @@
|
|||
#include "App.hpp"
|
||||
|
||||
#include <QCoreApplication>
|
||||
#include <QFileSelector>
|
||||
#include <QGuiApplication>
|
||||
#include <QLibraryInfo>
|
||||
#include <QQmlContext>
|
||||
#include <QQmlFileSelector>
|
||||
#include <QTimer>
|
||||
|
||||
#include "core/account/Account.hpp"
|
||||
#include "core/account/AccountProxy.hpp"
|
||||
#include "core/logger/QtLogger.hpp"
|
||||
#include "core/login/LoginPage.hpp"
|
||||
#include "core/notifier/Notifier.hpp"
|
||||
#include "core/phone-number/PhoneNumber.hpp"
|
||||
#include "core/phone-number/PhoneNumberProxy.hpp"
|
||||
#include "core/singleapplication/singleapplication.h"
|
||||
|
|
@ -50,6 +55,9 @@ App *App::getInstance() {
|
|||
return dynamic_cast<App *>(QApplication::instance());
|
||||
}
|
||||
|
||||
Notifier *App::getNotifier() const {
|
||||
return mNotifier;
|
||||
}
|
||||
//-----------------------------------------------------------
|
||||
// Initializations
|
||||
//-----------------------------------------------------------
|
||||
|
|
@ -76,11 +84,22 @@ void App::init() {
|
|||
|
||||
// QML
|
||||
mEngine = new QQmlApplicationEngine(this);
|
||||
// Provide `+custom` folders for custom components and `5.9` for old components.
|
||||
QStringList selectors("custom");
|
||||
const QVersionNumber &version = QLibraryInfo::version();
|
||||
if (version.majorVersion() == 5 && version.minorVersion() == 9) selectors.push_back("5.9");
|
||||
auto selector = new QQmlFileSelector(mEngine, mEngine);
|
||||
selector->setExtraSelectors(selectors);
|
||||
qInfo() << QStringLiteral("[App] Activated selectors:") << selector->selector()->allSelectors();
|
||||
|
||||
mEngine->addImportPath(":/");
|
||||
mEngine->rootContext()->setContextProperty("applicationDirPath", QGuiApplication::applicationDirPath());
|
||||
initCppInterfaces();
|
||||
mEngine->addImageProvider(ImageProvider::ProviderId, new ImageProvider());
|
||||
|
||||
// Enable notifications.
|
||||
mNotifier = new Notifier(mEngine);
|
||||
|
||||
const QUrl url(u"qrc:/Linphone/view/App/Main.qml"_qs);
|
||||
QObject::connect(
|
||||
mEngine, &QQmlApplicationEngine::objectCreated, this,
|
||||
|
|
@ -110,6 +129,7 @@ void App::initCppInterfaces() {
|
|||
qmlRegisterUncreatableType<PhoneNumber>(Constants::MainQmlUri, 1, 0, "PhoneNumber", QLatin1String("Uncreatable"));
|
||||
qmlRegisterType<AccountProxy>(Constants::MainQmlUri, 1, 0, "AccountProxy");
|
||||
qmlRegisterUncreatableType<Account>(Constants::MainQmlUri, 1, 0, "Account", QLatin1String("Uncreatable"));
|
||||
qmlRegisterUncreatableType<Call>(Constants::MainQmlUri, 1, 0, "Call", QLatin1String("Uncreatable"));
|
||||
|
||||
LinphoneEnums::registerMetaTypes();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -26,11 +26,13 @@
|
|||
#include "model/core/CoreModel.hpp"
|
||||
|
||||
class Thread;
|
||||
class Notifier;
|
||||
|
||||
class App : public SingleApplication {
|
||||
public:
|
||||
App(int &argc, char *argv[]);
|
||||
static App *getInstance();
|
||||
Notifier *getNotifier() const;
|
||||
|
||||
// App::postModelAsync(<lambda>) => run lambda in model thread and continue.
|
||||
// App::postModelSync(<lambda>) => run lambda in current thread and block connection.
|
||||
|
|
@ -43,6 +45,14 @@ public:
|
|||
QMetaObject::invokeMethod(CoreModel::getInstance().get(), callable);
|
||||
}
|
||||
template <typename Func, typename... Args>
|
||||
static auto postCoreAsync(Func &&callable, Args &&...args) {
|
||||
QMetaObject::invokeMethod(App::getInstance(), callable, args...);
|
||||
}
|
||||
template <typename Func>
|
||||
static auto postCoreAsync(Func &&callable) {
|
||||
QMetaObject::invokeMethod(App::getInstance(), callable);
|
||||
}
|
||||
template <typename Func, typename... Args>
|
||||
static auto postModelSync(Func &&callable, Args &&...args) {
|
||||
if (QThread::currentThread() != CoreModel::getInstance()->thread()) {
|
||||
bool end = false;
|
||||
|
|
@ -70,4 +80,5 @@ private:
|
|||
|
||||
QCommandLineParser *mParser = nullptr;
|
||||
Thread *mLinphoneThread = nullptr;
|
||||
Notifier *mNotifier = nullptr;
|
||||
};
|
||||
|
|
|
|||
|
|
@ -3,8 +3,10 @@ list(APPEND _LINPHONEAPP_SOURCES
|
|||
core/account/AccountList.cpp
|
||||
core/account/AccountProxy.cpp
|
||||
core/App.cpp
|
||||
core/call/Call.cpp
|
||||
core/logger/QtLogger.cpp
|
||||
core/login/LoginPage.cpp
|
||||
core/notifier/Notifier.cpp
|
||||
core/path/Paths.cpp
|
||||
core/phone-number/PhoneNumber.cpp
|
||||
core/phone-number/PhoneNumberList.cpp
|
||||
|
|
|
|||
81
Linphone/core/call/Call.cpp
Normal file
81
Linphone/core/call/Call.cpp
Normal file
|
|
@ -0,0 +1,81 @@
|
|||
/*
|
||||
* 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 "Call.hpp"
|
||||
#include "core/App.hpp"
|
||||
#include "tool/Utils.hpp"
|
||||
|
||||
DEFINE_ABSTRACT_OBJECT(Call)
|
||||
|
||||
Call::Call(const std::shared_ptr<linphone::Call> &call) : QObject(nullptr) {
|
||||
// Should be call from model Thread
|
||||
mustBeInLinphoneThread(getClassName());
|
||||
mCallModel = Utils::makeQObject_ptr<CallModel>(call);
|
||||
connect(mCallModel.get(), &CallModel::stateChanged, this, &Call::onStateChanged);
|
||||
connect(this, &Call::lAccept, mCallModel.get(), &CallModel::accept);
|
||||
connect(this, &Call::lDecline, mCallModel.get(), &CallModel::decline);
|
||||
connect(this, &Call::lTerminate, mCallModel.get(), &CallModel::terminate);
|
||||
mCallModel->setSelf(mCallModel);
|
||||
mState = LinphoneEnums::fromLinphone(call->getState());
|
||||
}
|
||||
|
||||
Call::~Call() {
|
||||
mustBeInMainThread("~" + getClassName());
|
||||
emit mCallModel->removeListener();
|
||||
}
|
||||
|
||||
LinphoneEnums::CallStatus Call::getStatus() const {
|
||||
return mStatus;
|
||||
}
|
||||
|
||||
void Call::setStatus(LinphoneEnums::CallStatus status) {
|
||||
mustBeInMainThread(log().arg(Q_FUNC_INFO));
|
||||
if (mStatus != status) {
|
||||
mStatus = status;
|
||||
emit statusChanged(mStatus);
|
||||
}
|
||||
}
|
||||
|
||||
LinphoneEnums::CallState Call::getState() const {
|
||||
return mState;
|
||||
}
|
||||
|
||||
void Call::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);
|
||||
}
|
||||
}
|
||||
|
||||
void Call::onStateChanged(linphone::Call::State state, const std::string &message) {
|
||||
setState(LinphoneEnums::fromLinphone(state), Utils::coreStringToAppString(message));
|
||||
}
|
||||
|
||||
QString Call::getLastErrorMessage() const {
|
||||
return mLastErrorMessage;
|
||||
}
|
||||
void Call::setLastErrorMessage(const QString &message) {
|
||||
if (mLastErrorMessage != message) {
|
||||
mLastErrorMessage = message;
|
||||
emit lastErrorMessageChanged();
|
||||
}
|
||||
}
|
||||
91
Linphone/core/call/Call.hpp
Normal file
91
Linphone/core/call/Call.hpp
Normal file
|
|
@ -0,0 +1,91 @@
|
|||
/*
|
||||
* 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 CALL_H_
|
||||
#define CALL_H_
|
||||
|
||||
#include "model/call/CallModel.hpp"
|
||||
#include "tool/LinphoneEnums.hpp"
|
||||
#include <QObject>
|
||||
#include <QSharedPointer>
|
||||
#include <linphone++/linphone.hh>
|
||||
|
||||
class Call : public QObject, public AbstractObject {
|
||||
Q_OBJECT
|
||||
|
||||
Q_PROPERTY(LinphoneEnums::CallStatus status READ getStatus NOTIFY statusChanged)
|
||||
Q_PROPERTY(LinphoneEnums::CallState state READ getState NOTIFY stateChanged)
|
||||
Q_PROPERTY(QString lastErrorMessage READ getLastErrorMessage NOTIFY lastErrorMessageChanged)
|
||||
|
||||
public:
|
||||
// Should be call from model Thread. Will be automatically in App thread after initialization
|
||||
Call(const std::shared_ptr<linphone::Call> &call);
|
||||
~Call();
|
||||
|
||||
LinphoneEnums::CallStatus getStatus() const;
|
||||
void setStatus(LinphoneEnums::CallStatus status);
|
||||
|
||||
LinphoneEnums::CallState getState() const;
|
||||
void setState(LinphoneEnums::CallState state, const QString &message);
|
||||
void onStateChanged(linphone::Call::State state, const std::string &message);
|
||||
|
||||
QString getLastErrorMessage() const;
|
||||
void setLastErrorMessage(const QString &message);
|
||||
|
||||
signals:
|
||||
void statusChanged(LinphoneEnums::CallStatus status);
|
||||
void stateChanged(LinphoneEnums::CallState state);
|
||||
void lastErrorMessageChanged();
|
||||
|
||||
// Linphone commands
|
||||
void lAccept(bool withVideo); // Accept an incoming call
|
||||
void lDecline(); // Decline an incoming call
|
||||
void lTerminate(); // Hangup a call
|
||||
/* 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 startRecording();
|
||||
Q_INVOKABLE void stopRecording();
|
||||
|
||||
Q_INVOKABLE void sendDtmf(const QString &dtmf);
|
||||
Q_INVOKABLE void verifyAuthenticationToken(bool verify);
|
||||
Q_INVOKABLE void updateStreams();
|
||||
Q_INVOKABLE void toggleSpeakerMute();
|
||||
*/
|
||||
private:
|
||||
std::shared_ptr<CallModel> mCallModel;
|
||||
LinphoneEnums::CallStatus mStatus;
|
||||
LinphoneEnums::CallState mState;
|
||||
QString mLastErrorMessage;
|
||||
|
||||
DECLARE_ABSTRACT_OBJECT
|
||||
};
|
||||
Q_DECLARE_METATYPE(Call *)
|
||||
#endif
|
||||
420
Linphone/core/notifier/Notifier.cpp
Normal file
420
Linphone/core/notifier/Notifier.cpp
Normal file
|
|
@ -0,0 +1,420 @@
|
|||
/*
|
||||
* 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 <QFileInfo>
|
||||
#include <QMutex>
|
||||
#include <QQmlApplicationEngine>
|
||||
#include <QQmlComponent>
|
||||
#include <QQmlContext>
|
||||
#include <QQuickItem>
|
||||
#include <QQuickView>
|
||||
#include <QQuickWindow>
|
||||
#include <QScreen>
|
||||
#include <QTimer>
|
||||
|
||||
#include "Notifier.hpp"
|
||||
|
||||
#include "core/App.hpp"
|
||||
#include "core/call/Call.hpp"
|
||||
#include "tool/LinphoneEnums.hpp"
|
||||
#include "tool/providers/ImageProvider.hpp"
|
||||
|
||||
DEFINE_ABSTRACT_OBJECT(Notifier)
|
||||
|
||||
// =============================================================================
|
||||
|
||||
using namespace std;
|
||||
|
||||
namespace {
|
||||
constexpr char NotificationsPath[] = "qrc:/Linphone/view/Item/Notification/";
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
// Notifications QML properties/methods.
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
constexpr char NotificationShowMethodName[] = "open";
|
||||
|
||||
constexpr char NotificationPropertyData[] = "notificationData";
|
||||
|
||||
constexpr char NotificationPropertyX[] = "popupX";
|
||||
constexpr char NotificationPropertyY[] = "popupY";
|
||||
|
||||
constexpr char NotificationPropertyWindow[] = "__internalWindow";
|
||||
|
||||
constexpr char NotificationPropertyTimer[] = "__timer";
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
// Arbitrary hardcoded values.
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
constexpr int NotificationSpacing = 10;
|
||||
constexpr int MaxNotificationsNumber = 5;
|
||||
} // namespace
|
||||
|
||||
// =============================================================================
|
||||
|
||||
template <class T>
|
||||
void setProperty(QObject &object, const char *property, const T &value) {
|
||||
if (!object.setProperty(property, QVariant(value))) {
|
||||
qWarning() << QStringLiteral("Unable to set property: `%1`.").arg(property);
|
||||
abort();
|
||||
}
|
||||
}
|
||||
|
||||
// =============================================================================
|
||||
// Available notifications.
|
||||
// =============================================================================
|
||||
|
||||
const QHash<int, Notifier::Notification> Notifier::Notifications = {
|
||||
//{Notifier::ReceivedMessage, {Notifier::ReceivedMessage, "NotificationReceivedMessage.qml", 10}},
|
||||
//{Notifier::ReceivedFileMessage, {Notifier::ReceivedFileMessage, "NotificationReceivedFileMessage.qml", 10}},
|
||||
{Notifier::ReceivedCall, {Notifier::ReceivedCall, "NotificationReceivedCall.qml", 30}},
|
||||
//{Notifier::NewVersionAvailable, {Notifier::NewVersionAvailable, "NotificationNewVersionAvailable.qml", 30}},
|
||||
//{Notifier::SnapshotWasTaken, {Notifier::SnapshotWasTaken, "NotificationSnapshotWasTaken.qml", 10}},
|
||||
//{Notifier::RecordingCompleted, {Notifier::RecordingCompleted, "NotificationRecordingCompleted.qml", 10}}
|
||||
};
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
Notifier::Notifier(QObject *parent) : QObject(parent) {
|
||||
mustBeInMainThread(getClassName());
|
||||
const int nComponents = Notifications.size();
|
||||
mComponents = new QQmlComponent *[nComponents];
|
||||
|
||||
QQmlEngine *engine = App::getInstance()->mEngine;
|
||||
for (const auto &key : Notifications.keys()) {
|
||||
QQmlComponent *component =
|
||||
new QQmlComponent(engine, QUrl(NotificationsPath + Notifier::Notifications[key].filename));
|
||||
if (Q_UNLIKELY(component->isError())) {
|
||||
qWarning() << QStringLiteral("Errors found in `Notification` component %1:").arg(key)
|
||||
<< component->errors();
|
||||
abort();
|
||||
}
|
||||
mComponents[key] = component;
|
||||
}
|
||||
|
||||
mMutex = new QMutex();
|
||||
}
|
||||
|
||||
Notifier::~Notifier() {
|
||||
mustBeInMainThread("~" + getClassName());
|
||||
delete mMutex;
|
||||
|
||||
const int nComponents = Notifications.size();
|
||||
for (int i = 0; i < nComponents; ++i)
|
||||
mComponents[i]->deleteLater();
|
||||
delete[] mComponents;
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
QObject *Notifier::createNotification(Notifier::NotificationType type, QVariantMap data) {
|
||||
QQuickItem *wrapperItem = nullptr;
|
||||
mMutex->lock();
|
||||
Q_ASSERT(mInstancesNumber <= MaxNotificationsNumber);
|
||||
if (mInstancesNumber == MaxNotificationsNumber) { // Check existing instances.
|
||||
qWarning() << QStringLiteral("Unable to create another notification.");
|
||||
mMutex->unlock();
|
||||
return nullptr;
|
||||
}
|
||||
QList<QScreen *> allScreens = QGuiApplication::screens();
|
||||
if (allScreens.size() > 0) { // Ensure to have a screen to avoid errors
|
||||
QQuickItem *previousWrapper = nullptr;
|
||||
++mInstancesNumber;
|
||||
bool showAsTool = false;
|
||||
#ifdef Q_OS_MACOS
|
||||
for (auto w : QGuiApplication::topLevelWindows()) {
|
||||
if ((w->windowState() & Qt::WindowFullScreen) == Qt::WindowFullScreen) {
|
||||
showAsTool = true;
|
||||
w->raise(); // Used to get focus on Mac (On Mac, A Tool is hidden if the app has not focus and the only
|
||||
// way to rid it is to use Widget Attributes(Qt::WA_MacAlwaysShowToolWindow) that is not
|
||||
// available)
|
||||
}
|
||||
}
|
||||
#endif
|
||||
for (int i = 0; i < allScreens.size(); ++i) {
|
||||
|
||||
// Use QQuickView to create a visual root object that is
|
||||
// independant from current application Window
|
||||
QScreen *screen = allScreens[i];
|
||||
// auto engine = App::getInstance()->mEngine;
|
||||
auto engine = new QQmlApplicationEngine();
|
||||
engine->addImageProvider(ImageProvider::ProviderId, new ImageProvider());
|
||||
engine->addImportPath(":/");
|
||||
// if(showAsTool) window->setProperty("showAsTool",true);
|
||||
engine->setInitialProperties(data);
|
||||
// engine->rootContext()->setContextProperty("applicationDirPath",QGuiApplication::applicationDirPath());
|
||||
// engine->setInitialProperties({{"screenIndex", i}});
|
||||
//, {"x", screen->geometry().x()}, {"y", screen->geometry().y()}});
|
||||
const QUrl url(QString(NotificationsPath) + Notifier::Notifications[type].filename);
|
||||
QObject::connect(
|
||||
engine, &QQmlApplicationEngine::objectCreated, this,
|
||||
[this, url, screen, engine](QObject *obj, const QUrl &objUrl) {
|
||||
if (!obj && url == objUrl) {
|
||||
qCritical() << "[App] Notifier.qml couldn't be load.";
|
||||
engine->deleteLater();
|
||||
exit(-1);
|
||||
} else {
|
||||
qWarning() << engine->rootObjects()[0];
|
||||
auto window = qobject_cast<QQuickWindow *>(obj);
|
||||
if (window) {
|
||||
int *screenHeightOffset = &mScreenHeightOffset[screen->name()]; // Access optimization
|
||||
QRect availableGeometry = screen->availableGeometry();
|
||||
int heightOffset =
|
||||
availableGeometry.y() +
|
||||
(availableGeometry.height() -
|
||||
window->height()); //*screen->devicePixelRatio(); when using manual scaler
|
||||
|
||||
window->setX(availableGeometry.x() +
|
||||
(availableGeometry.width() -
|
||||
window->property("width")
|
||||
.toInt())); //*screen->devicePixelRatio()); when using manual scaler
|
||||
window->setY(heightOffset - (*screenHeightOffset % heightOffset));
|
||||
qWarning() << window->geometry();
|
||||
}
|
||||
}
|
||||
},
|
||||
Qt::QueuedConnection);
|
||||
engine->load(url);
|
||||
}
|
||||
qInfo() << QStringLiteral("Create notifications:") << wrapperItem;
|
||||
}
|
||||
|
||||
mMutex->unlock();
|
||||
return wrapperItem;
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
void Notifier::showNotification(QObject *notification, int timeout) {
|
||||
// Display notification.
|
||||
QMetaObject::invokeMethod(notification, NotificationShowMethodName, Qt::DirectConnection);
|
||||
|
||||
QTimer *timer = new QTimer(notification);
|
||||
timer->setInterval(timeout);
|
||||
timer->setSingleShot(true);
|
||||
notification->setProperty(NotificationPropertyTimer, QVariant::fromValue(timer));
|
||||
|
||||
// Destroy it after timeout.
|
||||
QObject::connect(timer, &QTimer::timeout, this,
|
||||
[this, notification]() { deleteNotificationOnTimeout(QVariant::fromValue(notification)); });
|
||||
|
||||
// Called explicitly (by a click on notification for example)
|
||||
QObject::connect(notification, SIGNAL(deleteNotification(QVariant)), this, SLOT(deleteNotification(QVariant)));
|
||||
|
||||
timer->start();
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
void Notifier::deleteNotificationOnTimeout(QVariant notification) {
|
||||
#ifdef Q_OS_MACOS
|
||||
for (auto w : QGuiApplication::topLevelWindows()) {
|
||||
if ((w->windowState() & Qt::WindowFullScreen) == Qt::WindowFullScreen) {
|
||||
w->requestActivate(); // Used to get focus on fullscreens on Mac in order to avoid screen switching.
|
||||
}
|
||||
}
|
||||
#endif
|
||||
deleteNotification(notification);
|
||||
}
|
||||
|
||||
void Notifier::deleteNotification(QVariant notification) {
|
||||
mMutex->lock();
|
||||
|
||||
QObject *instance = notification.value<QObject *>();
|
||||
|
||||
// Notification marked destroyed.
|
||||
if (instance->property("__valid").isValid()) {
|
||||
mMutex->unlock();
|
||||
return;
|
||||
}
|
||||
|
||||
qInfo() << QStringLiteral("Delete notification:") << instance;
|
||||
|
||||
instance->setProperty("__valid", true);
|
||||
instance->property(NotificationPropertyTimer).value<QTimer *>()->stop();
|
||||
|
||||
mInstancesNumber--;
|
||||
Q_ASSERT(mInstancesNumber >= 0);
|
||||
|
||||
if (mInstancesNumber == 0) mScreenHeightOffset.clear();
|
||||
|
||||
mMutex->unlock();
|
||||
|
||||
instance->deleteLater();
|
||||
}
|
||||
|
||||
// =============================================================================
|
||||
|
||||
#define CREATE_NOTIFICATION(TYPE, DATA) \
|
||||
QObject *notification = createNotification(TYPE, DATA); \
|
||||
if (!notification) return; \
|
||||
const int timeout = Notifications[TYPE].getTimeout() * 1000; \
|
||||
showNotification(notification, timeout);
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
// Notification functions.
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
void Notifier::notifyReceivedCall(const shared_ptr<linphone::Call> &call) {
|
||||
mustBeInLinphoneThread(log().arg(Q_FUNC_INFO));
|
||||
auto model = new Call(call);
|
||||
model->moveToThread(this->thread());
|
||||
App::postCoreAsync([this, model]() {
|
||||
mustBeInMainThread(getClassName());
|
||||
QVariantMap map;
|
||||
map["call"].setValue(model);
|
||||
CREATE_NOTIFICATION(Notifier::ReceivedCall, map)
|
||||
|
||||
QObject::connect(
|
||||
model, &Call::statusChanged, notification, [this, notification](LinphoneEnums::CallStatus status) {
|
||||
qInfo() << log().arg("Delete notification on call status : %1").arg(LinphoneEnums::toString(status));
|
||||
deleteNotification(QVariant::fromValue(notification));
|
||||
});
|
||||
QObject::connect(model, &Call::destroyed, notification,
|
||||
[this, notification]() { deleteNotification(QVariant::fromValue(notification)); });
|
||||
});
|
||||
}
|
||||
|
||||
/*
|
||||
void Notifier::notifyReceivedMessages(const list<shared_ptr<linphone::ChatMessage>> &messages) {
|
||||
QVariantMap map;
|
||||
QString txt;
|
||||
if (messages.size() > 0) {
|
||||
shared_ptr<linphone::ChatMessage> message = messages.front();
|
||||
|
||||
if (messages.size() == 1) {
|
||||
auto fileContent = message->getFileTransferInformation();
|
||||
if (!fileContent) {
|
||||
foreach (auto content, message->getContents()) {
|
||||
if (content->isText()) txt += content->getUtf8Text().c_str();
|
||||
}
|
||||
} else if (fileContent->isVoiceRecording())
|
||||
//: 'Voice message received!' : message to warn the user in a notofication for voice messages.
|
||||
txt = tr("newVoiceMessage");
|
||||
else txt = tr("newFileMessage");
|
||||
if (txt.isEmpty() && message->hasConferenceInvitationContent())
|
||||
//: 'Conference invitation received!' : Notification about receiving an invitation to a conference.
|
||||
txt = tr("newConferenceInvitation");
|
||||
} else
|
||||
//: 'New messages received!' Notification that warn the user of new messages.
|
||||
txt = tr("newChatRoomMessages");
|
||||
map["message"] = txt;
|
||||
shared_ptr<linphone::ChatRoom> chatRoom(message->getChatRoom());
|
||||
map["timelineModel"].setValue(
|
||||
CoreManager::getInstance()->getTimelineListModel()->getTimeline(chatRoom, true).get());
|
||||
if (messages.size() == 1) { // Display only sender on mono message.
|
||||
map["peerAddress"] = Utils::coreStringToAppString(message->getFromAddress()->asStringUriOnly());
|
||||
map["fullPeerAddress"] = Utils::coreStringToAppString(message->getFromAddress()->asString());
|
||||
}
|
||||
map["localAddress"] = Utils::coreStringToAppString(message->getToAddress()->asStringUriOnly());
|
||||
map["fullLocalAddress"] = Utils::coreStringToAppString(message->getToAddress()->asString());
|
||||
map["window"].setValue(App::getInstance()->getMainWindow());
|
||||
CREATE_NOTIFICATION(Notifier::ReceivedMessage, map)
|
||||
}
|
||||
}
|
||||
|
||||
void Notifier::notifyReceivedReactions(
|
||||
const QList<QPair<std::shared_ptr<linphone::ChatMessage>, std::shared_ptr<const linphone::ChatMessageReaction>>>
|
||||
&reactions) {
|
||||
QVariantMap map;
|
||||
QString txt;
|
||||
|
||||
if (reactions.size() > 0) {
|
||||
ChatMessageModel *redirection = nullptr;
|
||||
QPair<shared_ptr<linphone::ChatMessage>, std::shared_ptr<const linphone::ChatMessageReaction>> reaction =
|
||||
reactions.front();
|
||||
shared_ptr<linphone::ChatMessage> message = reaction.first;
|
||||
shared_ptr<linphone::ChatRoom> chatRoom(message->getChatRoom());
|
||||
auto timelineModel = CoreManager::getInstance()->getTimelineListModel()->getTimeline(chatRoom, true);
|
||||
map["messageId"] = Utils::coreStringToAppString(message->getMessageId());
|
||||
if (reactions.size() == 1) {
|
||||
QString messageTxt;
|
||||
auto fileContent = message->getFileTransferInformation();
|
||||
if (!fileContent) {
|
||||
foreach (auto content, message->getContents()) {
|
||||
if (content->isText()) messageTxt += content->getUtf8Text().c_str();
|
||||
}
|
||||
} else if (fileContent->isVoiceRecording())
|
||||
//: 'Voice message' : Voice message type that has been reacted.
|
||||
messageTxt += tr("voiceMessageReact");
|
||||
else {
|
||||
QFileInfo file(Utils::coreStringToAppString(fileContent->getFilePath()));
|
||||
messageTxt += file.fileName();
|
||||
}
|
||||
if (messageTxt.isEmpty() && message->hasConferenceInvitationContent())
|
||||
//: 'Conference invitation' : Conference invitation message type that has been reacted.
|
||||
messageTxt += tr("conferenceInvitationReact");
|
||||
//: ''Has reacted by %1 to: %2' : Reaction message. %1=Reaction(emoji), %2=type of message(Voice
|
||||
//: Message/Conference invitation/ Message text)
|
||||
txt = tr("reactionMessage").arg(Utils::coreStringToAppString(reaction.second->getBody())).arg(messageTxt);
|
||||
|
||||
} else
|
||||
//: 'New reactions received!' : Notification that warn the user of new reactions.
|
||||
txt = tr("newReactionsMessages");
|
||||
map["message"] = txt;
|
||||
|
||||
map["timelineModel"].setValue(timelineModel.get());
|
||||
if (reactions.size() == 1) { // Display only sender on mono message.
|
||||
map["peerAddress"] = Utils::coreStringToAppString(reaction.second->getFromAddress()->asStringUriOnly());
|
||||
map["fullPeerAddress"] = Utils::coreStringToAppString(reaction.second->getFromAddress()->asString());
|
||||
}
|
||||
map["localAddress"] = Utils::coreStringToAppString(chatRoom->getLocalAddress()->asStringUriOnly());
|
||||
map["fullLocalAddress"] = Utils::coreStringToAppString(chatRoom->getLocalAddress()->asString());
|
||||
map["window"].setValue(App::getInstance()->getMainWindow());
|
||||
CREATE_NOTIFICATION(Notifier::ReceivedMessage, map)
|
||||
}
|
||||
}
|
||||
|
||||
void Notifier::notifyReceivedFileMessage(const shared_ptr<linphone::ChatMessage> &message,
|
||||
const shared_ptr<linphone::Content> &content) {
|
||||
QVariantMap map;
|
||||
shared_ptr<linphone::ChatRoom> chatRoom(message->getChatRoom());
|
||||
map["timelineModel"].setValue(
|
||||
CoreManager::getInstance()->getTimelineListModel()->getTimeline(chatRoom, true).get());
|
||||
map["fileUri"] = Utils::coreStringToAppString(content->getFilePath());
|
||||
if (Utils::getImage(map["fileUri"].toString()).isNull()) map["imageUri"] = "";
|
||||
else map["imageUri"] = map["fileUri"];
|
||||
map["fileSize"] = quint64(content->getSize() + content->getFileSize());
|
||||
CREATE_NOTIFICATION(Notifier::ReceivedFileMessage, map)
|
||||
}
|
||||
|
||||
|
||||
|
||||
void Notifier::notifyNewVersionAvailable(const QString &version, const QString &url) {
|
||||
QVariantMap map;
|
||||
map["message"] = tr("newVersionAvailable").arg(version);
|
||||
map["url"] = url;
|
||||
CREATE_NOTIFICATION(Notifier::NewVersionAvailable, map)
|
||||
}
|
||||
|
||||
void Notifier::notifySnapshotWasTaken(const QString &filePath) {
|
||||
QVariantMap map;
|
||||
map["filePath"] = filePath;
|
||||
CREATE_NOTIFICATION(Notifier::SnapshotWasTaken, map)
|
||||
}
|
||||
|
||||
void Notifier::notifyRecordingCompleted(const QString &filePath) {
|
||||
QVariantMap map;
|
||||
map["filePath"] = filePath;
|
||||
CREATE_NOTIFICATION(Notifier::RecordingCompleted, map)
|
||||
}
|
||||
*/
|
||||
#undef SHOW_NOTIFICATION
|
||||
#undef CREATE_NOTIFICATION
|
||||
104
Linphone/core/notifier/Notifier.hpp
Normal file
104
Linphone/core/notifier/Notifier.hpp
Normal file
|
|
@ -0,0 +1,104 @@
|
|||
/*
|
||||
* 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 NOTIFIER_H_
|
||||
#define NOTIFIER_H_
|
||||
|
||||
#include <memory>
|
||||
|
||||
#include "core/call/Call.hpp"
|
||||
#include "tool/AbstractObject.hpp"
|
||||
#include <QHash>
|
||||
#include <QObject>
|
||||
// =============================================================================
|
||||
|
||||
class QMutex;
|
||||
class QQmlComponent;
|
||||
|
||||
class Notifier : public QObject, public AbstractObject {
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
Notifier(QObject *parent = Q_NULLPTR);
|
||||
~Notifier();
|
||||
|
||||
enum NotificationType {
|
||||
ReceivedMessage,
|
||||
ReceivedFileMessage,
|
||||
ReceivedCall,
|
||||
NewVersionAvailable,
|
||||
SnapshotWasTaken,
|
||||
RecordingCompleted
|
||||
};
|
||||
|
||||
// void notifyReceivedCall(Call *call);
|
||||
void notifyReceivedCall(const std::shared_ptr<linphone::Call> &call); // Call from Linphone
|
||||
|
||||
/*
|
||||
void notifyReceivedMessages(const std::list<std::shared_ptr<linphone::ChatMessage>> &messages);
|
||||
void notifyReceivedReactions(
|
||||
const QList<QPair<std::shared_ptr<linphone::ChatMessage>, std::shared_ptr<const
|
||||
linphone::ChatMessageReaction>>> &reactions); void notifyReceivedFileMessage(const
|
||||
std::shared_ptr<linphone::ChatMessage> &message, const std::shared_ptr<linphone::Content> &content);
|
||||
|
||||
void notifyNewVersionAvailable(const QString &version, const QString &url);
|
||||
void notifySnapshotWasTaken(const QString &filePath);
|
||||
void notifyRecordingCompleted(const QString &filePath);
|
||||
*/
|
||||
|
||||
public slots:
|
||||
void deleteNotificationOnTimeout(QVariant notification);
|
||||
void deleteNotification(QVariant notification);
|
||||
|
||||
private:
|
||||
struct Notification {
|
||||
Notification(const int &type = 0, const QString &filename = QString(""), int timeout = 0) {
|
||||
this->type = type;
|
||||
this->filename = filename;
|
||||
this->timeout = timeout;
|
||||
}
|
||||
int getTimeout() const {
|
||||
if (type == Notifier::ReceivedCall) {
|
||||
// return CoreManager::getInstance()->getSettingsModel()->getIncomingCallTimeout();
|
||||
return 30;
|
||||
} else return timeout;
|
||||
}
|
||||
QString filename;
|
||||
|
||||
private:
|
||||
int timeout;
|
||||
int type;
|
||||
};
|
||||
|
||||
QObject *createNotification(NotificationType type, QVariantMap data);
|
||||
void showNotification(QObject *notification, int timeout);
|
||||
|
||||
QHash<QString, int> mScreenHeightOffset;
|
||||
int mInstancesNumber = 0;
|
||||
|
||||
QMutex *mMutex = nullptr;
|
||||
QQmlComponent **mComponents = nullptr;
|
||||
|
||||
static const QHash<int, Notification> Notifications;
|
||||
|
||||
DECLARE_ABSTRACT_OBJECT
|
||||
};
|
||||
|
||||
#endif // NOTIFIER_H_
|
||||
|
|
@ -3,10 +3,31 @@
|
|||
|
||||
#include <QLocale>
|
||||
#include <QTranslator>
|
||||
#include <qloggingcategory.h>
|
||||
|
||||
#include "core/App.hpp"
|
||||
|
||||
#ifdef QT_QML_DEBUG
|
||||
#include <QQmlDebuggingEnabler>
|
||||
#endif
|
||||
|
||||
#if QT_VERSION < QT_VERSION_CHECK(5, 15, 10)
|
||||
// From 5.15.2 to 5.15.10, sometimes, Accessibility freeze the application : Deactivate handlers.
|
||||
#define ACCESSBILITY_WORKAROUND
|
||||
#include <QAccessible>
|
||||
#include <QAccessibleEvent>
|
||||
void DummyUpdateHandler(QAccessibleEvent *event) {
|
||||
}
|
||||
void DummyRootObjectHandler(QObject *) {
|
||||
}
|
||||
#endif
|
||||
|
||||
int main(int argc, char *argv[]) {
|
||||
// Useful to share camera on Fullscreen (other context) or multiscreens
|
||||
QApplication::setAttribute(Qt::AA_ShareOpenGLContexts);
|
||||
// Disable QML cache. Avoid malformed cache.
|
||||
qputenv("QML_DISABLE_DISK_CACHE", "true");
|
||||
|
||||
App app(argc, argv);
|
||||
|
||||
QTranslator translator;
|
||||
|
|
@ -19,6 +40,11 @@ int main(int argc, char *argv[]) {
|
|||
}
|
||||
}
|
||||
|
||||
#ifdef ACCESSBILITY_WORKAROUND
|
||||
QAccessible::installUpdateHandler(DummyUpdateHandler);
|
||||
QAccessible::installRootObjectHandler(DummyRootObjectHandler);
|
||||
#endif
|
||||
|
||||
int result = 0;
|
||||
while (result >= 0) {
|
||||
result = app.exec();
|
||||
|
|
|
|||
|
|
@ -1,9 +1,10 @@
|
|||
list(APPEND _LINPHONEAPP_SOURCES
|
||||
model/account/AccountModel.cpp
|
||||
model/account/AccountManager.cpp
|
||||
|
||||
model/call/CallModel.cpp
|
||||
|
||||
model/core/CoreModel.cpp
|
||||
model/core/CoreListener.cpp
|
||||
|
||||
model/listener/Listener.hpp
|
||||
|
||||
|
|
|
|||
|
|
@ -93,6 +93,7 @@ void AccountManager::onRegistrationStateChanged(const std::shared_ptr<linphone::
|
|||
mAccountModel = nullptr;
|
||||
break;
|
||||
case linphone::RegistrationState::Ok:
|
||||
core->setDefaultAccount(account);
|
||||
emit mAccountModel->removeListener();
|
||||
mAccountModel = nullptr;
|
||||
break;
|
||||
|
|
|
|||
144
Linphone/model/call/CallModel.cpp
Normal file
144
Linphone/model/call/CallModel.cpp
Normal file
|
|
@ -0,0 +1,144 @@
|
|||
/*
|
||||
* 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 "CallModel.hpp"
|
||||
|
||||
#include <QDebug>
|
||||
|
||||
#include "model/core/CoreModel.hpp"
|
||||
|
||||
DEFINE_ABSTRACT_OBJECT(CallModel)
|
||||
|
||||
CallModel::CallModel(const std::shared_ptr<linphone::Call> &call, QObject *parent)
|
||||
: ::Listener<linphone::Call, linphone::CallListener>(call, parent) {
|
||||
mustBeInLinphoneThread(getClassName());
|
||||
}
|
||||
|
||||
CallModel::~CallModel() {
|
||||
mustBeInLinphoneThread("~" + getClassName());
|
||||
}
|
||||
|
||||
void CallModel::accept(bool withVideo) {
|
||||
mustBeInLinphoneThread(log().arg(Q_FUNC_INFO));
|
||||
|
||||
auto core = CoreModel::getInstance()->getCore();
|
||||
auto params = core->createCallParams(mMonitor);
|
||||
params->enableVideo(withVideo);
|
||||
// Answer with local call address.
|
||||
auto localAddress = mMonitor->getCallLog()->getLocalAddress();
|
||||
for (auto account : core->getAccountList()) {
|
||||
if (account->getParams()->getIdentityAddress()->weakEqual(localAddress)) {
|
||||
params->setAccount(account);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
mMonitor->acceptWithParams(params);
|
||||
}
|
||||
|
||||
void CallModel::decline() {
|
||||
mustBeInLinphoneThread(log().arg(Q_FUNC_INFO));
|
||||
auto errorInfo = linphone::Factory::get()->createErrorInfo();
|
||||
errorInfo->set("SIP", linphone::Reason::Declined, 603, "Decline", "");
|
||||
mMonitor->terminateWithErrorInfo(errorInfo);
|
||||
}
|
||||
|
||||
void CallModel::terminate() {
|
||||
mustBeInLinphoneThread(log().arg(Q_FUNC_INFO));
|
||||
mMonitor->terminate();
|
||||
}
|
||||
|
||||
void CallModel::onDtmfReceived(const std::shared_ptr<linphone::Call> &call, int dtmf) {
|
||||
emit dtmfReceived(call, dtmf);
|
||||
}
|
||||
|
||||
void CallModel::onGoclearAckSent(const std::shared_ptr<linphone::Call> &call) {
|
||||
emit goclearAckSent(call);
|
||||
}
|
||||
|
||||
void CallModel::onEncryptionChanged(const std::shared_ptr<linphone::Call> &call,
|
||||
bool on,
|
||||
const std::string &authenticationToken) {
|
||||
emit encryptionChanged(call, on, authenticationToken);
|
||||
}
|
||||
|
||||
void CallModel::onSendMasterKeyChanged(const std::shared_ptr<linphone::Call> &call, const std::string &sendMasterKey) {
|
||||
emit sendMasterKeyChanged(call, sendMasterKey);
|
||||
}
|
||||
|
||||
void CallModel::onReceiveMasterKeyChanged(const std::shared_ptr<linphone::Call> &call,
|
||||
const std::string &receiveMasterKey) {
|
||||
emit receiveMasterKeyChanged(call, receiveMasterKey);
|
||||
}
|
||||
|
||||
void CallModel::onInfoMessageReceived(const std::shared_ptr<linphone::Call> &call,
|
||||
const std::shared_ptr<const linphone::InfoMessage> &message) {
|
||||
emit infoMessageReceived(call, message);
|
||||
}
|
||||
|
||||
void CallModel::onStateChanged(const std::shared_ptr<linphone::Call> &call,
|
||||
linphone::Call::State state,
|
||||
const std::string &message) {
|
||||
emit stateChanged(state, message);
|
||||
}
|
||||
|
||||
void CallModel::onStatsUpdated(const std::shared_ptr<linphone::Call> &call,
|
||||
const std::shared_ptr<const linphone::CallStats> &stats) {
|
||||
emit statsUpdated(call, stats);
|
||||
}
|
||||
|
||||
void CallModel::onTransferStateChanged(const std::shared_ptr<linphone::Call> &call, linphone::Call::State state) {
|
||||
emit transferStateChanged(call, state);
|
||||
}
|
||||
|
||||
void CallModel::onAckProcessing(const std::shared_ptr<linphone::Call> &call,
|
||||
const std::shared_ptr<linphone::Headers> &ack,
|
||||
bool isReceived) {
|
||||
emit ackProcessing(call, ack, isReceived);
|
||||
}
|
||||
|
||||
void CallModel::onTmmbrReceived(const std::shared_ptr<linphone::Call> &call, int streamIndex, int tmmbr) {
|
||||
emit tmmbrReceived(call, streamIndex, tmmbr);
|
||||
}
|
||||
|
||||
void CallModel::onSnapshotTaken(const std::shared_ptr<linphone::Call> &call, const std::string &filePath) {
|
||||
emit snapshotTaken(call, filePath);
|
||||
}
|
||||
|
||||
void CallModel::onNextVideoFrameDecoded(const std::shared_ptr<linphone::Call> &call) {
|
||||
emit nextVideoFrameDecoded(call);
|
||||
}
|
||||
|
||||
void CallModel::onCameraNotWorking(const std::shared_ptr<linphone::Call> &call, const std::string &cameraName) {
|
||||
emit cameraNotWorking(call, cameraName);
|
||||
}
|
||||
|
||||
void CallModel::onVideoDisplayErrorOccurred(const std::shared_ptr<linphone::Call> &call, int errorCode) {
|
||||
emit videoDisplayErrorOccurred(call, errorCode);
|
||||
}
|
||||
|
||||
void CallModel::onAudioDeviceChanged(const std::shared_ptr<linphone::Call> &call,
|
||||
const std::shared_ptr<linphone::AudioDevice> &audioDevice) {
|
||||
emit audioDeviceChanged(call, audioDevice);
|
||||
}
|
||||
|
||||
void CallModel::onRemoteRecording(const std::shared_ptr<linphone::Call> &call, bool recording) {
|
||||
emit remoteRecording(call, recording);
|
||||
}
|
||||
105
Linphone/model/call/CallModel.hpp
Normal file
105
Linphone/model/call/CallModel.hpp
Normal file
|
|
@ -0,0 +1,105 @@
|
|||
/*
|
||||
* 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 CALL_MODEL_H_
|
||||
#define CALL_MODEL_H_
|
||||
|
||||
#include "model/listener/Listener.hpp"
|
||||
#include "tool/AbstractObject.hpp"
|
||||
|
||||
#include <QObject>
|
||||
#include <linphone++/linphone.hh>
|
||||
|
||||
class CallModel : public ::Listener<linphone::Call, linphone::CallListener>,
|
||||
public linphone::CallListener,
|
||||
public AbstractObject {
|
||||
Q_OBJECT
|
||||
public:
|
||||
CallModel(const std::shared_ptr<linphone::Call> &account, QObject *parent = nullptr);
|
||||
~CallModel();
|
||||
|
||||
void accept(bool withVideo);
|
||||
void decline();
|
||||
void terminate();
|
||||
|
||||
private:
|
||||
DECLARE_ABSTRACT_OBJECT
|
||||
|
||||
//--------------------------------------------------------------------------------
|
||||
// LINPHONE
|
||||
//--------------------------------------------------------------------------------
|
||||
virtual void onDtmfReceived(const std::shared_ptr<linphone::Call> &call, int dtmf) override;
|
||||
virtual void onGoclearAckSent(const std::shared_ptr<linphone::Call> &call) override;
|
||||
virtual void onEncryptionChanged(const std::shared_ptr<linphone::Call> &call,
|
||||
bool on,
|
||||
const std::string &authenticationToken) override;
|
||||
virtual void onSendMasterKeyChanged(const std::shared_ptr<linphone::Call> &call,
|
||||
const std::string &sendMasterKey) override;
|
||||
virtual void onReceiveMasterKeyChanged(const std::shared_ptr<linphone::Call> &call,
|
||||
const std::string &receiveMasterKey) override;
|
||||
virtual void onInfoMessageReceived(const std::shared_ptr<linphone::Call> &call,
|
||||
const std::shared_ptr<const linphone::InfoMessage> &message) override;
|
||||
virtual void onStateChanged(const std::shared_ptr<linphone::Call> &call,
|
||||
linphone::Call::State state,
|
||||
const std::string &message) override;
|
||||
virtual void onStatsUpdated(const std::shared_ptr<linphone::Call> &call,
|
||||
const std::shared_ptr<const linphone::CallStats> &stats) override;
|
||||
virtual void onTransferStateChanged(const std::shared_ptr<linphone::Call> &call,
|
||||
linphone::Call::State state) override;
|
||||
virtual void onAckProcessing(const std::shared_ptr<linphone::Call> &call,
|
||||
const std::shared_ptr<linphone::Headers> &ack,
|
||||
bool isReceived) override;
|
||||
virtual void onTmmbrReceived(const std::shared_ptr<linphone::Call> &call, int streamIndex, int tmmbr) override;
|
||||
virtual void onSnapshotTaken(const std::shared_ptr<linphone::Call> &call, const std::string &filePath) override;
|
||||
virtual void onNextVideoFrameDecoded(const std::shared_ptr<linphone::Call> &call) override;
|
||||
virtual void onCameraNotWorking(const std::shared_ptr<linphone::Call> &call,
|
||||
const std::string &cameraName) override;
|
||||
virtual void onVideoDisplayErrorOccurred(const std::shared_ptr<linphone::Call> &call, int errorCode) override;
|
||||
virtual void onAudioDeviceChanged(const std::shared_ptr<linphone::Call> &call,
|
||||
const std::shared_ptr<linphone::AudioDevice> &audioDevice) override;
|
||||
virtual void onRemoteRecording(const std::shared_ptr<linphone::Call> &call, bool recording) override;
|
||||
|
||||
signals:
|
||||
void dtmfReceived(const std::shared_ptr<linphone::Call> &call, int dtmf);
|
||||
void goclearAckSent(const std::shared_ptr<linphone::Call> &call);
|
||||
void
|
||||
encryptionChanged(const std::shared_ptr<linphone::Call> &call, bool on, const std::string &authenticationToken);
|
||||
void sendMasterKeyChanged(const std::shared_ptr<linphone::Call> &call, const std::string &sendMasterKey);
|
||||
void receiveMasterKeyChanged(const std::shared_ptr<linphone::Call> &call, const std::string &receiveMasterKey);
|
||||
void infoMessageReceived(const std::shared_ptr<linphone::Call> &call,
|
||||
const std::shared_ptr<const linphone::InfoMessage> &message);
|
||||
void stateChanged(linphone::Call::State state, const std::string &message);
|
||||
void statsUpdated(const std::shared_ptr<linphone::Call> &call,
|
||||
const std::shared_ptr<const linphone::CallStats> &stats);
|
||||
void transferStateChanged(const std::shared_ptr<linphone::Call> &call, linphone::Call::State state);
|
||||
void ackProcessing(const std::shared_ptr<linphone::Call> &call,
|
||||
const std::shared_ptr<linphone::Headers> &ack,
|
||||
bool isReceived);
|
||||
void tmmbrReceived(const std::shared_ptr<linphone::Call> &call, int streamIndex, int tmmbr);
|
||||
void snapshotTaken(const std::shared_ptr<linphone::Call> &call, const std::string &filePath);
|
||||
void nextVideoFrameDecoded(const std::shared_ptr<linphone::Call> &call);
|
||||
void cameraNotWorking(const std::shared_ptr<linphone::Call> &call, const std::string &cameraName);
|
||||
void videoDisplayErrorOccurred(const std::shared_ptr<linphone::Call> &call, int errorCode);
|
||||
virtual void audioDeviceChanged(const std::shared_ptr<linphone::Call> &call,
|
||||
const std::shared_ptr<linphone::AudioDevice> &audioDevice);
|
||||
void remoteRecording(const std::shared_ptr<linphone::Call> &call, bool recording);
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
@ -1,161 +0,0 @@
|
|||
/*
|
||||
* 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 "CoreListener.hpp"
|
||||
|
||||
// =============================================================================
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
CoreListener::CoreListener(QObject *parent) : QObject(parent) {
|
||||
}
|
||||
CoreListener::~CoreListener() {
|
||||
}
|
||||
|
||||
void CoreListener::onAccountRegistrationStateChanged(const std::shared_ptr<linphone::Core> &core,
|
||||
const std::shared_ptr<linphone::Account> &account,
|
||||
linphone::RegistrationState state,
|
||||
const std::string &message) {
|
||||
emit accountRegistrationStateChanged(core, account, state, message);
|
||||
}
|
||||
void CoreListener::onAuthenticationRequested(const std::shared_ptr<linphone::Core> &core,
|
||||
const std::shared_ptr<linphone::AuthInfo> &authInfo,
|
||||
linphone::AuthMethod method) {
|
||||
emit authenticationRequested(core, authInfo, method);
|
||||
}
|
||||
void CoreListener::onCallEncryptionChanged(const std::shared_ptr<linphone::Core> &core,
|
||||
const std::shared_ptr<linphone::Call> &call,
|
||||
bool on,
|
||||
const std::string &authenticationToken) {
|
||||
emit callEncryptionChanged(core, call, on, authenticationToken);
|
||||
}
|
||||
void CoreListener::onCallLogUpdated(const std::shared_ptr<linphone::Core> &core,
|
||||
const std::shared_ptr<linphone::CallLog> &callLog) {
|
||||
emit callLogUpdated(core, callLog);
|
||||
}
|
||||
void CoreListener::onCallStateChanged(const std::shared_ptr<linphone::Core> &core,
|
||||
const std::shared_ptr<linphone::Call> &call,
|
||||
linphone::Call::State state,
|
||||
const std::string &message) {
|
||||
emit callStateChanged(core, call, state, message);
|
||||
}
|
||||
void CoreListener::onCallStatsUpdated(const std::shared_ptr<linphone::Core> &core,
|
||||
const std::shared_ptr<linphone::Call> &call,
|
||||
const std::shared_ptr<const linphone::CallStats> &stats) {
|
||||
emit callStatsUpdated(core, call, stats);
|
||||
}
|
||||
void CoreListener::onCallCreated(const std::shared_ptr<linphone::Core> &lc,
|
||||
const std::shared_ptr<linphone::Call> &call) {
|
||||
emit callCreated(lc, call);
|
||||
}
|
||||
void CoreListener::onChatRoomRead(const std::shared_ptr<linphone::Core> &core,
|
||||
const std::shared_ptr<linphone::ChatRoom> &chatRoom) {
|
||||
emit chatRoomRead(core, chatRoom);
|
||||
}
|
||||
void CoreListener::onChatRoomStateChanged(const std::shared_ptr<linphone::Core> &core,
|
||||
const std::shared_ptr<linphone::ChatRoom> &chatRoom,
|
||||
linphone::ChatRoom::State state) {
|
||||
emit chatRoomStateChanged(core, chatRoom, state);
|
||||
}
|
||||
void CoreListener::onConferenceInfoReceived(const std::shared_ptr<linphone::Core> &core,
|
||||
const std::shared_ptr<const linphone::ConferenceInfo> &conferenceInfo) {
|
||||
emit conferenceInfoReceived(core, conferenceInfo);
|
||||
}
|
||||
void CoreListener::onConfiguringStatus(const std::shared_ptr<linphone::Core> &core,
|
||||
linphone::Config::ConfiguringState status,
|
||||
const std::string &message) {
|
||||
emit configuringStatus(core, status, message);
|
||||
}
|
||||
void CoreListener::onDtmfReceived(const std::shared_ptr<linphone::Core> &lc,
|
||||
const std::shared_ptr<linphone::Call> &call,
|
||||
int dtmf) {
|
||||
emit dtmfReceived(lc, call, dtmf);
|
||||
}
|
||||
void CoreListener::onEcCalibrationResult(const std::shared_ptr<linphone::Core> &core,
|
||||
linphone::EcCalibratorStatus status,
|
||||
int delayMs) {
|
||||
emit ecCalibrationResult(core, status, delayMs);
|
||||
}
|
||||
void CoreListener::onGlobalStateChanged(const std::shared_ptr<linphone::Core> &core,
|
||||
linphone::GlobalState gstate,
|
||||
const std::string &message) {
|
||||
emit globalStateChanged(core, gstate, message);
|
||||
}
|
||||
void CoreListener::onIsComposingReceived(const std::shared_ptr<linphone::Core> &core,
|
||||
const std::shared_ptr<linphone::ChatRoom> &room) {
|
||||
emit isComposingReceived(core, room);
|
||||
}
|
||||
void CoreListener::onLogCollectionUploadStateChanged(const std::shared_ptr<linphone::Core> &core,
|
||||
linphone::Core::LogCollectionUploadState state,
|
||||
const std::string &info) {
|
||||
emit logCollectionUploadStateChanged(core, state, info);
|
||||
}
|
||||
void CoreListener::onLogCollectionUploadProgressIndication(const std::shared_ptr<linphone::Core> &lc,
|
||||
size_t offset,
|
||||
size_t total) {
|
||||
emit logCollectionUploadProgressIndication(lc, offset, total);
|
||||
}
|
||||
void CoreListener::onMessageReceived(const std::shared_ptr<linphone::Core> &core,
|
||||
const std::shared_ptr<linphone::ChatRoom> &room,
|
||||
const std::shared_ptr<linphone::ChatMessage> &message) {
|
||||
emit messageReceived(core, room, message);
|
||||
}
|
||||
void CoreListener::onMessagesReceived(const std::shared_ptr<linphone::Core> &core,
|
||||
const std::shared_ptr<linphone::ChatRoom> &room,
|
||||
const std::list<std::shared_ptr<linphone::ChatMessage>> &messages) {
|
||||
emit messagesReceived(core, room, messages);
|
||||
}
|
||||
void CoreListener::onNewMessageReaction(const std::shared_ptr<linphone::Core> &core,
|
||||
const std::shared_ptr<linphone::ChatRoom> &chatRoom,
|
||||
const std::shared_ptr<linphone::ChatMessage> &message,
|
||||
const std::shared_ptr<const linphone::ChatMessageReaction> &reaction) {
|
||||
emit newMessageReaction(core, chatRoom, message, reaction);
|
||||
}
|
||||
void CoreListener::onNotifyPresenceReceivedForUriOrTel(
|
||||
const std::shared_ptr<linphone::Core> &core,
|
||||
const std::shared_ptr<linphone::Friend> &linphoneFriend,
|
||||
const std::string &uriOrTel,
|
||||
const std::shared_ptr<const linphone::PresenceModel> &presenceModel) {
|
||||
emit notifyPresenceReceivedForUriOrTel(core, linphoneFriend, uriOrTel, presenceModel);
|
||||
}
|
||||
void CoreListener::onNotifyPresenceReceived(const std::shared_ptr<linphone::Core> &core,
|
||||
const std::shared_ptr<linphone::Friend> &linphoneFriend) {
|
||||
emit notifyPresenceReceived(core, linphoneFriend);
|
||||
}
|
||||
void CoreListener::onQrcodeFound(const std::shared_ptr<linphone::Core> &core, const std::string &result) {
|
||||
emit qrcodeFound(core, result);
|
||||
}
|
||||
void CoreListener::onReactionRemoved(const std::shared_ptr<linphone::Core> &core,
|
||||
const std::shared_ptr<linphone::ChatRoom> &chatRoom,
|
||||
const std::shared_ptr<linphone::ChatMessage> &message,
|
||||
const std::shared_ptr<const linphone::Address> &address) {
|
||||
emit reactionRemoved(core, chatRoom, message, address);
|
||||
}
|
||||
void CoreListener::onTransferStateChanged(const std::shared_ptr<linphone::Core> &core,
|
||||
const std::shared_ptr<linphone::Call> &call,
|
||||
linphone::Call::State state) {
|
||||
emit transferStateChanged(core, call, state);
|
||||
}
|
||||
void CoreListener::onVersionUpdateCheckResultReceived(const std::shared_ptr<linphone::Core> &core,
|
||||
linphone::VersionUpdateCheckResult result,
|
||||
const std::string &version,
|
||||
const std::string &url) {
|
||||
emit versionUpdateCheckResultReceived(core, result, version, url);
|
||||
}
|
||||
|
|
@ -1,187 +0,0 @@
|
|||
/*
|
||||
* 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 CORE_LISTENER_H_
|
||||
#define CORE_LISTENER_H_
|
||||
|
||||
#include <QObject>
|
||||
#include <linphone++/linphone.hh>
|
||||
|
||||
// =============================================================================
|
||||
|
||||
class CoreListener : public QObject, public linphone::CoreListener {
|
||||
Q_OBJECT
|
||||
public:
|
||||
CoreListener(QObject *parent = nullptr);
|
||||
virtual ~CoreListener();
|
||||
|
||||
virtual void onAccountRegistrationStateChanged(const std::shared_ptr<linphone::Core> &core,
|
||||
const std::shared_ptr<linphone::Account> &account,
|
||||
linphone::RegistrationState state,
|
||||
const std::string &message) override;
|
||||
virtual void onAuthenticationRequested(const std::shared_ptr<linphone::Core> &core,
|
||||
const std::shared_ptr<linphone::AuthInfo> &authInfo,
|
||||
linphone::AuthMethod method) override;
|
||||
virtual void onCallEncryptionChanged(const std::shared_ptr<linphone::Core> &core,
|
||||
const std::shared_ptr<linphone::Call> &call,
|
||||
bool on,
|
||||
const std::string &authenticationToken) override;
|
||||
virtual void onCallLogUpdated(const std::shared_ptr<linphone::Core> &core,
|
||||
const std::shared_ptr<linphone::CallLog> &callLog) override;
|
||||
virtual void onCallStateChanged(const std::shared_ptr<linphone::Core> &core,
|
||||
const std::shared_ptr<linphone::Call> &call,
|
||||
linphone::Call::State state,
|
||||
const std::string &message) override;
|
||||
virtual void onCallStatsUpdated(const std::shared_ptr<linphone::Core> &core,
|
||||
const std::shared_ptr<linphone::Call> &call,
|
||||
const std::shared_ptr<const linphone::CallStats> &stats) override;
|
||||
virtual void onCallCreated(const std::shared_ptr<linphone::Core> &lc,
|
||||
const std::shared_ptr<linphone::Call> &call) override;
|
||||
virtual void onChatRoomRead(const std::shared_ptr<linphone::Core> &core,
|
||||
const std::shared_ptr<linphone::ChatRoom> &chatRoom) override;
|
||||
virtual void onChatRoomStateChanged(const std::shared_ptr<linphone::Core> &core,
|
||||
const std::shared_ptr<linphone::ChatRoom> &chatRoom,
|
||||
linphone::ChatRoom::State state) override;
|
||||
virtual void
|
||||
onConferenceInfoReceived(const std::shared_ptr<linphone::Core> &core,
|
||||
const std::shared_ptr<const linphone::ConferenceInfo> &conferenceInfo) override;
|
||||
virtual void onConfiguringStatus(const std::shared_ptr<linphone::Core> &core,
|
||||
linphone::Config::ConfiguringState status,
|
||||
const std::string &message) override;
|
||||
virtual void onDtmfReceived(const std::shared_ptr<linphone::Core> &lc,
|
||||
const std::shared_ptr<linphone::Call> &call,
|
||||
int dtmf) override;
|
||||
virtual void onEcCalibrationResult(const std::shared_ptr<linphone::Core> &core,
|
||||
linphone::EcCalibratorStatus status,
|
||||
int delayMs) override;
|
||||
virtual void onGlobalStateChanged(const std::shared_ptr<linphone::Core> &core,
|
||||
linphone::GlobalState gstate,
|
||||
const std::string &message) override;
|
||||
virtual void onIsComposingReceived(const std::shared_ptr<linphone::Core> &core,
|
||||
const std::shared_ptr<linphone::ChatRoom> &room) override;
|
||||
virtual void onLogCollectionUploadStateChanged(const std::shared_ptr<linphone::Core> &core,
|
||||
linphone::Core::LogCollectionUploadState state,
|
||||
const std::string &info) override;
|
||||
virtual void onLogCollectionUploadProgressIndication(const std::shared_ptr<linphone::Core> &lc,
|
||||
size_t offset,
|
||||
size_t total) override;
|
||||
virtual void onMessageReceived(const std::shared_ptr<linphone::Core> &core,
|
||||
const std::shared_ptr<linphone::ChatRoom> &room,
|
||||
const std::shared_ptr<linphone::ChatMessage> &message) override;
|
||||
virtual void onMessagesReceived(const std::shared_ptr<linphone::Core> &core,
|
||||
const std::shared_ptr<linphone::ChatRoom> &room,
|
||||
const std::list<std::shared_ptr<linphone::ChatMessage>> &messages) override;
|
||||
virtual void onNewMessageReaction(const std::shared_ptr<linphone::Core> &core,
|
||||
const std::shared_ptr<linphone::ChatRoom> &chatRoom,
|
||||
const std::shared_ptr<linphone::ChatMessage> &message,
|
||||
const std::shared_ptr<const linphone::ChatMessageReaction> &reaction) override;
|
||||
virtual void
|
||||
onNotifyPresenceReceivedForUriOrTel(const std::shared_ptr<linphone::Core> &core,
|
||||
const std::shared_ptr<linphone::Friend> &linphoneFriend,
|
||||
const std::string &uriOrTel,
|
||||
const std::shared_ptr<const linphone::PresenceModel> &presenceModel) override;
|
||||
virtual void onNotifyPresenceReceived(const std::shared_ptr<linphone::Core> &core,
|
||||
const std::shared_ptr<linphone::Friend> &linphoneFriend) override;
|
||||
virtual void onQrcodeFound(const std::shared_ptr<linphone::Core> &core, const std::string &result) override;
|
||||
virtual void onReactionRemoved(const std::shared_ptr<linphone::Core> &core,
|
||||
const std::shared_ptr<linphone::ChatRoom> &chatRoom,
|
||||
const std::shared_ptr<linphone::ChatMessage> &message,
|
||||
const std::shared_ptr<const linphone::Address> &address) override;
|
||||
virtual void onTransferStateChanged(const std::shared_ptr<linphone::Core> &core,
|
||||
const std::shared_ptr<linphone::Call> &call,
|
||||
linphone::Call::State state) override;
|
||||
virtual void onVersionUpdateCheckResultReceived(const std::shared_ptr<linphone::Core> &core,
|
||||
linphone::VersionUpdateCheckResult result,
|
||||
const std::string &version,
|
||||
const std::string &url) override;
|
||||
|
||||
signals:
|
||||
void accountRegistrationStateChanged(const std::shared_ptr<linphone::Core> &core,
|
||||
const std::shared_ptr<linphone::Account> &account,
|
||||
linphone::RegistrationState state,
|
||||
const std::string &message);
|
||||
void authenticationRequested(const std::shared_ptr<linphone::Core> &core,
|
||||
const std::shared_ptr<linphone::AuthInfo> &authInfo,
|
||||
linphone::AuthMethod method);
|
||||
void callEncryptionChanged(const std::shared_ptr<linphone::Core> &core,
|
||||
const std::shared_ptr<linphone::Call> &call,
|
||||
bool on,
|
||||
const std::string &authenticationToken);
|
||||
void callLogUpdated(const std::shared_ptr<linphone::Core> &core, const std::shared_ptr<linphone::CallLog> &callLog);
|
||||
void callStateChanged(const std::shared_ptr<linphone::Core> &core,
|
||||
const std::shared_ptr<linphone::Call> &call,
|
||||
linphone::Call::State state,
|
||||
const std::string &message);
|
||||
void callStatsUpdated(const std::shared_ptr<linphone::Core> &core,
|
||||
const std::shared_ptr<linphone::Call> &call,
|
||||
const std::shared_ptr<const linphone::CallStats> &stats);
|
||||
void callCreated(const std::shared_ptr<linphone::Core> &lc, const std::shared_ptr<linphone::Call> &call);
|
||||
void chatRoomRead(const std::shared_ptr<linphone::Core> &core, const std::shared_ptr<linphone::ChatRoom> &chatRoom);
|
||||
void chatRoomStateChanged(const std::shared_ptr<linphone::Core> &core,
|
||||
const std::shared_ptr<linphone::ChatRoom> &chatRoom,
|
||||
linphone::ChatRoom::State state);
|
||||
void conferenceInfoReceived(const std::shared_ptr<linphone::Core> &core,
|
||||
const std::shared_ptr<const linphone::ConferenceInfo> &conferenceInfo);
|
||||
void configuringStatus(const std::shared_ptr<linphone::Core> &core,
|
||||
linphone::Config::ConfiguringState status,
|
||||
const std::string &message);
|
||||
void dtmfReceived(const std::shared_ptr<linphone::Core> &lc, const std::shared_ptr<linphone::Call> &call, int dtmf);
|
||||
void
|
||||
ecCalibrationResult(const std::shared_ptr<linphone::Core> &core, linphone::EcCalibratorStatus status, int delayMs);
|
||||
void globalStateChanged(const std::shared_ptr<linphone::Core> &core,
|
||||
linphone::GlobalState gstate,
|
||||
const std::string &message);
|
||||
void isComposingReceived(const std::shared_ptr<linphone::Core> &core,
|
||||
const std::shared_ptr<linphone::ChatRoom> &room);
|
||||
void logCollectionUploadStateChanged(const std::shared_ptr<linphone::Core> &core,
|
||||
linphone::Core::LogCollectionUploadState state,
|
||||
const std::string &info);
|
||||
void logCollectionUploadProgressIndication(const std::shared_ptr<linphone::Core> &lc, size_t offset, size_t total);
|
||||
void messageReceived(const std::shared_ptr<linphone::Core> &core,
|
||||
const std::shared_ptr<linphone::ChatRoom> &room,
|
||||
const std::shared_ptr<linphone::ChatMessage> &message);
|
||||
void messagesReceived(const std::shared_ptr<linphone::Core> &core,
|
||||
const std::shared_ptr<linphone::ChatRoom> &room,
|
||||
const std::list<std::shared_ptr<linphone::ChatMessage>> &messages);
|
||||
void newMessageReaction(const std::shared_ptr<linphone::Core> &core,
|
||||
const std::shared_ptr<linphone::ChatRoom> &chatRoom,
|
||||
const std::shared_ptr<linphone::ChatMessage> &message,
|
||||
const std::shared_ptr<const linphone::ChatMessageReaction> &reaction);
|
||||
void notifyPresenceReceivedForUriOrTel(const std::shared_ptr<linphone::Core> &core,
|
||||
const std::shared_ptr<linphone::Friend> &linphoneFriend,
|
||||
const std::string &uriOrTel,
|
||||
const std::shared_ptr<const linphone::PresenceModel> &presenceModel);
|
||||
void notifyPresenceReceived(const std::shared_ptr<linphone::Core> &core,
|
||||
const std::shared_ptr<linphone::Friend> &linphoneFriend);
|
||||
void qrcodeFound(const std::shared_ptr<linphone::Core> &core, const std::string &result);
|
||||
void reactionRemoved(const std::shared_ptr<linphone::Core> &core,
|
||||
const std::shared_ptr<linphone::ChatRoom> &chatRoom,
|
||||
const std::shared_ptr<linphone::ChatMessage> &message,
|
||||
const std::shared_ptr<const linphone::Address> &address);
|
||||
void transferStateChanged(const std::shared_ptr<linphone::Core> &core,
|
||||
const std::shared_ptr<linphone::Call> &call,
|
||||
linphone::Call::State state);
|
||||
void versionUpdateCheckResultReceived(const std::shared_ptr<linphone::Core> &core,
|
||||
linphone::VersionUpdateCheckResult result,
|
||||
const std::string &version,
|
||||
const std::string &url);
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
@ -28,14 +28,17 @@
|
|||
#include <QTimer>
|
||||
|
||||
#include "core/App.hpp"
|
||||
#include "core/notifier/Notifier.hpp"
|
||||
#include "core/path/Paths.hpp"
|
||||
#include "tool/Utils.hpp"
|
||||
|
||||
// =============================================================================
|
||||
DEFINE_ABSTRACT_OBJECT(CoreModel)
|
||||
|
||||
QSharedPointer<CoreModel> CoreModel::gCoreModel;
|
||||
std::shared_ptr<CoreModel> CoreModel::gCoreModel;
|
||||
|
||||
CoreModel::CoreModel(const QString &configPath, QThread *parent) : QObject() {
|
||||
CoreModel::CoreModel(const QString &configPath, QThread *parent)
|
||||
: ::Listener<linphone::Core, linphone::CoreListener>(nullptr, parent) {
|
||||
connect(parent, &QThread::finished, this, [this]() {
|
||||
// Model thread
|
||||
if (mCore && mCore->getGlobalState() == linphone::GlobalState::On) mCore->stop();
|
||||
|
|
@ -50,8 +53,9 @@ CoreModel::CoreModel(const QString &configPath, QThread *parent) : QObject() {
|
|||
CoreModel::~CoreModel() {
|
||||
}
|
||||
|
||||
QSharedPointer<CoreModel> CoreModel::create(const QString &configPath, QThread *parent) {
|
||||
auto model = QSharedPointer<CoreModel>::create(configPath, parent);
|
||||
std::shared_ptr<CoreModel> CoreModel::create(const QString &configPath, QThread *parent) {
|
||||
auto model = std::make_shared<CoreModel>(configPath, parent);
|
||||
model->setSelf(model);
|
||||
gCoreModel = model;
|
||||
return model;
|
||||
}
|
||||
|
|
@ -64,6 +68,7 @@ void CoreModel::start() {
|
|||
mCore =
|
||||
linphone::Factory::get()->createCore(Utils::appStringToCoreString(Paths::getConfigFilePath(mConfigPath)),
|
||||
Utils::appStringToCoreString(Paths::getFactoryConfigFilePath()), nullptr);
|
||||
setMonitor(mCore);
|
||||
setPathsAfterCreation();
|
||||
mCore->start();
|
||||
setPathAfterStart();
|
||||
|
|
@ -71,7 +76,7 @@ void CoreModel::start() {
|
|||
}
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
QSharedPointer<CoreModel> CoreModel::getInstance() {
|
||||
std::shared_ptr<CoreModel> CoreModel::getInstance() {
|
||||
return gCoreModel;
|
||||
}
|
||||
|
||||
|
|
@ -131,3 +136,138 @@ void CoreModel::setPathAfterStart() {
|
|||
mCore->setRootCa(Utils::appStringToCoreString(Paths::getRootCaFilePath()));
|
||||
qInfo() << "[CoreModel] Using RootCa path : " << QString::fromStdString(mCore->getRootCa());
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------------------------------------------------------
|
||||
|
||||
void CoreModel::onAccountRegistrationStateChanged(const std::shared_ptr<linphone::Core> &core,
|
||||
const std::shared_ptr<linphone::Account> &account,
|
||||
linphone::RegistrationState state,
|
||||
const std::string &message) {
|
||||
emit accountRegistrationStateChanged(core, account, state, message);
|
||||
}
|
||||
void CoreModel::onAuthenticationRequested(const std::shared_ptr<linphone::Core> &core,
|
||||
const std::shared_ptr<linphone::AuthInfo> &authInfo,
|
||||
linphone::AuthMethod method) {
|
||||
emit authenticationRequested(core, authInfo, method);
|
||||
}
|
||||
void CoreModel::onCallEncryptionChanged(const std::shared_ptr<linphone::Core> &core,
|
||||
const std::shared_ptr<linphone::Call> &call,
|
||||
bool on,
|
||||
const std::string &authenticationToken) {
|
||||
emit callEncryptionChanged(core, call, on, authenticationToken);
|
||||
}
|
||||
void CoreModel::onCallLogUpdated(const std::shared_ptr<linphone::Core> &core,
|
||||
const std::shared_ptr<linphone::CallLog> &callLog) {
|
||||
emit callLogUpdated(core, callLog);
|
||||
}
|
||||
void CoreModel::onCallStateChanged(const std::shared_ptr<linphone::Core> &core,
|
||||
const std::shared_ptr<linphone::Call> &call,
|
||||
linphone::Call::State state,
|
||||
const std::string &message) {
|
||||
if (state == linphone::Call::State::IncomingReceived) {
|
||||
App::getInstance()->getNotifier()->notifyReceivedCall(call);
|
||||
}
|
||||
emit callStateChanged(core, call, state, message);
|
||||
}
|
||||
void CoreModel::onCallStatsUpdated(const std::shared_ptr<linphone::Core> &core,
|
||||
const std::shared_ptr<linphone::Call> &call,
|
||||
const std::shared_ptr<const linphone::CallStats> &stats) {
|
||||
emit callStatsUpdated(core, call, stats);
|
||||
}
|
||||
void CoreModel::onCallCreated(const std::shared_ptr<linphone::Core> &lc, const std::shared_ptr<linphone::Call> &call) {
|
||||
emit callCreated(lc, call);
|
||||
}
|
||||
void CoreModel::onChatRoomRead(const std::shared_ptr<linphone::Core> &core,
|
||||
const std::shared_ptr<linphone::ChatRoom> &chatRoom) {
|
||||
emit chatRoomRead(core, chatRoom);
|
||||
}
|
||||
void CoreModel::onChatRoomStateChanged(const std::shared_ptr<linphone::Core> &core,
|
||||
const std::shared_ptr<linphone::ChatRoom> &chatRoom,
|
||||
linphone::ChatRoom::State state) {
|
||||
emit chatRoomStateChanged(core, chatRoom, state);
|
||||
}
|
||||
void CoreModel::onConferenceInfoReceived(const std::shared_ptr<linphone::Core> &core,
|
||||
const std::shared_ptr<const linphone::ConferenceInfo> &conferenceInfo) {
|
||||
emit conferenceInfoReceived(core, conferenceInfo);
|
||||
}
|
||||
void CoreModel::onConfiguringStatus(const std::shared_ptr<linphone::Core> &core,
|
||||
linphone::Config::ConfiguringState status,
|
||||
const std::string &message) {
|
||||
emit configuringStatus(core, status, message);
|
||||
}
|
||||
void CoreModel::onDtmfReceived(const std::shared_ptr<linphone::Core> &lc,
|
||||
const std::shared_ptr<linphone::Call> &call,
|
||||
int dtmf) {
|
||||
emit dtmfReceived(lc, call, dtmf);
|
||||
}
|
||||
void CoreModel::onEcCalibrationResult(const std::shared_ptr<linphone::Core> &core,
|
||||
linphone::EcCalibratorStatus status,
|
||||
int delayMs) {
|
||||
emit ecCalibrationResult(core, status, delayMs);
|
||||
}
|
||||
void CoreModel::onGlobalStateChanged(const std::shared_ptr<linphone::Core> &core,
|
||||
linphone::GlobalState gstate,
|
||||
const std::string &message) {
|
||||
emit globalStateChanged(core, gstate, message);
|
||||
}
|
||||
void CoreModel::onIsComposingReceived(const std::shared_ptr<linphone::Core> &core,
|
||||
const std::shared_ptr<linphone::ChatRoom> &room) {
|
||||
emit isComposingReceived(core, room);
|
||||
}
|
||||
void CoreModel::onLogCollectionUploadStateChanged(const std::shared_ptr<linphone::Core> &core,
|
||||
linphone::Core::LogCollectionUploadState state,
|
||||
const std::string &info) {
|
||||
emit logCollectionUploadStateChanged(core, state, info);
|
||||
}
|
||||
void CoreModel::onLogCollectionUploadProgressIndication(const std::shared_ptr<linphone::Core> &lc,
|
||||
size_t offset,
|
||||
size_t total) {
|
||||
emit logCollectionUploadProgressIndication(lc, offset, total);
|
||||
}
|
||||
void CoreModel::onMessageReceived(const std::shared_ptr<linphone::Core> &core,
|
||||
const std::shared_ptr<linphone::ChatRoom> &room,
|
||||
const std::shared_ptr<linphone::ChatMessage> &message) {
|
||||
emit messageReceived(core, room, message);
|
||||
}
|
||||
void CoreModel::onMessagesReceived(const std::shared_ptr<linphone::Core> &core,
|
||||
const std::shared_ptr<linphone::ChatRoom> &room,
|
||||
const std::list<std::shared_ptr<linphone::ChatMessage>> &messages) {
|
||||
emit messagesReceived(core, room, messages);
|
||||
}
|
||||
void CoreModel::onNewMessageReaction(const std::shared_ptr<linphone::Core> &core,
|
||||
const std::shared_ptr<linphone::ChatRoom> &chatRoom,
|
||||
const std::shared_ptr<linphone::ChatMessage> &message,
|
||||
const std::shared_ptr<const linphone::ChatMessageReaction> &reaction) {
|
||||
emit newMessageReaction(core, chatRoom, message, reaction);
|
||||
}
|
||||
void CoreModel::onNotifyPresenceReceivedForUriOrTel(
|
||||
const std::shared_ptr<linphone::Core> &core,
|
||||
const std::shared_ptr<linphone::Friend> &linphoneFriend,
|
||||
const std::string &uriOrTel,
|
||||
const std::shared_ptr<const linphone::PresenceModel> &presenceModel) {
|
||||
emit notifyPresenceReceivedForUriOrTel(core, linphoneFriend, uriOrTel, presenceModel);
|
||||
}
|
||||
void CoreModel::onNotifyPresenceReceived(const std::shared_ptr<linphone::Core> &core,
|
||||
const std::shared_ptr<linphone::Friend> &linphoneFriend) {
|
||||
emit notifyPresenceReceived(core, linphoneFriend);
|
||||
}
|
||||
void CoreModel::onQrcodeFound(const std::shared_ptr<linphone::Core> &core, const std::string &result) {
|
||||
emit qrcodeFound(core, result);
|
||||
}
|
||||
void CoreModel::onReactionRemoved(const std::shared_ptr<linphone::Core> &core,
|
||||
const std::shared_ptr<linphone::ChatRoom> &chatRoom,
|
||||
const std::shared_ptr<linphone::ChatMessage> &message,
|
||||
const std::shared_ptr<const linphone::Address> &address) {
|
||||
emit reactionRemoved(core, chatRoom, message, address);
|
||||
}
|
||||
void CoreModel::onTransferStateChanged(const std::shared_ptr<linphone::Core> &core,
|
||||
const std::shared_ptr<linphone::Call> &call,
|
||||
linphone::Call::State state) {
|
||||
emit transferStateChanged(core, call, state);
|
||||
}
|
||||
void CoreModel::onVersionUpdateCheckResultReceived(const std::shared_ptr<linphone::Core> &core,
|
||||
linphone::VersionUpdateCheckResult result,
|
||||
const std::string &version,
|
||||
const std::string &url) {
|
||||
emit versionUpdateCheckResultReceived(core, result, version, url);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -28,17 +28,21 @@
|
|||
#include <QTimer>
|
||||
#include <linphone++/linphone.hh>
|
||||
|
||||
#include "model/listener/Listener.hpp"
|
||||
#include "model/logger/LoggerModel.hpp"
|
||||
#include "tool/AbstractObject.hpp"
|
||||
|
||||
// =============================================================================
|
||||
|
||||
class CoreModel : public QObject {
|
||||
class CoreModel : public ::Listener<linphone::Core, linphone::CoreListener>,
|
||||
public linphone::CoreListener,
|
||||
public AbstractObject {
|
||||
Q_OBJECT
|
||||
public:
|
||||
CoreModel(const QString &configPath, QThread *parent);
|
||||
~CoreModel();
|
||||
static QSharedPointer<CoreModel> create(const QString &configPath, QThread *parent);
|
||||
static QSharedPointer<CoreModel> getInstance();
|
||||
static std::shared_ptr<CoreModel> create(const QString &configPath, QThread *parent);
|
||||
static std::shared_ptr<CoreModel> getInstance();
|
||||
|
||||
std::shared_ptr<linphone::Core> getCore();
|
||||
|
||||
|
|
@ -61,7 +65,162 @@ private:
|
|||
void setPathsAfterCreation();
|
||||
void setPathAfterStart();
|
||||
|
||||
static QSharedPointer<CoreModel> gCoreModel;
|
||||
static std::shared_ptr<CoreModel> gCoreModel;
|
||||
|
||||
DECLARE_ABSTRACT_OBJECT
|
||||
//--------------------------------------------------------------------------------
|
||||
// LINPHONE
|
||||
//--------------------------------------------------------------------------------
|
||||
virtual void onAccountRegistrationStateChanged(const std::shared_ptr<linphone::Core> &core,
|
||||
const std::shared_ptr<linphone::Account> &account,
|
||||
linphone::RegistrationState state,
|
||||
const std::string &message) override;
|
||||
virtual void onAuthenticationRequested(const std::shared_ptr<linphone::Core> &core,
|
||||
const std::shared_ptr<linphone::AuthInfo> &authInfo,
|
||||
linphone::AuthMethod method) override;
|
||||
virtual void onCallEncryptionChanged(const std::shared_ptr<linphone::Core> &core,
|
||||
const std::shared_ptr<linphone::Call> &call,
|
||||
bool on,
|
||||
const std::string &authenticationToken) override;
|
||||
virtual void onCallLogUpdated(const std::shared_ptr<linphone::Core> &core,
|
||||
const std::shared_ptr<linphone::CallLog> &callLog) override;
|
||||
virtual void onCallStateChanged(const std::shared_ptr<linphone::Core> &core,
|
||||
const std::shared_ptr<linphone::Call> &call,
|
||||
linphone::Call::State state,
|
||||
const std::string &message) override;
|
||||
virtual void onCallStatsUpdated(const std::shared_ptr<linphone::Core> &core,
|
||||
const std::shared_ptr<linphone::Call> &call,
|
||||
const std::shared_ptr<const linphone::CallStats> &stats) override;
|
||||
virtual void onCallCreated(const std::shared_ptr<linphone::Core> &lc,
|
||||
const std::shared_ptr<linphone::Call> &call) override;
|
||||
virtual void onChatRoomRead(const std::shared_ptr<linphone::Core> &core,
|
||||
const std::shared_ptr<linphone::ChatRoom> &chatRoom) override;
|
||||
virtual void onChatRoomStateChanged(const std::shared_ptr<linphone::Core> &core,
|
||||
const std::shared_ptr<linphone::ChatRoom> &chatRoom,
|
||||
linphone::ChatRoom::State state) override;
|
||||
virtual void
|
||||
onConferenceInfoReceived(const std::shared_ptr<linphone::Core> &core,
|
||||
const std::shared_ptr<const linphone::ConferenceInfo> &conferenceInfo) override;
|
||||
virtual void onConfiguringStatus(const std::shared_ptr<linphone::Core> &core,
|
||||
linphone::Config::ConfiguringState status,
|
||||
const std::string &message) override;
|
||||
virtual void onDtmfReceived(const std::shared_ptr<linphone::Core> &lc,
|
||||
const std::shared_ptr<linphone::Call> &call,
|
||||
int dtmf) override;
|
||||
virtual void onEcCalibrationResult(const std::shared_ptr<linphone::Core> &core,
|
||||
linphone::EcCalibratorStatus status,
|
||||
int delayMs) override;
|
||||
virtual void onGlobalStateChanged(const std::shared_ptr<linphone::Core> &core,
|
||||
linphone::GlobalState gstate,
|
||||
const std::string &message) override;
|
||||
virtual void onIsComposingReceived(const std::shared_ptr<linphone::Core> &core,
|
||||
const std::shared_ptr<linphone::ChatRoom> &room) override;
|
||||
virtual void onLogCollectionUploadStateChanged(const std::shared_ptr<linphone::Core> &core,
|
||||
linphone::Core::LogCollectionUploadState state,
|
||||
const std::string &info) override;
|
||||
virtual void onLogCollectionUploadProgressIndication(const std::shared_ptr<linphone::Core> &lc,
|
||||
size_t offset,
|
||||
size_t total) override;
|
||||
virtual void onMessageReceived(const std::shared_ptr<linphone::Core> &core,
|
||||
const std::shared_ptr<linphone::ChatRoom> &room,
|
||||
const std::shared_ptr<linphone::ChatMessage> &message) override;
|
||||
virtual void onMessagesReceived(const std::shared_ptr<linphone::Core> &core,
|
||||
const std::shared_ptr<linphone::ChatRoom> &room,
|
||||
const std::list<std::shared_ptr<linphone::ChatMessage>> &messages) override;
|
||||
virtual void onNewMessageReaction(const std::shared_ptr<linphone::Core> &core,
|
||||
const std::shared_ptr<linphone::ChatRoom> &chatRoom,
|
||||
const std::shared_ptr<linphone::ChatMessage> &message,
|
||||
const std::shared_ptr<const linphone::ChatMessageReaction> &reaction) override;
|
||||
virtual void
|
||||
onNotifyPresenceReceivedForUriOrTel(const std::shared_ptr<linphone::Core> &core,
|
||||
const std::shared_ptr<linphone::Friend> &linphoneFriend,
|
||||
const std::string &uriOrTel,
|
||||
const std::shared_ptr<const linphone::PresenceModel> &presenceModel) override;
|
||||
virtual void onNotifyPresenceReceived(const std::shared_ptr<linphone::Core> &core,
|
||||
const std::shared_ptr<linphone::Friend> &linphoneFriend) override;
|
||||
virtual void onQrcodeFound(const std::shared_ptr<linphone::Core> &core, const std::string &result) override;
|
||||
virtual void onReactionRemoved(const std::shared_ptr<linphone::Core> &core,
|
||||
const std::shared_ptr<linphone::ChatRoom> &chatRoom,
|
||||
const std::shared_ptr<linphone::ChatMessage> &message,
|
||||
const std::shared_ptr<const linphone::Address> &address) override;
|
||||
virtual void onTransferStateChanged(const std::shared_ptr<linphone::Core> &core,
|
||||
const std::shared_ptr<linphone::Call> &call,
|
||||
linphone::Call::State state) override;
|
||||
virtual void onVersionUpdateCheckResultReceived(const std::shared_ptr<linphone::Core> &core,
|
||||
linphone::VersionUpdateCheckResult result,
|
||||
const std::string &version,
|
||||
const std::string &url) override;
|
||||
|
||||
signals:
|
||||
void accountRegistrationStateChanged(const std::shared_ptr<linphone::Core> &core,
|
||||
const std::shared_ptr<linphone::Account> &account,
|
||||
linphone::RegistrationState state,
|
||||
const std::string &message);
|
||||
void authenticationRequested(const std::shared_ptr<linphone::Core> &core,
|
||||
const std::shared_ptr<linphone::AuthInfo> &authInfo,
|
||||
linphone::AuthMethod method);
|
||||
void callEncryptionChanged(const std::shared_ptr<linphone::Core> &core,
|
||||
const std::shared_ptr<linphone::Call> &call,
|
||||
bool on,
|
||||
const std::string &authenticationToken);
|
||||
void callLogUpdated(const std::shared_ptr<linphone::Core> &core, const std::shared_ptr<linphone::CallLog> &callLog);
|
||||
void callStateChanged(const std::shared_ptr<linphone::Core> &core,
|
||||
const std::shared_ptr<linphone::Call> &call,
|
||||
linphone::Call::State state,
|
||||
const std::string &message);
|
||||
void callStatsUpdated(const std::shared_ptr<linphone::Core> &core,
|
||||
const std::shared_ptr<linphone::Call> &call,
|
||||
const std::shared_ptr<const linphone::CallStats> &stats);
|
||||
void callCreated(const std::shared_ptr<linphone::Core> &lc, const std::shared_ptr<linphone::Call> &call);
|
||||
void chatRoomRead(const std::shared_ptr<linphone::Core> &core, const std::shared_ptr<linphone::ChatRoom> &chatRoom);
|
||||
void chatRoomStateChanged(const std::shared_ptr<linphone::Core> &core,
|
||||
const std::shared_ptr<linphone::ChatRoom> &chatRoom,
|
||||
linphone::ChatRoom::State state);
|
||||
void conferenceInfoReceived(const std::shared_ptr<linphone::Core> &core,
|
||||
const std::shared_ptr<const linphone::ConferenceInfo> &conferenceInfo);
|
||||
void configuringStatus(const std::shared_ptr<linphone::Core> &core,
|
||||
linphone::Config::ConfiguringState status,
|
||||
const std::string &message);
|
||||
void dtmfReceived(const std::shared_ptr<linphone::Core> &lc, const std::shared_ptr<linphone::Call> &call, int dtmf);
|
||||
void
|
||||
ecCalibrationResult(const std::shared_ptr<linphone::Core> &core, linphone::EcCalibratorStatus status, int delayMs);
|
||||
void globalStateChanged(const std::shared_ptr<linphone::Core> &core,
|
||||
linphone::GlobalState gstate,
|
||||
const std::string &message);
|
||||
void isComposingReceived(const std::shared_ptr<linphone::Core> &core,
|
||||
const std::shared_ptr<linphone::ChatRoom> &room);
|
||||
void logCollectionUploadStateChanged(const std::shared_ptr<linphone::Core> &core,
|
||||
linphone::Core::LogCollectionUploadState state,
|
||||
const std::string &info);
|
||||
void logCollectionUploadProgressIndication(const std::shared_ptr<linphone::Core> &lc, size_t offset, size_t total);
|
||||
void messageReceived(const std::shared_ptr<linphone::Core> &core,
|
||||
const std::shared_ptr<linphone::ChatRoom> &room,
|
||||
const std::shared_ptr<linphone::ChatMessage> &message);
|
||||
void messagesReceived(const std::shared_ptr<linphone::Core> &core,
|
||||
const std::shared_ptr<linphone::ChatRoom> &room,
|
||||
const std::list<std::shared_ptr<linphone::ChatMessage>> &messages);
|
||||
void newMessageReaction(const std::shared_ptr<linphone::Core> &core,
|
||||
const std::shared_ptr<linphone::ChatRoom> &chatRoom,
|
||||
const std::shared_ptr<linphone::ChatMessage> &message,
|
||||
const std::shared_ptr<const linphone::ChatMessageReaction> &reaction);
|
||||
void notifyPresenceReceivedForUriOrTel(const std::shared_ptr<linphone::Core> &core,
|
||||
const std::shared_ptr<linphone::Friend> &linphoneFriend,
|
||||
const std::string &uriOrTel,
|
||||
const std::shared_ptr<const linphone::PresenceModel> &presenceModel);
|
||||
void notifyPresenceReceived(const std::shared_ptr<linphone::Core> &core,
|
||||
const std::shared_ptr<linphone::Friend> &linphoneFriend);
|
||||
void qrcodeFound(const std::shared_ptr<linphone::Core> &core, const std::string &result);
|
||||
void reactionRemoved(const std::shared_ptr<linphone::Core> &core,
|
||||
const std::shared_ptr<linphone::ChatRoom> &chatRoom,
|
||||
const std::shared_ptr<linphone::ChatMessage> &message,
|
||||
const std::shared_ptr<const linphone::Address> &address);
|
||||
void transferStateChanged(const std::shared_ptr<linphone::Core> &core,
|
||||
const std::shared_ptr<linphone::Call> &call,
|
||||
linphone::Call::State state);
|
||||
void versionUpdateCheckResultReceived(const std::shared_ptr<linphone::Core> &core,
|
||||
linphone::VersionUpdateCheckResult result,
|
||||
const std::string &version,
|
||||
const std::string &url);
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -41,7 +41,7 @@ template <class LinphoneClass, class ListenerClass>
|
|||
class Listener : public ListenerPrivate {
|
||||
public:
|
||||
Listener(std::shared_ptr<LinphoneClass> monitor, QObject *parent = nullptr) {
|
||||
mMonitor = monitor;
|
||||
setMonitor(monitor);
|
||||
}
|
||||
~Listener() {
|
||||
qDebug() << "Destroying Listener";
|
||||
|
|
@ -50,10 +50,15 @@ public:
|
|||
virtual void onRemoveListener() {
|
||||
setSelf(nullptr);
|
||||
}
|
||||
void setMonitor(std::shared_ptr<LinphoneClass> monitor) {
|
||||
if (mMonitor && mSelf) mMonitor->removeListener(mSelf);
|
||||
mMonitor = monitor;
|
||||
if (mMonitor && mSelf) mMonitor->addListener(mSelf);
|
||||
}
|
||||
void setSelf(const std::shared_ptr<ListenerClass> &self) {
|
||||
if (mMonitor && mSelf) mMonitor->removeListener(mSelf);
|
||||
mSelf = self;
|
||||
if (self) mMonitor->addListener(self);
|
||||
if (mMonitor && mSelf) mMonitor->addListener(self);
|
||||
}
|
||||
|
||||
protected:
|
||||
|
|
|
|||
|
|
@ -147,7 +147,7 @@ void LoggerModel::init() {
|
|||
mListener = std::make_shared<LoggerListener>();
|
||||
connect(mListener.get(), &LoggerListener::logReceived, this, &LoggerModel::onLinphoneLog);
|
||||
{
|
||||
std::shared_ptr<linphone::LoggingService> loggingService = linphone::LoggingService::get();
|
||||
std::shared_ptr<linphone::LoggingService> loggingService = mLoginService = linphone::LoggingService::get();
|
||||
loggingService->setDomain(Constants::AppDomain);
|
||||
loggingService->setLogLevel(linphone::LogLevel::Debug);
|
||||
loggingService->addListener(mListener);
|
||||
|
|
|
|||
|
|
@ -45,15 +45,15 @@ public:
|
|||
void init();
|
||||
void init(const std::shared_ptr<linphone::Config> &config);
|
||||
|
||||
|
||||
void onQtLog(QtMsgType type, QString file, int contextLine, QString msg);// Received from Qt
|
||||
void onQtLog(QtMsgType type, QString file, int contextLine, QString msg); // Received from Qt
|
||||
void onLinphoneLog(const std::shared_ptr<linphone::LoggingService> &,
|
||||
const std::string &domain,
|
||||
linphone::LogLevel level,
|
||||
const std::string &message);// Received from SDK
|
||||
const std::string &domain,
|
||||
linphone::LogLevel level,
|
||||
const std::string &message); // Received from SDK
|
||||
|
||||
signals:
|
||||
void linphoneLogReceived(const std::string &domain, linphone::LogLevel level, const std::string &message); // Send to Qt
|
||||
void
|
||||
linphoneLogReceived(const std::string &domain, linphone::LogLevel level, const std::string &message); // Send to Qt
|
||||
void verboseEnabledChanged();
|
||||
void qtOnlyEnabledChanged();
|
||||
|
||||
|
|
@ -62,6 +62,7 @@ private:
|
|||
bool mVerboseEnabled = false;
|
||||
bool mQtOnlyEnabled = false;
|
||||
std::shared_ptr<LoggerListener> mListener;
|
||||
std::shared_ptr<linphone::LoggingService> mLoginService; // Need to store one instance to avoid unwanted cleanup.
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -23,31 +23,40 @@
|
|||
#include <QDebug>
|
||||
#include <QTest>
|
||||
|
||||
#include "core/App.hpp"
|
||||
|
||||
DEFINE_ABSTRACT_OBJECT(VariantObject)
|
||||
|
||||
VariantObject::VariantObject(QObject *parent) {
|
||||
mThreadLocation = false;
|
||||
mustBeInMainThread(getClassName());
|
||||
mCoreObject = nullptr;
|
||||
}
|
||||
|
||||
VariantObject::VariantObject(QVariant value, QObject *parent) : mValue(value) {
|
||||
mThreadLocation = true;
|
||||
mustBeInMainThread(getClassName());
|
||||
connect(this, &VariantObject::updateValue, this, &VariantObject::setValue);
|
||||
mCoreObject = new VariantObject();
|
||||
connect(this, &VariantObject::valueUpdated, this, &VariantObject::setValue);
|
||||
mCoreObject = new VariantObject(nullptr);
|
||||
mCoreObject->moveToThread(CoreModel::getInstance()->thread());
|
||||
connect(mCoreObject, &VariantObject::valueChanged, this, &VariantObject::setValue);
|
||||
connect(mCoreObject, &VariantObject::valueChanged, mCoreObject, &QObject::deleteLater);
|
||||
}
|
||||
|
||||
VariantObject::~VariantObject() {
|
||||
mustBeInMainThread("~" + getClassName());
|
||||
if (mThreadLocation) mustBeInMainThread("~" + getClassName());
|
||||
else mustBeInLinphoneThread("~" + getClassName());
|
||||
}
|
||||
|
||||
QVariant VariantObject::getValue() const {
|
||||
mustBeInMainThread(QString(gClassName) + " : " + Q_FUNC_INFO);
|
||||
if (mThreadLocation) mustBeInMainThread(QString(gClassName) + " : " + Q_FUNC_INFO);
|
||||
else mustBeInLinphoneThread(QString(gClassName) + " : " + Q_FUNC_INFO);
|
||||
return mValue;
|
||||
}
|
||||
|
||||
void VariantObject::setValue(QVariant value) {
|
||||
mustBeInMainThread(QString(gClassName) + " : " + Q_FUNC_INFO);
|
||||
if (mThreadLocation) mustBeInMainThread(QString(gClassName) + " : " + Q_FUNC_INFO);
|
||||
else mustBeInLinphoneThread(QString(gClassName) + " : " + Q_FUNC_INFO);
|
||||
if (value != mValue) {
|
||||
mValue = value;
|
||||
emit valueChanged(mValue);
|
||||
|
|
|
|||
|
|
@ -42,14 +42,17 @@ public:
|
|||
QVariant getValue() const;
|
||||
void setValue(QVariant value);
|
||||
|
||||
// mCoreObject must be used to request update value : this object will be not be deleted by GUI so it is safe to use
|
||||
// inside model thread. call emit updateValue() from coreObject to set value from model.
|
||||
VariantObject *mCoreObject; // Ensure to use DeleteLater() after updating value
|
||||
|
||||
signals:
|
||||
void valueChanged(QVariant value);
|
||||
void updateValue(QVariant value);
|
||||
void valueUpdated(QVariant value);
|
||||
|
||||
private:
|
||||
QVariant mValue;
|
||||
bool mThreadLocation = true; // true=Core, false=Model
|
||||
DECLARE_ABSTRACT_OBJECT
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -19,9 +19,9 @@
|
|||
*/
|
||||
|
||||
#include "ToolModel.hpp"
|
||||
#include "core/App.hpp"
|
||||
#include "model/core/CoreModel.hpp"
|
||||
#include "tool/Utils.hpp"
|
||||
|
||||
#include <QDebug>
|
||||
#include <QTest>
|
||||
|
||||
|
|
@ -67,3 +67,58 @@ QString ToolModel::getDisplayName(QString address) {
|
|||
QString displayName = getDisplayName(interpretUrl(address));
|
||||
return displayName.isEmpty() ? address : displayName;
|
||||
}
|
||||
|
||||
Call *ToolModel::startAudioCall(const QString &sipAddress,
|
||||
const QString &prepareTransfertAddress,
|
||||
const QHash<QString, QString> &headers) {
|
||||
bool waitRegistrationForCall = true; // getSettingsModel()->getWaitRegistrationForCall()
|
||||
std::shared_ptr<linphone::Core> core = CoreModel::getInstance()->getCore();
|
||||
|
||||
std::shared_ptr<linphone::Address> address = interpretUrl(sipAddress);
|
||||
if (!address) {
|
||||
qCritical() << "[" + QString(gClassName) + "] The calling address is not an interpretable SIP address: "
|
||||
<< sipAddress;
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
std::shared_ptr<linphone::CallParams> params = core->createCallParams(nullptr);
|
||||
params->enableVideo(false);
|
||||
|
||||
QHashIterator<QString, QString> iterator(headers);
|
||||
while (iterator.hasNext()) {
|
||||
iterator.next();
|
||||
params->addCustomHeader(Utils::appStringToCoreString(iterator.key()),
|
||||
Utils::appStringToCoreString(iterator.value()));
|
||||
}
|
||||
if (core->getDefaultAccount()) params->setAccount(core->getDefaultAccount());
|
||||
// CallModel::setRecordFile(params, Utils::coreStringToAppString(address->getUsername()));
|
||||
auto call = core->inviteAddressWithParams(address, params);
|
||||
return call ? new Call(call) : nullptr;
|
||||
|
||||
/* TODO transfer
|
||||
|
||||
std::shared_ptr<linphone::Account> currentAccount = core->getDefaultAccount();
|
||||
if (currentAccount) {
|
||||
if (!waitRegistrationForCall || currentAccount->getState() == linphone::RegistrationState::Ok) {
|
||||
qWarning() << "prepareTransfert not impolemented";
|
||||
// CallModel::prepareTransfert(core->inviteAddressWithParams(address, params), prepareTransfertAddress);
|
||||
} else {
|
||||
qWarning() << "Waiting registration not implemented";
|
||||
|
||||
// QObject *context = new QObject();
|
||||
// QObject::connect(
|
||||
// CoreManager::getInstance()->getHandlers().get(), &CoreHandlers::registrationStateChanged, context,
|
||||
// [address, core, params, currentAccount, prepareTransfertAddress, context](
|
||||
// const std::shared_ptr<linphone::Account> &account, linphone::RegistrationState state) mutable {
|
||||
// if (context && account == currentAccount && state == linphone::RegistrationState::Ok) {
|
||||
// CallModel::prepareTransfert(core->inviteAddressWithParams(address, params),
|
||||
// prepareTransfertAddress);
|
||||
// context->deleteLater();
|
||||
// context = nullptr;
|
||||
// }
|
||||
// });
|
||||
}
|
||||
} else qWarning() << "prepareTransfert not impolemented";
|
||||
// CallModel::prepareTransfert(core->inviteAddressWithParams(address, params), prepareTransfertAddress);
|
||||
*/
|
||||
}
|
||||
|
|
|
|||
|
|
@ -21,8 +21,10 @@
|
|||
#ifndef TOOL_MODEL_H_
|
||||
#define TOOL_MODEL_H_
|
||||
|
||||
#include "core/call/Call.hpp"
|
||||
#include "tool/AbstractObject.hpp"
|
||||
|
||||
#include <QHash>
|
||||
#include <QObject>
|
||||
#include <linphone++/linphone.hh>
|
||||
|
||||
|
|
@ -37,6 +39,10 @@ public:
|
|||
static QString getDisplayName(const std::shared_ptr<const linphone::Address> &address);
|
||||
static QString getDisplayName(QString address);
|
||||
|
||||
static Call *startAudioCall(const QString &sipAddress,
|
||||
const QString &prepareTransfertAddress = "",
|
||||
const QHash<QString, QString> &headers = {});
|
||||
|
||||
private:
|
||||
DECLARE_ABSTRACT_OBJECT
|
||||
};
|
||||
|
|
|
|||
|
|
@ -27,6 +27,7 @@
|
|||
// =============================================================================
|
||||
|
||||
void LinphoneEnums::registerMetaTypes() {
|
||||
qRegisterMetaType<LinphoneEnums::CallState>();
|
||||
qRegisterMetaType<LinphoneEnums::CallStatus>();
|
||||
qRegisterMetaType<LinphoneEnums::ChatMessageState>();
|
||||
qRegisterMetaType<LinphoneEnums::ChatRoomState>();
|
||||
|
|
@ -81,6 +82,13 @@ LinphoneEnums::ChatRoomState LinphoneEnums::fromLinphone(const linphone::ChatRoo
|
|||
return static_cast<LinphoneEnums::ChatRoomState>(data);
|
||||
}
|
||||
|
||||
linphone::Call::State LinphoneEnums::toLinphone(const LinphoneEnums::CallState &data) {
|
||||
return static_cast<linphone::Call::State>(data);
|
||||
}
|
||||
LinphoneEnums::CallState LinphoneEnums::fromLinphone(const linphone::Call::State &data) {
|
||||
return static_cast<LinphoneEnums::CallState>(data);
|
||||
}
|
||||
|
||||
linphone::Call::Status LinphoneEnums::toLinphone(const LinphoneEnums::CallStatus &data) {
|
||||
return static_cast<linphone::Call::Status>(data);
|
||||
}
|
||||
|
|
@ -88,6 +96,25 @@ LinphoneEnums::CallStatus LinphoneEnums::fromLinphone(const linphone::Call::Stat
|
|||
return static_cast<LinphoneEnums::CallStatus>(data);
|
||||
}
|
||||
|
||||
QString LinphoneEnums::toString(const LinphoneEnums::CallStatus &data) {
|
||||
switch (data) {
|
||||
case LinphoneEnums::CallStatus::Declined:
|
||||
return "Declined";
|
||||
case LinphoneEnums::CallStatus::Missed:
|
||||
return "Missed";
|
||||
case LinphoneEnums::CallStatus::Success:
|
||||
return "Success";
|
||||
case LinphoneEnums::CallStatus::Aborted:
|
||||
return "Aborted";
|
||||
case LinphoneEnums::CallStatus::EarlyAborted:
|
||||
return "EarlyAborted";
|
||||
case LinphoneEnums::CallStatus::AcceptedElsewhere:
|
||||
return "AcceptedElsewhere";
|
||||
case LinphoneEnums::CallStatus::DeclinedElsewhere:
|
||||
return "DeclinedElsewhere";
|
||||
}
|
||||
}
|
||||
|
||||
linphone::Conference::Layout LinphoneEnums::toLinphone(const LinphoneEnums::ConferenceLayout &layout) {
|
||||
if (layout != LinphoneEnums::ConferenceLayout::AudioOnly) return static_cast<linphone::Conference::Layout>(layout);
|
||||
else return linphone::Conference::Layout::Grid; // Audio Only mode
|
||||
|
|
|
|||
|
|
@ -30,6 +30,7 @@
|
|||
|
||||
namespace LinphoneEnums {
|
||||
Q_NAMESPACE
|
||||
Q_CLASSINFO("RegisterEnumClassesUnscoped", "false") // Avoid name clashes
|
||||
|
||||
void registerMetaTypes();
|
||||
|
||||
|
|
@ -115,6 +116,34 @@ Q_ENUM_NS(ChatRoomState)
|
|||
linphone::ChatRoom::State toLinphone(const LinphoneEnums::ChatRoomState &data);
|
||||
LinphoneEnums::ChatRoomState fromLinphone(const linphone::ChatRoom::State &data);
|
||||
|
||||
enum class CallState {
|
||||
Idle = int(linphone::Call::State::Idle),
|
||||
IncomingReceived = int(linphone::Call::State::IncomingReceived),
|
||||
PushIncomingReceived = int(linphone::Call::State::PushIncomingReceived),
|
||||
OutgoingInit = int(linphone::Call::State::OutgoingInit),
|
||||
OutgoingProgress = int(linphone::Call::State::OutgoingProgress),
|
||||
OutgoingRinging = int(linphone::Call::State::OutgoingRinging),
|
||||
OutgoingEarlyMedia = int(linphone::Call::State::OutgoingEarlyMedia),
|
||||
Connected = int(linphone::Call::State::Connected),
|
||||
StreamsRunning = int(linphone::Call::State::StreamsRunning),
|
||||
Pausing = int(linphone::Call::State::Pausing),
|
||||
Paused = int(linphone::Call::State::Paused),
|
||||
Resuming = int(linphone::Call::State::Resuming),
|
||||
Referred = int(linphone::Call::State::Referred),
|
||||
Error = int(linphone::Call::State::Error),
|
||||
End = int(linphone::Call::State::End),
|
||||
PausedByRemote = int(linphone::Call::State::PausedByRemote),
|
||||
UpdatedByRemote = int(linphone::Call::State::UpdatedByRemote),
|
||||
IncomingEarlyMedia = int(linphone::Call::State::IncomingEarlyMedia),
|
||||
Updating = int(linphone::Call::State::Updating),
|
||||
Released = int(linphone::Call::State::Released),
|
||||
EarlyUpdatedByRemote = int(linphone::Call::State::EarlyUpdatedByRemote),
|
||||
EarlyUpdating = int(linphone::Call::State::EarlyUpdating)
|
||||
};
|
||||
Q_ENUM_NS(CallState)
|
||||
linphone::Call::State toLinphone(const LinphoneEnums::CallState &data);
|
||||
LinphoneEnums::CallState fromLinphone(const linphone::Call::State &data);
|
||||
|
||||
enum class CallStatus {
|
||||
Declined = int(linphone::Call::Status::Declined),
|
||||
Missed = int(linphone::Call::Status::Missed),
|
||||
|
|
@ -126,8 +155,9 @@ enum class CallStatus {
|
|||
};
|
||||
Q_ENUM_NS(CallStatus)
|
||||
|
||||
linphone::Call::Status toLinphone(const LinphoneEnums::CallStatus &capability);
|
||||
LinphoneEnums::CallStatus fromLinphone(const linphone::Call::Status &capability);
|
||||
linphone::Call::Status toLinphone(const LinphoneEnums::CallStatus &data);
|
||||
LinphoneEnums::CallStatus fromLinphone(const linphone::Call::Status &data);
|
||||
QString toString(const LinphoneEnums::CallStatus &data);
|
||||
|
||||
enum class ConferenceLayout {
|
||||
Grid = int(linphone::Conference::Layout::Grid),
|
||||
|
|
@ -227,7 +257,8 @@ LinphoneEnums::TransportType fromLinphone(const linphone::TransportType &type);
|
|||
QString toString(const LinphoneEnums::TransportType &type);
|
||||
void fromString(const QString &transportType, LinphoneEnums::TransportType *transport);
|
||||
} // namespace LinphoneEnums
|
||||
|
||||
/*
|
||||
Q_DECLARE_METATYPE(LinphoneEnums::CallState)
|
||||
Q_DECLARE_METATYPE(LinphoneEnums::CallStatus)
|
||||
Q_DECLARE_METATYPE(LinphoneEnums::ChatMessageState)
|
||||
Q_DECLARE_METATYPE(LinphoneEnums::ChatRoomState)
|
||||
|
|
@ -242,5 +273,5 @@ Q_DECLARE_METATYPE(LinphoneEnums::RecorderState)
|
|||
Q_DECLARE_METATYPE(LinphoneEnums::RegistrationState)
|
||||
Q_DECLARE_METATYPE(LinphoneEnums::TunnelMode)
|
||||
Q_DECLARE_METATYPE(LinphoneEnums::TransportType)
|
||||
|
||||
*/
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -21,6 +21,7 @@
|
|||
#include "Utils.hpp"
|
||||
|
||||
#include "core/App.hpp"
|
||||
#include "model/call/CallModel.hpp"
|
||||
#include "model/object/VariantObject.hpp"
|
||||
#include "model/tool/ToolModel.hpp"
|
||||
|
||||
|
|
@ -43,7 +44,25 @@ VariantObject *Utils::getDisplayName(const QString &address) {
|
|||
VariantObject *data = new VariantObject(address); // Scope : GUI
|
||||
App::postModelAsync([coreObject = data->mCoreObject, address]() mutable {
|
||||
QString displayName = ToolModel::getDisplayName(address);
|
||||
emit coreObject->valueChanged(displayName);
|
||||
coreObject->setValue(displayName);
|
||||
});
|
||||
return data;
|
||||
}
|
||||
|
||||
VariantObject *Utils::startAudioCall(const QString &sipAddress,
|
||||
const QString &prepareTransfertAddress,
|
||||
const QHash<QString, QString> &headers) {
|
||||
VariantObject *data = new VariantObject(QVariant()); // Scope : GUI
|
||||
qDebug() << "Calling " << sipAddress;
|
||||
App::postModelAsync([coreObject = data->mCoreObject, sipAddress, prepareTransfertAddress, headers]() mutable {
|
||||
auto call = ToolModel::startAudioCall(sipAddress, prepareTransfertAddress, headers);
|
||||
if (call && coreObject) {
|
||||
call->moveToThread(App::getInstance()->thread());
|
||||
coreObject->setValue(QVariant::fromValue(call));
|
||||
// App::postCoreAsync([data, call]() { data->setValue(QVariant::fromValue(call)); });
|
||||
// emit coreObject->valueChanged(call);
|
||||
}
|
||||
});
|
||||
|
||||
return data;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -49,6 +49,9 @@ public:
|
|||
}
|
||||
|
||||
Q_INVOKABLE static VariantObject *getDisplayName(const QString &address);
|
||||
Q_INVOKABLE static VariantObject *startAudioCall(const QString &sipAddress,
|
||||
const QString &prepareTransfertAddress = "",
|
||||
const QHash<QString, QString> &headers = {});
|
||||
|
||||
static inline QString coreStringToAppString(const std::string &str) {
|
||||
if (Constants::LinphoneLocaleEncoding == QString("UTF-8")) return QString::fromStdString(str);
|
||||
|
|
|
|||
|
|
@ -8,7 +8,12 @@ list(APPEND _LINPHONEAPP_QML_FILES
|
|||
view/Item/Carousel.qml
|
||||
view/Item/CheckBox.qml
|
||||
view/Item/ComboBox.qml
|
||||
view/Item/DesktopPopup.qml
|
||||
view/Item/DigitInput.qml
|
||||
|
||||
view/Item/Notification/Notification.qml
|
||||
view/Item/Notification/NotificationReceivedCall.qml
|
||||
|
||||
view/Item/PhoneNumberComboBox.qml
|
||||
view/Item/PhoneNumberInput.qml
|
||||
view/Item/RadioButton.qml
|
||||
|
|
@ -35,6 +40,7 @@ list(APPEND _LINPHONEAPP_QML_FILES
|
|||
# Prototypes
|
||||
view/Prototype/PhoneNumberPrototype.qml
|
||||
view/Prototype/AccountsPrototype.qml
|
||||
view/Prototype/CallPrototype.qml
|
||||
)
|
||||
|
||||
list(APPEND _LINPHONEAPP_QML_SINGLETONS
|
||||
|
|
|
|||
187
Linphone/view/Item/DesktopPopup.qml
Normal file
187
Linphone/view/Item/DesktopPopup.qml
Normal file
|
|
@ -0,0 +1,187 @@
|
|||
import QtQuick 2.7
|
||||
import QtQuick.Window 2.2
|
||||
|
||||
import QtQuick.Controls 2.2
|
||||
import QtQuick.Layouts 1.3
|
||||
import Qt.labs.platform 1.0
|
||||
|
||||
|
||||
// =============================================================================
|
||||
Window {
|
||||
id: mainItem
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
|
||||
property bool requestActivate: false
|
||||
//property int flags: Qt.SplashScreen
|
||||
|
||||
|
||||
|
||||
default property alias _content: content.data
|
||||
property bool _isOpen: false
|
||||
signal isOpened()
|
||||
signal isClosed()
|
||||
signal dataChanged()
|
||||
|
||||
on_ContentChanged: dataChanged(_content)
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
function open () {
|
||||
_isOpen = true;
|
||||
isOpened();
|
||||
}
|
||||
/*
|
||||
function close () {
|
||||
_isOpen = false
|
||||
isClosed()
|
||||
}
|
||||
*/
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
objectName: '__internalWindow'
|
||||
property bool isFrameLess : false;
|
||||
property bool showAsTool : false
|
||||
// Don't use Popup for flags : it could lead to error in geometry. On Mac, Using Tool ensure to have the Window on Top and fullscreen independant
|
||||
flags: Qt.BypassWindowManagerHint | (showAsTool?Qt.Tool:Qt.WindowStaysOnTopHint) | Qt.Window | Qt.FramelessWindowHint;
|
||||
opacity: 1.0
|
||||
height: _content[0] != null ? _content[0].height : 0
|
||||
width: _content[0] != null ? _content[0].width : 0
|
||||
visible:true
|
||||
Item {
|
||||
id: content
|
||||
anchors.fill:parent
|
||||
|
||||
property var $parent: mainItem
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
/*
|
||||
states: State {
|
||||
name: 'opening'
|
||||
when: _isOpen
|
||||
|
||||
PropertyChanges {
|
||||
opacity: 1.0
|
||||
target: window
|
||||
}
|
||||
}
|
||||
|
||||
transitions: [
|
||||
Transition {
|
||||
from: ''
|
||||
to: 'opening'
|
||||
ScriptAction {
|
||||
script: {
|
||||
if (wrapper.requestActivate) {
|
||||
window.requestActivate()
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
Transition {
|
||||
from: '*'
|
||||
to: ''
|
||||
ScriptAction {
|
||||
script: window.close()
|
||||
}
|
||||
}
|
||||
]
|
||||
*/
|
||||
}
|
||||
|
||||
/*
|
||||
Item {
|
||||
id: wrapper
|
||||
objectName: '__internalWrapper'
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
property alias popupX: window.x
|
||||
property alias popupY: window.y
|
||||
property bool requestActivate: false
|
||||
property int flags: Qt.SplashScreen
|
||||
|
||||
readonly property alias popupWidth: window.width
|
||||
readonly property alias popupHeight: window.height
|
||||
|
||||
default property alias _content: content.data
|
||||
property bool _isOpen: false
|
||||
signal isOpened()
|
||||
signal isClosed()
|
||||
signal dataChanged()
|
||||
|
||||
on_ContentChanged: dataChanged(_content)
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
function open () {
|
||||
_isOpen = true;
|
||||
isOpened();
|
||||
}
|
||||
|
||||
function close () {
|
||||
_isOpen = false
|
||||
isClosed()
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
// No size, no position.
|
||||
height: 0
|
||||
width: 0
|
||||
visible:true
|
||||
|
||||
Window {
|
||||
id: window
|
||||
objectName: '__internalWindow'
|
||||
property bool isFrameLess : false;
|
||||
property bool showAsTool : false
|
||||
// Don't use Popup for flags : it could lead to error in geometry. On Mac, Using Tool ensure to have the Window on Top and fullscreen independant
|
||||
flags: Qt.BypassWindowManagerHint | (showAsTool?Qt.Tool:Qt.WindowStaysOnTopHint) | Qt.Window | Qt.FramelessWindowHint;
|
||||
onXChanged: console.log(x)
|
||||
opacity: 1.0
|
||||
height: _content[0] != null ? _content[0].height : 0
|
||||
width: _content[0] != null ? _content[0].width : 0
|
||||
visible:true
|
||||
Item {
|
||||
id: content
|
||||
anchors.fill:parent
|
||||
|
||||
property var $parent: wrapper
|
||||
}
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
states: State {
|
||||
name: 'opening'
|
||||
when: _isOpen
|
||||
|
||||
PropertyChanges {
|
||||
opacity: 1.0
|
||||
target: window
|
||||
}
|
||||
}
|
||||
|
||||
transitions: [
|
||||
Transition {
|
||||
from: ''
|
||||
to: 'opening'
|
||||
ScriptAction {
|
||||
script: {
|
||||
if (wrapper.requestActivate) {
|
||||
window.requestActivate()
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
Transition {
|
||||
from: '*'
|
||||
to: ''
|
||||
ScriptAction {
|
||||
script: window.close()
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
*/
|
||||
57
Linphone/view/Item/Notification/Notification.qml
Normal file
57
Linphone/view/Item/Notification/Notification.qml
Normal file
|
|
@ -0,0 +1,57 @@
|
|||
import QtQuick 2.7
|
||||
import Linphone
|
||||
|
||||
// =============================================================================
|
||||
|
||||
DesktopPopup {
|
||||
id: notification
|
||||
|
||||
|
||||
property var notificationData: ({
|
||||
timelineModel : null
|
||||
})
|
||||
property int overrodeHeight
|
||||
default property alias _content: content.data
|
||||
|
||||
signal deleteNotification (var notification)
|
||||
|
||||
// Use as an intermediate between signal/slot without propagate the notification var : last signal parameter will be the last notification instance
|
||||
function deleteNotificationSlot(){
|
||||
deleteNotification(notification)
|
||||
}
|
||||
|
||||
function _close (cb) {
|
||||
if (cb) {
|
||||
cb()
|
||||
}
|
||||
deleteNotificationSlot();
|
||||
}
|
||||
|
||||
Rectangle {
|
||||
color: "#FFFFFF"
|
||||
height: overrodeHeight || 120
|
||||
width: 300
|
||||
|
||||
border {
|
||||
color: "#A1A1A1"
|
||||
width: 1
|
||||
}
|
||||
|
||||
Item {
|
||||
id: content
|
||||
|
||||
anchors.fill: parent
|
||||
}
|
||||
|
||||
Image {
|
||||
id: iconSign
|
||||
|
||||
anchors {
|
||||
left: parent.left
|
||||
top: parent.top
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
54
Linphone/view/Item/Notification/NotificationReceivedCall.qml
Normal file
54
Linphone/view/Item/Notification/NotificationReceivedCall.qml
Normal file
|
|
@ -0,0 +1,54 @@
|
|||
import QtQuick 2.7
|
||||
import QtQuick.Layouts 1.3
|
||||
import Linphone
|
||||
|
||||
// =============================================================================
|
||||
|
||||
Notification {
|
||||
id: notification
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
readonly property var call: notificationData && notificationData.call
|
||||
property var state: call.state
|
||||
onStateChanged:{
|
||||
if(state != LinphoneEnums.CallState.IncomingReceived){
|
||||
close()
|
||||
}
|
||||
}
|
||||
// ---------------------------------------------------------------------------
|
||||
ColumnLayout {
|
||||
anchors.fill: parent
|
||||
anchors.leftMargin: 15
|
||||
anchors.rightMargin: 15
|
||||
anchors.bottomMargin:15
|
||||
spacing: 0
|
||||
|
||||
// ---------------------------------------------------------------------
|
||||
// Action buttons.
|
||||
// ---------------------------------------------------------------------
|
||||
|
||||
RowLayout {
|
||||
Layout.fillHeight: true
|
||||
Layout.fillWidth: true
|
||||
Button {
|
||||
text: 'Accept'
|
||||
Layout.rightMargin: 20
|
||||
onClicked: {
|
||||
notification.call.lAccept()
|
||||
}
|
||||
}
|
||||
Item{
|
||||
Layout.fillWidth: true
|
||||
Layout.fillHeight: true
|
||||
}
|
||||
Button {
|
||||
text: 'Reject'
|
||||
Layout.rightMargin: 20
|
||||
onClicked: {
|
||||
notification.call.lDecline()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
80
Linphone/view/Prototype/CallPrototype.qml
Normal file
80
Linphone/view/Prototype/CallPrototype.qml
Normal file
|
|
@ -0,0 +1,80 @@
|
|||
import QtQuick 2.15
|
||||
import QtQuick.Layouts 1.0
|
||||
import QtQuick.Controls as Control
|
||||
import Linphone
|
||||
import UtilsCpp 1.0
|
||||
|
||||
// Snippet
|
||||
Window{
|
||||
id: mainItem
|
||||
height: 400
|
||||
width: 800
|
||||
onWidthChanged: console.log(width)
|
||||
property var callVarObject
|
||||
property var call: callVarObject ? callVarObject.value : null
|
||||
property var callState: call && call.state
|
||||
onCallStateChanged: console.log("State:" +callState)
|
||||
visible: true
|
||||
onCallChanged: console.log('New Call:' +call)
|
||||
ColumnLayout{
|
||||
anchors.fill: parent
|
||||
RowLayout {
|
||||
Layout.fillWidth: true
|
||||
LoginForm{
|
||||
}
|
||||
Rectangle{
|
||||
Layout.preferredWidth: 50
|
||||
Layout.preferredHeight: 50
|
||||
|
||||
color: LoginPageCpp.registrationState === LinphoneEnums.RegistrationState.Ok
|
||||
? 'green'
|
||||
: LoginPageCpp.registrationState === LinphoneEnums.RegistrationState.Failed || LoginPageCpp.registrationState === LinphoneEnums.RegistrationState.None
|
||||
? 'red'
|
||||
: 'orange'
|
||||
}
|
||||
TextInput {
|
||||
id: usernameToCall
|
||||
label: "Username to call"
|
||||
textInputWidth: 250
|
||||
}
|
||||
Button{
|
||||
text: 'Call'
|
||||
onClicked: {
|
||||
mainItem.callVarObject = UtilsCpp.startAudioCall(usernameToCall.inputText + "@sip.linphone.org")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Rectangle{
|
||||
Layout.fillWidth: true
|
||||
Layout.preferredHeight: 50
|
||||
color: call
|
||||
? call.state === LinphoneEnums.CallState.StreamsRunning
|
||||
? 'green'
|
||||
: call.state === LinphoneEnums.CallState.Released
|
||||
? 'pink'
|
||||
: 'orange'
|
||||
: 'red'
|
||||
Rectangle{
|
||||
anchors.centerIn: parent
|
||||
color: 'white'
|
||||
width: stateText.contentWidth
|
||||
height: stateText.contentHeight
|
||||
Text{
|
||||
id: stateText
|
||||
text: "State:"+(mainItem.callState ? mainItem.callState : 'None')
|
||||
}
|
||||
}
|
||||
}
|
||||
Text{
|
||||
id: errorMessageText
|
||||
text: mainItem.call ? mainItem.call.lastErrorMessage : ''
|
||||
color: 'red'
|
||||
}
|
||||
Item{
|
||||
Layout.fillHeight: true
|
||||
Layout.fillWidth: true
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
2
external/linphone-sdk
vendored
2
external/linphone-sdk
vendored
|
|
@ -1 +1 @@
|
|||
Subproject commit 8756a37ad10399a0c27d32590a0d1cc87ea97c2e
|
||||
Subproject commit aaeaad94a6e63f182f50318ed1a209c83b152d73
|
||||
Loading…
Add table
Reference in a new issue