mirror of
https://gitlab.linphone.org/BC/public/linphone-desktop.git
synced 2026-01-18 03:48:09 +00:00
Compare commits
96 commits
6.1.0-beta
...
master
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
1156bd78c0 | ||
|
|
befa4a2635 | ||
|
|
0cf3938dc3 | ||
|
|
c3b160ec3e | ||
|
|
dc1ec216e8 | ||
|
|
0bfa29dc55 | ||
|
|
0df7065b5e | ||
|
|
6d9b5efcc5 | ||
|
|
50ec67298e | ||
|
|
1bae93aab5 | ||
|
|
d40045d5bb | ||
|
|
13ec790648 | ||
|
|
528dc1e2bd | ||
|
|
31726b46cd | ||
|
|
876fdbe619 | ||
|
|
e849891548 | ||
|
|
c672762b63 | ||
|
|
e23a49fbd3 | ||
|
|
a9a1249ecd | ||
|
|
ed57ec1ea5 | ||
|
|
d4c1387c43 | ||
|
|
88aea7ba25 | ||
|
|
605ffdcdd5 | ||
|
|
21e8e2aaba | ||
|
|
60517741a2 | ||
|
|
5a90959125 | ||
|
|
c8428d6ade | ||
|
|
b2ae9213a2 | ||
|
|
d39a84ca4e | ||
|
|
dfc88b7657 | ||
|
|
f405754e24 | ||
|
|
cca8db9055 | ||
|
|
8ee8058065 | ||
|
|
96b20f42e2 | ||
|
|
5bbffa79d8 | ||
|
|
e3edeb1bcf | ||
|
|
7c2e9f6c12 | ||
|
|
ca4bdd3736 | ||
|
|
251f711250 | ||
|
|
37db390d5c | ||
|
|
04d2744bf2 | ||
|
|
a7ba374b8f | ||
|
|
29691485bf | ||
|
|
735c473b3c | ||
|
|
bba3edd4b6 | ||
|
|
514c337192 | ||
|
|
fea9a1b7be | ||
|
|
afd3514965 | ||
|
|
3f5797f453 | ||
|
|
db5f6dc2af | ||
|
|
d0cf951fe4 | ||
|
|
b802fec33c | ||
|
|
3c264fd3ee | ||
|
|
72e32ec160 | ||
|
|
bfbafab84b | ||
|
|
7a4adbcbb4 | ||
|
|
fa3ef0b1a8 | ||
|
|
2fc4439e16 | ||
|
|
0b9a0ead2a | ||
|
|
3870037905 | ||
|
|
e113058ae9 | ||
|
|
a4b38e4fd1 | ||
|
|
a0850b9967 | ||
|
|
bc5022c8f5 | ||
|
|
ac03de6663 | ||
|
|
58eb93d13b | ||
|
|
11487b3aeb | ||
|
|
ca73193f6c | ||
|
|
f2e49f21b0 | ||
|
|
a7c8e8db90 | ||
|
|
afc03daa22 | ||
|
|
74b2cf299b | ||
|
|
fcdbcdc9c1 | ||
|
|
3dbea1ccb2 | ||
|
|
d741e79e2e | ||
|
|
b3b40d6f99 | ||
|
|
d957fae94e | ||
|
|
e224f24e92 | ||
|
|
cef650fb6a | ||
|
|
9e10d5e9bd | ||
|
|
36c783c9e5 | ||
|
|
0d2e83a60d | ||
|
|
c70426f770 | ||
|
|
0c87a8d94e | ||
|
|
6f4e925766 | ||
|
|
99c2a6ddc6 | ||
|
|
cbd91b868d | ||
|
|
80bf126b23 | ||
|
|
db1f04350a | ||
|
|
08f2292881 | ||
|
|
229fbe1713 | ||
|
|
2d9f568e3d | ||
|
|
d4ce80f8c6 | ||
|
|
eb9fa8aefe | ||
|
|
cb63b1a112 | ||
|
|
b3135ea177 |
182 changed files with 13799 additions and 4552 deletions
|
|
@ -1,5 +1,5 @@
|
|||
.factorize_ubuntu2204: &docker_image_platform_and_runner_tag
|
||||
tags: [ "docker" ]
|
||||
tags: [ "docker-flat" ]
|
||||
image: gitlab.linphone.org:4567/bc/public/linphone-desktop/bc-dev-ubuntu-22-04-lts:$UBUNTU_2204_IMAGE_VERSION
|
||||
|
||||
ubuntu2204-ninja-gcc:
|
||||
|
|
@ -71,7 +71,7 @@ ubuntu2204-makefile-gcc-signed:
|
|||
#################################################
|
||||
|
||||
ubuntu2204-makefile-gcc-package:
|
||||
tags: [ "docker" ]
|
||||
tags: [ "docker-flat" ]
|
||||
image: gitlab.linphone.org:4567/bc/public/linphone-desktop/bc-dev-ubuntu-22-04-lts:$UBUNTU_2204_IMAGE_VERSION
|
||||
needs: []
|
||||
rules:
|
||||
|
|
@ -100,7 +100,7 @@ ubuntu2204-makefile-gcc-deploy:
|
|||
|
||||
ubuntu2204-makefile-gcc-plugins-deploy:
|
||||
stage: deploy
|
||||
tags: [ "deploy" ]
|
||||
tags: [ "deploy-flat" ]
|
||||
needs:
|
||||
- ubuntu2204-makefile-gcc
|
||||
only:
|
||||
|
|
|
|||
|
|
@ -30,12 +30,11 @@
|
|||
rm -f file.key
|
||||
|
||||
.deploy_linux: &deploy_linux |
|
||||
rsync -rlv --ignore-existing build/OUTPUT/Packages/*.AppImage $DEPLOY_SERVER:$UPLOAD_ROOT_PATH/$LINUX_PLATFORM/$APP_FOLDER
|
||||
|-
|
||||
if [[ $MAKE_RELEASE_FILE_URL != "" ]]; then
|
||||
rsync -rlv build/OUTPUT/Packages/RELEASE $DEPLOY_SERVER:$UPLOAD_ROOT_PATH/$LINUX_PLATFORM
|
||||
rsync -rlv build/OUTPUT/Packages/RELEASE $MAIN_DEPLOY_SERVER:$UPLOAD_ROOT_PATH/$LINUX_PLATFORM
|
||||
fi
|
||||
rsync -rlv --chmod=Fu=rw,Fg=r,Fo=r --ignore-existing build/OUTPUT/Packages/*.AppImage $DEPLOY_SERVER:$UPLOAD_ROOT_PATH/$LINUX_PLATFORM/$APP_FOLDER
|
||||
if [[ $MAKE_RELEASE_FILE_URL != "" ]]; then
|
||||
rsync -rlv --chmod=Fu=rw,Fg=r,Fo=r build/OUTPUT/Packages/RELEASE $DEPLOY_SERVER:$UPLOAD_ROOT_PATH/$LINUX_PLATFORM
|
||||
rsync -rlv --chmod=Fu=rw,Fg=r,Fo=r build/OUTPUT/Packages/RELEASE $MAIN_DEPLOY_SERVER:$UPLOAD_ROOT_PATH/$LINUX_PLATFORM
|
||||
fi
|
||||
|
||||
.linux-desktop:
|
||||
stage: build
|
||||
|
|
@ -74,6 +73,6 @@
|
|||
|
||||
.linux-deploy:
|
||||
stage: deploy
|
||||
tags: [ "deploy" ]
|
||||
tags: [ "deploy-flat" ]
|
||||
script:
|
||||
- *deploy_linux
|
||||
|
|
@ -26,7 +26,7 @@
|
|||
|
||||
.macosx-desktop:
|
||||
stage: build
|
||||
tags: [ "macos-min-xcode12.2" ]
|
||||
tags: [ "macmini-m1-xcode15-flat" ]
|
||||
rules:
|
||||
- if: $CI_PIPELINE_SOURCE == "merge_request_event" && $DOCKER_UPDATE == null && $SKIP_MACOSX == null
|
||||
- if: $CI_PIPELINE_SOURCE == "schedule" && $DOCKER_UPDATE == null && $SKIP_MACOSX == null
|
||||
|
|
@ -93,7 +93,7 @@ macosx-ninja-novideo:
|
|||
# WAIT for QT6 for arm64
|
||||
macosx-ninja-package:
|
||||
stage: package
|
||||
tags: [ "macos-min-xcode12.2" ]
|
||||
tags: [ "macmini-m1-xcode15-flat" ]
|
||||
needs: []
|
||||
rules:
|
||||
- !reference [.rules-merge-request-manual, rules]
|
||||
|
|
@ -117,7 +117,7 @@ macosx-ninja-package:
|
|||
|
||||
macosx-codesigning:
|
||||
stage: signing
|
||||
tags: [ "macos-min-xcode12.2" ]
|
||||
tags: [ "macmini-m1-xcode15-flat" ]
|
||||
needs:
|
||||
- macosx-ninja-package
|
||||
rules:
|
||||
|
|
@ -142,7 +142,7 @@ macosx-codesigning:
|
|||
|
||||
macosx-deploy:
|
||||
stage: deploy
|
||||
tags: [ "macos-min-xcode12.2" ]
|
||||
tags: [ "macmini-m1-xcode15-flat" ]
|
||||
needs:
|
||||
- macosx-codesigning
|
||||
only:
|
||||
|
|
@ -160,7 +160,7 @@ macosx-deploy:
|
|||
|
||||
macosx-makefile-plugins-deploy:
|
||||
stage: deploy
|
||||
tags: [ "macos-min-xcode12.2" ]
|
||||
tags: [ "macmini-m1-xcode15-flat" ]
|
||||
needs:
|
||||
- macosx-makefile
|
||||
only:
|
||||
|
|
|
|||
|
|
@ -92,11 +92,11 @@
|
|||
|
||||
.windows-vs2022:
|
||||
extends: .windows-vs
|
||||
tags: [ "windows-powershell-vs-17-2022" ]
|
||||
tags: [ "windows-powershell-vs-17-2022-flat" ]
|
||||
|
||||
.windows-codesigning:
|
||||
extends: .prepare
|
||||
tags: [ "windows-powershell-vs-17-2022-apps" ]
|
||||
tags: [ "windows-powershell-vs-17-2022-apps-flat" ]
|
||||
|
||||
.windows-msbuild-variables:
|
||||
variables:
|
||||
|
|
@ -232,15 +232,15 @@ win64-codesigning:
|
|||
|
||||
.win64-upload:
|
||||
stage: deploy
|
||||
tags: [ "windows-powershell" ]
|
||||
tags: [ "windows-powershell-flat" ]
|
||||
rules:
|
||||
- if: $NIGHTLY_MASTER
|
||||
- if: $DEPLOY_WINDOWS
|
||||
|
||||
script:
|
||||
- scp -pr build-desktop/OUTPUT/Packages/*.exe ${DEPLOY_SERVER}:${UPLOAD_ROOT_PATH}/${WINDOWS_PLATFORM}/${APP_FOLDER}
|
||||
- if ($MAKE_RELEASE_FILE_URL) { scp -pr build-desktop/OUTPUT/Packages/RELEASE ${DEPLOY_SERVER}:${UPLOAD_ROOT_PATH}/${WINDOWS_PLATFORM}/ }
|
||||
- if ($MAKE_RELEASE_FILE_URL) { scp -pr build-desktop/OUTPUT/Packages/RELEASE ${MAIN_DEPLOY_SERVER}:${UPLOAD_ROOT_PATH}/${WINDOWS_PLATFORM}/ }
|
||||
- rsync --perms --chmod=Fu=rw,Fg=r,Fo=r build-desktop/OUTPUT/Packages/*.exe ${DEPLOY_SERVER}:${UPLOAD_ROOT_PATH}/${WINDOWS_PLATFORM}/${APP_FOLDER}
|
||||
- if ($MAKE_RELEASE_FILE_URL) { rsync --perms --chmod=Fu=rw,Fg=r,Fo=r build-desktop/OUTPUT/Packages/RELEASE ${DEPLOY_SERVER}:${UPLOAD_ROOT_PATH}/${WINDOWS_PLATFORM}/ }
|
||||
- if ($MAKE_RELEASE_FILE_URL) { rsync --perms --chmod=Fu=rw,Fg=r,Fo=r build-desktop/OUTPUT/Packages/RELEASE ${MAIN_DEPLOY_SERVER}:${UPLOAD_ROOT_PATH}/${WINDOWS_PLATFORM}/ }
|
||||
|
||||
win64-ninja-vs2022-upload:
|
||||
extends:
|
||||
|
|
@ -250,7 +250,7 @@ win64-ninja-vs2022-upload:
|
|||
|
||||
.win64-plugins-upload:
|
||||
stage: deploy
|
||||
tags: [ "windows" ]
|
||||
tags: [ "windows-flat" ]
|
||||
rules:
|
||||
- if: $DEPLOY_PLUGINS
|
||||
script:
|
||||
|
|
|
|||
|
|
@ -21,7 +21,7 @@ variables:
|
|||
#CMAKE_OPTIONS: -DENABLE_LIME_X3DH=YES
|
||||
|
||||
# Docker image version
|
||||
UBUNTU_2204_IMAGE_VERSION: 20250930_add_commercial_qt_versions_5.15.14_5.15.19_6.8.1_6.8.3_6.9.1
|
||||
UBUNTU_2204_IMAGE_VERSION: 20251106_add_commercial_qt_version_5.15.14_5.15.19_6.8.1_6.8.3_6.9.1_6.10.0
|
||||
|
||||
|
||||
workflow:
|
||||
|
|
|
|||
|
|
@ -31,3 +31,9 @@ Group changes to describe their impact on the project, as follows:
|
|||
- Default screen (between contacts, call history, conversations & meetings list) will change depending on where you were when the app was paused or killed, and you will return to that last visited screen on the next startup.
|
||||
- Minimum supported Qt version is now 6.5.3
|
||||
- Some settings have changed name and/or section in linphonerc file.
|
||||
|
||||
|
||||
## [6.1.0] - XXXX-XX-XX
|
||||
|
||||
### Changed
|
||||
- Minimum supported Qt version is now 6.10.0
|
||||
|
|
@ -60,7 +60,6 @@ project(linphoneqt)
|
|||
|
||||
include(GNUInstallDirs)
|
||||
include(CheckCXXCompilerFlag)
|
||||
include(Linphone/application_info.cmake)
|
||||
|
||||
set(CMAKE_CXX_STANDARD 17)
|
||||
if(LINPHONEAPP_INSTALL_PREFIX)
|
||||
|
|
@ -72,8 +71,11 @@ endif()
|
|||
|
||||
set(CMAKE_INSTALL_PREFIX "${APPLICATION_OUTPUT_DIR}")
|
||||
|
||||
set(LINPHONEAPP_APPLICATION_NAME "Linphone6" CACHE STRING "Application name" )
|
||||
set(LINPHONEAPP_EXECUTABLE_NAME "linphone6" CACHE STRING "Executable name" )
|
||||
set(LINPHONEAPP_APPLICATION_NAME "Linphone" CACHE STRING "Application name" )
|
||||
set(LINPHONEAPP_EXECUTABLE_NAME "linphone" CACHE STRING "Executable name" )
|
||||
|
||||
# Include application_info.cmake here as the LINPHONEAPP_APPLICATION_NAME variable must be known as it is set to the APPLICATION_NAME variable.
|
||||
include(Linphone/application_info.cmake)
|
||||
|
||||
if( APPLE )
|
||||
set(LINPHONEAPP_MACOS_ARCHS "arm64" CACHE STRING "MacOS architectures to build: comma-separated list of values in [arm64, x86_64]")
|
||||
|
|
@ -206,7 +208,7 @@ set(ENABLE_CSHARP_WRAPPER OFF CACHE BOOL "Build the CSharp wrapper for Liblinpho
|
|||
set(ENABLE_THEORA OFF)
|
||||
set(ENABLE_QT_GL ${ENABLE_VIDEO})
|
||||
|
||||
find_package(Qt6 REQUIRED COMPONENTS Core Quick Widgets Core5Compat)
|
||||
find_package(Qt6 REQUIRED COMPONENTS Core Quick Widgets)
|
||||
|
||||
if(NOT Qt6_FOUND)
|
||||
message(FATAL_ERROR "Minimum supported Qt6!")
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
cmake_minimum_required(VERSION 3.16)
|
||||
|
||||
project(Linphone VERSION 6.1.0 LANGUAGES CXX)
|
||||
project(Linphone VERSION 6.2.0 LANGUAGES CXX)
|
||||
|
||||
################################################################
|
||||
# PACKAGES
|
||||
|
|
@ -22,7 +22,7 @@ set(APP_TARGETS ${LinphoneCxx_TARGET}
|
|||
${LibLinphone_TARGET})#Liblinphone
|
||||
|
||||
set(QT_DEFAULT_MAJOR_VERSION 6)
|
||||
set(QT_PACKAGES Quick Qml Widgets Svg Multimedia Test NetworkAuth Concurrent Core5Compat)# Search Core at first for initialize Qt scripts for next find_packages.
|
||||
set(QT_PACKAGES Quick Qml Widgets Svg Multimedia Test NetworkAuth Concurrent)# Search Core at first for initialize Qt scripts for next find_packages.
|
||||
if (UNIX AND NOT APPLE)
|
||||
list(APPEND QT_PACKAGES DBus)
|
||||
endif()
|
||||
|
|
@ -98,15 +98,11 @@ endif()
|
|||
|
||||
configure_file("${CMAKE_CURRENT_SOURCE_DIR}/config.h.cmake" "${CMAKE_CURRENT_BINARY_DIR}/config.h")
|
||||
|
||||
if(${Qt6_VERSION} VERSION_LESS "6.3.0")
|
||||
set(CMAKE_AUTOMOC ON)
|
||||
set(CMAKE_AUTORCC ON)
|
||||
set(CMAKE_AUTOUIC ON)
|
||||
else()
|
||||
qt6_standard_project_setup()
|
||||
if(${Qt6_VERSION} VERSION_LESS "6.10.0")
|
||||
message( FATAL_ERROR "Linphone requires Qt 6.10.0 or newer. Exiting CMake." )
|
||||
endif()
|
||||
|
||||
|
||||
qt6_standard_project_setup()
|
||||
|
||||
|
||||
################################################################
|
||||
|
|
@ -174,6 +170,12 @@ qt6_add_qml_module(Linphone
|
|||
RESOURCES data/fonts.qrc
|
||||
)
|
||||
|
||||
if (WIN32)
|
||||
if(MSVC AND (CMAKE_BUILD_TYPE STREQUAL "Debug" OR CMAKE_BUILD_TYPE STREQUAL "RelWithDebInfo"))
|
||||
install(FILES "$<TARGET_PDB_FILE:${TARGET_NAME}>" DESTINATION ${CMAKE_INSTALL_BINDIR})
|
||||
endif()
|
||||
endif()
|
||||
|
||||
qt6_add_resources(Linphone "resources" PREFIX "/" FILES ${_LINPHONEAPP_RC_FILES})
|
||||
set_property(TARGET Linphone PROPERTY POSITION_INDEPENDENT_CODE ON) #Need by Qt
|
||||
|
||||
|
|
@ -199,6 +201,7 @@ set_target_properties(${TARGET_NAME} PROPERTIES
|
|||
if(MSVC)
|
||||
set_target_properties(${TARGET_NAME} PROPERTIES PDB_NAME "${EXECUTABLE_NAME}_app")
|
||||
endif()
|
||||
set_target_properties(${TARGET_NAME} PROPERTIES WINDOWS_EXPORT_ALL_SYMBOLS ON)
|
||||
|
||||
if(WIN32)
|
||||
if(ENABLE_SCREENSHARING)
|
||||
|
|
|
|||
|
|
@ -267,9 +267,7 @@ void App::setAutoStart(bool enabled) {
|
|||
|
||||
void App::setAutoStart(bool enabled) {
|
||||
QSettings settings(AutoStartSettingsFilePath, QSettings::NativeFormat);
|
||||
QString parameters;
|
||||
if (!mSettings->getExitOnClose()) parameters = " --minimized";
|
||||
if (enabled) settings.setValue(EXECUTABLE_NAME, QDir::toNativeSeparators(applicationFilePath()) + parameters);
|
||||
if (enabled) settings.setValue(EXECUTABLE_NAME, QDir::toNativeSeparators(applicationFilePath()));
|
||||
else settings.remove(EXECUTABLE_NAME);
|
||||
|
||||
mAutoStart = enabled;
|
||||
|
|
@ -287,8 +285,11 @@ App::App(int &argc, char *argv[])
|
|||
: SingleApplication(argc, argv, true, Mode::User | Mode::ExcludeAppPath | Mode::ExcludeAppVersion) {
|
||||
// Do not use APPLICATION_NAME here.
|
||||
// The EXECUTABLE_NAME will be used in qt standard paths. It's our goal.
|
||||
QDir::setCurrent(
|
||||
QCoreApplication::applicationDirPath()); // Set working directory as the executable to allow relative paths.
|
||||
QThread::currentThread()->setPriority(QThread::HighPriority);
|
||||
qDebug() << "app thread is" << QThread::currentThread();
|
||||
lDebug() << "Starting app with Qt version" << qVersion();
|
||||
QCoreApplication::setApplicationName(EXECUTABLE_NAME);
|
||||
QApplication::setOrganizationDomain(EXECUTABLE_NAME);
|
||||
QCoreApplication::setApplicationVersion(APPLICATION_SEMVER);
|
||||
|
|
@ -305,7 +306,7 @@ App::App(int &argc, char *argv[])
|
|||
.arg(applicationVersion())
|
||||
.arg(Utils::getOsProduct())
|
||||
.arg(qVersion());
|
||||
|
||||
lInfo() << "at " << QDir().absolutePath();
|
||||
mCurrentDate = QDate::currentDate();
|
||||
mAutoStart = autoStartEnabled();
|
||||
mDateUpdateTimer.setInterval(60000);
|
||||
|
|
@ -336,7 +337,7 @@ void App::setSelf(QSharedPointer<App>(me)) {
|
|||
auto callCore = CallCore::create(call);
|
||||
mCoreModelConnection->invokeToCore([this, callCore] {
|
||||
auto callGui = new CallGui(callCore);
|
||||
auto win = getCallsWindow(QVariant::fromValue(callGui));
|
||||
auto win = getOrCreateCallsWindow(QVariant::fromValue(callGui));
|
||||
Utils::smartShowWindow(win);
|
||||
auto mainwin = getMainWindow();
|
||||
QMetaObject::invokeMethod(mainwin, "callCreated");
|
||||
|
|
@ -406,8 +407,12 @@ void App::setSelf(QSharedPointer<App>(me)) {
|
|||
mustBeInMainThread(log().arg(Q_FUNC_INFO));
|
||||
// There is an account added by a remote provisioning, force switching to main page
|
||||
// because the account may not be connected already
|
||||
QMetaObject::invokeMethod(mMainWindow, "openMainPage", Qt::DirectConnection,
|
||||
Q_ARG(QVariant, accountConnected));
|
||||
// if (accountConnected)
|
||||
if (mPossiblyLookForAddedAccount) {
|
||||
QMetaObject::invokeMethod(mMainWindow, "openMainPage", Qt::DirectConnection,
|
||||
Q_ARG(QVariant, accountConnected));
|
||||
}
|
||||
mPossiblyLookForAddedAccount = false;
|
||||
});
|
||||
}
|
||||
});
|
||||
|
|
@ -430,6 +435,43 @@ void App::setSelf(QSharedPointer<App>(me)) {
|
|||
});
|
||||
});
|
||||
|
||||
// Check update
|
||||
mCoreModelConnection->makeConnectToModel(
|
||||
&CoreModel::versionUpdateCheckResultReceived,
|
||||
[this](const std::shared_ptr<linphone::Core> &core, linphone::VersionUpdateCheckResult result,
|
||||
const std::string &version, const std::string &url, bool checkRequestedByUser) {
|
||||
mustBeInLinphoneThread(log().arg(Q_FUNC_INFO));
|
||||
mCoreModelConnection->invokeToCore([this, result, version, url, checkRequestedByUser] {
|
||||
switch (result) {
|
||||
case linphone::VersionUpdateCheckResult::Error:
|
||||
Utils::showInformationPopup(tr("info_popup_error_title"),
|
||||
//: An error occured while trying to check update. Please
|
||||
//: try again later or contact support team.
|
||||
tr("info_popup_error_checking_update"), false);
|
||||
break;
|
||||
case linphone::VersionUpdateCheckResult::NewVersionAvailable: {
|
||||
QString downloadLink =
|
||||
QStringLiteral("<a href='%1'><font color='DefaultStyle.main2_600'>%2</a>")
|
||||
.arg(url)
|
||||
//: Download it !
|
||||
.arg(tr("info_popup_new_version_download_label"));
|
||||
Utils::showInformationPopup(
|
||||
//: New version available !
|
||||
tr("info_popup_new_version_available_title"),
|
||||
//: A new version of Linphone (%1) is available. %2
|
||||
tr("info_popup_new_version_available_message").arg(version).arg(downloadLink));
|
||||
break;
|
||||
}
|
||||
case linphone::VersionUpdateCheckResult::UpToDate:
|
||||
if (checkRequestedByUser)
|
||||
//: Up to date
|
||||
Utils::showInformationPopup(tr("info_popup_version_up_to_date_title"),
|
||||
//: Your version is up to date
|
||||
tr("info_popup_version_up_to_date_message"));
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
//---------------------------------------------------------------------------------------------
|
||||
mCliModelConnection = SafeConnection<App, CliModel>::create(me, CliModel::getInstance());
|
||||
mCliModelConnection->makeConnectToCore(&App::receivedMessage, [this](int, const QByteArray &byteArray) {
|
||||
|
|
@ -646,20 +688,24 @@ void App::initCore() {
|
|||
} else lInfo() << log().arg("Stay minimized");
|
||||
firstOpen = false;
|
||||
lInfo() << log().arg("Checking remote provisioning");
|
||||
if (CoreModel::getInstance()->mConfigStatus == linphone::ConfiguringState::Failed &&
|
||||
mIsRestarting) {
|
||||
QMetaObject::invokeMethod(thread(), [this]() {
|
||||
auto message = CoreModel::getInstance()->mConfigMessage;
|
||||
//: not reachable
|
||||
if (message.isEmpty()) message = tr("configuration_error_detail");
|
||||
mustBeInMainThread(log().arg(Q_FUNC_INFO));
|
||||
//: Error
|
||||
Utils::showInformationPopup(
|
||||
tr("info_popup_error_title"),
|
||||
//: Remote provisioning failed : %1
|
||||
tr("info_popup_configuration_failed_message").arg(message), false);
|
||||
});
|
||||
if (mIsRestarting) {
|
||||
if (CoreModel::getInstance()->mConfigStatus == linphone::ConfiguringState::Failed) {
|
||||
QMetaObject::invokeMethod(thread(), [this]() {
|
||||
auto message = CoreModel::getInstance()->mConfigMessage;
|
||||
//: not reachable
|
||||
if (message.isEmpty()) message = tr("configuration_error_detail");
|
||||
mustBeInMainThread(log().arg(Q_FUNC_INFO));
|
||||
//: Error
|
||||
Utils::showInformationPopup(
|
||||
tr("info_popup_error_title"),
|
||||
//: Remote provisioning failed : %1
|
||||
tr("info_popup_configuration_failed_message").arg(message), false);
|
||||
});
|
||||
} else {
|
||||
mPossiblyLookForAddedAccount = true;
|
||||
}
|
||||
}
|
||||
checkForUpdate();
|
||||
mIsRestarting = false;
|
||||
|
||||
//---------------------------------------------------------------------------------------------
|
||||
|
|
@ -1024,7 +1070,38 @@ bool App::notify(QObject *receiver, QEvent *event) {
|
|||
return done;
|
||||
}
|
||||
|
||||
QQuickWindow *App::getCallsWindow(QVariant callGui) {
|
||||
void App::handleAppActivity() {
|
||||
auto handle = [this](QSharedPointer<AccountCore> accountCore) {
|
||||
if (!accountCore) return;
|
||||
auto accountPresence = accountCore->getPresence();
|
||||
if ((mMainWindow && mMainWindow->isActive() || (mCallsWindow && mCallsWindow->isActive())) &&
|
||||
accountPresence == LinphoneEnums::Presence::Away)
|
||||
accountCore->lSetPresence(LinphoneEnums::Presence::Online);
|
||||
if (((!mMainWindow || !mMainWindow->isActive()) && (!mCallsWindow || !mCallsWindow->isActive())) &&
|
||||
accountPresence == LinphoneEnums::Presence::Online)
|
||||
accountCore->lSetPresence(LinphoneEnums::Presence::Away);
|
||||
};
|
||||
if (mAccountList) {
|
||||
for (auto &account : mAccountList->getSharedList<AccountCore>())
|
||||
handle(account);
|
||||
} else {
|
||||
connect(
|
||||
this, &App::accountsChanged, this,
|
||||
[this, &handle] {
|
||||
if (mAccountList) {
|
||||
for (auto &account : mAccountList->getSharedList<AccountCore>())
|
||||
handle(account);
|
||||
}
|
||||
},
|
||||
Qt::SingleShotConnection);
|
||||
}
|
||||
}
|
||||
|
||||
QQuickWindow *App::getCallsWindow() {
|
||||
return mCallsWindow;
|
||||
}
|
||||
|
||||
QQuickWindow *App::getOrCreateCallsWindow(QVariant callGui) {
|
||||
mustBeInMainThread(getClassName());
|
||||
if (!mCallsWindow) {
|
||||
const QUrl callUrl("qrc:/qt/qml/Linphone/view/Page/Window/Call/CallsWindow.qml");
|
||||
|
|
@ -1059,6 +1136,7 @@ QQuickWindow *App::getCallsWindow(QVariant callGui) {
|
|||
}
|
||||
// window->setParent(mMainWindow);
|
||||
mCallsWindow = window;
|
||||
connect(mCallsWindow, &QQuickWindow::activeChanged, this, &App::handleAppActivity);
|
||||
}
|
||||
if (!callGui.isNull() && callGui.isValid()) mCallsWindow->setProperty("call", callGui);
|
||||
return mCallsWindow;
|
||||
|
|
@ -1081,8 +1159,11 @@ QQuickWindow *App::getMainWindow() const {
|
|||
}
|
||||
|
||||
void App::setMainWindow(QQuickWindow *data) {
|
||||
if (mMainWindow) disconnect(mMainWindow, &QQuickWindow::activeChanged, this, nullptr);
|
||||
if (mMainWindow != data) {
|
||||
mMainWindow = data;
|
||||
connect(mMainWindow, &QQuickWindow::activeChanged, this, &App::handleAppActivity);
|
||||
handleAppActivity();
|
||||
emit mainWindowChanged();
|
||||
}
|
||||
}
|
||||
|
|
@ -1357,6 +1438,12 @@ void App::setSysTrayIcon() {
|
|||
menu->addSeparator();
|
||||
}
|
||||
menu->addAction(markAllReadAction);
|
||||
//: Check for update
|
||||
if (mSettings->isCheckForUpdateAvailable()) {
|
||||
QAction *checkForUpdateAction = new QAction(tr("check_for_update"), root);
|
||||
root->connect(checkForUpdateAction, &QAction::triggered, this, [this] { checkForUpdate(true); });
|
||||
menu->addAction(checkForUpdateAction);
|
||||
}
|
||||
menu->addAction(quitAction);
|
||||
if (!mSystemTrayIcon) {
|
||||
systemTrayIcon->setContextMenu(menu); // This is a Qt bug. We cannot call setContextMenu more than once. So
|
||||
|
|
@ -1436,6 +1523,21 @@ QString App::getSdkVersion() {
|
|||
#endif
|
||||
}
|
||||
|
||||
QString App::getQtVersion() const {
|
||||
return qVersion();
|
||||
}
|
||||
|
||||
void App::checkForUpdate(bool requestedByUser) {
|
||||
mustBeInMainThread(log().arg(Q_FUNC_INFO));
|
||||
if (CoreModel::getInstance() && mCoreModelConnection) {
|
||||
mCoreModelConnection->invokeToModel([this, requestedByUser] {
|
||||
mustBeInLinphoneThread(log().arg(Q_FUNC_INFO));
|
||||
CoreModel::getInstance()->checkForUpdate(Utils::appStringToCoreString(applicationVersion()),
|
||||
requestedByUser);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
ChatGui *App::getCurrentChat() const {
|
||||
return mCurrentChat;
|
||||
}
|
||||
|
|
@ -1464,4 +1566,4 @@ QAction *App::createMarkAsReadAction(QQuickWindow *window) {
|
|||
mCoreModelConnection->invokeToModel([this]() { CoreModel::getInstance()->unreadNotificationsChanged(); });
|
||||
});
|
||||
return markAllReadAction;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -46,6 +46,7 @@ class App : public SingleApplication, public AbstractObject {
|
|||
Q_PROPERTY(AccountList *accounts READ getAccounts NOTIFY accountsChanged)
|
||||
Q_PROPERTY(CallList *calls READ getCalls NOTIFY callsChanged)
|
||||
Q_PROPERTY(QString shortApplicationVersion READ getShortApplicationVersion CONSTANT)
|
||||
Q_PROPERTY(QString qtVersion READ getQtVersion CONSTANT)
|
||||
Q_PROPERTY(QString gitBranchName READ getGitBranchName CONSTANT)
|
||||
Q_PROPERTY(QString sdkVersion READ getSdkVersion CONSTANT)
|
||||
Q_PROPERTY(ChatGui *currentChat READ getCurrentChat WRITE setCurrentChat NOTIFY currentChatChanged)
|
||||
|
|
@ -138,7 +139,9 @@ public:
|
|||
bool getCoreStarted() const;
|
||||
void setCoreStarted(bool started);
|
||||
|
||||
QQuickWindow *getCallsWindow(QVariant callGui = QVariant());
|
||||
QQuickWindow *getCallsWindow();
|
||||
Q_INVOKABLE void handleAppActivity();
|
||||
QQuickWindow *getOrCreateCallsWindow(QVariant callGui = QVariant());
|
||||
void setCallsWindowProperty(const char *id, QVariant property);
|
||||
void closeCallsWindow();
|
||||
|
||||
|
|
@ -164,7 +167,9 @@ public:
|
|||
QString getShortApplicationVersion();
|
||||
QString getGitBranchName();
|
||||
QString getSdkVersion();
|
||||
QString getQtVersion() const;
|
||||
|
||||
Q_INVOKABLE void checkForUpdate(bool requestedByUser = false);
|
||||
ChatGui *getCurrentChat() const;
|
||||
void setCurrentChat(ChatGui *chat);
|
||||
|
||||
|
|
@ -221,6 +226,7 @@ private:
|
|||
bool mAutoStart = false;
|
||||
bool mCoreStarted = false;
|
||||
bool mIsRestarting = false;
|
||||
bool mPossiblyLookForAddedAccount = false;
|
||||
QLocale mLocale = QLocale::system();
|
||||
DefaultTranslatorCore *mTranslatorCore = nullptr;
|
||||
DefaultTranslatorCore *mDefaultTranslatorCore = nullptr;
|
||||
|
|
|
|||
|
|
@ -84,6 +84,7 @@ AccountCore::AccountCore(const std::shared_ptr<linphone::Account> &account) : QO
|
|||
? Utils::coreStringToAppString(params->getAudioVideoConferenceFactoryAddress()->asString())
|
||||
: "";
|
||||
mLimeServerUrl = Utils::coreStringToAppString(params->getLimeServerUrl());
|
||||
mCcmpServerUrl = Utils::coreStringToAppString(params->getCcmpServerUrl());
|
||||
|
||||
// Add listener
|
||||
mAccountModel = Utils::makeQObject_ptr<AccountModel>(account); // OK
|
||||
|
|
@ -148,6 +149,7 @@ AccountCore::AccountCore(const AccountCore &accountCore) {
|
|||
mConferenceFactoryAddress = accountCore.mConferenceFactoryAddress;
|
||||
mAudioVideoConferenceFactoryAddress = accountCore.mAudioVideoConferenceFactoryAddress;
|
||||
mLimeServerUrl = accountCore.mLimeServerUrl;
|
||||
mCcmpServerUrl = accountCore.mCcmpServerUrl;
|
||||
}
|
||||
|
||||
void AccountCore::setSelf(QSharedPointer<AccountCore> me) {
|
||||
|
|
@ -236,6 +238,10 @@ void AccountCore::setSelf(QSharedPointer<AccountCore> me) {
|
|||
mAccountModelConnection->makeConnectToModel(&AccountModel::limeServerUrlChanged, [this](QString value) {
|
||||
mAccountModelConnection->invokeToCore([this, value]() { onLimeServerUrlChanged(value); });
|
||||
});
|
||||
mAccountModelConnection->makeConnectToModel(&AccountModel::ccmpServerUrlChanged, [this](QString value) {
|
||||
mAccountModelConnection->invokeToCore([this, value]() { onCcmpServerUrlChanged(value); });
|
||||
});
|
||||
|
||||
mAccountModelConnection->makeConnectToModel(
|
||||
&AccountModel::removed, [this]() { mAccountModelConnection->invokeToCore([this]() { emit removed(); }); });
|
||||
|
||||
|
|
@ -327,6 +333,7 @@ void AccountCore::reset(const AccountCore &accountCore) {
|
|||
setConferenceFactoryAddress(accountCore.mConferenceFactoryAddress);
|
||||
setAudioVideoConferenceFactoryAddress(accountCore.mAudioVideoConferenceFactoryAddress);
|
||||
setLimeServerUrl(accountCore.mLimeServerUrl);
|
||||
setCcmpServerUrl(accountCore.mCcmpServerUrl);
|
||||
}
|
||||
|
||||
const std::shared_ptr<AccountModel> &AccountCore::getModel() const {
|
||||
|
|
@ -574,6 +581,10 @@ QString AccountCore::getLimeServerUrl() {
|
|||
return mLimeServerUrl;
|
||||
}
|
||||
|
||||
QString AccountCore::getCcmpServerUrl() {
|
||||
return mCcmpServerUrl;
|
||||
}
|
||||
|
||||
void AccountCore::setMwiServerAddress(QString value) {
|
||||
if (mMwiServerAddress != value) {
|
||||
mMwiServerAddress = value;
|
||||
|
|
@ -678,6 +689,14 @@ void AccountCore::setLimeServerUrl(QString value) {
|
|||
}
|
||||
}
|
||||
|
||||
void AccountCore::setCcmpServerUrl(QString value) {
|
||||
if (mCcmpServerUrl != value) {
|
||||
mCcmpServerUrl = value;
|
||||
emit ccmpServerUrlChanged();
|
||||
setIsSaved(false);
|
||||
}
|
||||
}
|
||||
|
||||
bool AccountCore::isSaved() const {
|
||||
return mIsSaved;
|
||||
}
|
||||
|
|
@ -790,6 +809,13 @@ void AccountCore::onLimeServerUrlChanged(QString value) {
|
|||
}
|
||||
}
|
||||
|
||||
void AccountCore::onCcmpServerUrlChanged(QString value) {
|
||||
if (value != mCcmpServerUrl) {
|
||||
mCcmpServerUrl = value;
|
||||
emit ccmpServerUrlChanged();
|
||||
}
|
||||
}
|
||||
|
||||
void AccountCore::writeIntoModel(std::shared_ptr<AccountModel> model) const {
|
||||
mustBeInLinphoneThread(getClassName() + Q_FUNC_INFO);
|
||||
model->setMwiServerAddress(mMwiServerAddress);
|
||||
|
|
@ -806,6 +832,7 @@ void AccountCore::writeIntoModel(std::shared_ptr<AccountModel> model) const {
|
|||
model->setConferenceFactoryAddress(mConferenceFactoryAddress);
|
||||
model->setAudioVideoConferenceFactoryAddress(mAudioVideoConferenceFactoryAddress);
|
||||
model->setLimeServerUrl(mLimeServerUrl);
|
||||
model->setCcmpServerUrl(mCcmpServerUrl);
|
||||
model->setVoicemailAddress(mVoicemailAddress);
|
||||
}
|
||||
|
||||
|
|
@ -825,6 +852,7 @@ void AccountCore::writeFromModel(const std::shared_ptr<AccountModel> &model) {
|
|||
onConferenceFactoryAddressChanged(model->getConferenceFactoryAddress());
|
||||
onAudioVideoConferenceFactoryAddressChanged(model->getAudioVideoConferenceFactoryAddress());
|
||||
onLimeServerUrlChanged(model->getLimeServerUrl());
|
||||
onCcmpServerUrlChanged(model->getCcmpServerUrl());
|
||||
onVoicemailAddressChanged(model->getVoicemailAddress());
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -84,6 +84,7 @@ public:
|
|||
Q_PROPERTY(LinphoneEnums::Presence explicitPresence MEMBER mExplicitPresence NOTIFY presenceChanged)
|
||||
Q_PROPERTY(QString presenceNote READ getPresenceNote WRITE setPresenceNote NOTIFY presenceChanged)
|
||||
Q_PROPERTY(int maxPresenceNoteSize MEMBER mMaxPresenceNoteSize CONSTANT)
|
||||
Q_PROPERTY(QString ccmpServerUrl READ getCcmpServerUrl WRITE setCcmpServerUrl NOTIFY ccmpServerUrlChanged)
|
||||
|
||||
DECLARE_CORE_GET(int, voicemailCount, VoicemailCount)
|
||||
static QSharedPointer<AccountCore> create(const std::shared_ptr<linphone::Account> &account);
|
||||
|
|
@ -143,6 +144,7 @@ public:
|
|||
QString getAudioVideoConferenceFactoryAddress();
|
||||
QString getLimeServerUrl();
|
||||
QString getVoicemailAddress();
|
||||
QString getCcmpServerUrl();
|
||||
|
||||
void setMwiServerAddress(QString value);
|
||||
void setTransport(QString value);
|
||||
|
|
@ -157,6 +159,7 @@ public:
|
|||
void setAudioVideoConferenceFactoryAddress(QString value);
|
||||
void setLimeServerUrl(QString value);
|
||||
void setVoicemailAddress(QString value);
|
||||
void setCcmpServerUrl(QString value);
|
||||
|
||||
bool isSaved() const;
|
||||
void setIsSaved(bool saved);
|
||||
|
|
@ -175,6 +178,7 @@ public:
|
|||
void onConferenceFactoryAddressChanged(QString value);
|
||||
void onAudioVideoConferenceFactoryAddressChanged(QString value);
|
||||
void onLimeServerUrlChanged(QString value);
|
||||
void onCcmpServerUrlChanged(QString value);
|
||||
|
||||
DECLARE_CORE_GET(bool, showMwi, ShowMwi)
|
||||
|
||||
|
|
@ -220,6 +224,7 @@ signals:
|
|||
void isSavedChanged();
|
||||
void voicemailAddressChanged();
|
||||
void presenceChanged();
|
||||
void ccmpServerUrlChanged();
|
||||
|
||||
void setValueFailed(const QString &error);
|
||||
|
||||
|
|
@ -268,6 +273,7 @@ private:
|
|||
QString mAudioVideoConferenceFactoryAddress;
|
||||
QString mLimeServerUrl;
|
||||
QString mVoicemailAddress;
|
||||
QString mCcmpServerUrl;
|
||||
LinphoneEnums::Presence mPresence = LinphoneEnums::Presence::Undefined;
|
||||
LinphoneEnums::Presence mExplicitPresence;
|
||||
QString mPresenceNote;
|
||||
|
|
|
|||
|
|
@ -73,10 +73,10 @@ void CarddavCore::remove() {
|
|||
|
||||
void CarddavCore::setSelf(QSharedPointer<CarddavCore> me) {
|
||||
mCarddavModelConnection = SafeConnection<CarddavCore, CarddavModel>::create(me, mCarddavModel);
|
||||
mCarddavModelConnection->makeConnectToModel(&CarddavModel::saved, [this](bool success) {
|
||||
mCarddavModelConnection->invokeToCore([this, success]() {
|
||||
if (success) emit App::getInstance()->getSettings()->cardDAVAddressBookSynchronized();
|
||||
emit saved(success);
|
||||
mCarddavModelConnection->makeConnectToModel(&CarddavModel::saved, [this](bool success, QString message) {
|
||||
mCarddavModelConnection->invokeToCore([this, success, message]() {
|
||||
if (success) emit App::getInstance() -> getSettings()->cardDAVAddressBookSynchronized();
|
||||
emit saved(success, message);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
|
|
|||
|
|
@ -50,7 +50,7 @@ public:
|
|||
DECLARE_CORE_MEMBER(bool, storeNewFriendsInIt, StoreNewFriendsInIt)
|
||||
|
||||
signals:
|
||||
void saved(bool success);
|
||||
void saved(bool success, QString message);
|
||||
|
||||
private:
|
||||
std::shared_ptr<CarddavModel> mCarddavModel;
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright (c) 2010-2024 Belledonne Communications SARL.
|
||||
* Copyright (c) 2010-2026 Belledonne Communications SARL.
|
||||
*
|
||||
* This file is part of linphone-desktop
|
||||
* (see https://www.linphone.org).
|
||||
|
|
@ -28,6 +28,8 @@
|
|||
#include "tool/Utils.hpp"
|
||||
#include "tool/thread/SafeConnection.hpp"
|
||||
|
||||
#include <QQuickWindow>
|
||||
|
||||
DEFINE_ABSTRACT_OBJECT(CallCore)
|
||||
|
||||
/***********************************************************************/
|
||||
|
|
@ -107,9 +109,11 @@ CallCore::CallCore(const std::shared_ptr<linphone::Call> &call) : QObject(nullpt
|
|||
mCallModel->setSelf(mCallModel);
|
||||
mDuration = call->getDuration();
|
||||
mIsStarted = mDuration > 0;
|
||||
auto videoDirection = call->getParams()->getVideoDirection();
|
||||
auto callParams = call->getParams();
|
||||
auto videoDirection = callParams->getVideoDirection();
|
||||
mLocalVideoEnabled =
|
||||
videoDirection == linphone::MediaDirection::SendOnly || videoDirection == linphone::MediaDirection::SendRecv;
|
||||
mCameraEnabled = callParams->cameraEnabled();
|
||||
auto remoteParams = call->getRemoteParams();
|
||||
videoDirection = remoteParams ? remoteParams->getVideoDirection() : linphone::MediaDirection::Inactive;
|
||||
mRemoteVideoEnabled =
|
||||
|
|
@ -133,7 +137,7 @@ CallCore::CallCore(const std::shared_ptr<linphone::Call> &call) : QObject(nullpt
|
|||
mTransferState = LinphoneEnums::fromLinphone(call->getTransferState());
|
||||
mLocalToken = Utils::coreStringToAppString(mCallModel->getLocalAtuhenticationToken());
|
||||
mRemoteTokens = mCallModel->getRemoteAtuhenticationTokens();
|
||||
mEncryption = LinphoneEnums::fromLinphone(call->getParams()->getMediaEncryption());
|
||||
mEncryption = LinphoneEnums::fromLinphone(callParams->getMediaEncryption());
|
||||
auto tokenVerified = call->getAuthenticationTokenVerified();
|
||||
mIsMismatch = call->getZrtpCacheMismatchFlag();
|
||||
mIsSecured = (mEncryption == LinphoneEnums::MediaEncryption::Zrtp && tokenVerified) ||
|
||||
|
|
@ -160,7 +164,7 @@ CallCore::CallCore(const std::shared_ptr<linphone::Call> &call) : QObject(nullpt
|
|||
mPaused = mState == LinphoneEnums::CallState::Pausing || mState == LinphoneEnums::CallState::Paused ||
|
||||
mState == LinphoneEnums::CallState::PausedByRemote;
|
||||
|
||||
mRecording = call->getParams() && call->getParams()->isRecording();
|
||||
mRecording = callParams && callParams->isRecording();
|
||||
mRemoteRecording = call->getRemoteParams() && call->getRemoteParams()->isRecording();
|
||||
auto settingsModel = SettingsModel::getInstance();
|
||||
mMicrophoneVolume = call->getRecordVolume();
|
||||
|
|
@ -193,8 +197,8 @@ void CallCore::setSelf(QSharedPointer<CallCore> me) {
|
|||
mCallModelConnection->makeConnectToModel(&CallModel::speakerMutedChanged, [this](bool isMuted) {
|
||||
mCallModelConnection->invokeToCore([this, isMuted]() { setSpeakerMuted(isMuted); });
|
||||
});
|
||||
mCallModelConnection->makeConnectToCore(&CallCore::lSetLocalVideoEnabled, [this](bool enabled) {
|
||||
mCallModelConnection->invokeToModel([this, enabled]() { mCallModel->setLocalVideoEnabled(enabled); });
|
||||
mCallModelConnection->makeConnectToCore(&CallCore::lSetCameraEnabled, [this](bool enabled) {
|
||||
mCallModelConnection->invokeToModel([this, enabled]() { mCallModel->setCameraEnabled(enabled); });
|
||||
});
|
||||
mCallModelConnection->makeConnectToCore(&CallCore::lStartRecording, [this]() {
|
||||
mCallModelConnection->invokeToModel([this]() { mCallModel->startRecording(); });
|
||||
|
|
@ -204,15 +208,15 @@ void CallCore::setSelf(QSharedPointer<CallCore> me) {
|
|||
});
|
||||
mCallModelConnection->makeConnectToModel(
|
||||
&CallModel::recordingChanged, [this](const std::shared_ptr<linphone::Call> &call, bool recording) {
|
||||
mCallModelConnection->invokeToCore([this, recording]() {
|
||||
auto recordFile = QString::fromStdString(mCallModel->getRecordFile());
|
||||
mCallModelConnection->invokeToCore([this, recording, recordFile]() {
|
||||
setRecording(recording);
|
||||
if (recording == false) {
|
||||
//: "Enregistrement terminé"
|
||||
Utils::showInformationPopup(tr("call_record_end_message"),
|
||||
//: "L'appel a été enregistré dans le fichier : %1"
|
||||
tr("call_record_saved_in_file_message")
|
||||
.arg(QString::fromStdString(mCallModel->getRecordFile())),
|
||||
true, App::getInstance()->getCallsWindow());
|
||||
tr("call_record_saved_in_file_message").arg(recordFile), true,
|
||||
App::getInstance()->getOrCreateCallsWindow());
|
||||
}
|
||||
});
|
||||
});
|
||||
|
|
@ -244,6 +248,9 @@ void CallCore::setSelf(QSharedPointer<CallCore> me) {
|
|||
mCallModelConnection->makeConnectToModel(&CallModel::localVideoEnabledChanged, [this](bool enabled) {
|
||||
mCallModelConnection->invokeToCore([this, enabled]() { setLocalVideoEnabled(enabled); });
|
||||
});
|
||||
mCallModelConnection->makeConnectToModel(&CallModel::cameraEnabledChanged, [this](bool enabled) {
|
||||
mCallModelConnection->invokeToCore([this, enabled]() { setCameraEnabled(enabled); });
|
||||
});
|
||||
mCallModelConnection->makeConnectToModel(&CallModel::durationChanged, [this](int duration) {
|
||||
mCallModelConnection->invokeToCore([this, duration]() { setDuration(duration); });
|
||||
});
|
||||
|
|
@ -344,6 +351,8 @@ void CallCore::setSelf(QSharedPointer<CallCore> me) {
|
|||
});
|
||||
mCallModelConnection->makeConnectToModel(&CallModel::conferenceChanged, [this]() {
|
||||
auto conference = mCallModel->getMonitor()->getConference();
|
||||
// Force enable video if in conference to handle screen sharing
|
||||
if (conference && !mCallModel->videoEnabled()) mCallModel->enableVideo(true);
|
||||
QSharedPointer<ConferenceCore> core = conference ? ConferenceCore::create(conference) : nullptr;
|
||||
mCallModelConnection->invokeToCore([this, core]() { setConference(core); });
|
||||
});
|
||||
|
|
@ -442,6 +451,44 @@ void CallCore::setSelf(QSharedPointer<CallCore> me) {
|
|||
setVideoStats(videoStats);
|
||||
}
|
||||
});
|
||||
|
||||
mCallModelConnection->makeConnectToModel(&CallModel::headsetAnswerCallRequested, [this]() {
|
||||
mCallModelConnection->invokeToCore([this]() {
|
||||
const auto callList = App::getInstance()->getCallList();
|
||||
const auto currentPendingCall = callList->getFirstIncommingPendingCall();
|
||||
if (!currentPendingCall.isNull()) {
|
||||
const auto gui = new CallGui(currentPendingCall);
|
||||
Utils::openCallsWindow(gui);
|
||||
currentPendingCall->lAccept(false);
|
||||
}
|
||||
});
|
||||
});
|
||||
mCallModelConnection->makeConnectToModel(&CallModel::headsetEndCallRequested, [this]() {
|
||||
mCallModelConnection->invokeToCore([this]() {
|
||||
const auto window = Utils::getOrCreateCallsWindow();
|
||||
window->setProperty("callTerminatedByUser", true);
|
||||
lTerminate();
|
||||
});
|
||||
});
|
||||
mCallModelConnection->makeConnectToModel(&CallModel::headsetHoldCallRequested, [this]() {
|
||||
mCallModelConnection->invokeToCore([this]() { lSetPaused(true); });
|
||||
});
|
||||
mCallModelConnection->makeConnectToModel(&CallModel::headsetMicrophoneMuteToggled, [this](bool mute) {
|
||||
mCallModelConnection->invokeToCore([this, mute]() { lSetMicrophoneMuted(mute); });
|
||||
});
|
||||
mCallModelConnection->makeConnectToModel(&CallModel::headsetRejectCallRequested, [this]() {
|
||||
mCallModelConnection->invokeToCore([this]() {
|
||||
const auto callList = App::getInstance()->getCallList();
|
||||
const auto currentPendingCall = callList->getFirstIncommingPendingCall();
|
||||
if (!currentPendingCall.isNull()) {
|
||||
currentPendingCall->lDecline();
|
||||
}
|
||||
});
|
||||
});
|
||||
mCallModelConnection->makeConnectToModel(&CallModel::headsetResumeCallRequested, [this]() {
|
||||
mCallModelConnection->invokeToCore([this]() { lSetPaused(false); });
|
||||
});
|
||||
|
||||
if (mShouldFindRemoteFriend) findRemoteFriend(me);
|
||||
}
|
||||
|
||||
|
|
@ -558,6 +605,18 @@ void CallCore::setLocalVideoEnabled(bool enabled) {
|
|||
}
|
||||
}
|
||||
|
||||
bool CallCore::getCameraEnabled() const {
|
||||
return mCameraEnabled;
|
||||
}
|
||||
|
||||
void CallCore::setCameraEnabled(bool enabled) {
|
||||
if (mCameraEnabled != enabled) {
|
||||
mCameraEnabled = enabled;
|
||||
lDebug() << "CameraEnabled: " << mCameraEnabled;
|
||||
emit cameraEnabledChanged();
|
||||
}
|
||||
}
|
||||
|
||||
bool CallCore::getPaused() const {
|
||||
return mPaused;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -117,8 +117,8 @@ public:
|
|||
Q_PROPERTY(QStringList remoteTokens WRITE setRemoteTokens MEMBER mRemoteTokens NOTIFY remoteTokensChanged)
|
||||
Q_PROPERTY(
|
||||
bool remoteVideoEnabled READ getRemoteVideoEnabled WRITE setRemoteVideoEnabled NOTIFY remoteVideoEnabledChanged)
|
||||
Q_PROPERTY(
|
||||
bool localVideoEnabled READ getLocalVideoEnabled WRITE lSetLocalVideoEnabled NOTIFY localVideoEnabledChanged)
|
||||
Q_PROPERTY(bool localVideoEnabled READ getLocalVideoEnabled NOTIFY localVideoEnabledChanged)
|
||||
Q_PROPERTY(bool cameraEnabled READ getCameraEnabled WRITE lSetCameraEnabled NOTIFY cameraEnabledChanged)
|
||||
Q_PROPERTY(bool recording READ getRecording WRITE setRecording NOTIFY recordingChanged)
|
||||
Q_PROPERTY(bool remoteRecording READ getRemoteRecording WRITE setRemoteRecording NOTIFY remoteRecordingChanged)
|
||||
Q_PROPERTY(bool recordable READ getRecordable WRITE setRecordable NOTIFY recordableChanged)
|
||||
|
|
@ -201,6 +201,9 @@ public:
|
|||
bool getLocalVideoEnabled() const;
|
||||
void setLocalVideoEnabled(bool enabled);
|
||||
|
||||
bool getCameraEnabled() const;
|
||||
void setCameraEnabled(bool enabled);
|
||||
|
||||
bool getRecording() const;
|
||||
void setRecording(bool recording);
|
||||
|
||||
|
|
@ -255,6 +258,7 @@ signals:
|
|||
void remoteTokensChanged();
|
||||
void remoteVideoEnabledChanged(bool remoteVideoEnabled);
|
||||
void localVideoEnabledChanged();
|
||||
void cameraEnabledChanged();
|
||||
void recordingChanged();
|
||||
void remoteRecordingChanged();
|
||||
void recordableChanged();
|
||||
|
|
@ -275,7 +279,7 @@ signals:
|
|||
void lTerminateAllCalls(); // Hangup all calls
|
||||
void lSetSpeakerMuted(bool muted);
|
||||
void lSetMicrophoneMuted(bool isMuted);
|
||||
void lSetLocalVideoEnabled(bool enabled);
|
||||
void lSetCameraEnabled(bool enabled);
|
||||
void lSetVideoEnabled(bool enabled);
|
||||
void lSetPaused(bool paused);
|
||||
void lTransferCall(QString address);
|
||||
|
|
@ -331,6 +335,7 @@ private:
|
|||
bool mSpeakerMuted = false;
|
||||
bool mMicrophoneMuted = false;
|
||||
bool mLocalVideoEnabled = false;
|
||||
bool mCameraEnabled = false;
|
||||
bool mVideoEnabled = false;
|
||||
bool mPaused = false;
|
||||
bool mRemoteVideoEnabled = false;
|
||||
|
|
|
|||
|
|
@ -33,7 +33,7 @@ class CoreModel;
|
|||
|
||||
class CallList : public ListProxy, public AbstractObject {
|
||||
Q_OBJECT
|
||||
Q_PROPERTY(CallGui* currentCall READ getCurrentCall WRITE setCurrentCall NOTIFY currentCallChanged)
|
||||
Q_PROPERTY(CallGui *currentCall READ getCurrentCall WRITE setCurrentCall NOTIFY currentCallChanged)
|
||||
public:
|
||||
static QSharedPointer<CallList> create();
|
||||
// Create a CallCore and make connections to List.
|
||||
|
|
|
|||
|
|
@ -25,20 +25,32 @@
|
|||
|
||||
DEFINE_ABSTRACT_OBJECT(CallProxy)
|
||||
|
||||
CallProxy::CallProxy(QObject *parent) : LimitProxy(parent) {
|
||||
CallProxy::CallProxy() : SortFilterProxy() {
|
||||
mShowCurrentCall = true;
|
||||
}
|
||||
|
||||
CallProxy::~CallProxy() {
|
||||
}
|
||||
|
||||
CallGui *CallProxy::getCurrentCall() {
|
||||
auto model = getListModel<CallList>();
|
||||
auto model = qobject_cast<CallList *>(sourceModel());
|
||||
if (!mCurrentCall && model) mCurrentCall = model->getCurrentCall();
|
||||
return mCurrentCall;
|
||||
}
|
||||
|
||||
void CallProxy::setShowCurrentCall(bool show) {
|
||||
if (mShowCurrentCall != show) {
|
||||
mShowCurrentCall = show;
|
||||
emit showCurrentCallChanged();
|
||||
}
|
||||
}
|
||||
|
||||
bool CallProxy::showCurrentCall() const {
|
||||
return mShowCurrentCall;
|
||||
}
|
||||
|
||||
void CallProxy::setCurrentCall(CallGui *call) {
|
||||
getListModel<CallList>()->setCurrentCall(call);
|
||||
qobject_cast<CallList *>(sourceModel())->setCurrentCall(call);
|
||||
}
|
||||
|
||||
// Reset the default account to let UI build its new object if needed.
|
||||
|
|
@ -48,12 +60,12 @@ void CallProxy::resetCurrentCall() {
|
|||
}
|
||||
|
||||
bool CallProxy::getHaveCall() const {
|
||||
auto model = getListModel<CallList>();
|
||||
auto model = qobject_cast<CallList *>(sourceModel());
|
||||
return model ? model->getHaveCall() : false;
|
||||
}
|
||||
|
||||
void CallProxy::setSourceModel(QAbstractItemModel *model) {
|
||||
auto oldCallList = getListModel<CallList>();
|
||||
auto oldCallList = qobject_cast<CallList *>(sourceModel());
|
||||
if (oldCallList) {
|
||||
disconnect(oldCallList);
|
||||
}
|
||||
|
|
@ -63,24 +75,24 @@ void CallProxy::setSourceModel(QAbstractItemModel *model) {
|
|||
connect(newCallList, &CallList::haveCallChanged, this, &CallProxy::haveCallChanged, Qt::QueuedConnection);
|
||||
connect(this, &CallProxy::lMergeAll, newCallList, &CallList::lMergeAll);
|
||||
}
|
||||
setSourceModels(new SortFilterList(model));
|
||||
QSortFilterProxyModel::setSourceModel(model);
|
||||
}
|
||||
|
||||
bool CallProxy::SortFilterList::filterAcceptsRow(int sourceRow, const QModelIndex &sourceParent) const {
|
||||
bool CallProxy::filterAcceptsRow(int sourceRow, const QModelIndex &sourceParent) const {
|
||||
bool show = (mFilterText.isEmpty() || mFilterText == "*");
|
||||
auto callList = qobject_cast<CallList *>(sourceModel());
|
||||
auto call = callList->getAt<CallCore>(sourceRow);
|
||||
if (!mShowCurrentCall && call == callList->getCurrentCallCore()) return false;
|
||||
if (!show) {
|
||||
QRegularExpression search(QRegularExpression::escape(mFilterText),
|
||||
QRegularExpression::CaseInsensitiveOption |
|
||||
QRegularExpression::UseUnicodePropertiesOption);
|
||||
auto call = qobject_cast<CallList *>(sourceModel())->getAt<CallCore>(sourceRow);
|
||||
|
||||
show = call->getRemoteAddress().contains(search);
|
||||
}
|
||||
|
||||
return show;
|
||||
}
|
||||
|
||||
bool CallProxy::SortFilterList::lessThan(const QModelIndex &sourceLeft, const QModelIndex &sourceRight) const {
|
||||
bool CallProxy::lessThan(const QModelIndex &sourceLeft, const QModelIndex &sourceRight) const {
|
||||
auto l = getItemAtSource<CallList, CallCore>(sourceLeft.row());
|
||||
auto r = getItemAtSource<CallList, CallCore>(sourceRight.row());
|
||||
|
||||
|
|
|
|||
|
|
@ -28,15 +28,14 @@
|
|||
|
||||
// =============================================================================
|
||||
|
||||
class CallProxy : public LimitProxy, public AbstractObject {
|
||||
class CallProxy : public SortFilterProxy, public AbstractObject {
|
||||
Q_OBJECT
|
||||
Q_PROPERTY(CallGui *currentCall READ getCurrentCall WRITE setCurrentCall NOTIFY currentCallChanged)
|
||||
Q_PROPERTY(bool haveCall READ getHaveCall NOTIFY haveCallChanged)
|
||||
Q_PROPERTY(bool showCurrentCall READ showCurrentCall WRITE setShowCurrentCall NOTIFY showCurrentCallChanged)
|
||||
|
||||
public:
|
||||
DECLARE_SORTFILTER_CLASS()
|
||||
|
||||
CallProxy(QObject *parent = Q_NULLPTR);
|
||||
CallProxy();
|
||||
~CallProxy();
|
||||
|
||||
// Get a new object from List or give the stored one.
|
||||
|
|
@ -48,15 +47,23 @@ public:
|
|||
|
||||
bool getHaveCall() const;
|
||||
|
||||
void setShowCurrentCall(bool show);
|
||||
bool showCurrentCall() const;
|
||||
|
||||
void setSourceModel(QAbstractItemModel *sourceModel) override;
|
||||
|
||||
virtual bool filterAcceptsRow(int sourceRow, const QModelIndex &sourceParent) const override;
|
||||
virtual bool lessThan(const QModelIndex &sourceLeft, const QModelIndex &sourceRight) const override;
|
||||
|
||||
signals:
|
||||
void lMergeAll();
|
||||
void currentCallChanged();
|
||||
void haveCallChanged();
|
||||
void showCurrentCallChanged();
|
||||
|
||||
protected:
|
||||
CallGui *mCurrentCall = nullptr; // When null, a new UI object is build from List
|
||||
bool mShowCurrentCall = false;
|
||||
|
||||
DECLARE_ABSTRACT_OBJECT
|
||||
};
|
||||
|
|
|
|||
|
|
@ -118,6 +118,7 @@ ChatCore::ChatCore(const std::shared_ptr<linphone::ChatRoom> &chatRoom) : QObjec
|
|||
ChatCore::~ChatCore() {
|
||||
lDebug() << "[ChatCore] delete" << this;
|
||||
mustBeInMainThread("~" + getClassName());
|
||||
if (mChatModelConnection) mChatModelConnection->disconnect();
|
||||
emit mChatModel->removeListener();
|
||||
}
|
||||
|
||||
|
|
@ -162,14 +163,13 @@ void ChatCore::setSelf(QSharedPointer<ChatCore> me) {
|
|||
mChatModelConnection->makeConnectToCore(&ChatCore::lDelete, [this]() {
|
||||
mChatModelConnection->invokeToModel([this]() { mChatModel->deleteChatRoom(); });
|
||||
});
|
||||
mChatModelConnection->makeConnectToModel(
|
||||
&ChatModel::deleted, [this]() { mChatModelConnection->invokeToCore([this]() { emit deleted(); }); });
|
||||
|
||||
mChatModelConnection->makeConnectToModel(
|
||||
&ChatModel::stateChanged,
|
||||
[this](const std::shared_ptr<linphone::ChatRoom> &chatRoom, linphone::ChatRoom::State newState) {
|
||||
auto state = LinphoneEnums::fromLinphone(newState);
|
||||
bool isReadOnly = chatRoom->isReadOnly();
|
||||
if (newState == linphone::ChatRoom::State::Deleted) emit deleted();
|
||||
mChatModelConnection->invokeToCore([this, state, isReadOnly]() {
|
||||
setChatRoomState(state);
|
||||
setIsReadOnly(isReadOnly);
|
||||
|
|
@ -207,8 +207,8 @@ void ChatCore::setSelf(QSharedPointer<ChatCore> me) {
|
|||
&ChatModel::newEvent, [this](const std::shared_ptr<linphone::ChatRoom> &chatRoom,
|
||||
const std::shared_ptr<const linphone::EventLog> &eventLog) {
|
||||
if (mChatModel->getMonitor() != chatRoom) return;
|
||||
qDebug() << "EVENT LOG RECEIVED IN CHATROOM" << mChatModel->getTitle();
|
||||
auto event = EventLogCore::create(eventLog);
|
||||
lDebug() << "EVENT LOG RECEIVED IN CHATROOM" << mChatModel->getTitle();
|
||||
auto event = EventLogCore::create(eventLog, chatRoom);
|
||||
if (event->isHandled()) {
|
||||
mChatModelConnection->invokeToCore([this, event]() { emit eventsInserted({event}); });
|
||||
}
|
||||
|
|
@ -220,10 +220,10 @@ void ChatCore::setSelf(QSharedPointer<ChatCore> me) {
|
|||
&ChatModel::chatMessagesReceived, [this](const std::shared_ptr<linphone::ChatRoom> &chatRoom,
|
||||
const std::list<std::shared_ptr<linphone::EventLog>> &eventsLog) {
|
||||
if (mChatModel->getMonitor() != chatRoom) return;
|
||||
qDebug() << "CHAT MESSAGE RECEIVED IN CHATROOM" << mChatModel->getTitle();
|
||||
lDebug() << "CHAT MESSAGE RECEIVED IN CHATROOM" << mChatModel->getTitle();
|
||||
QList<QSharedPointer<EventLogCore>> list;
|
||||
for (auto &e : eventsLog) {
|
||||
auto event = EventLogCore::create(e);
|
||||
auto event = EventLogCore::create(e, chatRoom);
|
||||
list.push_back(event);
|
||||
}
|
||||
mChatModelConnection->invokeToCore([this, list]() {
|
||||
|
|
@ -234,13 +234,14 @@ void ChatCore::setSelf(QSharedPointer<ChatCore> me) {
|
|||
});
|
||||
|
||||
mChatModelConnection->makeConnectToCore(&ChatCore::lMarkAsRead, [this]() {
|
||||
auto mainWindow = Utils::getMainWindow();
|
||||
if (mainWindow->isActive()) mChatModelConnection->invokeToModel([this]() { mChatModel->markAsRead(); });
|
||||
auto lastActiveWindow = Utils::getLastActiveWindow();
|
||||
if (lastActiveWindow && lastActiveWindow->isActive())
|
||||
mChatModelConnection->invokeToModel([this]() { mChatModel->markAsRead(); });
|
||||
else {
|
||||
connect(mainWindow, &QQuickWindow::activeChanged, this, [this, mainWindow] {
|
||||
if (mainWindow->isActive()) {
|
||||
disconnect(mainWindow, &QQuickWindow::activeChanged, this, nullptr);
|
||||
mChatModelConnection->invokeToModel([this, mainWindow] { mChatModel->markAsRead(); });
|
||||
connect(lastActiveWindow, &QQuickWindow::activeChanged, this, [this, lastActiveWindow] {
|
||||
if (lastActiveWindow->isActive()) {
|
||||
disconnect(lastActiveWindow, &QQuickWindow::activeChanged, this, nullptr);
|
||||
mChatModelConnection->invokeToModel([this, lastActiveWindow] { mChatModel->markAsRead(); });
|
||||
}
|
||||
});
|
||||
}
|
||||
|
|
@ -285,7 +286,7 @@ void ChatCore::setSelf(QSharedPointer<ChatCore> me) {
|
|||
mChatModelConnection->makeConnectToModel(
|
||||
&ChatModel::chatMessageSending, [this](const std::shared_ptr<linphone::ChatRoom> &chatRoom,
|
||||
const std::shared_ptr<const linphone::EventLog> &eventLog) {
|
||||
auto event = EventLogCore::create(eventLog);
|
||||
auto event = EventLogCore::create(eventLog, chatRoom);
|
||||
mChatModelConnection->invokeToCore([this, event]() { emit eventsInserted({event}); });
|
||||
});
|
||||
mChatModelConnection->makeConnectToCore(
|
||||
|
|
@ -362,12 +363,16 @@ void ChatCore::setSelf(QSharedPointer<ChatCore> me) {
|
|||
auto participants = buildParticipants(chatRoom);
|
||||
mChatModelConnection->invokeToCore([this, participants]() { setParticipants(participants); });
|
||||
});
|
||||
mChatModelConnection->makeConnectToModel(
|
||||
&ChatModel::participantAdminStatusChanged, [this](const std::shared_ptr<linphone::ChatRoom> &chatRoom,
|
||||
const std::shared_ptr<const linphone::EventLog> &eventLog) {
|
||||
auto participants = buildParticipants(chatRoom);
|
||||
mChatModelConnection->invokeToCore([this, participants]() { setParticipants(participants); });
|
||||
});
|
||||
mChatModelConnection->makeConnectToModel(&ChatModel::participantAdminStatusChanged,
|
||||
[this](const std::shared_ptr<linphone::ChatRoom> &chatRoom,
|
||||
const std::shared_ptr<const linphone::EventLog> &eventLog) {
|
||||
auto participants = buildParticipants(chatRoom);
|
||||
bool meAdmin = chatRoom->getMe()->isAdmin();
|
||||
mChatModelConnection->invokeToCore([this, participants, meAdmin]() {
|
||||
setParticipants(participants);
|
||||
setMeAdmin(meAdmin);
|
||||
});
|
||||
});
|
||||
mChatModelConnection->makeConnectToCore(&ChatCore::lRemoveParticipantAtIndex, [this](int index) {
|
||||
mChatModelConnection->invokeToModel([this, index]() { mChatModel->removeParticipantAtIndex(index); });
|
||||
});
|
||||
|
|
@ -389,6 +394,7 @@ void ChatCore::setSelf(QSharedPointer<ChatCore> me) {
|
|||
[this](std::shared_ptr<linphone::Friend> f) { updateInfo(f); });
|
||||
mCoreModelConnection->makeConnectToModel(&CoreModel::friendRemoved,
|
||||
[this](std::shared_ptr<linphone::Friend> f) { updateInfo(f, true); });
|
||||
|
||||
}
|
||||
|
||||
QDateTime ChatCore::getLastUpdatedTime() const {
|
||||
|
|
@ -491,7 +497,7 @@ ChatMessageGui *ChatCore::getLastMessage() const {
|
|||
|
||||
void ChatCore::setLastMessage(QSharedPointer<ChatMessageCore> lastMessage) {
|
||||
if (mLastMessage != lastMessage) {
|
||||
disconnect(mLastMessage.get());
|
||||
if (mLastMessage) disconnect(mLastMessage.get(), &ChatMessageCore::messageStateChanged, this, nullptr);
|
||||
mLastMessage = lastMessage;
|
||||
connect(mLastMessage.get(), &ChatMessageCore::messageStateChanged, this, &ChatCore::lastMessageChanged);
|
||||
emit lastMessageChanged();
|
||||
|
|
@ -544,10 +550,6 @@ std::shared_ptr<ChatModel> ChatCore::getModel() const {
|
|||
return mChatModel;
|
||||
}
|
||||
|
||||
QSharedPointer<SafeConnection<ChatCore, ChatModel>> ChatCore::getChatModelConnection() const {
|
||||
return mChatModelConnection;
|
||||
}
|
||||
|
||||
bool ChatCore::isMuted() const {
|
||||
return mIsMuted;
|
||||
}
|
||||
|
|
@ -681,4 +683,4 @@ void ChatCore::updateInfo(const std::shared_ptr<linphone::Friend> &updatedFriend
|
|||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -64,7 +64,6 @@ public:
|
|||
Q_PROPERTY(
|
||||
int ephemeralLifetime READ getEphemeralLifetime WRITE lSetEphemeralLifetime NOTIFY ephemeralLifetimeChanged)
|
||||
Q_PROPERTY(bool muted READ isMuted WRITE lSetMuted NOTIFY mutedChanged)
|
||||
Q_PROPERTY(bool conferenceJoined MEMBER mConferenceJoined NOTIFY conferenceJoined)
|
||||
Q_PROPERTY(bool meAdmin READ getMeAdmin WRITE setMeAdmin NOTIFY meAdminChanged)
|
||||
Q_PROPERTY(QVariantList participants READ getParticipantsGui NOTIFY participantsChanged)
|
||||
Q_PROPERTY(QStringList participantsAddresses READ getParticipantsAddresses WRITE lSetParticipantsAddresses NOTIFY
|
||||
|
|
@ -142,7 +141,6 @@ public:
|
|||
void setComposingAddress(QString composingAddress);
|
||||
|
||||
std::shared_ptr<ChatModel> getModel() const;
|
||||
QSharedPointer<SafeConnection<ChatCore, ChatModel>> getChatModelConnection() const;
|
||||
|
||||
void setParticipants(QList<QSharedPointer<ParticipantCore>> participants);
|
||||
QList<QSharedPointer<ParticipantCore>> buildParticipants(const std::shared_ptr<linphone::ChatRoom> &chatRoom) const;
|
||||
|
|
|
|||
|
|
@ -54,13 +54,15 @@ ChatList::~ChatList() {
|
|||
}
|
||||
|
||||
void ChatList::connectItem(QSharedPointer<ChatCore> chat) {
|
||||
connect(chat.get(), &ChatCore::deleted, this, [this, chat] {
|
||||
disconnect(chat.get());
|
||||
remove(chat);
|
||||
// We cannot use countChanged here because it is called before mList
|
||||
// really has removed the item, then emit specific signal
|
||||
emit chatRemoved(chat ? new ChatGui(chat) : nullptr);
|
||||
});
|
||||
connect(
|
||||
chat.get(), &ChatCore::deleted, this,
|
||||
[this, chat] {
|
||||
disconnect(chat.get(), &ChatCore::unreadMessagesCountChanged, this, nullptr);
|
||||
disconnect(chat.get(), &ChatCore::lastUpdatedTimeChanged, this, nullptr);
|
||||
disconnect(chat.get(), &ChatCore::lastMessageChanged, this, nullptr);
|
||||
remove(chat);
|
||||
},
|
||||
Qt::SingleShotConnection);
|
||||
auto dataChange = [this, chat] {
|
||||
int i = -1;
|
||||
get(chat.get(), &i);
|
||||
|
|
@ -94,7 +96,6 @@ void ChatList::setSelf(QSharedPointer<ChatList> me) {
|
|||
mModelConnection->invokeToModel([this]() {
|
||||
mustBeInLinphoneThread(getClassName());
|
||||
beginResetModel();
|
||||
mList.clear();
|
||||
// Avoid copy to lambdas
|
||||
QList<QSharedPointer<ChatCore>> *chats = new QList<QSharedPointer<ChatCore>>();
|
||||
auto currentAccount = CoreModel::getInstance()->getCore()->getDefaultAccount();
|
||||
|
|
@ -118,6 +119,7 @@ void ChatList::setSelf(QSharedPointer<ChatList> me) {
|
|||
disconnect(chat.get(), &ChatCore::lastMessageChanged, this, nullptr);
|
||||
}
|
||||
}
|
||||
mList.clear();
|
||||
for (auto &chat : *chats) {
|
||||
connectItem(chat);
|
||||
}
|
||||
|
|
@ -143,18 +145,7 @@ void ChatList::setSelf(QSharedPointer<ChatList> me) {
|
|||
return;
|
||||
}
|
||||
auto chatCore = ChatCore::create(room);
|
||||
mModelConnection->invokeToCore([this, chatCore] {
|
||||
auto chatList = getSharedList<ChatCore>();
|
||||
auto it = std::find_if(chatList.begin(), chatList.end(), [chatCore](const QSharedPointer<ChatCore> item) {
|
||||
return item && chatCore && item->getModel() && chatCore->getModel() &&
|
||||
item->getModel()->getMonitor() == chatCore->getModel()->getMonitor();
|
||||
});
|
||||
if (it == chatList.end()) {
|
||||
connectItem(chatCore);
|
||||
add(chatCore);
|
||||
emit chatAdded();
|
||||
}
|
||||
});
|
||||
mModelConnection->invokeToCore([this, chatCore] { addChatInList(chatCore); });
|
||||
};
|
||||
mModelConnection->makeConnectToModel(&CoreModel::messageReceived,
|
||||
[this, addChatToList](const std::shared_ptr<linphone::Core> &core,
|
||||
|
|
@ -195,17 +186,19 @@ int ChatList::findChatIndex(ChatGui *chatGui) {
|
|||
return it == chatList.end() ? -1 : std::distance(chatList.begin(), it);
|
||||
}
|
||||
|
||||
void ChatList::addChatInList(QSharedPointer<ChatCore> chatCore) {
|
||||
bool ChatList::addChatInList(QSharedPointer<ChatCore> chatCore) {
|
||||
mustBeInMainThread(log().arg(Q_FUNC_INFO));
|
||||
auto chatList = getSharedList<ChatCore>();
|
||||
auto it = std::find_if(chatList.begin(), chatList.end(), [chatCore](const QSharedPointer<ChatCore> item) {
|
||||
return item && chatCore && item->getModel() && chatCore->getModel() &&
|
||||
item->getModel()->getMonitor() == chatCore->getModel()->getMonitor();
|
||||
return item && chatCore && item->getIdentifier() == chatCore->getIdentifier();
|
||||
});
|
||||
if (it == chatList.end()) {
|
||||
connectItem(chatCore);
|
||||
add(chatCore);
|
||||
emit chatAdded();
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
QVariant ChatList::data(const QModelIndex &index, int role) const {
|
||||
|
|
|
|||
|
|
@ -42,13 +42,12 @@ public:
|
|||
void connectItem(QSharedPointer<ChatCore> chat);
|
||||
|
||||
int findChatIndex(ChatGui *chat);
|
||||
void addChatInList(QSharedPointer<ChatCore> chatCore);
|
||||
bool addChatInList(QSharedPointer<ChatCore> chatCore);
|
||||
virtual QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const override;
|
||||
|
||||
signals:
|
||||
void lUpdate();
|
||||
void filterChanged(QString filter);
|
||||
void chatRemoved(ChatGui *chat);
|
||||
void chatAdded();
|
||||
void chatUpdated();
|
||||
|
||||
|
|
|
|||
|
|
@ -25,7 +25,7 @@
|
|||
|
||||
DEFINE_ABSTRACT_OBJECT(ChatProxy)
|
||||
|
||||
ChatProxy::ChatProxy(QObject *parent) : LimitProxy(parent) {
|
||||
ChatProxy::ChatProxy(QObject *parent) {
|
||||
mList = ChatList::create();
|
||||
setSourceModel(mList.get());
|
||||
setDynamicSortFilter(true);
|
||||
|
|
@ -35,53 +35,47 @@ ChatProxy::~ChatProxy() {
|
|||
}
|
||||
|
||||
void ChatProxy::setSourceModel(QAbstractItemModel *model) {
|
||||
auto oldChatList = getListModel<ChatList>();
|
||||
auto oldChatList = dynamic_cast<ChatList *>(sourceModel());
|
||||
if (oldChatList) {
|
||||
disconnect(oldChatList);
|
||||
disconnect(this, &ChatProxy::filterTextChanged, oldChatList, nullptr);
|
||||
disconnect(oldChatList, &ChatList::chatAdded, this, nullptr);
|
||||
disconnect(oldChatList, &ChatList::dataChanged, this, nullptr);
|
||||
}
|
||||
auto newChatList = dynamic_cast<ChatList *>(model);
|
||||
if (newChatList) {
|
||||
connect(this, &ChatProxy::filterTextChanged, newChatList,
|
||||
[this, newChatList] { emit newChatList->filterChanged(getFilterText()); });
|
||||
connect(newChatList, &ChatList::chatRemoved, this, &ChatProxy::chatRemoved);
|
||||
connect(newChatList, &ChatList::chatAdded, this, [this] { invalidate(); });
|
||||
connect(newChatList, &ChatList::dataChanged, this, [this] { invalidate(); });
|
||||
}
|
||||
auto firstList = new SortFilterList(model, Qt::AscendingOrder);
|
||||
firstList->setDynamicSortFilter(true);
|
||||
setSourceModels(firstList);
|
||||
QSortFilterProxyModel::setSourceModel(newChatList);
|
||||
sort(0);
|
||||
}
|
||||
|
||||
int ChatProxy::findChatIndex(ChatGui *chatGui) {
|
||||
auto chatList = getListModel<ChatList>();
|
||||
auto chatList = dynamic_cast<ChatList *>(sourceModel());
|
||||
if (chatList) {
|
||||
auto listIndex = chatList->findChatIndex(chatGui);
|
||||
if (listIndex != -1) {
|
||||
listIndex =
|
||||
dynamic_cast<SortFilterList *>(sourceModel())->mapFromSource(chatList->index(listIndex, 0)).row();
|
||||
if (mMaxDisplayItems <= listIndex) setMaxDisplayItems(listIndex + mDisplayItemsStep);
|
||||
listIndex = mapFromSource(chatList->index(listIndex, 0)).row();
|
||||
return listIndex;
|
||||
}
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
void ChatProxy::addChatInList(ChatGui *chatGui) {
|
||||
auto chatList = getListModel<ChatList>();
|
||||
bool ChatProxy::addChatInList(ChatGui *chatGui) {
|
||||
auto chatList = dynamic_cast<ChatList *>(sourceModel());
|
||||
if (chatList && chatGui) {
|
||||
chatList->addChatInList(chatGui->mCore);
|
||||
return chatList->addChatInList(chatGui->mCore);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool ChatProxy::SortFilterList::filterAcceptsRow(int sourceRow, const QModelIndex &sourceParent) const {
|
||||
return true;
|
||||
}
|
||||
|
||||
bool ChatProxy::SortFilterList::lessThan(const QModelIndex &sourceLeft, const QModelIndex &sourceRight) const {
|
||||
bool ChatProxy::lessThan(const QModelIndex &sourceLeft, const QModelIndex &sourceRight) const {
|
||||
if (!mFilterText.isEmpty()) return false;
|
||||
auto l = getItemAtSource<ChatList, ChatCore>(sourceLeft.row());
|
||||
auto r = getItemAtSource<ChatList, ChatCore>(sourceRight.row());
|
||||
if (l && r) return l->getLastUpdatedTime() >= r->getLastUpdatedTime();
|
||||
if (l && r) return l->getLastUpdatedTime() > r->getLastUpdatedTime();
|
||||
return false;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -21,29 +21,26 @@
|
|||
#ifndef CHAT_PROXY_H_
|
||||
#define CHAT_PROXY_H_
|
||||
|
||||
#include "../proxy/LimitProxy.hpp"
|
||||
#include "../proxy/SortFilterProxy.hpp"
|
||||
#include "core/chat/ChatGui.hpp"
|
||||
#include "core/chat/ChatList.hpp"
|
||||
#include "tool/AbstractObject.hpp"
|
||||
|
||||
// =============================================================================
|
||||
|
||||
class ChatProxy : public LimitProxy, public AbstractObject {
|
||||
class ChatProxy : public SortFilterProxy, public AbstractObject {
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
DECLARE_SORTFILTER_CLASS()
|
||||
|
||||
ChatProxy(QObject *parent = Q_NULLPTR);
|
||||
~ChatProxy();
|
||||
|
||||
void setSourceModel(QAbstractItemModel *sourceModel) override;
|
||||
|
||||
Q_INVOKABLE int findChatIndex(ChatGui *chatGui);
|
||||
Q_INVOKABLE void addChatInList(ChatGui *chatGui);
|
||||
bool lessThan(const QModelIndex &sourceLeft, const QModelIndex &sourceRight) const override;
|
||||
|
||||
signals:
|
||||
void chatRemoved(ChatGui *chat);
|
||||
Q_INVOKABLE int findChatIndex(ChatGui *chatGui);
|
||||
Q_INVOKABLE bool addChatInList(ChatGui *chatGui);
|
||||
|
||||
protected:
|
||||
QSharedPointer<ChatList> mList;
|
||||
|
|
|
|||
|
|
@ -112,88 +112,97 @@ ChatMessageCore::ChatMessageCore(const std::shared_ptr<linphone::ChatMessage> &c
|
|||
// lDebug() << "[ChatMessageCore] new" << this;
|
||||
mustBeInLinphoneThread(getClassName());
|
||||
App::getInstance()->mEngine->setObjectOwnership(this, QQmlEngine::CppOwnership);
|
||||
mChatMessageModel = Utils::makeQObject_ptr<ChatMessageModel>(chatmessage);
|
||||
mChatMessageModel->setSelf(mChatMessageModel);
|
||||
mText = ToolModel::getMessageFromContent(chatmessage->getContents());
|
||||
mUtf8Text = mChatMessageModel->getUtf8Text();
|
||||
mHasTextContent = mChatMessageModel->getHasTextContent();
|
||||
mTimestamp = QDateTime::fromSecsSinceEpoch(chatmessage->getTime());
|
||||
mIsOutgoing = chatmessage->isOutgoing();
|
||||
mIsRemoteMessage = !chatmessage->isOutgoing();
|
||||
mPeerAddress = Utils::coreStringToAppString(chatmessage->getPeerAddress()->asStringUriOnly());
|
||||
mPeerName = ToolModel::getDisplayName(chatmessage->getPeerAddress());
|
||||
auto fromAddress = chatmessage->getFromAddress();
|
||||
// fromAddress->clean();
|
||||
mFromAddress = Utils::coreStringToAppString(fromAddress->asStringUriOnly());
|
||||
mFromName = ToolModel::getDisplayName(chatmessage->getFromAddress());
|
||||
mToName = ToolModel::getDisplayName(chatmessage->getToAddress());
|
||||
if (chatmessage) {
|
||||
mChatMessageModel = Utils::makeQObject_ptr<ChatMessageModel>(chatmessage);
|
||||
mChatMessageModel->setSelf(mChatMessageModel);
|
||||
mText = ToolModel::getMessageFromMessage(chatmessage);
|
||||
mUtf8Text = mChatMessageModel->getUtf8Text();
|
||||
mHasTextContent = mChatMessageModel->getHasTextContent();
|
||||
mTimestamp = QDateTime::fromSecsSinceEpoch(chatmessage->getTime());
|
||||
mIsOutgoing = chatmessage->isOutgoing();
|
||||
mIsRetractable =
|
||||
chatmessage->isOutgoing() && chatmessage->isRetractable() && !chatmessage->getChatRoom()->isReadOnly();
|
||||
mIsRetracted = chatmessage->isRetracted();
|
||||
mIsEditable =
|
||||
chatmessage->isOutgoing() && chatmessage->isEditable() && !chatmessage->getChatRoom()->isReadOnly();
|
||||
mIsEdited = chatmessage->isEdited();
|
||||
mIsRemoteMessage = !chatmessage->isOutgoing();
|
||||
mPeerAddress = Utils::coreStringToAppString(chatmessage->getPeerAddress()->asStringUriOnly());
|
||||
mPeerName = ToolModel::getDisplayName(chatmessage->getPeerAddress());
|
||||
auto fromAddress = chatmessage->getFromAddress();
|
||||
// fromAddress->clean();
|
||||
mFromAddress = Utils::coreStringToAppString(fromAddress->asStringUriOnly());
|
||||
mFromName = ToolModel::getDisplayName(chatmessage->getFromAddress());
|
||||
mToName = ToolModel::getDisplayName(chatmessage->getToAddress());
|
||||
auto chatroom = chatmessage->getChatRoom();
|
||||
mIsFromChatGroup = chatroom->hasCapability((int)linphone::ChatRoom::Capabilities::Conference) &&
|
||||
!chatroom->hasCapability((int)linphone::ChatRoom::Capabilities::OneToOne);
|
||||
mIsRead = chatmessage->isRead();
|
||||
mMessageState = LinphoneEnums::fromLinphone(chatmessage->getState());
|
||||
mIsEphemeral = chatmessage->isEphemeral();
|
||||
|
||||
auto chatroom = chatmessage->getChatRoom();
|
||||
mIsFromChatGroup = chatroom->hasCapability((int)linphone::ChatRoom::Capabilities::Conference) &&
|
||||
!chatroom->hasCapability((int)linphone::ChatRoom::Capabilities::OneToOne);
|
||||
mIsRead = chatmessage->isRead();
|
||||
mMessageState = LinphoneEnums::fromLinphone(chatmessage->getState());
|
||||
mIsEphemeral = chatmessage->isEphemeral();
|
||||
if (mIsEphemeral) {
|
||||
auto now = QDateTime::currentDateTime();
|
||||
mEphemeralDuration = chatmessage->getEphemeralExpireTime() == 0
|
||||
? chatmessage->getEphemeralLifetime()
|
||||
: now.secsTo(QDateTime::fromSecsSinceEpoch(chatmessage->getEphemeralExpireTime()));
|
||||
}
|
||||
mMessageId = Utils::coreStringToAppString(chatmessage->getMessageId());
|
||||
for (auto content : chatmessage->getContents()) {
|
||||
auto contentCore = ChatMessageContentCore::create(content, mChatMessageModel);
|
||||
mChatMessageContentList.push_back(contentCore);
|
||||
if ((content->isFile() || content->isFileTransfer()) && !content->isVoiceRecording()) mHasFileContent = true;
|
||||
if (content->isIcalendar()) mIsCalendarInvite = true;
|
||||
if (content->isVoiceRecording()) {
|
||||
mIsVoiceRecording = true;
|
||||
mVoiceRecordingContent = contentCore;
|
||||
if (mIsEphemeral) {
|
||||
auto now = QDateTime::currentDateTime();
|
||||
mEphemeralDuration = chatmessage->getEphemeralExpireTime() == 0
|
||||
? chatmessage->getEphemeralLifetime()
|
||||
: now.secsTo(QDateTime::fromSecsSinceEpoch(chatmessage->getEphemeralExpireTime()));
|
||||
}
|
||||
}
|
||||
//: "Reactions": all reactions for one message label
|
||||
mTotalReactionsLabel = tr("all_reactions_label");
|
||||
auto reac = chatmessage->getOwnReaction();
|
||||
mOwnReaction = reac ? Utils::coreStringToAppString(reac->getBody()) : QString();
|
||||
for (auto &reaction : chatmessage->getReactions()) {
|
||||
if (reaction) {
|
||||
auto fromAddr = reaction->getFromAddress()->clone();
|
||||
fromAddr->clean();
|
||||
auto reac =
|
||||
Reaction::createMessageReactionVariant(Utils::coreStringToAppString(reaction->getBody()),
|
||||
Utils::coreStringToAppString(fromAddr->asStringUriOnly()));
|
||||
mReactions.append(reac);
|
||||
|
||||
auto it = std::find_if(mReactionsSingletonMap.begin(), mReactionsSingletonMap.end(),
|
||||
[body = reac.mBody](QVariant data) {
|
||||
auto dataBody = data.toMap()["body"].toString();
|
||||
return body == dataBody;
|
||||
});
|
||||
if (it == mReactionsSingletonMap.end())
|
||||
mReactionsSingletonMap.push_back(createReactionSingletonVariant(reac.mBody, 1));
|
||||
else {
|
||||
auto map = it->toMap();
|
||||
auto count = map["count"].toInt();
|
||||
++count;
|
||||
map.remove("count");
|
||||
map.insert("count", count);
|
||||
mReactionsSingletonMap.erase(it);
|
||||
mReactionsSingletonMap.push_back(map);
|
||||
mMessageId = Utils::coreStringToAppString(chatmessage->getMessageId());
|
||||
for (auto content : chatmessage->getContents()) {
|
||||
auto contentCore = ChatMessageContentCore::create(content, mChatMessageModel);
|
||||
mChatMessageContentList.push_back(contentCore);
|
||||
if ((content->isFile() || content->isFileTransfer()) && !content->isVoiceRecording())
|
||||
mHasFileContent = true;
|
||||
if (content->isIcalendar()) mIsCalendarInvite = true;
|
||||
if (content->isVoiceRecording()) {
|
||||
mIsVoiceRecording = true;
|
||||
mVoiceRecordingContent = contentCore;
|
||||
}
|
||||
}
|
||||
}
|
||||
connect(this, &ChatMessageCore::messageReactionChanged, this, &ChatMessageCore::resetReactionsSingleton);
|
||||
//: "Reactions": all reactions for one message label
|
||||
mTotalReactionsLabel = tr("all_reactions_label");
|
||||
auto reac = chatmessage->getOwnReaction();
|
||||
mOwnReaction = reac ? Utils::coreStringToAppString(reac->getBody()) : QString();
|
||||
for (auto &reaction : chatmessage->getReactions()) {
|
||||
if (reaction) {
|
||||
auto fromAddr = reaction->getFromAddress()->clone();
|
||||
fromAddr->clean();
|
||||
auto reac =
|
||||
Reaction::createMessageReactionVariant(Utils::coreStringToAppString(reaction->getBody()),
|
||||
Utils::coreStringToAppString(fromAddr->asStringUriOnly()));
|
||||
mReactions.append(reac);
|
||||
|
||||
mIsForward = chatmessage->isForward();
|
||||
mIsReply = chatmessage->isReply();
|
||||
if (mIsReply) {
|
||||
auto replymessage = chatmessage->getReplyMessage();
|
||||
if (replymessage) {
|
||||
mReplyText = ToolModel::getMessageFromContent(replymessage->getContents());
|
||||
if (mIsFromChatGroup) mRepliedToName = ToolModel::getDisplayName(replymessage->getFromAddress());
|
||||
auto it = std::find_if(mReactionsSingletonMap.begin(), mReactionsSingletonMap.end(),
|
||||
[body = reac.mBody](QVariant data) {
|
||||
auto dataBody = data.toMap()["body"].toString();
|
||||
return body == dataBody;
|
||||
});
|
||||
if (it == mReactionsSingletonMap.end())
|
||||
mReactionsSingletonMap.push_back(createReactionSingletonVariant(reac.mBody, 1));
|
||||
else {
|
||||
auto map = it->toMap();
|
||||
auto count = map["count"].toInt();
|
||||
++count;
|
||||
map.remove("count");
|
||||
map.insert("count", count);
|
||||
mReactionsSingletonMap.erase(it);
|
||||
mReactionsSingletonMap.push_back(map);
|
||||
}
|
||||
}
|
||||
}
|
||||
connect(this, &ChatMessageCore::messageReactionChanged, this, &ChatMessageCore::resetReactionsSingleton);
|
||||
|
||||
mIsForward = chatmessage->isForward();
|
||||
mIsReply = chatmessage->isReply();
|
||||
if (mIsReply) {
|
||||
auto replymessage = chatmessage->getReplyMessage();
|
||||
if (replymessage) {
|
||||
mReplyText = ToolModel::getMessageFromMessage(replymessage);
|
||||
if (mIsFromChatGroup) mRepliedToName = ToolModel::getDisplayName(replymessage->getFromAddress());
|
||||
}
|
||||
}
|
||||
mImdnStatusList = computeDeliveryStatus(chatmessage);
|
||||
}
|
||||
mImdnStatusList = computeDeliveryStatus(chatmessage);
|
||||
}
|
||||
|
||||
ChatMessageCore::~ChatMessageCore() {
|
||||
|
|
@ -204,6 +213,9 @@ void ChatMessageCore::setSelf(QSharedPointer<ChatMessageCore> me) {
|
|||
mChatMessageModelConnection->makeConnectToCore(&ChatMessageCore::lDelete, [this] {
|
||||
mChatMessageModelConnection->invokeToModel([this] { mChatMessageModel->deleteMessageFromChatRoom(true); });
|
||||
});
|
||||
mChatMessageModelConnection->makeConnectToCore(&ChatMessageCore::lRetract, [this] {
|
||||
mChatMessageModelConnection->invokeToModel([this] { mChatMessageModel->retractMessageFromChatRoom(); });
|
||||
});
|
||||
mChatMessageModelConnection->makeConnectToModel(&ChatMessageModel::messageDeleted, [this](bool deletedByUser) {
|
||||
mChatMessageModelConnection->invokeToCore([this, deletedByUser] {
|
||||
//: Deleted
|
||||
|
|
@ -347,6 +359,22 @@ void ChatMessageCore::setSelf(QSharedPointer<ChatMessageCore> me) {
|
|||
int duration = now.secsTo(QDateTime::fromSecsSinceEpoch(expireTime));
|
||||
mChatMessageModelConnection->invokeToCore([this, duration] { setEphemeralDuration(duration); });
|
||||
});
|
||||
|
||||
mChatMessageModelConnection->makeConnectToModel(&ChatMessageModel::retracted,
|
||||
[this](const std::shared_ptr<linphone::ChatMessage> &message) {
|
||||
QString text = ToolModel::getMessageFromMessage(message);
|
||||
mChatMessageModelConnection->invokeToCore([this, text] {
|
||||
setText(text);
|
||||
setRetracted();
|
||||
});
|
||||
});
|
||||
mChatMessageModelConnection->makeConnectToModel(&ChatMessageModel::contentEdited,
|
||||
[this](const std::shared_ptr<linphone::ChatMessage> &message) {
|
||||
mChatMessageModelConnection->invokeToCore([this] {
|
||||
mIsEdited = true;
|
||||
emit edited();
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
QList<ImdnStatus> ChatMessageCore::computeDeliveryStatus(const std::shared_ptr<linphone::ChatMessage> &message) {
|
||||
|
|
@ -469,6 +497,22 @@ void ChatMessageCore::setIsRead(bool read) {
|
|||
}
|
||||
}
|
||||
|
||||
void ChatMessageCore::setRetracted() {
|
||||
if (!mIsRetracted) {
|
||||
mIsRetracted = true;
|
||||
emit isRetractedChanged();
|
||||
emit messageStateChanged();
|
||||
}
|
||||
}
|
||||
|
||||
bool ChatMessageCore::isRetracted() const {
|
||||
return mIsRetracted;
|
||||
}
|
||||
|
||||
bool ChatMessageCore::isEdited() const {
|
||||
return mIsEdited;
|
||||
}
|
||||
|
||||
QString ChatMessageCore::getOwnReaction() const {
|
||||
return mOwnReaction;
|
||||
}
|
||||
|
|
@ -647,4 +691,4 @@ std::shared_ptr<ChatMessageModel> ChatMessageCore::getModel() const {
|
|||
|
||||
ChatMessageContentGui *ChatMessageCore::getVoiceRecordingContent() const {
|
||||
return new ChatMessageContentGui(mVoiceRecordingContent);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -111,6 +111,11 @@ class ChatMessageCore : public QObject, public AbstractObject {
|
|||
Q_PROPERTY(bool hasFileContent MEMBER mHasFileContent CONSTANT)
|
||||
Q_PROPERTY(bool isVoiceRecording MEMBER mIsVoiceRecording CONSTANT)
|
||||
Q_PROPERTY(bool isCalendarInvite MEMBER mIsCalendarInvite CONSTANT)
|
||||
Q_PROPERTY(bool isOutgoing MEMBER mIsOutgoing CONSTANT)
|
||||
Q_PROPERTY(bool isRetractable MEMBER mIsRetractable CONSTANT)
|
||||
Q_PROPERTY(bool isRetracted READ isRetracted NOTIFY isRetractedChanged)
|
||||
Q_PROPERTY(bool isEditable MEMBER mIsEditable CONSTANT)
|
||||
Q_PROPERTY(bool isEdited READ isEdited NOTIFY edited)
|
||||
|
||||
public:
|
||||
static QSharedPointer<ChatMessageCore> create(const std::shared_ptr<linphone::ChatMessage> &chatmessage);
|
||||
|
|
@ -143,6 +148,10 @@ public:
|
|||
bool isRead() const;
|
||||
void setIsRead(bool read);
|
||||
|
||||
bool isRetracted() const;
|
||||
void setRetracted();
|
||||
bool isEdited() const;
|
||||
|
||||
QString getOwnReaction() const;
|
||||
void setOwnReaction(const QString &reaction);
|
||||
QString getTotalReactionsLabel() const;
|
||||
|
|
@ -176,9 +185,12 @@ signals:
|
|||
void messageReactionChanged();
|
||||
void singletonReactionMapChanged();
|
||||
void ephemeralDurationChanged(int duration);
|
||||
void isRetractedChanged();
|
||||
void edited();
|
||||
|
||||
void lDelete();
|
||||
void deleted();
|
||||
void lRetract();
|
||||
void lMarkAsRead();
|
||||
void readChanged();
|
||||
void lSendReaction(const QString &reaction);
|
||||
|
|
@ -214,6 +226,10 @@ private:
|
|||
bool mIsVoiceRecording = false;
|
||||
bool mIsEphemeral = false;
|
||||
int mEphemeralDuration = 0;
|
||||
bool mIsRetractable = false;
|
||||
bool mIsRetracted = false;
|
||||
bool mIsEditable = false;
|
||||
bool mIsEdited = false;
|
||||
|
||||
bool mIsOutgoing = false;
|
||||
QString mTotalReactionsLabel;
|
||||
|
|
|
|||
|
|
@ -26,14 +26,16 @@
|
|||
|
||||
DEFINE_ABSTRACT_OBJECT(EventLogCore)
|
||||
|
||||
QSharedPointer<EventLogCore> EventLogCore::create(const std::shared_ptr<const linphone::EventLog> &eventLog) {
|
||||
auto sharedPointer = QSharedPointer<EventLogCore>(new EventLogCore(eventLog), &QObject::deleteLater);
|
||||
QSharedPointer<EventLogCore> EventLogCore::create(const std::shared_ptr<const linphone::EventLog> &eventLog,
|
||||
const std::shared_ptr<linphone::ChatRoom> &chatRoom) {
|
||||
auto sharedPointer = QSharedPointer<EventLogCore>(new EventLogCore(eventLog, chatRoom), &QObject::deleteLater);
|
||||
sharedPointer->setSelf(sharedPointer);
|
||||
sharedPointer->moveToThread(App::getInstance()->thread());
|
||||
return sharedPointer;
|
||||
}
|
||||
|
||||
EventLogCore::EventLogCore(const std::shared_ptr<const linphone::EventLog> &eventLog) {
|
||||
EventLogCore::EventLogCore(const std::shared_ptr<const linphone::EventLog> &eventLog,
|
||||
const std::shared_ptr<linphone::ChatRoom> &chatRoom) {
|
||||
mustBeInLinphoneThread(getClassName());
|
||||
App::getInstance()->mEngine->setObjectOwnership(this, QQmlEngine::CppOwnership);
|
||||
mEventLogType = LinphoneEnums::fromLinphone(eventLog->getType());
|
||||
|
|
@ -52,7 +54,7 @@ EventLogCore::EventLogCore(const std::shared_ptr<const linphone::EventLog> &even
|
|||
QString type = QString::fromLatin1(
|
||||
QMetaEnum::fromType<LinphoneEnums::EventLogType>().valueToKey(static_cast<int>(mEventLogType)));
|
||||
mEventId = type + QString::number(static_cast<qint64>(eventLog->getCreationTime()));
|
||||
computeEvent(eventLog);
|
||||
computeEvent(eventLog, chatRoom);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -94,7 +96,8 @@ std::shared_ptr<EventLogModel> EventLogCore::getModel() const {
|
|||
|
||||
// Events (other than ChatMessage and CallLog which are handled in their respective Core)
|
||||
|
||||
void EventLogCore::computeEvent(const std::shared_ptr<const linphone::EventLog> &eventLog) {
|
||||
void EventLogCore::computeEvent(const std::shared_ptr<const linphone::EventLog> &eventLog,
|
||||
const std::shared_ptr<linphone::ChatRoom> &chatRoom) {
|
||||
mustBeInLinphoneThread(getClassName());
|
||||
mHandled = true;
|
||||
mImportant = false;
|
||||
|
|
@ -104,9 +107,15 @@ void EventLogCore::computeEvent(const std::shared_ptr<const linphone::EventLog>
|
|||
|
||||
switch (eventLog->getType()) {
|
||||
case linphone::EventLog::Type::ConferenceCreated:
|
||||
if (chatRoom->hasCapability((int)linphone::ChatRoom::Capabilities::OneToOne) &&
|
||||
!chatRoom->hasCapability((int)linphone::ChatRoom::Capabilities::Conference))
|
||||
mHandled = false;
|
||||
mEventDetails = tr("conference_created_event");
|
||||
break;
|
||||
case linphone::EventLog::Type::ConferenceTerminated:
|
||||
if (chatRoom->hasCapability((int)linphone::ChatRoom::Capabilities::OneToOne) &&
|
||||
!chatRoom->hasCapability((int)linphone::ChatRoom::Capabilities::Conference))
|
||||
mHandled = false;
|
||||
mEventDetails = tr("conference_created_terminated");
|
||||
mImportant = true;
|
||||
break;
|
||||
|
|
|
|||
|
|
@ -51,8 +51,10 @@ class EventLogCore : public QObject, public AbstractObject {
|
|||
Q_PROPERTY(QDateTime timestamp READ getTimestamp CONSTANT)
|
||||
|
||||
public:
|
||||
static QSharedPointer<EventLogCore> create(const std::shared_ptr<const linphone::EventLog> &eventLog);
|
||||
EventLogCore(const std::shared_ptr<const linphone::EventLog> &eventLog);
|
||||
static QSharedPointer<EventLogCore> create(const std::shared_ptr<const linphone::EventLog> &eventLog,
|
||||
const std::shared_ptr<linphone::ChatRoom> &chatRoom);
|
||||
EventLogCore(const std::shared_ptr<const linphone::EventLog> &eventLog,
|
||||
const std::shared_ptr<linphone::ChatRoom> &chatRoom);
|
||||
~EventLogCore();
|
||||
void setSelf(QSharedPointer<EventLogCore> me);
|
||||
QString getEventLogId();
|
||||
|
|
@ -87,7 +89,8 @@ private:
|
|||
ChatMessageCore *getChatMessageCorePointer();
|
||||
CallHistoryCore *getCallHistoryCorePointer();
|
||||
std::shared_ptr<EventLogModel> mEventLogModel;
|
||||
void computeEvent(const std::shared_ptr<const linphone::EventLog> &eventLog);
|
||||
void computeEvent(const std::shared_ptr<const linphone::EventLog> &eventLog,
|
||||
const std::shared_ptr<linphone::ChatRoom> &chatRoom);
|
||||
};
|
||||
|
||||
#endif // EventLogCore_H_
|
||||
|
|
|
|||
|
|
@ -64,7 +64,8 @@ void EventLogList::disconnectItem(const QSharedPointer<EventLogCore> &item) {
|
|||
if (message) {
|
||||
disconnect(message.get(), &ChatMessageCore::isReadChanged, this, nullptr);
|
||||
disconnect(message.get(), &ChatMessageCore::deleted, this, nullptr);
|
||||
disconnect(message.get(), &ChatMessageCore::ephemeralDurationChanged, this, nullptr);
|
||||
disconnect(message.get(), &ChatMessageCore::edited, this, nullptr);
|
||||
disconnect(message.get(), &ChatMessageCore::isRetractedChanged, this, nullptr);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -78,49 +79,55 @@ void EventLogList::connectItem(const QSharedPointer<EventLogCore> &item) {
|
|||
if (mChatCore) emit mChatCore->lUpdateLastMessage();
|
||||
remove(item);
|
||||
});
|
||||
connect(message.get(), &ChatMessageCore::isRetractedChanged, this, [this, item] {
|
||||
if (mChatCore) emit mChatCore->lUpdateUnreadCount();
|
||||
});
|
||||
connect(message.get(), &ChatMessageCore::edited, this, [this, item] {
|
||||
auto eventLogModel = item->getModel();
|
||||
mCoreModelConnection->invokeToModel([this, eventLogModel, item]() {
|
||||
auto chatRoom = mChatCore->getModel()->getMonitor();
|
||||
auto newEventLog = EventLogCore::create(eventLogModel->getEventLog(), chatRoom);
|
||||
bool wasLastMessage =
|
||||
mChatCore->getModel()->getLastChatMessage() == eventLogModel->getEventLog()->getChatMessage();
|
||||
mCoreModelConnection->invokeToCore([this, newEventLog, wasLastMessage, item] {
|
||||
connectItem(newEventLog);
|
||||
replace(item, newEventLog);
|
||||
if (wasLastMessage) mChatCore->setLastMessage(newEventLog->getChatMessageCore());
|
||||
});
|
||||
});
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
void EventLogList::setChatCore(QSharedPointer<ChatCore> core) {
|
||||
auto updateChatCore = [this](QSharedPointer<ChatCore> core) {
|
||||
if (mChatCore != core) {
|
||||
if (mChatCore) {
|
||||
disconnect(mChatCore.get(), &ChatCore::eventsInserted, this, nullptr);
|
||||
disconnect(mChatCore.get(), &ChatCore::eventListCleared, this, nullptr);
|
||||
}
|
||||
mChatCore = core;
|
||||
if (mChatCore) {
|
||||
connect(mChatCore.get(), &ChatCore::eventListCleared, this, [this] { resetData(); });
|
||||
connect(mChatCore.get(), &ChatCore::eventsInserted, this,
|
||||
[this](QList<QSharedPointer<EventLogCore>> list) {
|
||||
auto eventsList = getSharedList<EventLogCore>();
|
||||
for (auto &event : list) {
|
||||
auto it = std::find_if(
|
||||
eventsList.begin(), eventsList.end(),
|
||||
[event](const QSharedPointer<EventLogCore> item) { return item == event; });
|
||||
if (it == eventsList.end()) {
|
||||
connectItem(event);
|
||||
add(event);
|
||||
int index;
|
||||
get(event.get(), &index);
|
||||
emit eventInserted(index, new EventLogGui(event));
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
lUpdate();
|
||||
emit chatGuiChanged();
|
||||
if (mChatCore != core) {
|
||||
if (mChatCore) {
|
||||
disconnect(mChatCore.get(), &ChatCore::eventsInserted, this, nullptr);
|
||||
disconnect(mChatCore.get(), &ChatCore::eventListCleared, this, nullptr);
|
||||
}
|
||||
};
|
||||
if (mIsUpdating) {
|
||||
connect(this, &EventLogList::isUpdatingChanged, this, [this, core, updateChatCore] {
|
||||
if (!mIsUpdating) {
|
||||
updateChatCore(core);
|
||||
disconnect(this, &EventLogList::isUpdatingChanged, this, nullptr);
|
||||
}
|
||||
});
|
||||
} else {
|
||||
updateChatCore(core);
|
||||
mChatCore = core;
|
||||
if (mChatCore) {
|
||||
connect(mChatCore.get(), &ChatCore::eventListCleared, this, [this] { resetData(); });
|
||||
connect(mChatCore.get(), &ChatCore::eventsInserted, this, [this](QList<QSharedPointer<EventLogCore>> list) {
|
||||
auto eventsList = getSharedList<EventLogCore>();
|
||||
for (auto &event : list) {
|
||||
auto it = std::find_if(eventsList.begin(), eventsList.end(),
|
||||
[event](const QSharedPointer<EventLogCore> item) { return item == event; });
|
||||
if (it == eventsList.end()) {
|
||||
connectItem(event);
|
||||
prepend(event);
|
||||
int index;
|
||||
get(event.get(), &index);
|
||||
if (event->getChatMessageCore() && !event->getChatMessageCore()->isRemoteMessage()) {
|
||||
emit eventInsertedByUser(index);
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
lUpdate();
|
||||
// setIsUpdating(false);
|
||||
emit chatGuiChanged();
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -136,6 +143,13 @@ void EventLogList::setDisplayItemsStep(int displayItemsStep) {
|
|||
}
|
||||
}
|
||||
|
||||
void EventLogList::markIndexAsRead(int index) {
|
||||
if (index < mList.count()) {
|
||||
auto eventLog = mList[index].objectCast<EventLogCore>();
|
||||
if (eventLog && eventLog->getChatMessageCore()) eventLog->getChatMessageCore()->lMarkAsRead();
|
||||
}
|
||||
}
|
||||
|
||||
void EventLogList::displayMore() {
|
||||
auto loadMoreItems = [this] {
|
||||
if (!mChatCore) return;
|
||||
|
|
@ -152,14 +166,17 @@ void EventLogList::displayMore() {
|
|||
auto linphoneLogs = chatModel->getHistoryRange(totalItemsCount, newCount);
|
||||
QList<QSharedPointer<EventLogCore>> *events = new QList<QSharedPointer<EventLogCore>>();
|
||||
for (auto it : linphoneLogs) {
|
||||
auto model = EventLogCore::create(it);
|
||||
events->push_back(model);
|
||||
auto model = EventLogCore::create(it, chatModel->getMonitor());
|
||||
if (it->getChatMessage() || model->isHandled()) events->push_front(model);
|
||||
}
|
||||
mCoreModelConnection->invokeToCore([this, events] {
|
||||
int currentCount = mList.count();
|
||||
for (auto it = events->end() - 1; it >= events->begin(); --it) {
|
||||
connectItem(*it);
|
||||
prepend(*it);
|
||||
if (!events->isEmpty()) {
|
||||
for (int i = events->size() - 1; i >= 0; --i) {
|
||||
const auto &ev = events->at(i);
|
||||
connectItem(ev);
|
||||
}
|
||||
add(*events);
|
||||
}
|
||||
});
|
||||
});
|
||||
|
|
@ -177,8 +194,10 @@ void EventLogList::displayMore() {
|
|||
|
||||
void EventLogList::loadMessagesUpTo(std::shared_ptr<linphone::EventLog> event) {
|
||||
mustBeInLinphoneThread(log().arg(Q_FUNC_INFO));
|
||||
auto oldestEventLoaded = getAt<EventLogCore>(0);
|
||||
auto linOldest = std::const_pointer_cast<linphone::EventLog>(oldestEventLoaded->getModel()->getEventLog());
|
||||
auto oldestEventLoaded = mList.count() > 0 ? getAt<EventLogCore>(mList.count() - 1) : nullptr;
|
||||
auto linOldest = oldestEventLoaded
|
||||
? std::const_pointer_cast<linphone::EventLog>(oldestEventLoaded->getModel()->getEventLog())
|
||||
: nullptr;
|
||||
auto chatModel = mChatCore->getModel();
|
||||
assert(chatModel);
|
||||
if (!chatModel) return;
|
||||
|
|
@ -187,47 +206,55 @@ void EventLogList::loadMessagesUpTo(std::shared_ptr<linphone::EventLog> event) {
|
|||
auto beforeEvents = chatModel->getHistoryRangeNear(mItemsToLoadBeforeSearchResult, 0, event, filters);
|
||||
auto linphoneLogs = chatModel->getHistoryRangeBetween(event, linOldest, filters);
|
||||
QList<QSharedPointer<EventLogCore>> *events = new QList<QSharedPointer<EventLogCore>>();
|
||||
for (auto it : beforeEvents) {
|
||||
auto model = EventLogCore::create(it);
|
||||
events->push_back(model);
|
||||
const auto &linChatRoom = chatModel->getMonitor();
|
||||
for (const auto &it : beforeEvents) {
|
||||
auto model = EventLogCore::create(it, linChatRoom);
|
||||
if (it->getChatMessage() || model->isHandled()) events->push_front(model);
|
||||
}
|
||||
for (auto it : linphoneLogs) {
|
||||
auto model = EventLogCore::create(it);
|
||||
events->push_back(model);
|
||||
for (const auto &it : linphoneLogs) {
|
||||
auto model = EventLogCore::create(it, linChatRoom);
|
||||
if (it->getChatMessage() || model->isHandled()) events->push_front(model);
|
||||
}
|
||||
mCoreModelConnection->invokeToCore([this, events, event] {
|
||||
for (auto &e : *events) {
|
||||
for (const auto &e : *events) {
|
||||
connectItem(e);
|
||||
add(e);
|
||||
}
|
||||
add(*events);
|
||||
emit messagesLoadedUpTo(event);
|
||||
});
|
||||
}
|
||||
|
||||
int EventLogList::findFirstUnreadIndex() {
|
||||
auto eventList = getSharedList<EventLogCore>();
|
||||
auto it = std::find_if(eventList.begin(), eventList.end(), [](const QSharedPointer<EventLogCore> item) {
|
||||
return item->getChatMessageCore() && !item->getChatMessageCore()->isRead();
|
||||
auto it = std::find_if(eventList.rbegin(), eventList.rend(), [](const QSharedPointer<EventLogCore> item) {
|
||||
auto chatmessage = item->getChatMessageCore();
|
||||
return chatmessage && !chatmessage->isRead();
|
||||
});
|
||||
return it == eventList.end() ? -1 : std::distance(eventList.begin(), it);
|
||||
return it == eventList.rend() ? -1 : std::distance(it, eventList.rend()) - 1;
|
||||
}
|
||||
|
||||
void EventLogList::findChatMessageWithFilter(QString filter,
|
||||
QSharedPointer<EventLogCore> startEvent,
|
||||
bool forward,
|
||||
bool isFirstResearch) {
|
||||
void EventLogList::findChatMessageWithFilter(QString filter, int startIndex, bool forward, bool isFirstResearch) {
|
||||
if (mChatCore) {
|
||||
if (isFirstResearch) mLastFoundResult.reset();
|
||||
auto chatModel = mChatCore->getModel();
|
||||
auto startEvent =
|
||||
startIndex >= 0 && startIndex < mList.count() ? mList[startIndex].objectCast<EventLogCore>() : nullptr;
|
||||
lInfo() << log().arg("searching event starting from index") << startIndex << "| event :"
|
||||
<< (startEvent && startEvent->getChatMessageCore() ? startEvent->getChatMessageCore()->getText()
|
||||
: "null")
|
||||
<< "| filter :" << filter;
|
||||
auto startEventModel = startEvent ? startEvent->getModel() : nullptr;
|
||||
mCoreModelConnection->invokeToModel([this, chatModel, startEventModel, filter, forward, isFirstResearch] {
|
||||
auto linStartEvent = startEventModel ? startEventModel->getEventLog() : nullptr;
|
||||
auto eventLog = chatModel->searchMessageByText(filter, linStartEvent, forward);
|
||||
if (!eventLog)
|
||||
if (!eventLog) {
|
||||
// event not found, search in the entire history
|
||||
lInfo() << log().arg("not found, search in entire history");
|
||||
auto eventLog = chatModel->searchMessageByText(filter, nullptr, forward);
|
||||
}
|
||||
int index = -1;
|
||||
if (eventLog) {
|
||||
lInfo() << log().arg("event with filter found") << eventLog.get();
|
||||
auto eventList = getSharedList<EventLogCore>();
|
||||
auto it = std::find_if(eventList.begin(), eventList.end(),
|
||||
[eventLog](const QSharedPointer<EventLogCore> item) {
|
||||
|
|
@ -255,6 +282,7 @@ void EventLogList::findChatMessageWithFilter(QString filter,
|
|||
loadMessagesUpTo(eventLog);
|
||||
}
|
||||
} else {
|
||||
lInfo() << log().arg("event not found at all in history");
|
||||
mCoreModelConnection->invokeToCore([this, index] { emit messageWithFilterFound(index); });
|
||||
}
|
||||
});
|
||||
|
|
@ -277,6 +305,9 @@ void EventLogList::setSelf(QSharedPointer<EventLogList> me) {
|
|||
}
|
||||
setIsUpdating(true);
|
||||
beginResetModel();
|
||||
for (auto &event : getSharedList<EventLogCore>()) {
|
||||
disconnectItem(event);
|
||||
}
|
||||
mList.clear();
|
||||
if (!mChatCore) {
|
||||
endResetModel();
|
||||
|
|
@ -294,17 +325,10 @@ void EventLogList::setSelf(QSharedPointer<EventLogList> me) {
|
|||
auto linphoneLogs = chatModel->getHistoryRange(0, mDisplayItemsStep);
|
||||
QList<QSharedPointer<EventLogCore>> *events = new QList<QSharedPointer<EventLogCore>>();
|
||||
for (auto it : linphoneLogs) {
|
||||
auto model = EventLogCore::create(it);
|
||||
events->push_back(model);
|
||||
auto model = EventLogCore::create(it, chatModel->getMonitor());
|
||||
if (it->getChatMessage() || model->isHandled()) events->push_front(model);
|
||||
}
|
||||
mCoreModelConnection->invokeToCore([this, events] {
|
||||
for (auto &event : getSharedList<EventLogCore>()) {
|
||||
auto message = event->getChatMessageCore();
|
||||
if (message) {
|
||||
disconnect(message.get(), &ChatMessageCore::ephemeralDurationChanged, this, nullptr);
|
||||
disconnect(message.get(), &ChatMessageCore::deleted, this, nullptr);
|
||||
}
|
||||
}
|
||||
for (auto &event : *events) {
|
||||
connectItem(event);
|
||||
mList.append(event);
|
||||
|
|
|
|||
|
|
@ -54,13 +54,12 @@ public:
|
|||
|
||||
int findFirstUnreadIndex();
|
||||
|
||||
void markIndexAsRead(int index);
|
||||
|
||||
void displayMore();
|
||||
void setDisplayItemsStep(int displayItemsStep);
|
||||
|
||||
void findChatMessageWithFilter(QString filter,
|
||||
QSharedPointer<EventLogCore> startEvent,
|
||||
bool forward = true,
|
||||
bool isFirstResearch = true);
|
||||
void findChatMessageWithFilter(QString filter, int startIndex, bool forward = true, bool isFirstResearch = true);
|
||||
|
||||
void setSelf(QSharedPointer<EventLogList> me);
|
||||
virtual QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const override;
|
||||
|
|
@ -69,7 +68,7 @@ public:
|
|||
signals:
|
||||
void lUpdate();
|
||||
void filterChanged(QString filter);
|
||||
void eventInserted(int index, EventLogGui *message);
|
||||
void eventInsertedByUser(int index);
|
||||
void messageWithFilterFound(int index);
|
||||
void listAboutToBeReset();
|
||||
void chatGuiChanged();
|
||||
|
|
@ -79,7 +78,6 @@ signals:
|
|||
private:
|
||||
QString mFilter;
|
||||
QSharedPointer<ChatCore> mChatCore;
|
||||
QSharedPointer<SafeConnection<ChatCore, ChatModel>> mChatModelConnection;
|
||||
QSharedPointer<SafeConnection<EventLogList, CoreModel>> mCoreModelConnection;
|
||||
int mDisplayItemsStep = 0;
|
||||
int mItemsToLoadBeforeSearchResult = 3;
|
||||
|
|
|
|||
|
|
@ -26,7 +26,7 @@
|
|||
|
||||
DEFINE_ABSTRACT_OBJECT(EventLogProxy)
|
||||
|
||||
EventLogProxy::EventLogProxy(QObject *parent) : LimitProxy(parent) {
|
||||
EventLogProxy::EventLogProxy(QObject *parent) : QSortFilterProxyModel(parent) {
|
||||
mList = EventLogList::create();
|
||||
setSourceModel(mList.get());
|
||||
}
|
||||
|
|
@ -35,54 +35,41 @@ EventLogProxy::~EventLogProxy() {
|
|||
}
|
||||
|
||||
void EventLogProxy::setSourceModel(QAbstractItemModel *model) {
|
||||
auto oldEventLogList = getListModel<EventLogList>();
|
||||
auto oldEventLogList = dynamic_cast<EventLogList *>(sourceModel());
|
||||
if (oldEventLogList) {
|
||||
disconnect(oldEventLogList);
|
||||
disconnect(oldEventLogList, &EventLogList::displayItemsStepChanged, this, nullptr);
|
||||
disconnect(oldEventLogList, &EventLogList::messageWithFilterFound, this, nullptr);
|
||||
disconnect(oldEventLogList, &EventLogList::eventInsertedByUser, this, nullptr);
|
||||
}
|
||||
auto newEventLogList = dynamic_cast<EventLogList *>(model);
|
||||
if (newEventLogList) {
|
||||
connect(newEventLogList, &EventLogList::listAboutToBeReset, this, &EventLogProxy::listAboutToBeReset);
|
||||
connect(newEventLogList, &EventLogList::chatGuiChanged, this, &EventLogProxy::chatGuiChanged);
|
||||
connect(this, &EventLogProxy::displayItemsStepChanged, newEventLogList,
|
||||
[this, newEventLogList] { newEventLogList->setDisplayItemsStep(mDisplayItemsStep); });
|
||||
connect(newEventLogList, &EventLogList::eventInserted, this,
|
||||
[this, newEventLogList](int index, EventLogGui *event) {
|
||||
invalidate();
|
||||
int proxyIndex = -1;
|
||||
if (index != -1) {
|
||||
proxyIndex = dynamic_cast<SortFilterList *>(sourceModel())
|
||||
->mapFromSource(newEventLogList->index(index, 0))
|
||||
.row();
|
||||
}
|
||||
loadUntil(proxyIndex);
|
||||
emit eventInserted(proxyIndex, event);
|
||||
});
|
||||
connect(newEventLogList, &EventLogList::messageWithFilterFound, this, [this, newEventLogList](int i) {
|
||||
connect(this, &EventLogProxy::layoutChanged, newEventLogList, [this, i, newEventLogList] {
|
||||
disconnect(this, &EventLogProxy::layoutChanged, newEventLogList, nullptr);
|
||||
auto model = getListModel<EventLogList>();
|
||||
int proxyIndex =
|
||||
dynamic_cast<SortFilterList *>(sourceModel())->mapFromSource(newEventLogList->index(i, 0)).row();
|
||||
if (i != -1) {
|
||||
loadUntil(proxyIndex);
|
||||
}
|
||||
emit indexWithFilterFound(proxyIndex);
|
||||
});
|
||||
invalidate();
|
||||
auto model = dynamic_cast<EventLogList *>(sourceModel());
|
||||
int proxyIndex = mapFromSource(newEventLogList->index(i, 0)).row();
|
||||
if (i != -1) {
|
||||
loadUntil(proxyIndex);
|
||||
}
|
||||
emit indexWithFilterFound(proxyIndex);
|
||||
});
|
||||
connect(newEventLogList, &EventLogList::eventInsertedByUser, this, [this, newEventLogList](int i) {
|
||||
int proxyIndex = mapFromSource(newEventLogList->index(i, 0)).row();
|
||||
emit eventInsertedByUser(proxyIndex);
|
||||
});
|
||||
}
|
||||
setSourceModels(new SortFilterList(model, Qt::DescendingOrder));
|
||||
sort(0, Qt::DescendingOrder);
|
||||
QSortFilterProxyModel::setSourceModel(model);
|
||||
}
|
||||
|
||||
ChatGui *EventLogProxy::getChatGui() {
|
||||
auto model = getListModel<EventLogList>();
|
||||
auto model = dynamic_cast<EventLogList *>(sourceModel());
|
||||
if (!mChatGui && model) mChatGui = model->getChat();
|
||||
return mChatGui;
|
||||
}
|
||||
|
||||
void EventLogProxy::setChatGui(ChatGui *chat) {
|
||||
getListModel<EventLogList>()->setChatGui(chat);
|
||||
auto model = dynamic_cast<EventLogList *>(sourceModel());
|
||||
if (model) model->setChatGui(chat);
|
||||
}
|
||||
|
||||
EventLogGui *EventLogProxy::getEventAtIndex(int i) {
|
||||
|
|
@ -90,29 +77,86 @@ EventLogGui *EventLogProxy::getEventAtIndex(int i) {
|
|||
return eventCore == nullptr ? nullptr : new EventLogGui(eventCore);
|
||||
}
|
||||
|
||||
int EventLogProxy::getCount() const {
|
||||
return rowCount();
|
||||
}
|
||||
|
||||
int EventLogProxy::getInitialDisplayItems() const {
|
||||
return mInitialDisplayItems;
|
||||
}
|
||||
|
||||
void EventLogProxy::setInitialDisplayItems(int initialItems) {
|
||||
if (mInitialDisplayItems != initialItems) {
|
||||
mInitialDisplayItems = initialItems;
|
||||
if (getMaxDisplayItems() <= mInitialDisplayItems) setMaxDisplayItems(initialItems);
|
||||
if (getDisplayItemsStep() <= 0) setDisplayItemsStep(initialItems);
|
||||
emit initialDisplayItemsChanged();
|
||||
}
|
||||
}
|
||||
|
||||
int EventLogProxy::getDisplayCount(int listCount, int maxCount) {
|
||||
return maxCount >= 0 ? qMin(listCount, maxCount) : listCount;
|
||||
}
|
||||
|
||||
int EventLogProxy::getDisplayCount(int listCount) const {
|
||||
return getDisplayCount(listCount, mMaxDisplayItems);
|
||||
}
|
||||
|
||||
QSharedPointer<EventLogCore> EventLogProxy::getEventCoreAtIndex(int i) {
|
||||
return getItemAt<SortFilterList, EventLogList, EventLogCore>(i);
|
||||
auto model = dynamic_cast<EventLogList *>(sourceModel());
|
||||
if (model) {
|
||||
return model->getAt<EventLogCore>(mapToSource(index(i, 0)).row());
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
void EventLogProxy::displayMore() {
|
||||
auto model = getListModel<EventLogList>();
|
||||
auto model = dynamic_cast<EventLogList *>(sourceModel());
|
||||
if (model) {
|
||||
model->displayMore();
|
||||
}
|
||||
}
|
||||
int EventLogProxy::getMaxDisplayItems() const {
|
||||
return mMaxDisplayItems;
|
||||
}
|
||||
|
||||
void EventLogProxy::setMaxDisplayItems(int maxItems) {
|
||||
if (mMaxDisplayItems != maxItems) {
|
||||
auto model = sourceModel();
|
||||
int modelCount = model ? model->rowCount() : 0;
|
||||
int oldCount = getDisplayCount(modelCount);
|
||||
mMaxDisplayItems = maxItems;
|
||||
if (getInitialDisplayItems() > mMaxDisplayItems) setInitialDisplayItems(maxItems);
|
||||
if (getDisplayItemsStep() <= 0) setDisplayItemsStep(maxItems);
|
||||
emit maxDisplayItemsChanged();
|
||||
|
||||
if (model && getDisplayCount(modelCount) != oldCount) {
|
||||
invalidate();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int EventLogProxy::getDisplayItemsStep() const {
|
||||
return mDisplayItemsStep;
|
||||
}
|
||||
|
||||
void EventLogProxy::setDisplayItemsStep(int step) {
|
||||
if (step > 0 && mDisplayItemsStep != step) {
|
||||
mDisplayItemsStep = step;
|
||||
emit displayItemsStepChanged();
|
||||
}
|
||||
}
|
||||
|
||||
void EventLogProxy::loadUntil(int index) {
|
||||
auto confInfoList = getListModel<EventLogList>();
|
||||
if (mMaxDisplayItems < index) setMaxDisplayItems(index + mDisplayItemsStep);
|
||||
}
|
||||
|
||||
int EventLogProxy::findFirstUnreadIndex() {
|
||||
auto eventLogList = getListModel<EventLogList>();
|
||||
auto eventLogList = dynamic_cast<EventLogList *>(sourceModel());
|
||||
if (eventLogList) {
|
||||
auto listIndex = eventLogList->findFirstUnreadIndex();
|
||||
if (listIndex != -1) {
|
||||
listIndex =
|
||||
dynamic_cast<SortFilterList *>(sourceModel())->mapFromSource(eventLogList->index(listIndex, 0)).row();
|
||||
listIndex = mapFromSource(eventLogList->index(listIndex, 0)).row();
|
||||
if (mMaxDisplayItems <= listIndex) setMaxDisplayItems(listIndex + mDisplayItemsStep);
|
||||
return listIndex;
|
||||
} else {
|
||||
|
|
@ -122,32 +166,43 @@ int EventLogProxy::findFirstUnreadIndex() {
|
|||
return 0;
|
||||
}
|
||||
|
||||
QString EventLogProxy::getFilterText() const {
|
||||
return mFilterText;
|
||||
}
|
||||
|
||||
void EventLogProxy::setFilterText(const QString &filter) {
|
||||
if (mFilterText != filter) {
|
||||
#if QT_VERSION >= QT_VERSION_CHECK(6, 10, 0)
|
||||
beginFilterChange();
|
||||
mFilterText = filter;
|
||||
endFilterChange();
|
||||
#else
|
||||
mFilterText = filter;
|
||||
invalidateFilter();
|
||||
#endif
|
||||
emit filterTextChanged();
|
||||
}
|
||||
}
|
||||
|
||||
QSharedPointer<EventLogCore> EventLogProxy::getAt(int atIndex) const {
|
||||
auto model = dynamic_cast<EventLogList *>(sourceModel());
|
||||
if (model) {
|
||||
return model->getAt<EventLogCore>(mapToSource(index(atIndex, 0)).row());
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
void EventLogProxy::markIndexAsRead(int proxyIndex) {
|
||||
auto event = getItemAt<SortFilterList, EventLogList, EventLogCore>(proxyIndex);
|
||||
auto event = getAt(proxyIndex);
|
||||
if (event && event->getChatMessageCore()) event->getChatMessageCore()->lMarkAsRead();
|
||||
}
|
||||
|
||||
void EventLogProxy::findIndexCorrespondingToFilter(int startIndex, bool forward, bool isFirstResearch) {
|
||||
auto filter = getFilterText();
|
||||
if (filter.isEmpty()) return;
|
||||
auto eventLogList = getListModel<EventLogList>();
|
||||
auto eventLogList = dynamic_cast<EventLogList *>(sourceModel());
|
||||
if (eventLogList) {
|
||||
auto startEvent = mLastSearchStart;
|
||||
if (!startEvent) {
|
||||
startEvent = getItemAt<SortFilterList, EventLogList, EventLogCore>(startIndex);
|
||||
}
|
||||
eventLogList->findChatMessageWithFilter(filter, startEvent, forward, isFirstResearch);
|
||||
auto listIndex = mapToSource(index(startIndex, 0)).row();
|
||||
eventLogList->findChatMessageWithFilter(filter, listIndex, forward, isFirstResearch);
|
||||
}
|
||||
}
|
||||
|
||||
bool EventLogProxy::SortFilterList::filterAcceptsRow(int sourceRow, const QModelIndex &sourceParent) const {
|
||||
auto l = getItemAtSource<EventLogList, EventLogCore>(sourceRow);
|
||||
return l != nullptr;
|
||||
}
|
||||
|
||||
bool EventLogProxy::SortFilterList::lessThan(const QModelIndex &sourceLeft, const QModelIndex &sourceRight) const {
|
||||
auto l = getItemAtSource<EventLogList, EventLogCore>(sourceLeft.row());
|
||||
auto r = getItemAtSource<EventLogList, EventLogCore>(sourceRight.row());
|
||||
if (l && r) return l->getTimestamp() <= r->getTimestamp();
|
||||
return true;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -22,19 +22,26 @@
|
|||
#define EVENT_LIST_PROXY_H_
|
||||
|
||||
#include "EventLogList.hpp"
|
||||
#include "core/proxy/LimitProxy.hpp"
|
||||
// #include "core/proxy/LimitProxy.hpp"
|
||||
#include "tool/AbstractObject.hpp"
|
||||
#include <QSortFilterProxyModel>
|
||||
|
||||
// =============================================================================
|
||||
|
||||
class ChatGui;
|
||||
|
||||
class EventLogProxy : public LimitProxy, public AbstractObject {
|
||||
class EventLogProxy : public QSortFilterProxyModel, public AbstractObject {
|
||||
Q_OBJECT
|
||||
Q_PROPERTY(int count READ getCount NOTIFY countChanged)
|
||||
Q_PROPERTY(ChatGui *chatGui READ getChatGui WRITE setChatGui NOTIFY chatGuiChanged)
|
||||
Q_PROPERTY(int initialDisplayItems READ getInitialDisplayItems WRITE setInitialDisplayItems NOTIFY
|
||||
initialDisplayItemsChanged)
|
||||
Q_PROPERTY(int maxDisplayItems READ getMaxDisplayItems WRITE setMaxDisplayItems NOTIFY maxDisplayItemsChanged)
|
||||
Q_PROPERTY(int displayItemsStep READ getDisplayItemsStep WRITE setDisplayItemsStep NOTIFY displayItemsStepChanged)
|
||||
Q_PROPERTY(QString filterText READ getFilterText WRITE setFilterText NOTIFY filterTextChanged)
|
||||
|
||||
public:
|
||||
DECLARE_SORTFILTER_CLASS()
|
||||
// DECLARE_SORTFILTER_CLASS()
|
||||
|
||||
EventLogProxy(QObject *parent = Q_NULLPTR);
|
||||
~EventLogProxy();
|
||||
|
|
@ -43,8 +50,27 @@ public:
|
|||
void setChatGui(ChatGui *chat);
|
||||
|
||||
void setSourceModel(QAbstractItemModel *sourceModel) override;
|
||||
virtual int getCount() const;
|
||||
static int getDisplayCount(int listCount, int maxCount);
|
||||
int getDisplayCount(int listCount) const;
|
||||
int getInitialDisplayItems() const;
|
||||
void setInitialDisplayItems(int initialItems);
|
||||
|
||||
Q_INVOKABLE void displayMore() override;
|
||||
int getMaxDisplayItems() const;
|
||||
void setMaxDisplayItems(int maxItems);
|
||||
|
||||
int getDisplayItemsStep() const;
|
||||
void setDisplayItemsStep(int step);
|
||||
|
||||
QString getFilterText() const;
|
||||
void setFilterText(const QString &filter);
|
||||
|
||||
// bool filterAcceptsRow(int sourceRow, const QModelIndex &sourceParent) const override;
|
||||
// bool lessThan(const QModelIndex &sourceLeft, const QModelIndex &sourceRight) const override;
|
||||
|
||||
QSharedPointer<EventLogCore> getAt(int atIndex) const;
|
||||
|
||||
Q_INVOKABLE void displayMore();
|
||||
Q_INVOKABLE void loadUntil(int index);
|
||||
Q_INVOKABLE EventLogGui *getEventAtIndex(int i);
|
||||
QSharedPointer<EventLogCore> getEventCoreAtIndex(int i);
|
||||
|
|
@ -53,15 +79,23 @@ public:
|
|||
Q_INVOKABLE void findIndexCorrespondingToFilter(int startIndex, bool forward = true, bool isFirstResearch = true);
|
||||
|
||||
signals:
|
||||
void eventInserted(int index, EventLogGui *message);
|
||||
void eventInsertedByUser(int index);
|
||||
void indexWithFilterFound(int index);
|
||||
void listAboutToBeReset();
|
||||
void chatGuiChanged();
|
||||
void countChanged();
|
||||
void initialDisplayItemsChanged();
|
||||
void maxDisplayItemsChanged();
|
||||
void displayItemsStepChanged();
|
||||
void filterTextChanged();
|
||||
|
||||
protected:
|
||||
QSharedPointer<EventLogList> mList;
|
||||
QSharedPointer<EventLogCore> mLastSearchStart;
|
||||
ChatGui *mChatGui = nullptr;
|
||||
int mInitialDisplayItems = -1;
|
||||
int mMaxDisplayItems = -1;
|
||||
int mDisplayItemsStep = 5;
|
||||
QString mFilterText;
|
||||
DECLARE_ABSTRACT_OBJECT
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -46,7 +46,7 @@ ChatMessageContentCore::ChatMessageContentCore(const std::shared_ptr<linphone::C
|
|||
mName = QFileInfo(fileName).baseName();
|
||||
}
|
||||
}
|
||||
mFilePath = Utils::coreStringToAppString(content->getFilePath());
|
||||
mFilePath = QDir::fromNativeSeparators(Utils::coreStringToAppString(content->getFilePath()));
|
||||
mIsFile = content->isFile();
|
||||
mIsFileEncrypted = content->isFileEncrypted();
|
||||
mIsFileTransfer = content->isFileTransfer();
|
||||
|
|
@ -67,8 +67,8 @@ ChatMessageContentCore::ChatMessageContentCore(const std::shared_ptr<linphone::C
|
|||
mRichFormatText = ToolModel::encodeTextToQmlRichFormat(mUtf8Text, {}, chatRoom);
|
||||
mWasDownloaded = !mFilePath.isEmpty() && QFileInfo(mFilePath).isFile();
|
||||
mThumbnail = mFilePath.isEmpty()
|
||||
? QString()
|
||||
: QStringLiteral("image://%1/%2").arg(ThumbnailProvider::ProviderId).arg(mFilePath);
|
||||
? QUrl()
|
||||
: QUrl(QString("image://%1/%2").arg(ThumbnailProvider::ProviderId).arg(mFilePath));
|
||||
mChatMessageContentModel = Utils::makeQObject_ptr<ChatMessageContentModel>(content, chatMessageModel);
|
||||
}
|
||||
}
|
||||
|
|
@ -92,11 +92,22 @@ void ChatMessageContentCore::setSelf(QSharedPointer<ChatMessageContentCore> me)
|
|||
});
|
||||
mChatMessageContentModelConnection->makeConnectToModel(
|
||||
&ChatMessageContentModel::thumbnailChanged, [this, updateThumbnailType](QString thumbnail) {
|
||||
mChatMessageContentModelConnection->invokeToCore([this, thumbnail] { setThumbnail(thumbnail); });
|
||||
mChatMessageContentModelConnection->invokeToCore([this, thumbnail] { setThumbnail(QUrl(thumbnail)); });
|
||||
});
|
||||
|
||||
mChatMessageContentModelConnection->makeConnectToCore(&ChatMessageContentCore::lDownloadFile, [this]() {
|
||||
mChatMessageContentModelConnection->invokeToModel([this] { mChatMessageContentModel->downloadFile(mName); });
|
||||
mChatMessageContentModelConnection->invokeToModel([this] {
|
||||
QString *error = new QString();
|
||||
bool downloaded = mChatMessageContentModel->downloadFile(mName, error);
|
||||
if (!downloaded) {
|
||||
mChatMessageContentModelConnection->invokeToCore([this, error] {
|
||||
//: Error downloading file %1
|
||||
if (error->isEmpty()) *error = tr("download_file_default_error").arg(mName);
|
||||
Utils::showInformationPopup(tr("info_popup_error_titile"), *error, false);
|
||||
delete error;
|
||||
});
|
||||
} else delete error;
|
||||
});
|
||||
});
|
||||
mChatMessageContentModelConnection->makeConnectToModel(
|
||||
&ChatMessageContentModel::wasDownloadedChanged,
|
||||
|
|
@ -239,11 +250,11 @@ bool ChatMessageContentCore::wasDownloaded() const {
|
|||
return mWasDownloaded;
|
||||
}
|
||||
|
||||
QString ChatMessageContentCore::getThumbnail() const {
|
||||
QUrl ChatMessageContentCore::getThumbnail() const {
|
||||
return mThumbnail;
|
||||
}
|
||||
|
||||
void ChatMessageContentCore::setThumbnail(const QString &data) {
|
||||
void ChatMessageContentCore::setThumbnail(const QUrl &data) {
|
||||
if (mThumbnail != data) {
|
||||
mThumbnail = data;
|
||||
emit thumbnailChanged();
|
||||
|
|
|
|||
|
|
@ -36,7 +36,7 @@ class ChatMessageContentCore : public QObject, public AbstractObject {
|
|||
Q_PROPERTY(QString name READ getName CONSTANT)
|
||||
Q_PROPERTY(quint64 fileOffset READ getFileOffset WRITE setFileOffset NOTIFY fileOffsetChanged)
|
||||
|
||||
Q_PROPERTY(QString thumbnail READ getThumbnail WRITE setThumbnail NOTIFY thumbnailChanged)
|
||||
Q_PROPERTY(QUrl thumbnail READ getThumbnail WRITE setThumbnail NOTIFY thumbnailChanged)
|
||||
Q_PROPERTY(bool wasDownloaded READ wasDownloaded WRITE setWasDownloaded NOTIFY wasDownloadedChanged)
|
||||
Q_PROPERTY(QString filePath READ getFilePath WRITE setFilePath NOTIFY filePathChanged)
|
||||
Q_PROPERTY(QString utf8Text READ getUtf8Text CONSTANT)
|
||||
|
|
@ -84,8 +84,8 @@ public:
|
|||
int getFileDuration() const;
|
||||
ConferenceInfoGui *getConferenceInfoGui() const;
|
||||
|
||||
void setThumbnail(const QString &data);
|
||||
QString getThumbnail() const;
|
||||
void setThumbnail(const QUrl &data);
|
||||
QUrl getThumbnail() const;
|
||||
|
||||
bool wasDownloaded() const;
|
||||
void setWasDownloaded(bool downloaded);
|
||||
|
|
@ -121,7 +121,7 @@ private:
|
|||
bool mIsText;
|
||||
bool mIsVoiceRecording;
|
||||
int mFileDuration;
|
||||
QString mThumbnail;
|
||||
QUrl mThumbnail;
|
||||
QString mUtf8Text;
|
||||
QString mRichFormatText;
|
||||
QString mFilePath;
|
||||
|
|
|
|||
|
|
@ -197,7 +197,8 @@ void ChatMessageContentList::setSelf(QSharedPointer<ChatMessageContentList> me)
|
|||
|
||||
mModelConnection->makeConnectToCore(&ChatMessageContentList::lUpdate, [this]() {
|
||||
for (auto &content : getSharedList<ChatMessageContentCore>()) {
|
||||
if (content) disconnect(content.get());
|
||||
if (content) disconnect(content.get(), &ChatMessageContentCore::wasDownloadedChanged, this, nullptr);
|
||||
if (content) disconnect(content.get(), &ChatMessageContentCore::thumbnailChanged, this, nullptr);
|
||||
}
|
||||
if (!mChatMessageCore) return;
|
||||
auto contents = mChatMessageCore->getChatMessageContentList();
|
||||
|
|
|
|||
|
|
@ -47,6 +47,7 @@ ConferenceCore::ConferenceCore(const std::shared_ptr<linphone::Conference> &conf
|
|||
mIsLocalScreenSharing = mConferenceModel->isLocalScreenSharing();
|
||||
mIsScreenSharingEnabled = mConferenceModel->isScreenSharingEnabled();
|
||||
mIsRecording = conference->isRecording();
|
||||
if (conference->getCurrentParams()) mIsChatEnabled = conference->getCurrentParams()->chatEnabled();
|
||||
auto me = conference->getMe();
|
||||
auto confAddress = conference->getConferenceAddress();
|
||||
if (confAddress) {
|
||||
|
|
@ -205,6 +206,10 @@ void ConferenceCore::setIsScreenSharingEnabled(bool state) {
|
|||
}
|
||||
}
|
||||
|
||||
bool ConferenceCore::isChatEnabled() const {
|
||||
return mIsChatEnabled;
|
||||
}
|
||||
|
||||
std::shared_ptr<ConferenceModel> ConferenceCore::getModel() const {
|
||||
return mConferenceModel;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -37,6 +37,7 @@ class ConferenceCore : public QObject, public AbstractObject {
|
|||
Q_OBJECT
|
||||
public:
|
||||
Q_PROPERTY(QDateTime startDate READ getStartDate CONSTANT)
|
||||
Q_PROPERTY(bool isChatEnabled READ isChatEnabled CONSTANT)
|
||||
// Q_PROPERTY(ParticipantDeviceList *participantDevices READ getParticipantDeviceList CONSTANT)
|
||||
// Q_PROPERTY(ParticipantModel* localParticipant READ getLocalParticipant NOTIFY localParticipantChanged)
|
||||
Q_PROPERTY(bool isReady MEMBER mIsReady WRITE setIsReady NOTIFY isReadyChanged)
|
||||
|
|
@ -81,6 +82,8 @@ public:
|
|||
void setIsLocalScreenSharing(bool state);
|
||||
void setIsScreenSharingEnabled(bool state);
|
||||
|
||||
bool isChatEnabled() const;
|
||||
|
||||
std::shared_ptr<ConferenceModel> getModel() const;
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
|
|
@ -108,6 +111,7 @@ private:
|
|||
bool mIsRecording = false;
|
||||
bool mIsLocalScreenSharing = false;
|
||||
bool mIsScreenSharingEnabled = false;
|
||||
bool mIsChatEnabled = false;
|
||||
QString mSubject;
|
||||
QString mConfUri;
|
||||
QDateTime mStartDate = QDateTime::currentDateTime();
|
||||
|
|
|
|||
|
|
@ -21,12 +21,15 @@
|
|||
#include "ConferenceInfoCore.hpp"
|
||||
|
||||
#include "core/App.hpp"
|
||||
#include "core/path/Paths.hpp"
|
||||
#include "core/proxy/ListProxy.hpp"
|
||||
#include "model/object/VariantObject.hpp"
|
||||
#include "model/tool/ToolModel.hpp"
|
||||
#include "tool/Utils.hpp"
|
||||
#include "tool/thread/SafeConnection.hpp"
|
||||
|
||||
#include <QDesktopServices>
|
||||
|
||||
DEFINE_ABSTRACT_OBJECT(ConferenceInfoCore)
|
||||
|
||||
QSharedPointer<ConferenceInfoCore>
|
||||
|
|
@ -69,6 +72,7 @@ ConferenceInfoCore::ConferenceInfoCore(std::shared_ptr<linphone::ConferenceInfo>
|
|||
mUri = address && address->isValid() && !address->getDomain().empty()
|
||||
? Utils::coreStringToAppString(address->asStringUriOnly())
|
||||
: "";
|
||||
mIcalendarString = Utils::coreStringToAppString(conferenceInfo->getIcalendarString());
|
||||
mDateTime = QDateTime::fromMSecsSinceEpoch(conferenceInfo->getDateTime() * 1000);
|
||||
mDuration = conferenceInfo->getDuration();
|
||||
mEndDateTime = mDateTime.addSecs(mDuration * 60);
|
||||
|
|
@ -123,6 +127,7 @@ ConferenceInfoCore::ConferenceInfoCore(const ConferenceInfoCore &conferenceInfoC
|
|||
mIsEnded = conferenceInfoCore.mIsEnded;
|
||||
mInviteEnabled = conferenceInfoCore.mInviteEnabled;
|
||||
mConferenceInfoState = conferenceInfoCore.mConferenceInfoState;
|
||||
mIcalendarString = conferenceInfoCore.mIcalendarString;
|
||||
}
|
||||
|
||||
ConferenceInfoCore::~ConferenceInfoCore() {
|
||||
|
|
@ -195,8 +200,9 @@ void ConferenceInfoCore::setSelf(QSharedPointer<ConferenceInfoCore> me) {
|
|||
QString uri;
|
||||
if (state == linphone::ConferenceScheduler::State::Ready) {
|
||||
uri = mConferenceInfoModel->getConferenceScheduler()->getUri();
|
||||
emit CoreModel::getInstance()->conferenceInfoReceived(
|
||||
CoreModel::getInstance()->getCore(), mConferenceInfoModel->getConferenceInfo());
|
||||
emit CoreModel::getInstance() -> conferenceInfoReceived(
|
||||
CoreModel::getInstance()->getCore(),
|
||||
mConferenceInfoModel->getConferenceInfo());
|
||||
}
|
||||
mConfInfoModelConnection->invokeToCore([this, state = LinphoneEnums::fromLinphone(state),
|
||||
infoState = LinphoneEnums::fromLinphone(confInfoState),
|
||||
|
|
@ -600,6 +606,9 @@ void ConferenceInfoCore::save() {
|
|||
} else lCritical() << "No default account";
|
||||
// Add text capability for chat in conf
|
||||
linphoneConf->setCapability(linphone::StreamType::Text, true);
|
||||
if (SettingsModel::getInstance()->getCreateEndToEndEncryptedMeetingsAndGroupCalls())
|
||||
linphoneConf->setSecurityLevel(linphone::Conference::SecurityLevel::EndToEnd);
|
||||
else linphoneConf->setSecurityLevel(linphone::Conference::SecurityLevel::PointToPoint);
|
||||
auto confInfoModel = Utils::makeQObject_ptr<ConferenceInfoModel>(linphoneConf);
|
||||
auto confSchedulerModel = confInfoModel->getConferenceScheduler();
|
||||
if (!confSchedulerModel) {
|
||||
|
|
@ -649,3 +658,14 @@ bool ConferenceInfoCore::isAllDayConf() const {
|
|||
return mDateTime.time().hour() == 0 && mDateTime.time().minute() == 0 && mEndDateTime.time().hour() == 23 &&
|
||||
mEndDateTime.time().minute() == 59;
|
||||
}
|
||||
|
||||
void ConferenceInfoCore::exportConferenceToICS() const {
|
||||
QString filePath(Paths::getAppLocalDirPath() + "conference.ics");
|
||||
QFile file(filePath);
|
||||
if (file.open(QIODevice::WriteOnly | QIODevice::Text)) {
|
||||
QTextStream out(&file);
|
||||
out << mIcalendarString;
|
||||
file.close();
|
||||
}
|
||||
QDesktopServices::openUrl(QUrl::fromLocalFile(filePath));
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
/*
|
||||
/*
|
||||
* Copyright (c) 2022 Belledonne Communications SARL.
|
||||
*
|
||||
* This file is part of linphone-desktop
|
||||
|
|
@ -135,6 +135,8 @@ public:
|
|||
|
||||
Q_INVOKABLE bool isAllDayConf() const;
|
||||
|
||||
Q_INVOKABLE void exportConferenceToICS() const;
|
||||
|
||||
signals:
|
||||
void dateTimeChanged();
|
||||
void endDateTimeChanged();
|
||||
|
|
@ -177,6 +179,7 @@ private:
|
|||
QString mSubject;
|
||||
QString mDescription;
|
||||
QString mUri;
|
||||
QString mIcalendarString;
|
||||
QVariantList mParticipants;
|
||||
QSharedPointer<TimeZoneModel> mTimeZoneModel;
|
||||
LinphoneEnums::ConferenceSchedulerState mConferenceSchedulerState;
|
||||
|
|
|
|||
|
|
@ -235,13 +235,17 @@ int ConferenceInfoList::getCurrentDateIndex() {
|
|||
return it == confInfoList.end() ? -1 : std::distance(confInfoList.begin(), it);
|
||||
}
|
||||
|
||||
QSharedPointer<ConferenceInfoCore> ConferenceInfoList::getCurrentDateConfInfo() {
|
||||
QSharedPointer<ConferenceInfoCore> ConferenceInfoList::getCurrentDateConfInfo(bool enableCancelledConference) {
|
||||
auto today = QDate::currentDate();
|
||||
auto confInfoList = getSharedList<ConferenceInfoCore>();
|
||||
QList<QSharedPointer<ConferenceInfoCore>>::iterator it;
|
||||
if (mHaveCurrentDate) {
|
||||
it = std::find_if(confInfoList.begin(), confInfoList.end(),
|
||||
[today](const QSharedPointer<ConferenceInfoCore> &item) {
|
||||
[today, enableCancelledConference](const QSharedPointer<ConferenceInfoCore> &item) {
|
||||
if (!item) return false;
|
||||
if (!enableCancelledConference &&
|
||||
item->getConferenceInfoState() == LinphoneEnums::ConferenceInfoState::Cancelled)
|
||||
return false;
|
||||
return item && item->getDateTimeUtc().date() == today;
|
||||
});
|
||||
} else it = std::find(confInfoList.begin(), confInfoList.end(), nullptr);
|
||||
|
|
|
|||
|
|
@ -48,7 +48,7 @@ public:
|
|||
void updateHaveCurrentDate();
|
||||
|
||||
int getCurrentDateIndex();
|
||||
QSharedPointer<ConferenceInfoCore> getCurrentDateConfInfo();
|
||||
QSharedPointer<ConferenceInfoCore> getCurrentDateConfInfo(bool enableCancelledConference = false);
|
||||
|
||||
QSharedPointer<ConferenceInfoCore> build(const std::shared_ptr<linphone::ConferenceInfo> &conferenceInfo);
|
||||
void connectItem(QSharedPointer<ConferenceInfoCore> confInfoCore);
|
||||
|
|
|
|||
|
|
@ -105,7 +105,7 @@ void ConferenceInfoProxy::clear() {
|
|||
mList->clearData();
|
||||
}
|
||||
|
||||
ConferenceInfoGui *ConferenceInfoProxy::getCurrentDateConfInfo() {
|
||||
ConferenceInfoGui *ConferenceInfoProxy::getCurrentDateConfInfo(bool enableCancelledConference) {
|
||||
if (mList) {
|
||||
auto confInfo = mList->getCurrentDateConfInfo();
|
||||
return confInfo ? new ConferenceInfoGui(confInfo) : nullptr;
|
||||
|
|
@ -150,7 +150,7 @@ bool ConferenceInfoProxy::SortFilterList::lessThan(const QModelIndex &sourceLeft
|
|||
auto nowDate = QDate::currentDate();
|
||||
if (!l || !r) { // sort on date
|
||||
auto rdate = r ? r->getDateTimeUtc().date() : QDate::currentDate();
|
||||
return !l ? nowDate <= r->getDateTimeUtc().date() : l->getDateTimeUtc().date() < nowDate;
|
||||
return !l ? nowDate < r->getDateTimeUtc().date() : l->getDateTimeUtc().date() < nowDate;
|
||||
} else {
|
||||
return l->getDateTimeUtc() < r->getDateTimeUtc();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -47,7 +47,7 @@ public:
|
|||
bool getAccountConnected() const;
|
||||
|
||||
Q_INVOKABLE void clear();
|
||||
Q_INVOKABLE ConferenceInfoGui *getCurrentDateConfInfo();
|
||||
Q_INVOKABLE ConferenceInfoGui *getCurrentDateConfInfo(bool enableCancelledConference = false);
|
||||
Q_INVOKABLE int loadUntil(ConferenceInfoGui *confInfo);
|
||||
int loadUntil(QSharedPointer<ConferenceInfoCore> data);
|
||||
signals:
|
||||
|
|
|
|||
|
|
@ -130,7 +130,7 @@ Notifier::~Notifier() {
|
|||
bool Notifier::createNotification(Notifier::NotificationType type, QVariantMap data) {
|
||||
mMutex->lock();
|
||||
// Q_ASSERT(mInstancesNumber <= MaxNotificationsNumber);
|
||||
if (mInstancesNumber == MaxNotificationsNumber) { // Check existing instances.
|
||||
if (mInstancesNumber >= MaxNotificationsNumber) { // Check existing instances.
|
||||
qWarning() << QStringLiteral("Unable to create another notification.");
|
||||
mMutex->unlock();
|
||||
return false;
|
||||
|
|
@ -288,9 +288,6 @@ void Notifier::notifyReceivedCall(const shared_ptr<linphone::Call> &call) {
|
|||
auto voicemailAddress = linphone::Factory::get()->createAddress(
|
||||
Utils::appStringToCoreString(accountModel->getVoicemailAddress()));
|
||||
if (voicemailAddress) call->transferTo(voicemailAddress);
|
||||
} else {
|
||||
lInfo() << log().arg("Declining call.");
|
||||
call->decline(linphone::Reason::Busy);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
|
@ -335,7 +332,8 @@ void Notifier::notifyReceivedMessages(const std::shared_ptr<linphone::ChatRoom>
|
|||
if (receiverAccount) {
|
||||
auto senderAccount = ToolModel::findAccount(message->getFromAddress());
|
||||
auto currentAccount = CoreModel::getInstance()->getCore()->getDefaultAccount();
|
||||
if (senderAccount && senderAccount->getContactAddress()->weakEqual(currentAccount->getContactAddress())) {
|
||||
if (senderAccount && senderAccount->getContactAddress() && currentAccount->getContactAddress() &&
|
||||
senderAccount->getContactAddress()->weakEqual(currentAccount->getContactAddress())) {
|
||||
qDebug() << "sender is current account, return";
|
||||
return;
|
||||
}
|
||||
|
|
@ -369,6 +367,7 @@ void Notifier::notifyReceivedMessages(const std::shared_ptr<linphone::ChatRoom>
|
|||
};
|
||||
|
||||
if (messages.size() == 1) { // Display only sender on mono message.
|
||||
if (message->isRead()) return;
|
||||
getMessage(message);
|
||||
if (txt.isEmpty()) { // Do not notify message without content
|
||||
qDebug() << "empty notif, return";
|
||||
|
|
|
|||
|
|
@ -48,7 +48,7 @@ ParticipantInfoList::~ParticipantInfoList() {
|
|||
|
||||
void ParticipantInfoList::setChatCore(const QSharedPointer<ChatCore> &chatCore) {
|
||||
mustBeInMainThread(log().arg(Q_FUNC_INFO));
|
||||
if (mChatCore) disconnect(mChatCore.get());
|
||||
if (mChatCore) disconnect(mChatCore.get(), &ChatCore::participantsChanged, this, nullptr);
|
||||
mChatCore = chatCore;
|
||||
lDebug() << "[ParticipantInfoList] : set Chat " << mChatCore.get();
|
||||
clearData();
|
||||
|
|
|
|||
|
|
@ -109,7 +109,7 @@ void ParticipantProxy::setShowMe(const bool &show) {
|
|||
if (list->mShowMe != show) {
|
||||
list->mShowMe = show;
|
||||
emit showMeChanged();
|
||||
invalidateFilter();
|
||||
invalidate();
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -115,6 +115,7 @@ static inline QDir getAppPackageDir() {
|
|||
}
|
||||
|
||||
static inline QString getAppPackageDataDirPath() {
|
||||
QDir executableDir(QCoreApplication::applicationDirPath());
|
||||
QDir dir = getAppPackageDir();
|
||||
#ifdef __APPLE__
|
||||
if (!dir.cd("Resources")) {
|
||||
|
|
@ -126,17 +127,21 @@ static inline QString getAppPackageDataDirPath() {
|
|||
dir.mkdir("share");
|
||||
dir.cd("share");
|
||||
}
|
||||
return dir.absolutePath();
|
||||
lInfo() << executableDir.absolutePath() << " VS " << dir.absolutePath() << " == " << executableDir.relativeFilePath(dir.absolutePath());
|
||||
return executableDir.relativeFilePath(dir.absolutePath());
|
||||
}
|
||||
|
||||
static inline QString getAppPackageMsPluginsDirPath() {
|
||||
QDir executableDir(QCoreApplication::applicationDirPath());
|
||||
QDir dir = getAppPackageDir();
|
||||
dir.cd(MSPLUGINS_DIR);
|
||||
return dir.absolutePath();
|
||||
return executableDir.relativeFilePath(dir.absolutePath());
|
||||
}
|
||||
|
||||
static inline QString getAppPackagePluginsDirPath() {
|
||||
return getAppPackageDir().absolutePath() + Constants::PathPlugins;
|
||||
QDir executableDir(QCoreApplication::applicationDirPath());
|
||||
QDir packageDir = getAppPackageDir();
|
||||
return executableDir.relativeFilePath( packageDir.absolutePath() + Constants::PathPlugins);
|
||||
}
|
||||
|
||||
static inline QString getAppAssistantConfigDirPath() {
|
||||
|
|
@ -159,29 +164,6 @@ static inline QString getAppFriendsFilePath() {
|
|||
return QStandardPaths::writableLocation(QStandardPaths::AppLocalDataLocation) + Constants::PathFriendsList;
|
||||
}
|
||||
|
||||
static inline QString getAppRootCaFilePath() {
|
||||
QString rootca = getAppPackageDataDirPath() + Constants::PathRootCa;
|
||||
if (Paths::filePathExists(rootca)) { // Packaged
|
||||
return rootca;
|
||||
} else {
|
||||
lInfo() << "Root ca path does not exist. Create it";
|
||||
QFileInfo rootcaInfo(rootca);
|
||||
if (!rootcaInfo.absoluteDir().exists()) {
|
||||
QDir dataDir(getAppPackageDataDirPath());
|
||||
if (!dataDir.mkpath(Constants::PathRootCa)) {
|
||||
lCritical() << "ERROR : COULD NOT CREATE DIRECTORY WITH PATH" << Constants::PathRootCa;
|
||||
return "";
|
||||
}
|
||||
}
|
||||
QFile rootCaFile(rootca);
|
||||
if (rootCaFile.open(QIODevice::ReadWrite)) return rootca;
|
||||
else {
|
||||
lCritical() << "ERROR : COULD NOT CREATE ROOTCA WITH PATH" << rootca;
|
||||
}
|
||||
}
|
||||
return "";
|
||||
}
|
||||
|
||||
static inline QString getAppMessageHistoryFilePath() {
|
||||
return QStandardPaths::writableLocation(QStandardPaths::AppLocalDataLocation) + Constants::PathMessageHistoryList;
|
||||
}
|
||||
|
|
@ -198,7 +180,9 @@ bool Paths::filePathExists(const QString &path, const bool isWritable) {
|
|||
QFile file(path);
|
||||
return file.exists();
|
||||
}
|
||||
|
||||
bool Paths::isSameRelativeFile(const QString &filePath, const QString &relativeFilePath) {
|
||||
return filePath != relativeFilePath && QFileInfo(relativeFilePath) == QFileInfo(filePath);
|
||||
}
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
QString Paths::getAppLocalDirPath() {
|
||||
|
|
@ -283,15 +267,16 @@ QString Paths::getLogsDirPath() {
|
|||
Constants::PathLogs);
|
||||
}
|
||||
|
||||
QString Paths::getAppRootCaFilePath() {
|
||||
// Hardcoded because it comes from linphone and is not customizable.
|
||||
return getReadableFilePath(getAppPackageDataDirPath() + "/linphone/rootca.pem");
|
||||
}
|
||||
|
||||
QString Paths::getMessageHistoryFilePath() {
|
||||
return getReadableFilePath(
|
||||
getAppMessageHistoryFilePath()); // No need to ensure that the file exists as this DB is deprecated
|
||||
}
|
||||
|
||||
QString Paths::getPackageDataDirPath() {
|
||||
return getReadableDirPath(getAppPackageDataDirPath() + Constants::PathData);
|
||||
}
|
||||
|
||||
QString Paths::getPackageMsPluginsDirPath() {
|
||||
return getReadableDirPath(getAppPackageMsPluginsDirPath());
|
||||
}
|
||||
|
|
@ -300,10 +285,6 @@ QString Paths::getPackagePluginsAppDirPath() {
|
|||
return getReadableDirPath(getAppPackagePluginsDirPath() + Constants::PathPluginsApp);
|
||||
}
|
||||
|
||||
QString Paths::getPackageSoundsResourcesDirPath() {
|
||||
return getReadableDirPath(getAppPackageDataDirPath() + Constants::PathSounds);
|
||||
}
|
||||
|
||||
QString Paths::getPackageTopDirPath() {
|
||||
return getReadableDirPath(getAppPackageDataDirPath());
|
||||
}
|
||||
|
|
@ -319,10 +300,6 @@ QStringList Paths::getPluginsAppFolders() {
|
|||
return pluginPaths;
|
||||
}
|
||||
|
||||
QString Paths::getRootCaFilePath() {
|
||||
return getReadableFilePath(getAppRootCaFilePath());
|
||||
}
|
||||
|
||||
QString Paths::getToolsDirPath() {
|
||||
return getWritableDirPath(QStandardPaths::writableLocation(QStandardPaths::AppLocalDataLocation) +
|
||||
Constants::PathTools);
|
||||
|
|
|
|||
|
|
@ -27,8 +27,13 @@
|
|||
|
||||
namespace Paths {
|
||||
bool filePathExists(const QString &path, const bool isWritable = false);
|
||||
//bool convertToRelativePath(const QString &path, QString *relativePath);
|
||||
|
||||
// Return true if paths are different and point to the same file
|
||||
bool isSameRelativeFile(const QString &filePath, const QString &relativeFilePath);
|
||||
|
||||
QString getAppLocalDirPath();
|
||||
QString getAppRootCaFilePath();
|
||||
QString getAssistantConfigDirPath();
|
||||
QString getAvatarsDirPath();
|
||||
QString getVCardsPath();
|
||||
|
|
@ -44,14 +49,11 @@ QString getFriendsListFilePath();
|
|||
QString getLimeDatabasePath();
|
||||
QString getLogsDirPath();
|
||||
QString getMessageHistoryFilePath();
|
||||
QString getPackageDataDirPath();
|
||||
QString getPackageMsPluginsDirPath();
|
||||
QString getPackagePluginsAppDirPath();
|
||||
QString getPackageSoundsResourcesDirPath();
|
||||
QString getPackageTopDirPath();
|
||||
QString getPluginsAppDirPath();
|
||||
QStringList getPluginsAppFolders();
|
||||
QString getRootCaFilePath();
|
||||
QString getToolsDirPath();
|
||||
QString getUserCertificatesDirPath();
|
||||
QString getZrtpDataFilePath();
|
||||
|
|
|
|||
|
|
@ -51,8 +51,25 @@ PayloadTypeCore::~PayloadTypeCore() {
|
|||
|
||||
void PayloadTypeCore::setSelf(QSharedPointer<PayloadTypeCore> me) {
|
||||
mPayloadTypeModelConnection = SafeConnection<PayloadTypeCore, PayloadTypeModel>::create(me, mPayloadTypeModel);
|
||||
DEFINE_CORE_GETSET_CONNECT(mPayloadTypeModelConnection, PayloadTypeCore, PayloadTypeModel, mPayloadTypeModel, bool,
|
||||
enabled, Enabled)
|
||||
mPayloadTypeModelConnection->makeConnectToCore(&PayloadTypeCore::setEnabled, [this](bool enabled) {
|
||||
if (enabled != mEnabled) {
|
||||
mChanged = true;
|
||||
emit changed();
|
||||
}
|
||||
mEnabled = enabled;
|
||||
});
|
||||
mPayloadTypeModelConnection->makeConnectToModel(&PayloadTypeModel::enabledChanged, [this](bool enabled) {
|
||||
mPayloadTypeModelConnection->invokeToCore([this, enabled]() {
|
||||
if (mEnabled != enabled) {
|
||||
mEnabled = enabled;
|
||||
emit enabledChanged();
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
void PayloadTypeCore::save() {
|
||||
if (mChanged) mPayloadTypeModelConnection->invokeToModel([this]() { mPayloadTypeModel->setEnabled(mEnabled); });
|
||||
}
|
||||
|
||||
PayloadTypeCore::Family PayloadTypeCore::getFamily() {
|
||||
|
|
|
|||
|
|
@ -43,7 +43,7 @@ public:
|
|||
const std::shared_ptr<linphone::PayloadType> &payloadType);
|
||||
|
||||
PayloadTypeCore(Family family, const std::shared_ptr<linphone::PayloadType> &payloadType);
|
||||
PayloadTypeCore(){};
|
||||
PayloadTypeCore() {};
|
||||
~PayloadTypeCore();
|
||||
|
||||
void setSelf(QSharedPointer<PayloadTypeCore> me);
|
||||
|
|
@ -51,9 +51,15 @@ public:
|
|||
bool isDownloadable();
|
||||
QString getMimeType();
|
||||
|
||||
Q_INVOKABLE void save();
|
||||
|
||||
signals:
|
||||
void changed();
|
||||
|
||||
protected:
|
||||
Family mFamily;
|
||||
bool mDownloadable = false;
|
||||
bool mChanged = false;
|
||||
DECLARE_CORE_GETSET_MEMBER(bool, enabled, Enabled)
|
||||
DECLARE_CORE_MEMBER(QString, mimeType, MimeType)
|
||||
DECLARE_CORE_MEMBER(QString, encoderDescription, EncoderDescription)
|
||||
|
|
|
|||
|
|
@ -37,13 +37,21 @@ LimitProxy::~LimitProxy() {
|
|||
bool LimitProxy::filterAcceptsRow(int sourceRow, const QModelIndex &sourceParent) const {
|
||||
return mMaxDisplayItems == -1 || sourceRow < mMaxDisplayItems;
|
||||
}
|
||||
|
||||
void LimitProxy::invalidateFilter() {
|
||||
// TODO for a better filter management by encapsulating filter change between begin/end
|
||||
#if QT_VERSION < QT_VERSION_CHECK(6, 10, 0)
|
||||
QSortFilterProxyModel::invalidateFilter();
|
||||
#else
|
||||
QSortFilterProxyModel::beginFilterChange();
|
||||
QSortFilterProxyModel::endFilterChange();
|
||||
#endif
|
||||
}
|
||||
void LimitProxy::setSourceModels(SortFilterProxy *firstList) {
|
||||
auto secondList = firstList->sourceModel();
|
||||
if (secondList) {
|
||||
connect(secondList, &QAbstractItemModel::rowsInserted, this, &LimitProxy::onAdded);
|
||||
connect(secondList, &QAbstractItemModel::rowsRemoved, this, &LimitProxy::onRemoved);
|
||||
connect(secondList, &QAbstractItemModel::modelReset, this, &LimitProxy::invalidateRowsFilter);
|
||||
connect(secondList, &QAbstractItemModel::modelReset, this, &LimitProxy::invalidate);
|
||||
}
|
||||
connect(firstList, &SortFilterProxy::filterTextChanged, this, &LimitProxy::filterTextChanged);
|
||||
connect(firstList, &SortFilterProxy::filterTypeChanged, this, &LimitProxy::filterTypeChanged);
|
||||
|
|
@ -60,8 +68,8 @@ void LimitProxy::setSourceModels(SortFilterProxy *firstList) {
|
|||
|
||||
/*
|
||||
void LimitProxy::setSourceModels(SortFilterProxy *firstList, QAbstractItemModel *secondList) {
|
||||
connect(secondList, &QAbstractItemModel::rowsInserted, this, &LimitProxy::invalidateFilter);
|
||||
connect(secondList, &QAbstractItemModel::rowsRemoved, this, &LimitProxy::invalidateFilter);
|
||||
connect(secondList, &QAbstractItemModel::rowsInserted, this, &LimitProxy::invalidate);
|
||||
connect(secondList, &QAbstractItemModel::rowsRemoved, this, &LimitProxy::invalidate);
|
||||
connect(firstList, &SortFilterProxy::filterTextChanged, this, &LimitProxy::filterTextChanged);
|
||||
setSourceModel(firstList);
|
||||
}*/
|
||||
|
|
@ -119,7 +127,7 @@ void LimitProxy::setMaxDisplayItems(int maxItems) {
|
|||
emit maxDisplayItemsChanged();
|
||||
|
||||
if (model && getDisplayCount(modelCount) != oldCount) {
|
||||
invalidateFilter();
|
||||
invalidate();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -178,6 +186,6 @@ void LimitProxy::onAdded() {
|
|||
void LimitProxy::onRemoved() {
|
||||
int count = sourceModel()->rowCount();
|
||||
if (mMaxDisplayItems > 0 && mMaxDisplayItems <= count) {
|
||||
invalidateFilter();
|
||||
invalidate();
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -41,7 +41,7 @@ public:
|
|||
LimitProxy(QObject *parent = nullptr);
|
||||
virtual ~LimitProxy();
|
||||
virtual bool filterAcceptsRow(int sourceRow, const QModelIndex &sourceParent) const override;
|
||||
|
||||
virtual void invalidateFilter();
|
||||
// Helper for setting the limit with sorted/filtered list
|
||||
void setSourceModels(SortFilterProxy *firstList);
|
||||
|
||||
|
|
|
|||
|
|
@ -26,6 +26,9 @@ SortFilterProxy::SortFilterProxy(QAbstractItemModel *list) : QSortFilterProxyMod
|
|||
setSourceModel(list);
|
||||
}
|
||||
|
||||
SortFilterProxy::SortFilterProxy() {
|
||||
}
|
||||
|
||||
SortFilterProxy::SortFilterProxy(QAbstractItemModel *list, Qt::SortOrder order) : SortFilterProxy(list) {
|
||||
sort(0, order);
|
||||
}
|
||||
|
|
@ -63,9 +66,15 @@ int SortFilterProxy::getFilterType() const {
|
|||
|
||||
void SortFilterProxy::setFilterType(int filterType) {
|
||||
if (getFilterType() != filterType) {
|
||||
#if QT_VERSION >= QT_VERSION_CHECK(6, 10, 0)
|
||||
beginFilterChange();
|
||||
mFilterType = filterType;
|
||||
endFilterChange();
|
||||
#else
|
||||
mFilterType = filterType;
|
||||
invalidateFilter();
|
||||
#endif
|
||||
emit filterTypeChanged(filterType);
|
||||
invalidate();
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -75,8 +84,14 @@ QString SortFilterProxy::getFilterText() const {
|
|||
|
||||
void SortFilterProxy::setFilterText(const QString &filter) {
|
||||
if (mFilterText != filter) {
|
||||
#if QT_VERSION >= QT_VERSION_CHECK(6, 10, 0)
|
||||
beginFilterChange();
|
||||
mFilterText = filter;
|
||||
endFilterChange();
|
||||
#else
|
||||
mFilterText = filter;
|
||||
invalidateFilter();
|
||||
#endif
|
||||
emit filterTextChanged();
|
||||
}
|
||||
}
|
||||
|
|
@ -90,5 +105,10 @@ void SortFilterProxy::remove(int index, int count) {
|
|||
}
|
||||
|
||||
void SortFilterProxy::invalidateFilter() {
|
||||
QSortFilterProxyModel::invalidateFilter();
|
||||
#if QT_VERSION >= QT_VERSION_CHECK(6, 10, 0)
|
||||
QSortFilterProxyModel::beginFilterChange();
|
||||
QSortFilterProxyModel::endFilterChange();
|
||||
#else
|
||||
invalidateFilter();
|
||||
#endif
|
||||
}
|
||||
|
|
|
|||
|
|
@ -41,6 +41,7 @@ public:
|
|||
Q_PROPERTY(int filterType READ getFilterType WRITE setFilterType NOTIFY filterTypeChanged)
|
||||
Q_PROPERTY(QString filterText READ getFilterText WRITE setFilterText NOTIFY filterTextChanged)
|
||||
|
||||
SortFilterProxy();
|
||||
SortFilterProxy(QAbstractItemModel *parent);
|
||||
SortFilterProxy(QAbstractItemModel *parent, Qt::SortOrder order);
|
||||
virtual ~SortFilterProxy();
|
||||
|
|
|
|||
|
|
@ -94,18 +94,29 @@ void MagicSearchList::setSelf(QSharedPointer<MagicSearchList> me) {
|
|||
[this](const std::list<std::shared_ptr<linphone::SearchResult>> &results) {
|
||||
auto *contacts = new QList<QSharedPointer<FriendCore>>();
|
||||
auto ldapContacts = ToolModel::getLdapFriendList();
|
||||
|
||||
auto core = CoreModel::getInstance()->getCore();
|
||||
auto userAddress = core->getDefaultAccount() && core->getDefaultAccount()->getParams()
|
||||
? core->getDefaultAccount()->getParams()->getIdentityAddress()
|
||||
: nullptr;
|
||||
for (auto it : results) {
|
||||
QSharedPointer<FriendCore> contact;
|
||||
auto linphoneFriend = it->getFriend();
|
||||
bool isStored = false;
|
||||
if (linphoneFriend) {
|
||||
if (!mShowMe && userAddress && userAddress->weakEqual(linphoneFriend->getAddress())) {
|
||||
lWarning() << log().arg("do not show my own address in this contact list");
|
||||
continue;
|
||||
}
|
||||
isStored =
|
||||
(ldapContacts->findFriendByAddress(linphoneFriend->getAddress()) != linphoneFriend);
|
||||
contact = FriendCore::create(linphoneFriend, isStored, it->getSourceFlags());
|
||||
contacts->append(contact);
|
||||
} else if (auto address = it->getAddress()) {
|
||||
auto linphoneFriend = CoreModel::getInstance()->getCore()->createFriend();
|
||||
if (!mShowMe && userAddress && userAddress->weakEqual(address)) {
|
||||
lWarning() << log().arg("do not show my own address in this contact list");
|
||||
continue;
|
||||
}
|
||||
auto linphoneFriend = core->createFriend();
|
||||
linphoneFriend->setAddress(address);
|
||||
contact = FriendCore::create(linphoneFriend, isStored, it->getSourceFlags());
|
||||
auto displayName = Utils::coreStringToAppString(address->getDisplayName());
|
||||
|
|
@ -125,7 +136,7 @@ void MagicSearchList::setSelf(QSharedPointer<MagicSearchList> me) {
|
|||
contacts->append(contact);
|
||||
} else if (!it->getPhoneNumber().empty()) {
|
||||
auto phoneNumber = it->getPhoneNumber();
|
||||
linphoneFriend = CoreModel::getInstance()->getCore()->createFriend();
|
||||
linphoneFriend = core->createFriend();
|
||||
linphoneFriend->addPhoneNumber(phoneNumber);
|
||||
contact = FriendCore::create(linphoneFriend, isStored, it->getSourceFlags());
|
||||
contact->setGivenName(Utils::coreStringToAppString(it->getPhoneNumber()));
|
||||
|
|
@ -202,6 +213,17 @@ void MagicSearchList::setMaxResults(int maxResults) {
|
|||
}
|
||||
}
|
||||
|
||||
bool MagicSearchList::getShowMe() const {
|
||||
return mShowMe;
|
||||
}
|
||||
|
||||
void MagicSearchList::setShowMe(bool showMe) {
|
||||
if (mShowMe != showMe) {
|
||||
mShowMe = showMe;
|
||||
emit showMeChanged(mShowMe);
|
||||
}
|
||||
}
|
||||
|
||||
LinphoneEnums::MagicSearchAggregation MagicSearchList::getAggregationFlag() const {
|
||||
return mAggregationFlag;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -41,7 +41,7 @@ public:
|
|||
~MagicSearchList();
|
||||
|
||||
void setSelf(QSharedPointer<MagicSearchList> me);
|
||||
void connectContact(FriendCore* data);
|
||||
void connectContact(FriendCore *data);
|
||||
void setSearch(const QString &search);
|
||||
void setResults(const QList<QSharedPointer<FriendCore>> &contacts);
|
||||
void add(QSharedPointer<FriendCore> contact);
|
||||
|
|
@ -55,6 +55,9 @@ public:
|
|||
int getMaxResults() const;
|
||||
void setMaxResults(int maxResults);
|
||||
|
||||
bool getShowMe() const;
|
||||
void setShowMe(bool showMe);
|
||||
|
||||
virtual QHash<int, QByteArray> roleNames() const override;
|
||||
virtual QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const override;
|
||||
|
||||
|
|
@ -68,6 +71,7 @@ signals:
|
|||
void sourceFlagsChanged(int sourceFlags);
|
||||
void aggregationFlagChanged(LinphoneEnums::MagicSearchAggregation flag);
|
||||
void maxResultsChanged(int maxResults);
|
||||
void showMeChanged(bool showMe);
|
||||
|
||||
void friendCreated(int index, FriendGui *data);
|
||||
void friendStarredChanged();
|
||||
|
|
@ -81,6 +85,7 @@ private:
|
|||
LinphoneEnums::MagicSearchAggregation mAggregationFlag;
|
||||
QString mSearchFilter;
|
||||
int mMaxResults = -1;
|
||||
bool mShowMe = false;
|
||||
|
||||
std::shared_ptr<MagicSearchModel> mMagicSearch;
|
||||
QSharedPointer<SafeConnection<MagicSearchList, MagicSearchModel>> mModelConnection;
|
||||
|
|
|
|||
|
|
@ -148,6 +148,14 @@ void MagicSearchProxy::setMaxResults(int flags) {
|
|||
mList->setMaxResults(flags);
|
||||
}
|
||||
|
||||
bool MagicSearchProxy::getShowMe() const {
|
||||
return mList->getShowMe();
|
||||
}
|
||||
|
||||
void MagicSearchProxy::setShowMe(bool showMe) {
|
||||
mList->setShowMe(showMe);
|
||||
}
|
||||
|
||||
MagicSearchProxy *MagicSearchProxy::getParentProxy() const {
|
||||
return mParentProxy;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -34,6 +34,7 @@ class MagicSearchProxy : public LimitProxy {
|
|||
Q_PROPERTY(int sourceFlags READ getSourceFlags WRITE setSourceFlags NOTIFY sourceFlagsChanged)
|
||||
|
||||
Q_PROPERTY(int maxResults READ getMaxResults WRITE setMaxResults NOTIFY maxResultsChanged)
|
||||
Q_PROPERTY(bool showMe READ getShowMe WRITE setShowMe NOTIFY showMeChanged)
|
||||
Q_PROPERTY(LinphoneEnums::MagicSearchAggregation aggregationFlag READ getAggregationFlag WRITE setAggregationFlag
|
||||
NOTIFY aggregationFlagChanged)
|
||||
|
||||
|
|
@ -60,6 +61,9 @@ public:
|
|||
int getMaxResults() const;
|
||||
void setMaxResults(int maxResults);
|
||||
|
||||
bool getShowMe() const;
|
||||
void setShowMe(bool showMe);
|
||||
|
||||
MagicSearchProxy *getParentProxy() const;
|
||||
void setList(QSharedPointer<MagicSearchList> list);
|
||||
Q_INVOKABLE void setParentProxy(MagicSearchProxy *proxy);
|
||||
|
|
@ -77,6 +81,7 @@ signals:
|
|||
void sourceFlagsChanged(int sourceFlags);
|
||||
void aggregationFlagChanged(LinphoneEnums::MagicSearchAggregation aggregationFlag);
|
||||
void maxResultsChanged(int maxResults);
|
||||
void showMeChanged(bool showMe);
|
||||
void forceUpdate();
|
||||
void localFriendCreated(int index);
|
||||
void parentProxyChanged();
|
||||
|
|
|
|||
|
|
@ -61,6 +61,13 @@ SettingsCore::SettingsCore(QObject *parent) : QObject(parent) {
|
|||
mRingtoneFolder = mRingtonePath.left(mRingtonePath.lastIndexOf(QDir::separator()));
|
||||
}
|
||||
|
||||
// Network
|
||||
mIpv6Enabled = settingsModel->getIpv6Enabled();
|
||||
|
||||
// Advanced
|
||||
mAutoStart = settingsModel->getAutoStart();
|
||||
mHideFps = settingsModel->getHideFps();
|
||||
|
||||
// Audio
|
||||
mCaptureDevices = settingsModel->getCaptureDevices();
|
||||
mPlaybackDevices = settingsModel->getPlaybackDevices();
|
||||
|
|
@ -107,13 +114,15 @@ SettingsCore::SettingsCore(QObject *parent) : QObject(parent) {
|
|||
mEmojiFont = settingsModel->getEmojiFont();
|
||||
mTextMessageFont = settingsModel->getTextMessageFont();
|
||||
|
||||
// Check for update
|
||||
mIsCheckForUpdateAvailable = settingsModel->isCheckForUpdateAvailable();
|
||||
|
||||
// Ui
|
||||
INIT_CORE_MEMBER(DisableChatFeature, settingsModel)
|
||||
INIT_CORE_MEMBER(DisableMeetingsFeature, settingsModel)
|
||||
INIT_CORE_MEMBER(DisableBroadcastFeature, settingsModel)
|
||||
INIT_CORE_MEMBER(HideSettings, settingsModel)
|
||||
INIT_CORE_MEMBER(HideAccountSettings, settingsModel)
|
||||
INIT_CORE_MEMBER(HideFps, settingsModel)
|
||||
INIT_CORE_MEMBER(DisableCallRecordings, settingsModel)
|
||||
INIT_CORE_MEMBER(AssistantHideCreateAccount, settingsModel)
|
||||
INIT_CORE_MEMBER(AssistantHideCreateAccount, settingsModel)
|
||||
|
|
@ -129,7 +138,6 @@ SettingsCore::SettingsCore(QObject *parent) : QObject(parent) {
|
|||
INIT_CORE_MEMBER(AutoStart, settingsModel)
|
||||
INIT_CORE_MEMBER(ExitOnClose, settingsModel)
|
||||
INIT_CORE_MEMBER(SyncLdapContacts, settingsModel)
|
||||
INIT_CORE_MEMBER(Ipv6Enabled, settingsModel)
|
||||
INIT_CORE_MEMBER(ConfigLocale, settingsModel)
|
||||
INIT_CORE_MEMBER(DownloadFolder, settingsModel)
|
||||
|
||||
|
|
@ -138,7 +146,6 @@ SettingsCore::SettingsCore(QObject *parent) : QObject(parent) {
|
|||
INIT_CORE_MEMBER(CallToneIndicationsEnabled, settingsModel)
|
||||
INIT_CORE_MEMBER(CommandLine, settingsModel)
|
||||
INIT_CORE_MEMBER(DisableCommandLine, settingsModel)
|
||||
INIT_CORE_MEMBER(DisableCallForward, settingsModel)
|
||||
INIT_CORE_MEMBER(CallForwardToAddress, settingsModel)
|
||||
|
||||
INIT_CORE_MEMBER(ThemeMainColor, settingsModel)
|
||||
|
|
@ -207,10 +214,10 @@ SettingsCore::SettingsCore(const SettingsCore &settingsCore) {
|
|||
mAssistantGoDirectlyToThirdPartySipAccountLogin = settingsCore.mAssistantGoDirectlyToThirdPartySipAccountLogin;
|
||||
mAssistantThirdPartySipAccountDomain = settingsCore.mAssistantThirdPartySipAccountDomain;
|
||||
mAssistantThirdPartySipAccountTransport = settingsCore.mAssistantThirdPartySipAccountTransport;
|
||||
mAutoStart = settingsCore.mAutoStart;
|
||||
mExitOnClose = settingsCore.mExitOnClose;
|
||||
mSyncLdapContacts = settingsCore.mSyncLdapContacts;
|
||||
mIpv6Enabled = settingsCore.mIpv6Enabled;
|
||||
mAutoStart = settingsCore.mAutoStart;
|
||||
mConfigLocale = settingsCore.mConfigLocale;
|
||||
mDownloadFolder = settingsCore.mDownloadFolder;
|
||||
mShortcutCount = settingsCore.mShortcutCount;
|
||||
|
|
@ -218,7 +225,7 @@ SettingsCore::SettingsCore(const SettingsCore &settingsCore) {
|
|||
mCallToneIndicationsEnabled = settingsCore.mCallToneIndicationsEnabled;
|
||||
mCommandLine = settingsCore.mCommandLine;
|
||||
mDisableCommandLine = settingsCore.mDisableCommandLine;
|
||||
mDisableCallForward = settingsCore.mDisableCallForward;
|
||||
mCallForwardToAddress = settingsCore.mCallForwardToAddress;
|
||||
|
||||
mDefaultDomain = settingsCore.mDefaultDomain;
|
||||
mShowAccountDevices = settingsCore.mShowAccountDevices;
|
||||
|
|
@ -234,6 +241,13 @@ void SettingsCore::setSelf(QSharedPointer<SettingsCore> me) {
|
|||
mustBeInLinphoneThread(getClassName());
|
||||
mSettingsModelConnection = SafeConnection<SettingsCore, SettingsModel>::create(me, SettingsModel::getInstance());
|
||||
|
||||
mSettingsModelConnection->makeConnectToModel(&SettingsModel::captureGraphRunningChanged, [this](bool running) {
|
||||
mSettingsModelConnection->invokeToCore([this, running] {
|
||||
mCaptureGraphRunning = running;
|
||||
emit captureGraphRunningChanged(running);
|
||||
});
|
||||
});
|
||||
|
||||
// VFS
|
||||
mSettingsModelConnection->makeConnectToModel(&SettingsModel::vfsEnabledChanged, [this](const bool enabled) {
|
||||
mSettingsModelConnection->invokeToCore([this, enabled]() { setVfsEnabled(enabled); });
|
||||
|
|
@ -250,6 +264,31 @@ void SettingsCore::setSelf(QSharedPointer<SettingsCore> me) {
|
|||
mSettingsModelConnection->invokeToCore([this, enabled]() { setEchoCancellationEnabled(enabled); });
|
||||
});
|
||||
|
||||
// IPV6
|
||||
mSettingsModelConnection->makeConnectToModel(&SettingsModel::ipv6EnabledChanged, [this](const bool enabled) {
|
||||
mSettingsModelConnection->invokeToCore([this, enabled]() { setIpv6Enabled(enabled); });
|
||||
});
|
||||
|
||||
// Call Forward
|
||||
mSettingsModelConnection->makeConnectToModel(
|
||||
&SettingsModel::callForwardToAddressChanged, [this](const QString address) {
|
||||
mSettingsModelConnection->invokeToCore([this, address]() { setCallForwardToAddress(address); });
|
||||
});
|
||||
|
||||
// Hide FPS
|
||||
mSettingsModelConnection->makeConnectToModel(&SettingsModel::hideFpsChanged, [this](const bool hide) {
|
||||
mSettingsModelConnection->invokeToCore([this, hide]() { setHideFps(hide); });
|
||||
});
|
||||
|
||||
// AutoStart
|
||||
mSettingsModelConnection->makeConnectToModel(&SettingsModel::autoStartChanged, [this](const bool enabled) {
|
||||
mSettingsModelConnection->invokeToCore([this, enabled]() {
|
||||
bool emitSignal = mAutoStart != enabled;
|
||||
setAutoStart(enabled);
|
||||
if (emitSignal) emit autoStartChanged();
|
||||
});
|
||||
});
|
||||
|
||||
// Auto download incoming files
|
||||
mSettingsModelConnection->makeConnectToModel(
|
||||
&SettingsModel::autoDownloadReceivedFilesChanged, [this](const bool enabled) {
|
||||
|
|
@ -294,7 +333,7 @@ void SettingsCore::setSelf(QSharedPointer<SettingsCore> me) {
|
|||
});
|
||||
});
|
||||
mSettingsModelConnection->makeConnectToModel(&SettingsModel::playbackGainChanged, [this](const float value) {
|
||||
mSettingsModelConnection->invokeToCore([this, value]() { setPlaybackGain(value); });
|
||||
mSettingsModelConnection->invokeToCore([this, value]() { setPlaybackGainFromModel(value); });
|
||||
});
|
||||
|
||||
mSettingsModelConnection->makeConnectToCore(&SettingsCore::lSetCaptureGain, [this](const float value) {
|
||||
|
|
@ -304,7 +343,7 @@ void SettingsCore::setSelf(QSharedPointer<SettingsCore> me) {
|
|||
});
|
||||
});
|
||||
mSettingsModelConnection->makeConnectToModel(&SettingsModel::captureGainChanged, [this](const float value) {
|
||||
mSettingsModelConnection->invokeToCore([this, value]() { setCaptureGain(value); });
|
||||
mSettingsModelConnection->invokeToCore([this, value]() { setCaptureGainFromModel(value); });
|
||||
});
|
||||
|
||||
mSettingsModelConnection->makeConnectToModel(&SettingsModel::micVolumeChanged, [this](const float value) {
|
||||
|
|
@ -440,8 +479,6 @@ void SettingsCore::setSelf(QSharedPointer<SettingsCore> me) {
|
|||
ExitOnClose)
|
||||
DEFINE_CORE_GETSET_CONNECT(mSettingsModelConnection, SettingsCore, SettingsModel, settingsModel, bool,
|
||||
syncLdapContacts, SyncLdapContacts)
|
||||
DEFINE_CORE_GETSET_CONNECT(mSettingsModelConnection, SettingsCore, SettingsModel, settingsModel, bool, ipv6Enabled,
|
||||
Ipv6Enabled)
|
||||
DEFINE_CORE_GETSET_CONNECT(mSettingsModelConnection, SettingsCore, SettingsModel, settingsModel, QString,
|
||||
configLocale, ConfigLocale)
|
||||
DEFINE_CORE_GETSET_CONNECT(mSettingsModelConnection, SettingsCore, SettingsModel, settingsModel, QString,
|
||||
|
|
@ -456,10 +493,6 @@ void SettingsCore::setSelf(QSharedPointer<SettingsCore> me) {
|
|||
commandLine, CommandLine)
|
||||
DEFINE_CORE_GETSET_CONNECT(mSettingsModelConnection, SettingsCore, SettingsModel, settingsModel, bool,
|
||||
disableCommandLine, DisableCommandLine)
|
||||
DEFINE_CORE_GETSET_CONNECT(mSettingsModelConnection, SettingsCore, SettingsModel, settingsModel, bool,
|
||||
disableCallForward, DisableCallForward)
|
||||
DEFINE_CORE_GETSET_CONNECT(mSettingsModelConnection, SettingsCore, SettingsModel, settingsModel, QString,
|
||||
callForwardToAddress, CallForwardToAddress)
|
||||
DEFINE_CORE_GETSET_CONNECT(mSettingsModelConnection, SettingsCore, SettingsModel, settingsModel, QString,
|
||||
themeAboutPictureUrl, ThemeAboutPictureUrl)
|
||||
DEFINE_CORE_GETSET_CONNECT(mSettingsModelConnection, SettingsCore, SettingsModel, settingsModel, QString,
|
||||
|
|
@ -549,13 +582,14 @@ void SettingsCore::reset(const SettingsCore &settingsCore) {
|
|||
setAssistantGoDirectlyToThirdPartySipAccountLogin(settingsCore.mAssistantGoDirectlyToThirdPartySipAccountLogin);
|
||||
setAssistantThirdPartySipAccountDomain(settingsCore.mAssistantThirdPartySipAccountDomain);
|
||||
setAssistantThirdPartySipAccountTransport(settingsCore.mAssistantThirdPartySipAccountTransport);
|
||||
setAutoStart(settingsCore.mAutoStart);
|
||||
setExitOnClose(settingsCore.mExitOnClose);
|
||||
setSyncLdapContacts(settingsCore.mSyncLdapContacts);
|
||||
setCardDAVMinCharForResearch(settingsCore.mCardDAVMinCharForResearch);
|
||||
setIpv6Enabled(settingsCore.mIpv6Enabled);
|
||||
setAutoStart(settingsCore.mAutoStart);
|
||||
setConfigLocale(settingsCore.mConfigLocale);
|
||||
setDownloadFolder(settingsCore.mDownloadFolder);
|
||||
setCallForwardToAddress(settingsCore.mCallForwardToAddress);
|
||||
}
|
||||
|
||||
QString SettingsCore::getConfigPath(const QCommandLineParser &parser) {
|
||||
|
|
@ -614,6 +648,36 @@ void SettingsCore::setEchoCancellationEnabled(bool enabled) {
|
|||
}
|
||||
}
|
||||
|
||||
void SettingsCore::setIpv6Enabled(bool enabled) {
|
||||
if (mIpv6Enabled != enabled) {
|
||||
mIpv6Enabled = enabled;
|
||||
emit ipv6EnabledChanged();
|
||||
setIsSaved(false);
|
||||
}
|
||||
}
|
||||
|
||||
void SettingsCore::setAutoStart(bool enabled) {
|
||||
if (mAutoStart != enabled) {
|
||||
mAutoStart = enabled;
|
||||
setIsSaved(false);
|
||||
}
|
||||
}
|
||||
|
||||
void SettingsCore::setCallForwardToAddress(QString address) {
|
||||
if (mCallForwardToAddress != address) {
|
||||
mCallForwardToAddress = address;
|
||||
setIsSaved(false);
|
||||
}
|
||||
}
|
||||
|
||||
void SettingsCore::setHideFps(bool hide) {
|
||||
if (mHideFps != hide) {
|
||||
mHideFps = hide;
|
||||
emit hideFpsChanged();
|
||||
setIsSaved(false);
|
||||
}
|
||||
}
|
||||
|
||||
void SettingsCore::setAutoDownloadReceivedFiles(bool enabled) {
|
||||
if (mAutoDownloadReceivedFiles != enabled) {
|
||||
mAutoDownloadReceivedFiles = enabled;
|
||||
|
|
@ -706,7 +770,7 @@ bool SettingsCore::isSaved() const {
|
|||
void SettingsCore::setIsSaved(bool saved) {
|
||||
if (mIsSaved != saved) {
|
||||
mIsSaved = saved;
|
||||
emit isSavedChanged();
|
||||
emit isSavedChanged(saved);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -757,6 +821,13 @@ void SettingsCore::setCaptureGain(float gain) {
|
|||
}
|
||||
}
|
||||
|
||||
void SettingsCore::setCaptureGainFromModel(float gain) {
|
||||
if (mCaptureGain != gain) {
|
||||
mCaptureGain = gain;
|
||||
emit captureGainChanged(gain);
|
||||
}
|
||||
}
|
||||
|
||||
QVariantMap SettingsCore::getConferenceLayout() const {
|
||||
return mConferenceLayout;
|
||||
}
|
||||
|
|
@ -801,6 +872,13 @@ void SettingsCore::setPlaybackGain(float gain) {
|
|||
}
|
||||
}
|
||||
|
||||
void SettingsCore::setPlaybackGainFromModel(float gain) {
|
||||
if (mPlaybackGain != gain) {
|
||||
mPlaybackGain = gain;
|
||||
emit playbackGainChanged(gain);
|
||||
}
|
||||
}
|
||||
|
||||
QVariantMap SettingsCore::getCaptureDevice() const {
|
||||
return mCaptureDevice;
|
||||
}
|
||||
|
|
@ -998,10 +1076,6 @@ void SettingsCore::setShowAccountDevices(bool show) {
|
|||
}
|
||||
}
|
||||
|
||||
bool SettingsCore::getAutoStart() const {
|
||||
return mAutoStart;
|
||||
}
|
||||
|
||||
bool SettingsCore::getExitOnClose() const {
|
||||
return mExitOnClose;
|
||||
}
|
||||
|
|
@ -1028,7 +1102,8 @@ QString SettingsCore::getConfigLocale() const {
|
|||
QString SettingsCore::getDownloadFolder() const {
|
||||
auto path = mDownloadFolder;
|
||||
if (mDownloadFolder.isEmpty()) path = Paths::getDownloadDirPath();
|
||||
return QDir::cleanPath(path) + QDir::separator();
|
||||
QString cleanPath = QDir::cleanPath(path);
|
||||
return cleanPath;
|
||||
}
|
||||
|
||||
void SettingsCore::writeIntoModel(std::shared_ptr<SettingsModel> model) const {
|
||||
|
|
@ -1088,12 +1163,13 @@ void SettingsCore::writeIntoModel(std::shared_ptr<SettingsModel> model) const {
|
|||
model->setAssistantGoDirectlyToThirdPartySipAccountLogin(mAssistantGoDirectlyToThirdPartySipAccountLogin);
|
||||
model->setAssistantThirdPartySipAccountDomain(mAssistantThirdPartySipAccountDomain);
|
||||
model->setAssistantThirdPartySipAccountTransport(mAssistantThirdPartySipAccountTransport);
|
||||
model->setAutoStart(mAutoStart);
|
||||
model->setExitOnClose(mExitOnClose);
|
||||
model->setSyncLdapContacts(mSyncLdapContacts);
|
||||
model->setIpv6Enabled(mIpv6Enabled);
|
||||
model->setAutoStart(mAutoStart);
|
||||
model->setConfigLocale(mConfigLocale);
|
||||
model->setDownloadFolder(mDownloadFolder);
|
||||
model->setCallForwardToAddress(mCallForwardToAddress);
|
||||
}
|
||||
|
||||
void SettingsCore::writeFromModel(const std::shared_ptr<SettingsModel> &model) {
|
||||
|
|
@ -1112,6 +1188,9 @@ void SettingsCore::writeFromModel(const std::shared_ptr<SettingsModel> &model) {
|
|||
mRingtoneFileName =
|
||||
ringtone.exists() ? ringtone.fileName() : mRingtonePath.right(mRingtonePath.lastIndexOf(QDir::separator()));
|
||||
|
||||
// Advanced
|
||||
mAutoStart = model->getAutoStart();
|
||||
|
||||
// Chat
|
||||
mAutoDownloadReceivedFiles = model->getAutoDownloadReceivedFiles();
|
||||
|
||||
|
|
@ -1143,6 +1222,9 @@ void SettingsCore::writeFromModel(const std::shared_ptr<SettingsModel> &model) {
|
|||
mLogsFolder = model->getLogsFolder();
|
||||
mLogsEmail = model->getLogsEmail();
|
||||
|
||||
// Check update
|
||||
mIsCheckForUpdateAvailable = model->isCheckForUpdateAvailable();
|
||||
|
||||
// UI
|
||||
mDisableChatFeature = model->getDisableChatFeature();
|
||||
mDisableMeetingsFeature = model->getDisableMeetingsFeature();
|
||||
|
|
@ -1167,13 +1249,20 @@ void SettingsCore::writeFromModel(const std::shared_ptr<SettingsModel> &model) {
|
|||
mSyncLdapContacts = model->getSyncLdapContacts();
|
||||
mCardDAVMinCharForResearch = model->getCardDAVMinCharResearch();
|
||||
mIpv6Enabled = model->getIpv6Enabled();
|
||||
mAutoStart = model->getAutoStart();
|
||||
mConfigLocale = model->getConfigLocale();
|
||||
mDownloadFolder = model->getDownloadFolder();
|
||||
mCallForwardToAddress = model->getCallForwardToAddress();
|
||||
}
|
||||
|
||||
bool SettingsCore::isCheckForUpdateAvailable() const {
|
||||
return mIsCheckForUpdateAvailable;
|
||||
}
|
||||
|
||||
void SettingsCore::save() {
|
||||
mustBeInMainThread(getClassName() + Q_FUNC_INFO);
|
||||
SettingsCore *thisCopy = new SettingsCore(*this);
|
||||
emit autoStartChanged();
|
||||
if (SettingsModel::getInstance()) {
|
||||
mSettingsModelConnection->invokeToModel([this, thisCopy] {
|
||||
mustBeInLinphoneThread(getClassName() + Q_FUNC_INFO);
|
||||
|
|
|
|||
|
|
@ -62,6 +62,17 @@ public:
|
|||
Q_PROPERTY(QVariantMap playbackDevice READ getPlaybackDevice WRITE setPlaybackDevice NOTIFY playbackDeviceChanged)
|
||||
Q_PROPERTY(QVariantMap ringerDevice READ getRingerDevice WRITE setRingerDevice NOTIFY ringerDeviceChanged)
|
||||
|
||||
// Call Forward
|
||||
Q_PROPERTY(QString callForwardToAddress READ getCallForwardToAddress WRITE setCallForwardToAddress NOTIFY
|
||||
callForwardToAddressChanged)
|
||||
|
||||
// Network
|
||||
Q_PROPERTY(bool ipv6Enabled READ getIpv6Enabled WRITE setIpv6Enabled NOTIFY ipv6EnabledChanged)
|
||||
Q_PROPERTY(bool hideFps READ getHideFps WRITE setHideFps NOTIFY hideFpsChanged)
|
||||
|
||||
// Advanced
|
||||
Q_PROPERTY(bool autoStart READ getAutoStart WRITE setAutoStart NOTIFY autoStartChanged)
|
||||
|
||||
Q_PROPERTY(
|
||||
QVariantMap conferenceLayout READ getConferenceLayout WRITE setConferenceLayout NOTIFY conferenceLayoutChanged)
|
||||
Q_PROPERTY(
|
||||
|
|
@ -144,9 +155,11 @@ public:
|
|||
|
||||
float getPlaybackGain() const;
|
||||
void setPlaybackGain(float gain);
|
||||
void setPlaybackGainFromModel(float gain);
|
||||
|
||||
float getCaptureGain() const;
|
||||
void setCaptureGain(float gain);
|
||||
void setCaptureGainFromModel(float gain);
|
||||
|
||||
QVariantList getCaptureDevices() const;
|
||||
void setCaptureDevices(QVariantList devices);
|
||||
|
|
@ -193,6 +206,32 @@ public:
|
|||
Q_INVOKABLE void closeCallSettings();
|
||||
Q_INVOKABLE void updateMicVolume() const;
|
||||
|
||||
// Call Forward. --------------------------------------------------------------------
|
||||
|
||||
QString getCallForwardToAddress() {
|
||||
return mCallForwardToAddress;
|
||||
}
|
||||
void setCallForwardToAddress(QString address);
|
||||
|
||||
// Network. --------------------------------------------------------------------
|
||||
|
||||
bool getIpv6Enabled() {
|
||||
return mIpv6Enabled;
|
||||
}
|
||||
void setIpv6Enabled(bool enabled);
|
||||
|
||||
// Advanced. --------------------------------------------------------------------
|
||||
|
||||
bool getAutoStart() {
|
||||
return mAutoStart;
|
||||
}
|
||||
void setAutoStart(bool enabled);
|
||||
|
||||
bool getHideFps() {
|
||||
return mHideFps;
|
||||
}
|
||||
void setHideFps(bool hide);
|
||||
|
||||
bool getLogsEnabled() const;
|
||||
void setLogsEnabled(bool enabled);
|
||||
|
||||
|
|
@ -218,6 +257,7 @@ public:
|
|||
bool getCardDAVMinCharForResearch() const;
|
||||
void setCardDAVMinCharForResearch(int min);
|
||||
|
||||
bool isCheckForUpdateAvailable() const;
|
||||
Q_INVOKABLE void save();
|
||||
Q_INVOKABLE void undo();
|
||||
|
||||
|
|
@ -226,7 +266,6 @@ public:
|
|||
DECLARE_CORE_GETSET_MEMBER(bool, disableBroadcastFeature, DisableBroadcastFeature)
|
||||
DECLARE_CORE_GETSET_MEMBER(bool, hideSettings, HideSettings)
|
||||
DECLARE_CORE_GETSET_MEMBER(bool, hideAccountSettings, HideAccountSettings)
|
||||
DECLARE_CORE_GETSET_MEMBER(bool, hideFps, HideFps)
|
||||
DECLARE_CORE_GETSET_MEMBER(bool, disableCallRecordings, DisableCallRecordings)
|
||||
DECLARE_CORE_GETSET_MEMBER(bool, assistantHideCreateAccount, AssistantHideCreateAccount)
|
||||
DECLARE_CORE_GETSET_MEMBER(bool, assistantDisableQrCode, AssistantDisableQrCode)
|
||||
|
|
@ -239,10 +278,8 @@ public:
|
|||
AssistantGoDirectlyToThirdPartySipAccountLogin)
|
||||
DECLARE_CORE_GETSET_MEMBER(QString, assistantThirdPartySipAccountDomain, AssistantThirdPartySipAccountDomain)
|
||||
DECLARE_CORE_GETSET_MEMBER(QString, assistantThirdPartySipAccountTransport, AssistantThirdPartySipAccountTransport)
|
||||
DECLARE_CORE_GETSET(bool, autoStart, AutoStart)
|
||||
DECLARE_CORE_GETSET(bool, exitOnClose, ExitOnClose)
|
||||
DECLARE_CORE_GETSET(bool, syncLdapContacts, SyncLdapContacts)
|
||||
DECLARE_CORE_GETSET_MEMBER(bool, ipv6Enabled, Ipv6Enabled)
|
||||
DECLARE_CORE_GETSET(QString, configLocale, ConfigLocale)
|
||||
DECLARE_CORE_GETSET(QString, downloadFolder, DownloadFolder)
|
||||
// Read-only
|
||||
|
|
@ -251,8 +288,6 @@ public:
|
|||
DECLARE_CORE_GETSET_MEMBER(bool, callToneIndicationsEnabled, CallToneIndicationsEnabled)
|
||||
DECLARE_CORE_GETSET_MEMBER(bool, disableCommandLine, DisableCommandLine)
|
||||
DECLARE_CORE_GETSET_MEMBER(QString, commandLine, CommandLine)
|
||||
DECLARE_CORE_GETSET_MEMBER(bool, disableCallForward, DisableCallForward)
|
||||
DECLARE_CORE_GETSET_MEMBER(QString, callForwardToAddress, CallForwardToAddress)
|
||||
DECLARE_CORE_GET_CONSTANT(QFont, emojiFont, EmojiFont)
|
||||
DECLARE_CORE_GET_CONSTANT(QFont, textMessageFont, TextMessageFont)
|
||||
// Theme
|
||||
|
|
@ -282,6 +317,17 @@ signals:
|
|||
void captureDevicesChanged(const QVariantList &devices);
|
||||
void playbackDevicesChanged(const QVariantList &devices);
|
||||
void ringerDevicesChanged(const QVariantList &devices);
|
||||
|
||||
// Network
|
||||
void ipv6EnabledChanged();
|
||||
|
||||
// Call Forward
|
||||
void callForwardToAddressChanged();
|
||||
|
||||
// Advanced
|
||||
void autoStartChanged();
|
||||
void hideFpsChanged();
|
||||
|
||||
void conferenceLayoutsChanged(const QVariantList &layouts);
|
||||
void mediaEncryptionsChanged(const QVariantList &encryptions);
|
||||
|
||||
|
|
@ -302,7 +348,7 @@ signals:
|
|||
|
||||
void createEndToEndEncryptedMeetingsAndGroupCallsChanged(bool endtoend);
|
||||
|
||||
void isSavedChanged();
|
||||
void isSavedChanged(bool saved);
|
||||
|
||||
void lSetPlaybackDevice(QVariantMap device);
|
||||
void playbackDeviceChanged(const QVariantMap &device);
|
||||
|
|
@ -380,6 +426,16 @@ private:
|
|||
float mPlaybackGain;
|
||||
int mEchoCancellationCalibration;
|
||||
|
||||
// Network
|
||||
bool mIpv6Enabled;
|
||||
|
||||
// Call Forward
|
||||
QString mCallForwardToAddress;
|
||||
|
||||
// Advanced
|
||||
bool mAutoStart;
|
||||
bool mHideFps;
|
||||
|
||||
// Debug logs
|
||||
bool mLogsEnabled;
|
||||
bool mFullLogsEnabled;
|
||||
|
|
@ -401,6 +457,9 @@ private:
|
|||
// CardDAV
|
||||
int mCardDAVMinCharForResearch = 0;
|
||||
|
||||
// Check update
|
||||
bool mIsCheckForUpdateAvailable = false;
|
||||
|
||||
DECLARE_ABSTRACT_OBJECT
|
||||
};
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -2,6 +2,7 @@ list(APPEND _LINPHONEAPP_RC_FILES data/assistant/use-app-sip-account.rc
|
|||
data/assistant/create-app-sip-account.rc
|
||||
data/assistant/use-other-sip-account.rc
|
||||
data/shaders/roundEffect.frag.qsb
|
||||
data/shaders/opacityMask.frag.qsb
|
||||
data/emoji/emoji.json
|
||||
)
|
||||
|
||||
|
|
|
|||
1
Linphone/data/image/calendar-plus.svg
Normal file
1
Linphone/data/image/calendar-plus.svg
Normal file
|
|
@ -0,0 +1 @@
|
|||
<svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" fill="#000000" viewBox="0 0 256 256"><path d="M208,32H184V24a8,8,0,0,0-16,0v8H88V24a8,8,0,0,0-16,0v8H48A16,16,0,0,0,32,48V208a16,16,0,0,0,16,16H208a16,16,0,0,0,16-16V48A16,16,0,0,0,208,32ZM72,48v8a8,8,0,0,0,16,0V48h80v8a8,8,0,0,0,16,0V48h24V80H48V48ZM208,208H48V96H208V208Zm-48-56a8,8,0,0,1-8,8H136v16a8,8,0,0,1-16,0V160H104a8,8,0,0,1,0-16h16V128a8,8,0,0,1,16,0v16h16A8,8,0,0,1,160,152Z"></path></svg>
|
||||
|
After Width: | Height: | Size: 464 B |
BIN
Linphone/data/image/qt-logo.png
Normal file
BIN
Linphone/data/image/qt-logo.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 2.7 KiB |
|
|
@ -80,7 +80,7 @@
|
|||
<location filename="../../core/account/AccountCore.cpp" line="500"/>
|
||||
<source>manage_account_status_cleared_summary</source>
|
||||
<extracomment>"Compte désactivé, vous ne recevrez ni appel ni message."</extracomment>
|
||||
<translation type="unfinished"></translation>
|
||||
<translation>Compte desactivat, no rebràs pas trucades ni missatges.</translation>
|
||||
</message>
|
||||
</context>
|
||||
<context>
|
||||
|
|
@ -2187,6 +2187,11 @@
|
|||
<extracomment>Could not open file : unknown path %1</extracomment>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../../core/chat/message/content/ChatMessageContentCore.cpp" line="108"/>
|
||||
<source>info_popup_error_titile</source>
|
||||
<translation>Error</translation>
|
||||
</message>
|
||||
</context>
|
||||
<context>
|
||||
<name>ChatMessageContentList</name>
|
||||
|
|
@ -2241,18 +2246,6 @@ Error</extracomment>
|
|||
</context>
|
||||
<context>
|
||||
<name>ChatMessageContentModel</name>
|
||||
<message>
|
||||
<location filename="../../model/chat/message/content/ChatMessageContentModel.cpp" line="105"/>
|
||||
<source>popup_error_title</source>
|
||||
<extracomment>Error</extracomment>
|
||||
<translation>Error</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../../model/chat/message/content/ChatMessageContentModel.cpp" line="108"/>
|
||||
<source>popup_download_error_message</source>
|
||||
<extracomment>This file was already downloaded and is no more on the server. Your peer have to resend it if you want to get it</extracomment>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
</context>
|
||||
<context>
|
||||
<name>ChatMessageCore</name>
|
||||
|
|
@ -2606,7 +2599,7 @@ Error</extracomment>
|
|||
<message>
|
||||
<location filename="../../view/Page/Form/Contact/ContactEdition.qml" line="62"/>
|
||||
<source>close_accessible_name</source>
|
||||
<extracomment>Close %n</extracomment>
|
||||
<extracomment>Close %1</extracomment>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
|
|
@ -7429,4 +7422,12 @@ Failed to create 1-1 conversation with %1 !</extracomment>
|
|||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
</context>
|
||||
<context>
|
||||
<name>CoreModel</name>
|
||||
<message>
|
||||
<location filename="../../model/core/CoreModel.cpp" line="220"/>
|
||||
<source>info_popup_error_title</source>
|
||||
<translation>Error</translation>
|
||||
</message>
|
||||
</context>
|
||||
</TS>
|
||||
|
|
|
|||
File diff suppressed because it is too large
Load diff
File diff suppressed because it is too large
Load diff
File diff suppressed because it is too large
Load diff
|
|
@ -2241,18 +2241,6 @@ Error</extracomment>
|
|||
</context>
|
||||
<context>
|
||||
<name>ChatMessageContentModel</name>
|
||||
<message>
|
||||
<location filename="../../model/chat/message/content/ChatMessageContentModel.cpp" line="105"/>
|
||||
<source>popup_error_title</source>
|
||||
<extracomment>Error</extracomment>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../../model/chat/message/content/ChatMessageContentModel.cpp" line="108"/>
|
||||
<source>popup_download_error_message</source>
|
||||
<extracomment>This file was already downloaded and is no more on the server. Your peer have to resend it if you want to get it</extracomment>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
</context>
|
||||
<context>
|
||||
<name>ChatMessageCore</name>
|
||||
|
|
@ -2606,7 +2594,7 @@ Error</extracomment>
|
|||
<message>
|
||||
<location filename="../../view/Page/Form/Contact/ContactEdition.qml" line="62"/>
|
||||
<source>close_accessible_name</source>
|
||||
<extracomment>Close %n</extracomment>
|
||||
<extracomment>Close %1</extracomment>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
|
|
|
|||
|
|
@ -19,7 +19,7 @@
|
|||
<location filename="../../view/Page/Layout/Settings/AbstractSettingsLayout.qml" line="90"/>
|
||||
<source>save_settings_accessible_name</source>
|
||||
<extracomment>Save %1 settings</extracomment>
|
||||
<translation type="unfinished"></translation>
|
||||
<translation>Gorde %1 ezarpenak</translation>
|
||||
</message>
|
||||
</context>
|
||||
<context>
|
||||
|
|
@ -152,37 +152,37 @@
|
|||
<location filename="../../model/account/AccountModel.cpp" line="253"/>
|
||||
<source>set_mwi_server_address_failed_error_message</source>
|
||||
<extracomment>"Unable to set voicemail server address, failed creating address from %1" : %1 is address</extracomment>
|
||||
<translation type="unfinished"></translation>
|
||||
<translation>Ezin da ahots-postontziaren zerbitzariaren helbidea ezarri, huts egin du %1 (e)tik helbidea sortzean</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../../model/account/AccountModel.cpp" line="292"/>
|
||||
<source>set_server_address_failed_error_message</source>
|
||||
<extracomment>"Unable to set server address, failed creating address from %1"</extracomment>
|
||||
<translation type="unfinished"></translation>
|
||||
<translation>Ezin da zerbitzariaren helbidea ezarri, huts egin du %1(e)tik helbidea sortzean</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../../model/account/AccountModel.cpp" line="309"/>
|
||||
<source>set_outbound_proxy_uri_failed_error_message</source>
|
||||
<extracomment>Unable to set outbound proxy uri, failed creating address from %1</extracomment>
|
||||
<translation type="unfinished"></translation>
|
||||
<translation>Ezin da irteerako proxy uri-a ezarri, huts egin du %1 (e)tik helbidea sortzean</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../../model/account/AccountModel.cpp" line="418"/>
|
||||
<source>set_conference_factory_address_failed_error_message</source>
|
||||
<extracomment>"Unable to set the conversation server address, failed creating address from %1"</extracomment>
|
||||
<translation type="unfinished"></translation>
|
||||
<translation>Ezin da elkarrizketa-zerbitzariaren helbidea ezarri, huts egin du %1 (e)tik helbidea sortzean</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../../model/account/AccountModel.cpp" line="440"/>
|
||||
<source>set_audio_conference_factory_address_failed_error_message</source>
|
||||
<extracomment>"Unable to set the meeting server address, failed creating address from %1"</extracomment>
|
||||
<translation type="unfinished"></translation>
|
||||
<translation>Ezin da bilera-zerbitzariaren helbidea ezarri, huts egin du %1 (e)tik helbidea sortzean</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../../model/account/AccountModel.cpp" line="487"/>
|
||||
<source>set_voicemail_address_failed_error_message</source>
|
||||
<extracomment>Unable to set voicemail address, failed creating address from %1</extracomment>
|
||||
<translation type="unfinished"></translation>
|
||||
<translation>Ezin da ahots-postontziaren helbidea ezarri, huts egin du %1 (e)tik helbidea sortzean</translation>
|
||||
</message>
|
||||
</context>
|
||||
<context>
|
||||
|
|
@ -302,7 +302,7 @@
|
|||
<location filename="../../view/Page/Layout/Settings/AccountSettingsGeneralLayout.qml" line="345"/>
|
||||
<source>device_last_updated_time_no_info</source>
|
||||
<extracomment>"No information"</extracomment>
|
||||
<translation type="unfinished"></translation>
|
||||
<translation>Ez dago informaziorik</translation>
|
||||
</message>
|
||||
</context>
|
||||
<context>
|
||||
|
|
@ -415,7 +415,7 @@
|
|||
<message>
|
||||
<location filename="../../view/Page/Layout/Settings/AccountSettingsParametersLayout.qml" line="127"/>
|
||||
<source>account_settings_registrar_uri_title</source>
|
||||
<translation type="unfinished"></translation>
|
||||
<translation>Erregistratu URIa</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../../view/Page/Layout/Settings/AccountSettingsParametersLayout.qml" line="140"/>
|
||||
|
|
@ -426,7 +426,7 @@
|
|||
<location filename="../../view/Page/Layout/Settings/AccountSettingsParametersLayout.qml" line="145"/>
|
||||
<source>login_proxy_server_url_tooltip</source>
|
||||
<extracomment>"If this field is filled, the outbound proxy will be enabled automatically. Leave it empty to disable it."</extracomment>
|
||||
<translation type="unfinished"></translation>
|
||||
<translation>Eremu hau betetzen bada, irteerako proxya automatikoki aktibatuko da. Utzi hutsik desaktibatzeko.</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../../view/Page/Layout/Settings/AccountSettingsParametersLayout.qml" line="157"/>
|
||||
|
|
@ -490,16 +490,16 @@
|
|||
<source>add_participant_selected_count</source>
|
||||
<comment>0</comment>
|
||||
<extracomment>"%n participant(s) sélectionné(s)"</extracomment>
|
||||
<translation type="unfinished">
|
||||
<numerusform></numerusform>
|
||||
<numerusform></numerusform>
|
||||
<translation>
|
||||
<numerusform>Partaide %1 aukeratuta</numerusform>
|
||||
<numerusform>%1 partaide aukeratuta</numerusform>
|
||||
</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../../view/Page/Form/Meeting/AddParticipantsForm.qml" line="95"/>
|
||||
<source>remove_participant_accessible_name</source>
|
||||
<extracomment>Remove participant %1</extracomment>
|
||||
<translation type="unfinished"></translation>
|
||||
<translation>Ezabatu %1 partaidea</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../../view/Page/Form/Meeting/AddParticipantsForm.qml" line="151"/>
|
||||
|
|
@ -578,7 +578,7 @@
|
|||
<location filename="../../view/Page/Layout/Settings/AdvancedSettingsLayout.qml" line="103"/>
|
||||
<source>download_apply_remote_provisioning_accessible_name</source>
|
||||
<extracomment>"Download and apply remote provisioning"</extracomment>
|
||||
<translation type="unfinished"></translation>
|
||||
<translation>Deskargatu eta aplikatu urruneko hornikuntza</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../../view/Page/Layout/Settings/AdvancedSettingsLayout.qml" line="116"/>
|
||||
|
|
@ -724,7 +724,7 @@
|
|||
<message>
|
||||
<location filename="../../core/App.cpp" line="1448"/>
|
||||
<source>mark_all_read_action</source>
|
||||
<translation type="unfinished"></translation>
|
||||
<translation>Markatu denak irakurrita bezala</translation>
|
||||
</message>
|
||||
</context>
|
||||
<context>
|
||||
|
|
@ -849,7 +849,7 @@
|
|||
<location filename="../../view/Page/Layout/Settings/CallForwardSettingsLayout.qml" line="73"/>
|
||||
<source>settings_call_forward_activate_title</source>
|
||||
<extracomment>"Forward calls"</extracomment>
|
||||
<translation type="unfinished"></translation>
|
||||
<translation>Deiak desbideratzea</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../../view/Page/Layout/Settings/CallForwardSettingsLayout.qml" line="75"/>
|
||||
|
|
@ -2187,6 +2187,11 @@
|
|||
<extracomment>Could not open file : unknown path %1</extracomment>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../../core/chat/message/content/ChatMessageContentCore.cpp" line="108"/>
|
||||
<source>info_popup_error_titile</source>
|
||||
<translation>Errorea</translation>
|
||||
</message>
|
||||
</context>
|
||||
<context>
|
||||
<name>ChatMessageContentList</name>
|
||||
|
|
@ -2241,18 +2246,6 @@ Error</extracomment>
|
|||
</context>
|
||||
<context>
|
||||
<name>ChatMessageContentModel</name>
|
||||
<message>
|
||||
<location filename="../../model/chat/message/content/ChatMessageContentModel.cpp" line="105"/>
|
||||
<source>popup_error_title</source>
|
||||
<extracomment>Error</extracomment>
|
||||
<translation>Errorea</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../../model/chat/message/content/ChatMessageContentModel.cpp" line="108"/>
|
||||
<source>popup_download_error_message</source>
|
||||
<extracomment>This file was already downloaded and is no more on the server. Your peer have to resend it if you want to get it</extracomment>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
</context>
|
||||
<context>
|
||||
<name>ChatMessageCore</name>
|
||||
|
|
@ -2606,7 +2599,7 @@ Error</extracomment>
|
|||
<message>
|
||||
<location filename="../../view/Page/Form/Contact/ContactEdition.qml" line="62"/>
|
||||
<source>close_accessible_name</source>
|
||||
<extracomment>Close %n</extracomment>
|
||||
<extracomment>Close %1</extracomment>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
|
|
@ -7433,4 +7426,12 @@ Failed to create 1-1 conversation with %1 !</extracomment>
|
|||
<translation>Ok</translation>
|
||||
</message>
|
||||
</context>
|
||||
<context>
|
||||
<name>CoreModel</name>
|
||||
<message>
|
||||
<location filename="../../model/core/CoreModel.cpp" line="220"/>
|
||||
<source>info_popup_error_title</source>
|
||||
<translation>Errorea</translation>
|
||||
</message>
|
||||
</context>
|
||||
</TS>
|
||||
|
|
|
|||
7434
Linphone/data/languages/fi.ts
Normal file
7434
Linphone/data/languages/fi.ts
Normal file
File diff suppressed because it is too large
Load diff
File diff suppressed because it is too large
Load diff
|
|
@ -2241,18 +2241,6 @@ Error</extracomment>
|
|||
</context>
|
||||
<context>
|
||||
<name>ChatMessageContentModel</name>
|
||||
<message>
|
||||
<location filename="../../model/chat/message/content/ChatMessageContentModel.cpp" line="105"/>
|
||||
<source>popup_error_title</source>
|
||||
<extracomment>Error</extracomment>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../../model/chat/message/content/ChatMessageContentModel.cpp" line="108"/>
|
||||
<source>popup_download_error_message</source>
|
||||
<extracomment>This file was already downloaded and is no more on the server. Your peer have to resend it if you want to get it</extracomment>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
</context>
|
||||
<context>
|
||||
<name>ChatMessageCore</name>
|
||||
|
|
@ -2606,7 +2594,7 @@ Error</extracomment>
|
|||
<message>
|
||||
<location filename="../../view/Page/Form/Contact/ContactEdition.qml" line="62"/>
|
||||
<source>close_accessible_name</source>
|
||||
<extracomment>Close %n</extracomment>
|
||||
<extracomment>Close %1</extracomment>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
|
|
|
|||
|
|
@ -2241,18 +2241,6 @@ Error</extracomment>
|
|||
</context>
|
||||
<context>
|
||||
<name>ChatMessageContentModel</name>
|
||||
<message>
|
||||
<location filename="../../model/chat/message/content/ChatMessageContentModel.cpp" line="105"/>
|
||||
<source>popup_error_title</source>
|
||||
<extracomment>Error</extracomment>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../../model/chat/message/content/ChatMessageContentModel.cpp" line="108"/>
|
||||
<source>popup_download_error_message</source>
|
||||
<extracomment>This file was already downloaded and is no more on the server. Your peer have to resend it if you want to get it</extracomment>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
</context>
|
||||
<context>
|
||||
<name>ChatMessageCore</name>
|
||||
|
|
@ -2606,7 +2594,7 @@ Error</extracomment>
|
|||
<message>
|
||||
<location filename="../../view/Page/Form/Contact/ContactEdition.qml" line="62"/>
|
||||
<source>close_accessible_name</source>
|
||||
<extracomment>Close %n</extracomment>
|
||||
<extracomment>Close %1</extracomment>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
|
|
|
|||
|
|
@ -2241,18 +2241,6 @@ Error</extracomment>
|
|||
</context>
|
||||
<context>
|
||||
<name>ChatMessageContentModel</name>
|
||||
<message>
|
||||
<location filename="../../model/chat/message/content/ChatMessageContentModel.cpp" line="105"/>
|
||||
<source>popup_error_title</source>
|
||||
<extracomment>Error</extracomment>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../../model/chat/message/content/ChatMessageContentModel.cpp" line="108"/>
|
||||
<source>popup_download_error_message</source>
|
||||
<extracomment>This file was already downloaded and is no more on the server. Your peer have to resend it if you want to get it</extracomment>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
</context>
|
||||
<context>
|
||||
<name>ChatMessageCore</name>
|
||||
|
|
@ -2606,7 +2594,7 @@ Error</extracomment>
|
|||
<message>
|
||||
<location filename="../../view/Page/Form/Contact/ContactEdition.qml" line="62"/>
|
||||
<source>close_accessible_name</source>
|
||||
<extracomment>Close %n</extracomment>
|
||||
<extracomment>Close %1</extracomment>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
|
|
|
|||
|
|
@ -1121,7 +1121,7 @@
|
|||
<location filename="../../model/call/CallModel.cpp" line="376"/>
|
||||
<source>call_error_io_error_toast</source>
|
||||
<extracomment>"Unavailable service or network error"</extracomment>
|
||||
<translation type="unfinished"></translation>
|
||||
<translation>Serviço indisponível ou erro de rede</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../../model/call/CallModel.cpp" line="380"/>
|
||||
|
|
@ -1668,7 +1668,7 @@
|
|||
<location filename="../../view/Page/Window/Call/CallsWindow.qml" line="1114"/>
|
||||
<source>conference_participants_list_title</source>
|
||||
<extracomment>"Participants (%1)"</extracomment>
|
||||
<translation type="unfinished"></translation>
|
||||
<translation>Participantes (%1)</translation>
|
||||
</message>
|
||||
<message numerus="yes">
|
||||
<location filename="../../view/Page/Window/Call/CallsWindow.qml" line="1135"/>
|
||||
|
|
@ -2187,6 +2187,11 @@
|
|||
<extracomment>Could not open file : unknown path %1</extracomment>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../../core/chat/message/content/ChatMessageContentCore.cpp" line="108"/>
|
||||
<source>info_popup_error_titile</source>
|
||||
<translation>Erro</translation>
|
||||
</message>
|
||||
</context>
|
||||
<context>
|
||||
<name>ChatMessageContentList</name>
|
||||
|
|
@ -2241,18 +2246,6 @@ Error</extracomment>
|
|||
</context>
|
||||
<context>
|
||||
<name>ChatMessageContentModel</name>
|
||||
<message>
|
||||
<location filename="../../model/chat/message/content/ChatMessageContentModel.cpp" line="105"/>
|
||||
<source>popup_error_title</source>
|
||||
<extracomment>Error</extracomment>
|
||||
<translation>Erro</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../../model/chat/message/content/ChatMessageContentModel.cpp" line="108"/>
|
||||
<source>popup_download_error_message</source>
|
||||
<extracomment>This file was already downloaded and is no more on the server. Your peer have to resend it if you want to get it</extracomment>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
</context>
|
||||
<context>
|
||||
<name>ChatMessageCore</name>
|
||||
|
|
@ -2606,7 +2599,7 @@ Error</extracomment>
|
|||
<message>
|
||||
<location filename="../../view/Page/Form/Contact/ContactEdition.qml" line="62"/>
|
||||
<source>close_accessible_name</source>
|
||||
<extracomment>Close %n</extracomment>
|
||||
<extracomment>Close %1</extracomment>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
|
|
@ -3229,7 +3222,7 @@ Error</extracomment>
|
|||
<message>
|
||||
<location filename="../../view/Page/Layout/Chat/ConversationInfos.qml" line="270"/>
|
||||
<source>group_infos_participants</source>
|
||||
<translation type="unfinished"></translation>
|
||||
<translation>Participantes (%1)</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../../view/Page/Layout/Chat/ConversationInfos.qml" line="287"/>
|
||||
|
|
@ -7429,4 +7422,12 @@ Failed to create 1-1 conversation with %1 !</extracomment>
|
|||
<translation>Ok</translation>
|
||||
</message>
|
||||
</context>
|
||||
<context>
|
||||
<name>CoreModel</name>
|
||||
<message>
|
||||
<location filename="../../model/core/CoreModel.cpp" line="220"/>
|
||||
<source>info_popup_error_title</source>
|
||||
<translation>Erro</translation>
|
||||
</message>
|
||||
</context>
|
||||
</TS>
|
||||
|
|
|
|||
File diff suppressed because it is too large
Load diff
|
|
@ -2189,6 +2189,11 @@
|
|||
<extracomment>Could not open file : unknown path %1</extracomment>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../../core/chat/message/content/ChatMessageContentCore.cpp" line="108"/>
|
||||
<source>info_popup_error_titile</source>
|
||||
<translation>Ошибка</translation>
|
||||
</message>
|
||||
</context>
|
||||
<context>
|
||||
<name>ChatMessageContentList</name>
|
||||
|
|
@ -2244,18 +2249,6 @@ Error</extracomment>
|
|||
</context>
|
||||
<context>
|
||||
<name>ChatMessageContentModel</name>
|
||||
<message>
|
||||
<location filename="../../model/chat/message/content/ChatMessageContentModel.cpp" line="105"/>
|
||||
<source>popup_error_title</source>
|
||||
<extracomment>Error</extracomment>
|
||||
<translation>Ошибка</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../../model/chat/message/content/ChatMessageContentModel.cpp" line="108"/>
|
||||
<source>popup_download_error_message</source>
|
||||
<extracomment>This file was already downloaded and is no more on the server. Your peer have to resend it if you want to get it</extracomment>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
</context>
|
||||
<context>
|
||||
<name>ChatMessageCore</name>
|
||||
|
|
@ -2610,7 +2603,7 @@ Error</extracomment>
|
|||
<message>
|
||||
<location filename="../../view/Page/Form/Contact/ContactEdition.qml" line="62"/>
|
||||
<source>close_accessible_name</source>
|
||||
<extracomment>Close %n</extracomment>
|
||||
<extracomment>Close %1</extracomment>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
|
|
@ -7455,4 +7448,12 @@ Failed to create 1-1 conversation with %1 !</extracomment>
|
|||
<translation>Ок</translation>
|
||||
</message>
|
||||
</context>
|
||||
<context>
|
||||
<name>CoreModel</name>
|
||||
<message>
|
||||
<location filename="../../model/core/CoreModel.cpp" line="220"/>
|
||||
<source>info_popup_error_title</source>
|
||||
<translation>Ошибка</translation>
|
||||
</message>
|
||||
</context>
|
||||
</TS>
|
||||
|
|
|
|||
|
|
@ -2244,18 +2244,6 @@ Error</extracomment>
|
|||
</context>
|
||||
<context>
|
||||
<name>ChatMessageContentModel</name>
|
||||
<message>
|
||||
<location filename="../../model/chat/message/content/ChatMessageContentModel.cpp" line="105"/>
|
||||
<source>popup_error_title</source>
|
||||
<extracomment>Error</extracomment>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../../model/chat/message/content/ChatMessageContentModel.cpp" line="108"/>
|
||||
<source>popup_download_error_message</source>
|
||||
<extracomment>This file was already downloaded and is no more on the server. Your peer have to resend it if you want to get it</extracomment>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
</context>
|
||||
<context>
|
||||
<name>ChatMessageCore</name>
|
||||
|
|
@ -2610,7 +2598,7 @@ Error</extracomment>
|
|||
<message>
|
||||
<location filename="../../view/Page/Form/Contact/ContactEdition.qml" line="62"/>
|
||||
<source>close_accessible_name</source>
|
||||
<extracomment>Close %n</extracomment>
|
||||
<extracomment>Close %1</extracomment>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
|
|
|
|||
|
|
@ -2189,6 +2189,11 @@
|
|||
<extracomment>Could not open file : unknown path %1</extracomment>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../../core/chat/message/content/ChatMessageContentCore.cpp" line="108"/>
|
||||
<source>info_popup_error_titile</source>
|
||||
<translation>Помилка</translation>
|
||||
</message>
|
||||
</context>
|
||||
<context>
|
||||
<name>ChatMessageContentList</name>
|
||||
|
|
@ -2244,18 +2249,6 @@ Error</extracomment>
|
|||
</context>
|
||||
<context>
|
||||
<name>ChatMessageContentModel</name>
|
||||
<message>
|
||||
<location filename="../../model/chat/message/content/ChatMessageContentModel.cpp" line="105"/>
|
||||
<source>popup_error_title</source>
|
||||
<extracomment>Error</extracomment>
|
||||
<translation>Помилка</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../../model/chat/message/content/ChatMessageContentModel.cpp" line="108"/>
|
||||
<source>popup_download_error_message</source>
|
||||
<extracomment>This file was already downloaded and is no more on the server. Your peer have to resend it if you want to get it</extracomment>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
</context>
|
||||
<context>
|
||||
<name>ChatMessageCore</name>
|
||||
|
|
@ -2610,7 +2603,7 @@ Error</extracomment>
|
|||
<message>
|
||||
<location filename="../../view/Page/Form/Contact/ContactEdition.qml" line="62"/>
|
||||
<source>close_accessible_name</source>
|
||||
<extracomment>Close %n</extracomment>
|
||||
<extracomment>Close %1</extracomment>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
|
|
@ -7455,4 +7448,12 @@ Failed to create 1-1 conversation with %1 !</extracomment>
|
|||
<translation>Ок</translation>
|
||||
</message>
|
||||
</context>
|
||||
<context>
|
||||
<name>CoreModel</name>
|
||||
<message>
|
||||
<location filename="../../model/core/CoreModel.cpp" line="220"/>
|
||||
<source>info_popup_error_title</source>
|
||||
<translation>Помилка</translation>
|
||||
</message>
|
||||
</context>
|
||||
</TS>
|
||||
|
|
|
|||
|
|
@ -7,7 +7,7 @@
|
|||
<location filename="../../view/Page/Layout/Settings/AbstractSettingsLayout.qml" line="67"/>
|
||||
<source>return_accessible_name</source>
|
||||
<extracomment>Return</extracomment>
|
||||
<translation type="unfinished"></translation>
|
||||
<translation>返回</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../../view/Page/Layout/Settings/AbstractSettingsLayout.qml" line="86"/>
|
||||
|
|
@ -19,7 +19,7 @@
|
|||
<location filename="../../view/Page/Layout/Settings/AbstractSettingsLayout.qml" line="90"/>
|
||||
<source>save_settings_accessible_name</source>
|
||||
<extracomment>Save %1 settings</extracomment>
|
||||
<translation type="unfinished"></translation>
|
||||
<translation>保存%1设置</translation>
|
||||
</message>
|
||||
</context>
|
||||
<context>
|
||||
|
|
@ -152,37 +152,37 @@
|
|||
<location filename="../../model/account/AccountModel.cpp" line="253"/>
|
||||
<source>set_mwi_server_address_failed_error_message</source>
|
||||
<extracomment>"Unable to set voicemail server address, failed creating address from %1" : %1 is address</extracomment>
|
||||
<translation type="unfinished"></translation>
|
||||
<translation>无法设置语音信箱服务器地址,未能从%1创建地址</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../../model/account/AccountModel.cpp" line="292"/>
|
||||
<source>set_server_address_failed_error_message</source>
|
||||
<extracomment>"Unable to set server address, failed creating address from %1"</extracomment>
|
||||
<translation type="unfinished"></translation>
|
||||
<translation>无法设置服务器地址,未能从%1创建地址</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../../model/account/AccountModel.cpp" line="309"/>
|
||||
<source>set_outbound_proxy_uri_failed_error_message</source>
|
||||
<extracomment>Unable to set outbound proxy uri, failed creating address from %1</extracomment>
|
||||
<translation type="unfinished"></translation>
|
||||
<translation>无法设置出站代理 URI,无法从 %1 创建地址</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../../model/account/AccountModel.cpp" line="418"/>
|
||||
<source>set_conference_factory_address_failed_error_message</source>
|
||||
<extracomment>"Unable to set the conversation server address, failed creating address from %1"</extracomment>
|
||||
<translation type="unfinished"></translation>
|
||||
<translation>无法设置会话服务器地址,未能从%1创建地址</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../../model/account/AccountModel.cpp" line="440"/>
|
||||
<source>set_audio_conference_factory_address_failed_error_message</source>
|
||||
<extracomment>"Unable to set the meeting server address, failed creating address from %1"</extracomment>
|
||||
<translation type="unfinished"></translation>
|
||||
<translation>无法设置会议服务器地址,未能从%1创建地址</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../../model/account/AccountModel.cpp" line="487"/>
|
||||
<source>set_voicemail_address_failed_error_message</source>
|
||||
<extracomment>Unable to set voicemail address, failed creating address from %1</extracomment>
|
||||
<translation type="unfinished"></translation>
|
||||
<translation>无法设置语音信箱地址,无法从%1创建地址</translation>
|
||||
</message>
|
||||
</context>
|
||||
<context>
|
||||
|
|
@ -302,7 +302,7 @@
|
|||
<location filename="../../view/Page/Layout/Settings/AccountSettingsGeneralLayout.qml" line="345"/>
|
||||
<source>device_last_updated_time_no_info</source>
|
||||
<extracomment>"No information"</extracomment>
|
||||
<translation type="unfinished"></translation>
|
||||
<translation>无信息</translation>
|
||||
</message>
|
||||
</context>
|
||||
<context>
|
||||
|
|
@ -645,13 +645,13 @@
|
|||
<location filename="../../core/App.cpp" line="660"/>
|
||||
<source>info_popup_configuration_failed_message</source>
|
||||
<extracomment>Remote provisioning failed : %1</extracomment>
|
||||
<translation type="unfinished"></translation>
|
||||
<translation>远程配置失败:%1</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../../core/App.cpp" line="654"/>
|
||||
<source>configuration_error_detail</source>
|
||||
<extracomment>not reachable</extracomment>
|
||||
<translation type="unfinished"></translation>
|
||||
<translation>无法接通</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../../core/App.cpp" line="926"/>
|
||||
|
|
@ -725,6 +725,11 @@
|
|||
<source>mark_all_read_action</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../../core/App.cpp" line="452"/>
|
||||
<source>info_popup_new_version_download_label</source>
|
||||
<translation> </translation>
|
||||
</message>
|
||||
</context>
|
||||
<context>
|
||||
<name>AuthenticationDialog</name>
|
||||
|
|
@ -2185,6 +2190,11 @@
|
|||
<extracomment>Could not open file : unknown path %1</extracomment>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../../core/chat/message/content/ChatMessageContentCore.cpp" line="108"/>
|
||||
<source>info_popup_error_titile</source>
|
||||
<translation>错误</translation>
|
||||
</message>
|
||||
</context>
|
||||
<context>
|
||||
<name>ChatMessageContentList</name>
|
||||
|
|
@ -2238,18 +2248,6 @@ Error</extracomment>
|
|||
</context>
|
||||
<context>
|
||||
<name>ChatMessageContentModel</name>
|
||||
<message>
|
||||
<location filename="../../model/chat/message/content/ChatMessageContentModel.cpp" line="105"/>
|
||||
<source>popup_error_title</source>
|
||||
<extracomment>Error</extracomment>
|
||||
<translation>错误</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../../model/chat/message/content/ChatMessageContentModel.cpp" line="108"/>
|
||||
<source>popup_download_error_message</source>
|
||||
<extracomment>This file was already downloaded and is no more on the server. Your peer have to resend it if you want to get it</extracomment>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
</context>
|
||||
<context>
|
||||
<name>ChatMessageCore</name>
|
||||
|
|
@ -2602,7 +2600,7 @@ Error</extracomment>
|
|||
<message>
|
||||
<location filename="../../view/Page/Form/Contact/ContactEdition.qml" line="62"/>
|
||||
<source>close_accessible_name</source>
|
||||
<extracomment>Close %n</extracomment>
|
||||
<extracomment>Close %1</extracomment>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
|
|
@ -7411,4 +7409,12 @@ Failed to create 1-1 conversation with %1 !</extracomment>
|
|||
<translation>OK</translation>
|
||||
</message>
|
||||
</context>
|
||||
<context>
|
||||
<name>CoreModel</name>
|
||||
<message>
|
||||
<location filename="../../model/core/CoreModel.cpp" line="220"/>
|
||||
<source>info_popup_error_title</source>
|
||||
<translation>错误</translation>
|
||||
</message>
|
||||
</context>
|
||||
</TS>
|
||||
|
|
|
|||
|
|
@ -19,6 +19,7 @@
|
|||
*/
|
||||
|
||||
#include "AccountManager.hpp"
|
||||
#include "tool/accessibility/AccessibilityHelper.hpp"
|
||||
|
||||
#include <QDebug>
|
||||
#include <QDesktopServices>
|
||||
|
|
@ -66,7 +67,7 @@ bool AccountManager::login(QString username,
|
|||
mustBeInLinphoneThread(log().arg(Q_FUNC_INFO));
|
||||
auto core = CoreModel::getInstance()->getCore();
|
||||
auto factory = linphone::Factory::get();
|
||||
QString assistantFile = (!QString::compare(domain, "sip.linphone.org") || domain.isEmpty())
|
||||
QString assistantFile = (!QString::compare(domain, "sip.linphone.org", Qt::CaseInsensitive) || domain.isEmpty())
|
||||
? "use-app-sip-account.rc"
|
||||
: "use-other-sip-account.rc";
|
||||
auto account = createAccount(assistantFile);
|
||||
|
|
@ -81,8 +82,13 @@ bool AccountManager::login(QString username,
|
|||
auto otherAccounts = core->getAccountList();
|
||||
for (auto otherAccount : otherAccounts) {
|
||||
auto otherParams = otherAccount->getParams();
|
||||
if (otherParams->getIdentityAddress()->getUsername() == Utils::appStringToCoreString(username) &&
|
||||
otherParams->getDomain() == Utils::appStringToCoreString(domain)) {
|
||||
if (domain.isEmpty()) {
|
||||
lDebug() << "domain is empty, setting \"sip.linphone.org\" by default";
|
||||
domain = "sip.linphone.org";
|
||||
}
|
||||
if (!QString::compare(Utils::coreStringToAppString(otherParams->getIdentityAddress()->getUsername()), username,
|
||||
Qt::CaseInsensitive) &&
|
||||
!QString::compare(Utils::coreStringToAppString(otherParams->getDomain()), domain, Qt::CaseInsensitive)) {
|
||||
//: "The account is already connected"
|
||||
*errorMessage = tr("assistant_account_login_already_connected_error");
|
||||
return false;
|
||||
|
|
@ -96,7 +102,7 @@ bool AccountManager::login(QString username,
|
|||
}
|
||||
if (!outboundProxyAddress.isEmpty()) {
|
||||
auto linOutboundProxyAddress = ToolModel::interpretUrl(outboundProxyAddress);
|
||||
params->setRoutesAddresses({linOutboundProxyAddress});
|
||||
if (linOutboundProxyAddress) params->setRoutesAddresses({linOutboundProxyAddress});
|
||||
}
|
||||
if (!domain.isEmpty()) {
|
||||
identity->setDomain(Utils::appStringToCoreString(domain));
|
||||
|
|
@ -153,6 +159,7 @@ bool AccountManager::login(QString username,
|
|||
errorMessage = tr("assistant_account_login_forbidden_error");
|
||||
//: "Error during connection, please verify your parameters"
|
||||
else errorMessage = tr("assistant_account_login_error");
|
||||
AccessibilityHelper::announceMessage(errorMessage);
|
||||
mAccountModel->removeAccount();
|
||||
} else if (state == linphone::RegistrationState::Ok) {
|
||||
core->setDefaultAccount(account);
|
||||
|
|
|
|||
|
|
@ -125,7 +125,7 @@ void AccountModel::setPictureUri(QString uri) {
|
|||
// Hack because Account doesn't provide callbacks on updated data
|
||||
// emit pictureUriChanged(uri);
|
||||
auto core = CoreModel::getInstance()->getCore();
|
||||
emit CoreModel::getInstance()->defaultAccountChanged(core, core->getDefaultAccount());
|
||||
emit CoreModel::getInstance() -> defaultAccountChanged(core, core->getDefaultAccount());
|
||||
}
|
||||
|
||||
void AccountModel::onDefaultAccountChanged() {
|
||||
|
|
@ -148,7 +148,7 @@ void AccountModel::removeAccount() {
|
|||
? Utils::coreStringToAppString(params->getIdentityAddress()->asString())
|
||||
: "Null");
|
||||
mToRemove = true;
|
||||
if (mMonitor) core->removeAccount(mMonitor);
|
||||
if (mMonitor) core->removeAccountWithData(mMonitor);
|
||||
}
|
||||
|
||||
std::shared_ptr<linphone::Account> AccountModel::getAccount() const {
|
||||
|
|
@ -182,7 +182,7 @@ void AccountModel::setDisplayName(QString displayName) {
|
|||
// Hack because Account doesn't provide callbacks on updated data
|
||||
// emit displayNameChanged(displayName);
|
||||
auto core = CoreModel::getInstance()->getCore();
|
||||
emit CoreModel::getInstance()->defaultAccountChanged(core, core->getDefaultAccount());
|
||||
emit CoreModel::getInstance() -> defaultAccountChanged(core, core->getDefaultAccount());
|
||||
}
|
||||
|
||||
void AccountModel::setDialPlan(int index) {
|
||||
|
|
@ -274,7 +274,7 @@ void AccountModel::setTransport(linphone::TransportType value, bool save) {
|
|||
|
||||
QString AccountModel::getRegistrarUri() const {
|
||||
if (mMonitor->getParams()->getServerAddress())
|
||||
return Utils::coreStringToAppString(mMonitor->getParams()->getServerAddress()->asString());
|
||||
return Utils::coreStringToAppString(mMonitor->getParams()->getServerAddress()->asStringUriOnly());
|
||||
else return "";
|
||||
}
|
||||
|
||||
|
|
@ -292,13 +292,12 @@ void AccountModel::setRegistrarUri(QString value) {
|
|||
emit setValueFailed(tr("set_server_address_failed_error_message").arg(value));
|
||||
qWarning() << "Unable to set ServerAddress, failed creating address from" << value;
|
||||
}
|
||||
emit registrarUriChanged(Utils::coreStringToAppString(address->asString()));
|
||||
}
|
||||
|
||||
QString AccountModel::getOutboundProxyUri() const {
|
||||
auto routeAddresses = mMonitor->getParams()->getRoutesAddresses();
|
||||
auto outbound =
|
||||
routeAddresses.empty() ? QString() : Utils::coreStringToAppString(routeAddresses.front()->asString());
|
||||
routeAddresses.empty() ? QString() : Utils::coreStringToAppString(routeAddresses.front()->asStringUriOnly());
|
||||
return outbound;
|
||||
}
|
||||
|
||||
|
|
@ -308,11 +307,11 @@ void AccountModel::setOutboundProxyUri(QString value) {
|
|||
//: Unable to set outbound proxy uri, failed creating address from %1
|
||||
emit setValueFailed(tr("set_outbound_proxy_uri_failed_error_message").arg(value));
|
||||
return;
|
||||
} else {
|
||||
auto params = mMonitor->getParams()->clone();
|
||||
params->setRoutesAddresses({linOutboundProxyAddress});
|
||||
emit outboundProxyUriChanged(value);
|
||||
}
|
||||
auto params = mMonitor->getParams()->clone();
|
||||
params->setRoutesAddresses({linOutboundProxyAddress});
|
||||
|
||||
emit outboundProxyUriChanged(value);
|
||||
}
|
||||
|
||||
bool AccountModel::getOutboundProxyEnabled() const {
|
||||
|
|
@ -400,7 +399,7 @@ void AccountModel::setExpire(int value) {
|
|||
|
||||
QString AccountModel::getConferenceFactoryAddress() const {
|
||||
auto confAddress = mMonitor->getParams()->getConferenceFactoryAddress();
|
||||
return confAddress ? Utils::coreStringToAppString(confAddress->asString()) : QString();
|
||||
return confAddress ? Utils::coreStringToAppString(confAddress->asStringUriOnly()) : QString();
|
||||
}
|
||||
|
||||
void AccountModel::setConferenceFactoryAddress(QString value) {
|
||||
|
|
@ -422,7 +421,7 @@ void AccountModel::setConferenceFactoryAddress(QString value) {
|
|||
|
||||
QString AccountModel::getAudioVideoConferenceFactoryAddress() const {
|
||||
auto confAddress = mMonitor->getParams()->getAudioVideoConferenceFactoryAddress();
|
||||
return confAddress ? Utils::coreStringToAppString(confAddress->asString()) : QString();
|
||||
return confAddress ? Utils::coreStringToAppString(confAddress->asStringUriOnly()) : QString();
|
||||
}
|
||||
|
||||
void AccountModel::setAudioVideoConferenceFactoryAddress(QString value) {
|
||||
|
|
@ -491,7 +490,7 @@ void AccountModel::setVoicemailAddress(QString value) {
|
|||
|
||||
QString AccountModel::getVoicemailAddress() const {
|
||||
auto addr = mMonitor->getParams()->getVoicemailAddress();
|
||||
return addr ? Utils::coreStringToAppString(addr->asString()) : "";
|
||||
return addr ? Utils::coreStringToAppString(addr->asStringUriOnly()) : "";
|
||||
}
|
||||
|
||||
// UserData (see hpp for explanations)
|
||||
|
|
@ -585,7 +584,7 @@ void AccountModel::setPresence(LinphoneEnums::Presence presence,
|
|||
}
|
||||
|
||||
setNotificationsAllowed(
|
||||
presence != LinphoneEnums::Presence::DoNotDisturb &&
|
||||
presence != LinphoneEnums::Presence::Offline && presence != LinphoneEnums::Presence::DoNotDisturb &&
|
||||
(presence != LinphoneEnums::Presence::Away ||
|
||||
core->getConfig()->getBool(accountSection, "allow_notifications_in_presence_away", true)) &&
|
||||
(presence != LinphoneEnums::Presence::Busy ||
|
||||
|
|
@ -606,4 +605,16 @@ bool AccountModel::forwardToVoiceMailInDndPresence() {
|
|||
|
||||
std::list<std::shared_ptr<linphone::ChatRoom>> AccountModel::getChatRooms() {
|
||||
return mMonitor->getChatRooms();
|
||||
}
|
||||
}
|
||||
|
||||
QString AccountModel::getCcmpServerUrl() const {
|
||||
return Utils::coreStringToAppString(mMonitor->getParams()->getCcmpServerUrl());
|
||||
}
|
||||
|
||||
void AccountModel::setCcmpServerUrl(QString value) {
|
||||
mustBeInLinphoneThread(log().arg(Q_FUNC_INFO));
|
||||
auto params = mMonitor->getParams()->clone();
|
||||
params->setCcmpServerUrl(Utils::appStringToCoreString(value));
|
||||
mMonitor->setParams(params);
|
||||
emit ccmpServerUrlChanged(value);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -91,6 +91,8 @@ public:
|
|||
std::string configAccountSection();
|
||||
bool forwardToVoiceMailInDndPresence();
|
||||
std::list<std::shared_ptr<linphone::ChatRoom>> getChatRooms();
|
||||
QString getCcmpServerUrl() const;
|
||||
void setCcmpServerUrl(QString value);
|
||||
|
||||
signals:
|
||||
void registrationStateChanged(const std::shared_ptr<linphone::Account> &account,
|
||||
|
|
@ -126,6 +128,7 @@ signals:
|
|||
void showMwiChanged(bool show);
|
||||
void voicemailAddressChanged(QString value);
|
||||
void presenceChanged(LinphoneEnums::Presence presence, bool userInitiated);
|
||||
void ccmpServerUrlChanged(QString value);
|
||||
|
||||
void setValueFailed(const QString &errorMessage);
|
||||
|
||||
|
|
|
|||
|
|
@ -97,15 +97,16 @@ void CarddavModel::remove() {
|
|||
void CarddavModel::onSyncStatusChanged(const std::shared_ptr<linphone::FriendList> &friendList,
|
||||
linphone::FriendList::SyncStatus status,
|
||||
const std::string &message) {
|
||||
lInfo() << log().arg("carddav sync status changed :") << message;
|
||||
if (status == linphone::FriendList::SyncStatus::Successful) {
|
||||
lInfo() << log().arg("Successfully synchronized:") << mCarddavFriendList->getUri();
|
||||
setMonitor(nullptr);
|
||||
SettingsModel::setCardDAVListForNewFriends(mStoreNewFriendsInIt ? friendList->getDisplayName() : "");
|
||||
emit saved(true);
|
||||
emit saved(true, Utils::coreStringToAppString(message));
|
||||
}
|
||||
if (status == linphone::FriendList::SyncStatus::Failure) {
|
||||
lWarning() << log().arg("Synchronization failure:") << mCarddavFriendList->getUri();
|
||||
setMonitor(nullptr);
|
||||
emit saved(false);
|
||||
emit saved(false, Utils::coreStringToAppString(message));
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -36,12 +36,17 @@ public:
|
|||
CarddavModel(const std::shared_ptr<linphone::FriendList> &carddavFriendList, QObject *parent = nullptr);
|
||||
~CarddavModel();
|
||||
|
||||
void save(std::string displayName, std::string uri, std::string username, std::string password, std::string realm, bool storeNewFriendsInIt);
|
||||
void save(std::string displayName,
|
||||
std::string uri,
|
||||
std::string username,
|
||||
std::string password,
|
||||
std::string realm,
|
||||
bool storeNewFriendsInIt);
|
||||
void remove();
|
||||
bool storeNewFriendsInIt();
|
||||
|
||||
signals:
|
||||
void saved(bool success);
|
||||
void saved(bool success, QString message);
|
||||
void removed();
|
||||
|
||||
private:
|
||||
|
|
|
|||
|
|
@ -28,17 +28,16 @@ LdapModel::LdapModel(const std::shared_ptr<linphone::RemoteContactDirectory> &ld
|
|||
mustBeInLinphoneThread(getClassName());
|
||||
if (ldap) {
|
||||
mLdap = ldap;
|
||||
mLdapParamsClone = mLdap->getLdapParams();
|
||||
mLdapParamsClone = mLdap->getLdapRemoteContactDirectory();
|
||||
} else {
|
||||
mLdapParamsClone = CoreModel::getInstance()->getCore()->createLdapParams();
|
||||
mLdapParamsClone->setDelay(2000);
|
||||
mLdapParamsClone->enableTls(true);
|
||||
mLdapParamsClone->setEnabled(true);
|
||||
|
||||
mLdap = CoreModel::getInstance()->getCore()->createLdapRemoteContactDirectory(mLdapParamsClone);
|
||||
mLdap->setDelay(2000);
|
||||
mLdap->setTimeout(5);
|
||||
mLdap->setLimit(50);
|
||||
mLdap->setMinCharacters(0); // Needs to be 0 if Contacts list should be synchronized with LDAP AB
|
||||
mLdap->enable(true);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -65,7 +64,7 @@ void LdapModel::save() {
|
|||
mLdap->setMinCharacters(oldMinChars);
|
||||
core->addRemoteContactDirectory(mLdap);
|
||||
lDebug() << log().arg("LDAP Server saved");
|
||||
mLdapParamsClone = mLdap->getLdapParams();
|
||||
mLdapParamsClone = mLdap->getLdapRemoteContactDirectory();
|
||||
// Clean cache to take account new searches
|
||||
auto ldapFriendList = core->getFriendListByName("ldap_friends");
|
||||
if (ldapFriendList) core->removeFriendList(ldapFriendList);
|
||||
|
|
@ -92,7 +91,7 @@ void LdapModel::setDebug(const bool &data) {
|
|||
}
|
||||
}
|
||||
|
||||
DEFINE_GETSET(LdapModel, bool, enabled, Enabled, mLdapParamsClone)
|
||||
DEFINE_GETSET_ENABLE(LdapModel, enabled, Enabled, mLdap)
|
||||
DEFINE_GETSET_MODEL_STRING(LdapModel, serverUrl, ServerUrl, mLdap)
|
||||
DEFINE_GETSET_MODEL_STRING(LdapModel, bindDn, BindDn, mLdapParamsClone)
|
||||
DEFINE_GETSET_MODEL_STRING(LdapModel, password, Password, mLdapParamsClone)
|
||||
|
|
@ -107,7 +106,7 @@ DEFINE_GETSET_MODEL_STRING(LdapModel, baseObject, BaseObject, mLdapParamsClone)
|
|||
DEFINE_GETSET_MODEL_STRING(LdapModel, filter, Filter, mLdapParamsClone)
|
||||
DEFINE_GETSET(LdapModel, int, limit, Limit, mLdap)
|
||||
DEFINE_GETSET(LdapModel, int, timeout, Timeout, mLdap)
|
||||
DEFINE_GETSET(LdapModel, int, delay, Delay, mLdapParamsClone)
|
||||
DEFINE_GETSET(LdapModel, int, delay, Delay, mLdap)
|
||||
DEFINE_GETSET(LdapModel, int, minCharacters, MinCharacters, mLdap)
|
||||
DEFINE_GETSET_MODEL_STRING(LdapModel, nameAttribute, NameAttribute, mLdapParamsClone)
|
||||
DEFINE_GETSET_MODEL_STRING(LdapModel, sipAttribute, SipAttribute, mLdapParamsClone)
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright (c) 2010-2024 Belledonne Communications SARL.
|
||||
* Copyright (c) 2010-2026 Belledonne Communications SARL.
|
||||
*
|
||||
* This file is part of linphone-desktop
|
||||
* (see https://www.linphone.org).
|
||||
|
|
@ -69,6 +69,7 @@ void CallModel::accept(bool withVideo) {
|
|||
activateLocalVideo(params, withVideo);
|
||||
mMonitor->acceptWithParams(params);
|
||||
emit localVideoEnabledChanged(withVideo);
|
||||
emit cameraEnabledChanged(params->cameraEnabled());
|
||||
}
|
||||
|
||||
void CallModel::decline() {
|
||||
|
|
@ -104,7 +105,9 @@ void CallModel::transferTo(const std::shared_ptr<linphone::Address> &address) {
|
|||
|
||||
void CallModel::transferToAnother(const std::shared_ptr<linphone::Call> &call) {
|
||||
mustBeInLinphoneThread(log().arg(Q_FUNC_INFO));
|
||||
if (mMonitor->transferToAnother(call) == -1)
|
||||
if (!call) return;
|
||||
// Transfer paused call to current call
|
||||
if (call->transferToAnother(mMonitor) == -1)
|
||||
lWarning() << log()
|
||||
.arg(QStringLiteral("Unable to transfer: `%1`."))
|
||||
.arg(Utils::coreStringToAppString(call->getRemoteAddress()->asStringUriOnly()));
|
||||
|
|
@ -128,13 +131,25 @@ void CallModel::setSpeakerMuted(bool isMuted) {
|
|||
emit speakerMutedChanged(isMuted);
|
||||
}
|
||||
|
||||
void CallModel::enableVideo(bool enable) {
|
||||
mustBeInLinphoneThread(log().arg(Q_FUNC_INFO));
|
||||
auto params = CoreModel::getInstance()->getCore()->createCallParams(mMonitor);
|
||||
params->enableVideo(enable);
|
||||
mMonitor->update(params);
|
||||
}
|
||||
|
||||
bool CallModel::videoEnabled() const {
|
||||
return mMonitor->getParams()->videoEnabled();
|
||||
}
|
||||
|
||||
void CallModel::activateLocalVideo(std::shared_ptr<linphone::CallParams> ¶ms, bool enable) {
|
||||
lInfo() << sLog()
|
||||
.arg("Updating call with video enabled and media direction set to %1")
|
||||
.arg((int)params->getVideoDirection());
|
||||
params->enableVideo(SettingsModel::getInstance()->getVideoEnabled());
|
||||
auto videoDirection = enable ? linphone::MediaDirection::SendRecv : linphone::MediaDirection::RecvOnly;
|
||||
params->setVideoDirection(videoDirection);
|
||||
auto videoDirection = params->getVideoDirection();
|
||||
params->setVideoDirection(enable || params->screenSharingEnabled() ? linphone::MediaDirection::SendRecv
|
||||
: linphone::MediaDirection::RecvOnly);
|
||||
}
|
||||
|
||||
void CallModel::setLocalVideoEnabled(bool enabled) {
|
||||
|
|
@ -144,6 +159,15 @@ void CallModel::setLocalVideoEnabled(bool enabled) {
|
|||
mMonitor->update(params);
|
||||
}
|
||||
|
||||
void CallModel::setCameraEnabled(bool enabled) {
|
||||
mustBeInLinphoneThread(log().arg(Q_FUNC_INFO));
|
||||
auto params = CoreModel::getInstance()->getCore()->createCallParams(mMonitor);
|
||||
activateLocalVideo(params, enabled);
|
||||
lInfo() << log().arg("Enable camera :") << enabled;
|
||||
params->enableCamera(enabled);
|
||||
mMonitor->update(params);
|
||||
}
|
||||
|
||||
void CallModel::startRecording() {
|
||||
mustBeInLinphoneThread(log().arg(Q_FUNC_INFO));
|
||||
mMonitor->startRecording();
|
||||
|
|
@ -431,8 +455,11 @@ void CallModel::onStateChanged(const std::shared_ptr<linphone::Call> &call,
|
|||
setConference(call->getConference());
|
||||
mDurationTimer.start();
|
||||
// After UpdatedByRemote, video direction could be changed.
|
||||
auto videoDirection = call->getParams()->getVideoDirection();
|
||||
auto params = call->getParams();
|
||||
auto videoDirection = params->getVideoDirection();
|
||||
auto remoteVideoDirection = call->getRemoteParams()->getVideoDirection();
|
||||
lInfo() << log().arg("Camera enabled changed") << params->cameraEnabled();
|
||||
emit cameraEnabledChanged(params->cameraEnabled());
|
||||
emit localVideoEnabledChanged(videoDirection == linphone::MediaDirection::SendOnly ||
|
||||
videoDirection == linphone::MediaDirection::SendRecv);
|
||||
emit remoteVideoEnabledChanged(remoteVideoDirection == linphone::MediaDirection::SendOnly ||
|
||||
|
|
@ -491,6 +518,7 @@ void CallModel::onVideoDisplayErrorOccurred(const std::shared_ptr<linphone::Call
|
|||
|
||||
void CallModel::onAudioDeviceChanged(const std::shared_ptr<linphone::Call> &call,
|
||||
const std::shared_ptr<linphone::AudioDevice> &audioDevice) {
|
||||
lInfo() << log().arg("audio device changed");
|
||||
emit audioDeviceChanged(call, audioDevice);
|
||||
}
|
||||
|
||||
|
|
@ -501,3 +529,27 @@ void CallModel::onRemoteRecording(const std::shared_ptr<linphone::Call> &call, b
|
|||
void CallModel::onAuthenticationTokenVerified(const std::shared_ptr<linphone::Call> &call, bool verified) {
|
||||
emit authenticationTokenVerified(call, verified);
|
||||
}
|
||||
|
||||
void CallModel::onHeadsetAnswerCallRequested(const std::shared_ptr<linphone::Call> &call) {
|
||||
emit headsetAnswerCallRequested();
|
||||
}
|
||||
|
||||
void CallModel::onHeadsetEndCallRequested(const std::shared_ptr<linphone::Call> &call) {
|
||||
emit headsetEndCallRequested();
|
||||
}
|
||||
|
||||
void CallModel::onHeadsetHoldCallRequested(const std::shared_ptr<linphone::Call> &call) {
|
||||
emit headsetHoldCallRequested();
|
||||
}
|
||||
|
||||
void CallModel::onHeadsetMicrophoneMuteToggled(const std::shared_ptr<linphone::Call> &call, bool mute) {
|
||||
emit headsetMicrophoneMuteToggled(mute);
|
||||
}
|
||||
|
||||
void CallModel::onHeadsetRejectCallRequested(const std::shared_ptr<linphone::Call> &call) {
|
||||
emit headsetRejectCallRequested();
|
||||
}
|
||||
|
||||
void CallModel::onHeadsetResumeCallRequested(const std::shared_ptr<linphone::Call> &call) {
|
||||
emit headsetResumeCallRequested();
|
||||
}
|
||||
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright (c) 2010-2024 Belledonne Communications SARL.
|
||||
* Copyright (c) 2010-2026 Belledonne Communications SARL.
|
||||
*
|
||||
* This file is part of linphone-desktop
|
||||
* (see https://www.linphone.org).
|
||||
|
|
@ -45,6 +45,7 @@ public:
|
|||
void setMicrophoneMuted(bool isMuted);
|
||||
void setSpeakerMuted(bool isMuted);
|
||||
void setLocalVideoEnabled(bool enabled);
|
||||
void setCameraEnabled(bool enabled);
|
||||
void startRecording();
|
||||
void stopRecording();
|
||||
void setRecordFile(const std::string &path);
|
||||
|
|
@ -82,7 +83,8 @@ public:
|
|||
LinphoneEnums::VideoSourceScreenSharingType getVideoSourceType() const;
|
||||
int getScreenSharingIndex() const;
|
||||
void setVideoSourceDescriptorModel(std::shared_ptr<VideoSourceDescriptorModel> model = nullptr);
|
||||
|
||||
void enableVideo(bool enable);
|
||||
bool videoEnabled() const;
|
||||
static void activateLocalVideo(std::shared_ptr<linphone::CallParams> ¶ms, bool enable);
|
||||
|
||||
void sendDtmf(const QString &dtmf);
|
||||
|
|
@ -97,6 +99,7 @@ signals:
|
|||
void microphoneVolumeChanged(float);
|
||||
void pausedChanged(bool paused);
|
||||
void remoteVideoEnabledChanged(bool remoteVideoEnabled);
|
||||
void cameraEnabledChanged(bool enalbed);
|
||||
void localVideoEnabledChanged(bool enabled);
|
||||
void recordingChanged(const std::shared_ptr<linphone::Call> &call, bool recording);
|
||||
void speakerVolumeGainChanged(float volume);
|
||||
|
|
@ -153,6 +156,12 @@ private:
|
|||
const std::shared_ptr<linphone::AudioDevice> &audioDevice) override;
|
||||
virtual void onRemoteRecording(const std::shared_ptr<linphone::Call> &call, bool recording) override;
|
||||
virtual void onAuthenticationTokenVerified(const std::shared_ptr<linphone::Call> &call, bool verified) override;
|
||||
virtual void onHeadsetAnswerCallRequested(const std::shared_ptr<linphone::Call> &call) override;
|
||||
virtual void onHeadsetEndCallRequested(const std::shared_ptr<linphone::Call> &call) override;
|
||||
virtual void onHeadsetHoldCallRequested(const std::shared_ptr<linphone::Call> &call) override;
|
||||
virtual void onHeadsetMicrophoneMuteToggled(const std::shared_ptr<linphone::Call> &call, bool mute) override;
|
||||
virtual void onHeadsetRejectCallRequested(const std::shared_ptr<linphone::Call> &call) override;
|
||||
virtual void onHeadsetResumeCallRequested(const std::shared_ptr<linphone::Call> &call) override;
|
||||
|
||||
signals:
|
||||
void dtmfReceived(const std::shared_ptr<linphone::Call> &call, int dtmf);
|
||||
|
|
@ -182,6 +191,12 @@ signals:
|
|||
const std::shared_ptr<linphone::AudioDevice> &audioDevice);
|
||||
void remoteRecording(const std::shared_ptr<linphone::Call> &call, bool recording);
|
||||
void authenticationTokenVerified(const std::shared_ptr<linphone::Call> &call, bool verified);
|
||||
void headsetAnswerCallRequested();
|
||||
void headsetEndCallRequested();
|
||||
void headsetHoldCallRequested();
|
||||
void headsetMicrophoneMuteToggled(bool mute);
|
||||
void headsetRejectCallRequested();
|
||||
void headsetResumeCallRequested();
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -44,7 +44,7 @@ ChatModel::ChatModel(const std::shared_ptr<linphone::ChatRoom> &chatroom, QObjec
|
|||
|
||||
ChatModel::~ChatModel() {
|
||||
mustBeInLinphoneThread("~" + getClassName());
|
||||
disconnect(CoreModel::getInstance().get(), &CoreModel::messageReadInChatRoom, this, nullptr);
|
||||
disconnect(CoreModel::getInstance().get(), &CoreModel::chatRoomRead, this, nullptr);
|
||||
}
|
||||
|
||||
QDateTime ChatModel::getLastUpdateTime() {
|
||||
|
|
@ -173,7 +173,6 @@ void ChatModel::leave() {
|
|||
|
||||
void ChatModel::deleteChatRoom() {
|
||||
CoreModel::getInstance()->getCore()->deleteChatRoom(mMonitor);
|
||||
emit deleted();
|
||||
}
|
||||
|
||||
std::shared_ptr<linphone::ChatMessage>
|
||||
|
|
@ -186,6 +185,11 @@ ChatModel::createReplyMessage(const std::shared_ptr<linphone::ChatMessage> &mess
|
|||
return mMonitor->createReplyMessage(message);
|
||||
}
|
||||
|
||||
std::shared_ptr<linphone::ChatMessage>
|
||||
ChatModel::createReplacesMessage(const std::shared_ptr<linphone::ChatMessage> &message) {
|
||||
return mMonitor->createReplacesMessage(message);
|
||||
}
|
||||
|
||||
std::shared_ptr<linphone::ChatMessage>
|
||||
ChatModel::createForwardMessage(const std::shared_ptr<linphone::ChatMessage> &message) {
|
||||
return mMonitor->createForwardMessage(message);
|
||||
|
|
@ -212,7 +216,7 @@ ChatModel::searchMessageByText(QString text, std::shared_ptr<const linphone::Eve
|
|||
}
|
||||
|
||||
void ChatModel::compose() {
|
||||
mMonitor->compose();
|
||||
mMonitor->composeTextMessage();
|
||||
}
|
||||
|
||||
linphone::ChatRoom::State ChatModel::getState() const {
|
||||
|
|
|
|||
|
|
@ -68,6 +68,7 @@ public:
|
|||
|
||||
std::shared_ptr<linphone::ChatMessage> createReplyMessage(const std::shared_ptr<linphone::ChatMessage> &message);
|
||||
std::shared_ptr<linphone::ChatMessage> createForwardMessage(const std::shared_ptr<linphone::ChatMessage> &message);
|
||||
std::shared_ptr<linphone::ChatMessage> createReplacesMessage(const std::shared_ptr<linphone::ChatMessage> &message);
|
||||
|
||||
std::shared_ptr<linphone::ChatMessage> createTextMessageFromText(QString text);
|
||||
std::shared_ptr<linphone::ChatMessage> createMessage(QString text,
|
||||
|
|
|
|||
|
|
@ -51,7 +51,7 @@ ChatMessageModel::~ChatMessageModel() {
|
|||
}
|
||||
|
||||
QString ChatMessageModel::getText() const {
|
||||
return ToolModel::getMessageFromContent(mMonitor->getContents());
|
||||
return ToolModel::getMessageFromMessage(mMonitor);
|
||||
}
|
||||
|
||||
QString ChatMessageModel::getUtf8Text() const {
|
||||
|
|
@ -92,7 +92,7 @@ bool ChatMessageModel::isRead() const {
|
|||
void ChatMessageModel::markAsRead() {
|
||||
mMonitor->markAsRead();
|
||||
emit messageRead();
|
||||
emit CoreModel::getInstance()->messageReadInChatRoom(mMonitor->getChatRoom());
|
||||
emit CoreModel::getInstance() -> messageReadInChatRoom(mMonitor->getChatRoom());
|
||||
}
|
||||
|
||||
void ChatMessageModel::deleteMessageFromChatRoom(bool deletedByUser) {
|
||||
|
|
@ -103,6 +103,13 @@ void ChatMessageModel::deleteMessageFromChatRoom(bool deletedByUser) {
|
|||
}
|
||||
}
|
||||
|
||||
void ChatMessageModel::retractMessageFromChatRoom() {
|
||||
auto chatRoom = mMonitor->getChatRoom();
|
||||
if (chatRoom) {
|
||||
chatRoom->retractMessage(mMonitor);
|
||||
}
|
||||
}
|
||||
|
||||
void ChatMessageModel::sendReaction(const QString &reaction) {
|
||||
auto linReaction = mMonitor->createReaction(Utils::appStringToCoreString(reaction));
|
||||
linReaction->send();
|
||||
|
|
@ -188,3 +195,11 @@ void ChatMessageModel::onEphemeralMessageTimerStarted(const std::shared_ptr<linp
|
|||
void ChatMessageModel::onEphemeralMessageDeleted(const std::shared_ptr<linphone::ChatMessage> &message) {
|
||||
emit ephemeralMessageDeleted(message);
|
||||
}
|
||||
|
||||
void ChatMessageModel::onRetracted(const std::shared_ptr<linphone::ChatMessage> &message) {
|
||||
emit retracted(message);
|
||||
}
|
||||
|
||||
void ChatMessageModel::onContentEdited(const std::shared_ptr<linphone::ChatMessage> &message) {
|
||||
emit contentEdited(message);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -52,6 +52,7 @@ public:
|
|||
void markAsRead();
|
||||
|
||||
void deleteMessageFromChatRoom(bool deletedByUser);
|
||||
void retractMessageFromChatRoom();
|
||||
|
||||
void sendReaction(const QString &reaction);
|
||||
|
||||
|
|
@ -95,6 +96,8 @@ signals:
|
|||
void ephemeralMessageTimerStarted(const std::shared_ptr<linphone::ChatMessage> &message);
|
||||
void ephemeralMessageDeleted(const std::shared_ptr<linphone::ChatMessage> &message);
|
||||
void ephemeralMessageTimeUpdated(const std::shared_ptr<linphone::ChatMessage> &message, int expireTime);
|
||||
void retracted(const std::shared_ptr<linphone::ChatMessage> &message);
|
||||
void contentEdited(const std::shared_ptr<linphone::ChatMessage> &message);
|
||||
|
||||
private:
|
||||
linphone::ChatMessage::State mMessageState;
|
||||
|
|
@ -130,6 +133,8 @@ private:
|
|||
const std::shared_ptr<const linphone::ParticipantImdnState> &state) override;
|
||||
void onEphemeralMessageTimerStarted(const std::shared_ptr<linphone::ChatMessage> &message) override;
|
||||
void onEphemeralMessageDeleted(const std::shared_ptr<linphone::ChatMessage> &message) override;
|
||||
void onRetracted(const std::shared_ptr<linphone::ChatMessage> &message) override;
|
||||
void onContentEdited(const std::shared_ptr<linphone::ChatMessage> &message) override;
|
||||
};
|
||||
|
||||
#endif
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -74,8 +74,12 @@ void ChatMessageContentModel::removeDownloadedFile(QString filePath) {
|
|||
}
|
||||
}
|
||||
|
||||
void ChatMessageContentModel::downloadFile(const QString &name) {
|
||||
if (!mChatMessageModel) return;
|
||||
bool ChatMessageContentModel::downloadFile(const QString &name, QString *error) {
|
||||
if (!mChatMessageModel) {
|
||||
//: Internal error : message object does not exist anymore !
|
||||
if (error) *error = tr("download_error_object_doesnt_exist");
|
||||
return false;
|
||||
}
|
||||
switch (mChatMessageModel->getState()) {
|
||||
case linphone::ChatMessage::State::Delivered:
|
||||
case linphone::ChatMessage::State::DeliveredToUser:
|
||||
|
|
@ -83,10 +87,13 @@ void ChatMessageContentModel::downloadFile(const QString &name) {
|
|||
case linphone::ChatMessage::State::FileTransferDone:
|
||||
break;
|
||||
case linphone::ChatMessage::State::FileTransferInProgress:
|
||||
return;
|
||||
return true;
|
||||
default:
|
||||
lWarning() << QStringLiteral("Wrong message state when requesting downloading, state=.")
|
||||
<< LinphoneEnums::fromLinphone(mChatMessageModel->getState());
|
||||
auto state = LinphoneEnums::fromLinphone(mChatMessageModel->getState());
|
||||
lWarning() << QStringLiteral("Wrong message state when requesting downloading, state=") << state;
|
||||
//: Error while trying to download content : %1
|
||||
if (error) *error = tr("download_file_server_error").arg(LinphoneEnums::toString(state));
|
||||
return false;
|
||||
}
|
||||
bool soFarSoGood;
|
||||
const QString safeFilePath = Utils::getSafeFilePath(
|
||||
|
|
@ -94,21 +101,32 @@ void ChatMessageContentModel::downloadFile(const QString &name) {
|
|||
|
||||
if (!soFarSoGood) {
|
||||
lWarning() << QStringLiteral("Unable to create safe file path for: %1.").arg(name);
|
||||
return;
|
||||
//: Unable to create safe file path for: %1
|
||||
if (error) *error = tr("download_file_error_no_safe_file_path").arg(name);
|
||||
return false;
|
||||
}
|
||||
mContent->setFilePath(Utils::appStringToCoreString(safeFilePath));
|
||||
|
||||
if (!mContent->isFileTransfer()) {
|
||||
lWarning() << QStringLiteral("file transfer is not available");
|
||||
Utils::showInformationPopup(
|
||||
//: Error
|
||||
tr("popup_error_title"),
|
||||
//: This file was already downloaded and is no more on the server. Your peer have to resend it if you want
|
||||
//: to get it
|
||||
tr("popup_download_error_message"), false);
|
||||
//: This file was already downloaded and is no more on the server. Your peer have to resend it if you want
|
||||
//: to get it
|
||||
if (error) *error = tr("download_file_error_file_transfer_unavailable");
|
||||
return false;
|
||||
} else if (mContent->getName().empty()) {
|
||||
lWarning() << QStringLiteral("content name is null, can't download it !");
|
||||
//: Content name is null, can't download it !
|
||||
if (error) *error = tr("download_file_error_null_name");
|
||||
return false;
|
||||
} else {
|
||||
if (!mChatMessageModel->getMonitor()->downloadContent(mContent))
|
||||
lDebug() << log().arg("download file : %1").arg(name);
|
||||
auto downloaded = mChatMessageModel->getMonitor()->downloadContent(mContent);
|
||||
if (!downloaded) {
|
||||
lWarning() << QStringLiteral("Unable to download file of entry %1.").arg(name);
|
||||
//: Unable to download file of entry %1
|
||||
if (error) *error = tr("download_file_error_unable_to_download").arg(name);
|
||||
}
|
||||
return downloaded;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -40,17 +40,21 @@ public:
|
|||
std::shared_ptr<ChatMessageModel> chatMessageModel);
|
||||
~ChatMessageContentModel();
|
||||
|
||||
QString getThumbnail() const;
|
||||
|
||||
void setThumbnail(const QString &data);
|
||||
void setWasDownloaded(bool wasDownloaded);
|
||||
|
||||
void createThumbnail();
|
||||
void removeDownloadedFile(QString filePath);
|
||||
|
||||
void downloadFile(const QString &name);
|
||||
/**
|
||||
* Returns true if download succeed, false otherwise
|
||||
*/
|
||||
bool downloadFile(const QString &name, QString *error = nullptr);
|
||||
void cancelDownloadFile();
|
||||
void openFile(const QString &name, bool wasDownloaded, bool showDirectory = false);
|
||||
/**
|
||||
* Returns true if file saved successfully, false otherwise
|
||||
*/
|
||||
bool saveAs(const QString &path);
|
||||
|
||||
const std::shared_ptr<linphone::Content> &getContent() const;
|
||||
|
|
@ -70,4 +74,4 @@ private:
|
|||
QSharedPointer<ConferenceInfoModel> mConferenceInfoModel;
|
||||
};
|
||||
|
||||
#endif
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -236,8 +236,8 @@ void ConferenceModel::onParticipantDeviceMediaCapabilityChanged(
|
|||
void ConferenceModel::onParticipantDeviceMediaAvailabilityChanged(
|
||||
const std::shared_ptr<linphone::Conference> &conference,
|
||||
const std::shared_ptr<const linphone::ParticipantDevice> &participantDevice) {
|
||||
lInfo() << "onParticipantDeviceMediaAvailabilityChanged: "
|
||||
<< (int)participantDevice->getStreamAvailability(linphone::StreamType::Video)
|
||||
lInfo() << "onParticipantDeviceMediaAvailabilityChanged: video stream available ="
|
||||
<< participantDevice->getStreamAvailability(linphone::StreamType::Video)
|
||||
<< ". Device: " << participantDevice->getAddress()->asString().c_str();
|
||||
emit participantDeviceMediaAvailabilityChanged(participantDevice);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -114,6 +114,10 @@ void CoreModel::start() {
|
|||
if (mCore->getLogCollectionUploadServerUrl().empty())
|
||||
mCore->setLogCollectionUploadServerUrl(Constants::DefaultUploadLogsServer);
|
||||
|
||||
/// These 2 API should not be used as they manage internal gains insterad of those of the soundcard.
|
||||
// Use playback/capture gain from capture graph and call only
|
||||
mCore->setMicGainDb(0.0);
|
||||
mCore->setPlaybackGainDb(0.0);
|
||||
mIterateTimer = new QTimer(this);
|
||||
mIterateTimer->setInterval(20);
|
||||
connect(mIterateTimer, &QTimer::timeout, [this]() { mCore->iterate(); });
|
||||
|
|
@ -171,8 +175,6 @@ void CoreModel::setPathBeforeCreation() {
|
|||
std::shared_ptr<linphone::Factory> factory = linphone::Factory::get();
|
||||
SET_FACTORY_PATH(Msplugins, Paths::getPackageMsPluginsDirPath());
|
||||
SET_FACTORY_PATH(TopResources, Paths::getPackageTopDirPath());
|
||||
SET_FACTORY_PATH(SoundResources, Paths::getPackageSoundsResourcesDirPath());
|
||||
SET_FACTORY_PATH(DataResources, Paths::getPackageDataDirPath());
|
||||
SET_FACTORY_PATH(Data, Paths::getAppLocalDirPath());
|
||||
SET_FACTORY_PATH(Download, Paths::getDownloadDirPath());
|
||||
SET_FACTORY_PATH(Config, Paths::getConfigDirPath(true));
|
||||
|
|
@ -199,8 +201,13 @@ void CoreModel::setPathAfterStart() {
|
|||
mCore->setUserCertificatesPath(Utils::appStringToCoreString(Paths::getUserCertificatesDirPath()));
|
||||
lInfo() << "[CoreModel] Using UserCertificate path : " << QString::fromStdString(mCore->getUserCertificatesPath());
|
||||
// Use application path if Linphone default is not available
|
||||
if (mCore->getRootCa().empty() || !Paths::filePathExists(Utils::coreStringToAppString(mCore->getRootCa())))
|
||||
mCore->setRootCa(Utils::appStringToCoreString(Paths::getRootCaFilePath()));
|
||||
QString rootCaPath = Utils::coreStringToAppString(mCore->getRootCa());
|
||||
QString relativeRootCa = Paths::getAppRootCaFilePath();
|
||||
lDebug() << "[CoreModel] Getting rootCa paths: " << rootCaPath << " VS " << relativeRootCa;
|
||||
if (!Paths::filePathExists(rootCaPath) || Paths::isSameRelativeFile(rootCaPath, relativeRootCa)) {
|
||||
lInfo() << "[CoreModel] Reset rootCa path to: " << relativeRootCa;
|
||||
mCore->setRootCa(Utils::appStringToCoreString(relativeRootCa));
|
||||
}
|
||||
lInfo() << "[CoreModel] Using RootCa path : " << QString::fromStdString(mCore->getRootCa());
|
||||
}
|
||||
|
||||
|
|
@ -216,7 +223,10 @@ QString CoreModel::getFetchConfig(QString filePath, bool *error) {
|
|||
if (!filePath.isEmpty()) filePath = "file://" + filePath;
|
||||
}
|
||||
if (filePath.isEmpty()) {
|
||||
qWarning() << "Remote provisionning cannot be retrieved. Command have been cleaned";
|
||||
qWarning() << "Remote provisioning cannot be retrieved. Command have been cleaned";
|
||||
Utils::showInformationPopup(tr("info_popup_error_title"),
|
||||
//: "Remote provisioning cannot be retrieved"
|
||||
tr("fetching_config_failed_error_message"), false);
|
||||
*error = true;
|
||||
}
|
||||
}
|
||||
|
|
@ -365,6 +375,23 @@ void CoreModel::searchInMagicSearch(QString filter,
|
|||
mMagicSearch->search(filter, sourceFlags, aggregation, maxResults);
|
||||
}
|
||||
|
||||
void CoreModel::checkForUpdate(const std::string &applicationVersion, bool requestedByUser) {
|
||||
mCheckVersionRequestedByUser = requestedByUser;
|
||||
auto settingsModel = SettingsModel::getInstance();
|
||||
if (settingsModel->isCheckForUpdateEnabled()) {
|
||||
if (settingsModel->getVersionCheckUrl().isEmpty())
|
||||
settingsModel->setVersionCheckUrl(Constants::VersionCheckReleaseUrl);
|
||||
lInfo() << log().arg("Checking for update for version") << applicationVersion;
|
||||
getCore()->checkForUpdate(applicationVersion);
|
||||
} else {
|
||||
lWarning() << log().arg("Check for update settings is not set");
|
||||
}
|
||||
}
|
||||
|
||||
bool CoreModel::isCheckVersionRequestedByUser() const {
|
||||
return mCheckVersionRequestedByUser;
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------------------------------------------------------
|
||||
|
||||
void CoreModel::onAccountAdded(const std::shared_ptr<linphone::Core> &core,
|
||||
|
|
@ -522,6 +549,7 @@ void CoreModel::onLogCollectionUploadProgressIndication(const std::shared_ptr<li
|
|||
void CoreModel::onMessageReceived(const std::shared_ptr<linphone::Core> &core,
|
||||
const std::shared_ptr<linphone::ChatRoom> &room,
|
||||
const std::shared_ptr<linphone::ChatMessage> &message) {
|
||||
if (SettingsModel::getInstance()->getDisableChatFeature()) return;
|
||||
if (message->isOutgoing()) return;
|
||||
emit unreadNotificationsChanged();
|
||||
std::list<std::shared_ptr<linphone::ChatMessage>> messages;
|
||||
|
|
@ -534,6 +562,7 @@ void CoreModel::onMessageReceived(const std::shared_ptr<linphone::Core> &core,
|
|||
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) {
|
||||
if (SettingsModel::getInstance()->getDisableChatFeature()) return;
|
||||
std::list<std::shared_ptr<linphone::ChatMessage>> finalMessages;
|
||||
for (auto &message : messages) {
|
||||
if (message->isOutgoing()) continue;
|
||||
|
|
@ -551,6 +580,7 @@ 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) {
|
||||
if (SettingsModel::getInstance()->getDisableChatFeature()) return;
|
||||
emit newMessageReaction(core, chatRoom, message, reaction);
|
||||
}
|
||||
void CoreModel::onNotifyPresenceReceivedForUriOrTel(
|
||||
|
|
@ -571,6 +601,7 @@ 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) {
|
||||
if (SettingsModel::getInstance()->getDisableChatFeature()) return;
|
||||
emit reactionRemoved(core, chatRoom, message, address);
|
||||
}
|
||||
void CoreModel::onTransferStateChanged(const std::shared_ptr<linphone::Core> &core,
|
||||
|
|
@ -582,7 +613,7 @@ void CoreModel::onVersionUpdateCheckResultReceived(const std::shared_ptr<linphon
|
|||
linphone::VersionUpdateCheckResult result,
|
||||
const std::string &version,
|
||||
const std::string &url) {
|
||||
emit versionUpdateCheckResultReceived(core, result, version, url);
|
||||
emit versionUpdateCheckResultReceived(core, result, version, url, mCheckVersionRequestedByUser);
|
||||
}
|
||||
|
||||
void CoreModel::onFriendListRemoved(const std::shared_ptr<linphone::Core> &core,
|
||||
|
|
@ -608,3 +639,12 @@ void CoreModel::onFriendListRemoved(const std::shared_ptr<linphone::Core> &core,
|
|||
}
|
||||
*/
|
||||
}
|
||||
|
||||
void CoreModel::onAudioDevicesListUpdated(const std::shared_ptr<linphone::Core> &core) {
|
||||
emit audioDevicesListUpdated(core);
|
||||
}
|
||||
|
||||
void CoreModel::onAudioDeviceChanged(const std::shared_ptr<linphone::Core> &core,
|
||||
const std::shared_ptr<linphone::AudioDevice> &device) {
|
||||
emit audioDeviceChanged(core, device);
|
||||
}
|
||||
|
|
@ -71,6 +71,9 @@ public:
|
|||
LinphoneEnums::MagicSearchAggregation aggregation,
|
||||
int maxResults);
|
||||
|
||||
void checkForUpdate(const std::string &applicationVersion, bool requestedByUser = false);
|
||||
bool isCheckVersionRequestedByUser() const;
|
||||
|
||||
bool mEnd = false;
|
||||
linphone::ConfiguringState mConfigStatus;
|
||||
QString mConfigMessage;
|
||||
|
|
@ -97,6 +100,7 @@ private:
|
|||
QMap<QString, OIDCModel *> mOpenIdConnections;
|
||||
std::shared_ptr<MagicSearchModel> mMagicSearch;
|
||||
bool mStarted = false;
|
||||
bool mCheckVersionRequestedByUser = false;
|
||||
|
||||
void setPathBeforeCreation();
|
||||
void setPathsAfterCreation();
|
||||
|
|
@ -202,6 +206,9 @@ private:
|
|||
const std::string &url) override;
|
||||
virtual void onFriendListRemoved(const std::shared_ptr<linphone::Core> &core,
|
||||
const std::shared_ptr<linphone::FriendList> &friendList) override;
|
||||
virtual void onAudioDevicesListUpdated(const std::shared_ptr<linphone::Core> &core) override;
|
||||
virtual void onAudioDeviceChanged(const std::shared_ptr<linphone::Core> &core,
|
||||
const std::shared_ptr<linphone::AudioDevice> &device) override;
|
||||
|
||||
signals:
|
||||
void accountAdded(const std::shared_ptr<linphone::Core> &core, const std::shared_ptr<linphone::Account> &account);
|
||||
|
|
@ -281,9 +288,13 @@ signals:
|
|||
void versionUpdateCheckResultReceived(const std::shared_ptr<linphone::Core> &core,
|
||||
linphone::VersionUpdateCheckResult result,
|
||||
const std::string &version,
|
||||
const std::string &url);
|
||||
const std::string &url,
|
||||
bool checkRequestedByUser);
|
||||
void friendListRemoved(const std::shared_ptr<linphone::Core> &core,
|
||||
const std::shared_ptr<linphone::FriendList> &friendList);
|
||||
void audioDevicesListUpdated(const std::shared_ptr<linphone::Core> &core);
|
||||
void audioDeviceChanged(const std::shared_ptr<linphone::Core> &core,
|
||||
const std::shared_ptr<linphone::AudioDevice> &device);
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -155,5 +155,5 @@ void MagicSearchModel::updateFriendListWithFriend(const std::shared_ptr<linphone
|
|||
}
|
||||
qInfo() << log().arg("Adding Friend:") << linphoneFriend.get();
|
||||
if (friendList) friendList->addFriend(linphoneFriend);
|
||||
emit CoreModel::getInstance()->friendCreated(linphoneFriend);
|
||||
emit CoreModel::getInstance() -> friendCreated(linphoneFriend);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -81,6 +81,20 @@ SettingsModel::SettingsModel() {
|
|||
QObject::connect(CoreModel::getInstance().get(), &CoreModel::lastCallEnded, this, [this]() {
|
||||
if (mCaptureGraphListenerCount > 0) createCaptureGraph(); // Repair the capture graph
|
||||
});
|
||||
QObject::connect(CoreModel::getInstance().get(), &CoreModel::audioDevicesListUpdated, this,
|
||||
[this](const std::shared_ptr<linphone::Core> &core) {
|
||||
lInfo() << log().arg("audio device list updated");
|
||||
updateCallSettings();
|
||||
});
|
||||
QObject::connect(
|
||||
CoreModel::getInstance().get(), &CoreModel::audioDeviceChanged, this,
|
||||
[this](const std::shared_ptr<linphone::Core> &core, const std::shared_ptr<linphone::AudioDevice> &device) {
|
||||
lInfo() << log().arg("audio device changed");
|
||||
if (device) lInfo() << "device :" << device->getDeviceName();
|
||||
// emit playbackDeviceChanged(getPlaybackDevice());
|
||||
// emit captureDeviceChanged(getCaptureDevice());
|
||||
// emit ringerDeviceChanged(getRingerDevice());
|
||||
});
|
||||
}
|
||||
|
||||
SettingsModel::~SettingsModel() {
|
||||
|
|
@ -173,8 +187,10 @@ void SettingsModel::stopCaptureGraph() {
|
|||
|
||||
// Force a call on the 'detect' method of all audio filters, updating new or removed devices
|
||||
void SettingsModel::accessCallSettings() {
|
||||
// Audio
|
||||
mustBeInLinphoneThread(log().arg(Q_FUNC_INFO));
|
||||
startCaptureGraph();
|
||||
|
||||
// Audio
|
||||
CoreModel::getInstance()->getCore()->reloadSoundDevices();
|
||||
emit captureDevicesChanged(getCaptureDevices());
|
||||
emit playbackDevicesChanged(getPlaybackDevices());
|
||||
|
|
@ -185,12 +201,28 @@ void SettingsModel::accessCallSettings() {
|
|||
emit playbackGainChanged(getPlaybackGain());
|
||||
emit captureGainChanged(getCaptureGain());
|
||||
|
||||
startCaptureGraph();
|
||||
// Video
|
||||
CoreModel::getInstance()->getCore()->reloadVideoDevices();
|
||||
emit videoDevicesChanged(getVideoDevices());
|
||||
}
|
||||
|
||||
void SettingsModel::updateCallSettings() {
|
||||
mustBeInLinphoneThread(log().arg(Q_FUNC_INFO));
|
||||
|
||||
// Audio
|
||||
emit captureDevicesChanged(getCaptureDevices());
|
||||
emit playbackDevicesChanged(getPlaybackDevices());
|
||||
emit playbackDeviceChanged(getPlaybackDevice());
|
||||
emit ringerDevicesChanged(getRingerDevices());
|
||||
emit ringerDeviceChanged(getRingerDevice());
|
||||
emit captureDeviceChanged(getCaptureDevice());
|
||||
emit playbackGainChanged(getPlaybackGain());
|
||||
emit captureGainChanged(getCaptureGain());
|
||||
|
||||
// Video
|
||||
emit videoDevicesChanged(getVideoDevices());
|
||||
}
|
||||
|
||||
void SettingsModel::closeCallSettings() {
|
||||
mustBeInLinphoneThread(log().arg(Q_FUNC_INFO));
|
||||
stopCaptureGraph();
|
||||
|
|
@ -205,13 +237,12 @@ bool SettingsModel::getCaptureGraphRunning() {
|
|||
float SettingsModel::getMicVolume() {
|
||||
mustBeInLinphoneThread(log().arg(Q_FUNC_INFO));
|
||||
float v = 0.0;
|
||||
|
||||
if (mSimpleCaptureGraph && mSimpleCaptureGraph->isRunning()) {
|
||||
v = mSimpleCaptureGraph->getCaptureVolume();
|
||||
} else {
|
||||
auto call = CoreModel::getInstance()->getCore()->getCurrentCall();
|
||||
if (call) {
|
||||
v = MediastreamerUtils::computeVu(call->getRecordVolume());
|
||||
v = call->getRecordVolume();
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -221,33 +252,49 @@ float SettingsModel::getMicVolume() {
|
|||
|
||||
float SettingsModel::getPlaybackGain() const {
|
||||
mustBeInLinphoneThread(log().arg(Q_FUNC_INFO));
|
||||
float dbGain = CoreModel::getInstance()->getCore()->getPlaybackGainDb();
|
||||
return MediastreamerUtils::dbToLinear(dbGain);
|
||||
if (mSimpleCaptureGraph && mSimpleCaptureGraph->isRunning()) {
|
||||
return mSimpleCaptureGraph->getPlaybackGain();
|
||||
} else {
|
||||
auto call = CoreModel::getInstance()->getCore()->getCurrentCall();
|
||||
if (call) return call->getSpeakerVolumeGain();
|
||||
else return 0.0;
|
||||
}
|
||||
}
|
||||
|
||||
void SettingsModel::setPlaybackGain(float gain) {
|
||||
mustBeInLinphoneThread(log().arg(Q_FUNC_INFO));
|
||||
float oldGain = getPlaybackGain();
|
||||
CoreModel::getInstance()->getCore()->setPlaybackGainDb(MediastreamerUtils::linearToDb(gain));
|
||||
if (mSimpleCaptureGraph && mSimpleCaptureGraph->isRunning()) {
|
||||
mSimpleCaptureGraph->setPlaybackGain(gain);
|
||||
}
|
||||
auto currentCall = CoreModel::getInstance()->getCore()->getCurrentCall();
|
||||
if (currentCall) {
|
||||
currentCall->setSpeakerVolumeGain(gain);
|
||||
}
|
||||
if ((int)(oldGain * 1000) != (int)(gain * 1000)) emit playbackGainChanged(gain);
|
||||
}
|
||||
|
||||
float SettingsModel::getCaptureGain() const {
|
||||
mustBeInLinphoneThread(getClassName());
|
||||
float dbGain = CoreModel::getInstance()->getCore()->getMicGainDb();
|
||||
return MediastreamerUtils::dbToLinear(dbGain);
|
||||
if (mSimpleCaptureGraph && mSimpleCaptureGraph->isRunning()) {
|
||||
return mSimpleCaptureGraph->getCaptureGain();
|
||||
} else {
|
||||
auto call = CoreModel::getInstance()->getCore()->getCurrentCall();
|
||||
if (call) return call->getMicrophoneVolumeGain();
|
||||
else return 0.0;
|
||||
}
|
||||
}
|
||||
|
||||
void SettingsModel::setCaptureGain(float gain) {
|
||||
mustBeInLinphoneThread(log().arg(Q_FUNC_INFO));
|
||||
float oldGain = getCaptureGain();
|
||||
CoreModel::getInstance()->getCore()->setMicGainDb(MediastreamerUtils::linearToDb(gain));
|
||||
if (mSimpleCaptureGraph && mSimpleCaptureGraph->isRunning()) {
|
||||
mSimpleCaptureGraph->setCaptureGain(gain);
|
||||
}
|
||||
auto currentCall = CoreModel::getInstance()->getCore()->getCurrentCall();
|
||||
if (currentCall) {
|
||||
currentCall->setMicrophoneVolumeGain(gain);
|
||||
}
|
||||
if ((int)(oldGain * 1000) != (int)(gain * 1000)) emit captureGainChanged(gain);
|
||||
}
|
||||
|
||||
|
|
@ -395,14 +442,20 @@ void SettingsModel::setPlaybackDevice(const QVariantMap &device) {
|
|||
|
||||
QVariantMap SettingsModel::getRingerDevice() const {
|
||||
mustBeInLinphoneThread(log().arg(Q_FUNC_INFO));
|
||||
auto id = Utils::coreStringToAppString(CoreModel::getInstance()->getCore()->getRingerDevice());
|
||||
auto audioDevice = ToolModel::findAudioDevice(id, linphone::AudioDevice::Capabilities::CapabilityPlay);
|
||||
return ToolModel::createVariant(audioDevice);
|
||||
for (const auto &device : CoreModel::getInstance()->getCore()->getExtendedAudioDevices()) {
|
||||
if (device->getUseForRinging()) return ToolModel::createVariant(device);
|
||||
}
|
||||
return ToolModel::createVariant(nullptr);
|
||||
}
|
||||
|
||||
void SettingsModel::setRingerDevice(QVariantMap device) {
|
||||
mustBeInLinphoneThread(log().arg(Q_FUNC_INFO));
|
||||
CoreModel::getInstance()->getCore()->setRingerDevice(Utils::appStringToCoreString(device["id"].toString()));
|
||||
for (const auto &ldevice : CoreModel::getInstance()->getCore()->getExtendedAudioDevices()) {
|
||||
auto id = Utils::appStringToCoreString(device["id"].toString());
|
||||
if (ldevice->getId() == id) {
|
||||
ldevice->setUseForRinging(true);
|
||||
} else ldevice->setUseForRinging(false);
|
||||
}
|
||||
emit ringerDeviceChanged(device);
|
||||
}
|
||||
|
||||
|
|
@ -784,26 +837,13 @@ QString SettingsModel::getDefaultDomain() const {
|
|||
mConfig->getString(SettingsModel::AppSection, "default_domain", "sip.linphone.org"));
|
||||
}
|
||||
|
||||
void SettingsModel::enableCallForward(QString destination) {
|
||||
// TODO implement business logic to activate call forward to destination on PBX via external API (contains voicemail
|
||||
// or a destination).
|
||||
mConfig->setString(UiSection, "call_forward_to_address", Utils::appStringToCoreString(destination));
|
||||
emit callForwardToAddressChanged(getCallForwardToAddress());
|
||||
}
|
||||
|
||||
void SettingsModel::disableCallForward() {
|
||||
// TODO implement business logic to de-activate call forward on PBX via external API
|
||||
mConfig->setString(UiSection, "call_forward_to_address", "");
|
||||
}
|
||||
|
||||
QString SettingsModel::getCallForwardToAddress() const {
|
||||
mustBeInLinphoneThread(log().arg(Q_FUNC_INFO));
|
||||
return Utils::coreStringToAppString(mConfig->getString(UiSection, "call_forward_to_address", ""));
|
||||
}
|
||||
|
||||
void SettingsModel::setCallForwardToAddress(const QString &data) {
|
||||
if (data == "") disableCallForward();
|
||||
else enableCallForward(data);
|
||||
mConfig->setString(UiSection, "call_forward_to_address", Utils::appStringToCoreString(data)); // TODO implement BL
|
||||
emit(callForwardToAddressChanged(data));
|
||||
}
|
||||
|
||||
|
|
@ -855,6 +895,40 @@ bool SettingsModel::getDisableMeetingsFeature() const {
|
|||
return !!mConfig->getInt(UiSection, "disable_meetings_feature", 0);
|
||||
}
|
||||
|
||||
bool SettingsModel::isCheckForUpdateAvailable() const {
|
||||
#ifdef ENABLE_UPDATE_CHECK
|
||||
return true;
|
||||
#else
|
||||
return false;
|
||||
#endif
|
||||
}
|
||||
|
||||
bool SettingsModel::isCheckForUpdateEnabled() const {
|
||||
return !!mConfig->getInt(UiSection, "check_for_update_enabled", isCheckForUpdateAvailable());
|
||||
}
|
||||
|
||||
void SettingsModel::setCheckForUpdateEnabled(bool enable) {
|
||||
mConfig->setInt(UiSection, "check_for_update_enabled", enable);
|
||||
emit checkForUpdateEnabledChanged();
|
||||
}
|
||||
|
||||
QString SettingsModel::getVersionCheckUrl() {
|
||||
auto url = mConfig->getString("misc", "version_check_url_root", "");
|
||||
if (url == "") {
|
||||
url = Constants::VersionCheckReleaseUrl;
|
||||
if (url != "") mConfig->setString("misc", "version_check_url_root", url);
|
||||
}
|
||||
return Utils::coreStringToAppString(url);
|
||||
}
|
||||
|
||||
void SettingsModel::setVersionCheckUrl(const QString &url) {
|
||||
if (url != getVersionCheckUrl()) {
|
||||
// Do not trim the url before because we want to update GUI from potential auto fix.
|
||||
mConfig->setString("misc", "version_check_url_root", Utils::appStringToCoreString(url.trimmed()));
|
||||
emit versionCheckUrlChanged();
|
||||
}
|
||||
}
|
||||
|
||||
void SettingsModel::setChatNotificationSoundPath(const QString &path) {
|
||||
QString cleanedPath = QDir::cleanPath(path);
|
||||
mConfig->setString(UiSection, "chat_sound_notification_file", Utils::appStringToCoreString(cleanedPath));
|
||||
|
|
@ -1052,13 +1126,6 @@ DEFINE_GETSET_CONFIG(SettingsModel,
|
|||
DisableCommandLine,
|
||||
"disable_command_line",
|
||||
false)
|
||||
DEFINE_GETSET_CONFIG(SettingsModel,
|
||||
bool,
|
||||
Bool,
|
||||
disableCallForward,
|
||||
DisableCallForward,
|
||||
"disable_call_forward",
|
||||
true)
|
||||
DEFINE_GETSET_CONFIG_STRING(SettingsModel,
|
||||
themeMainColor,
|
||||
ThemeMainColor,
|
||||
|
|
|
|||
Some files were not shown because too many files have changed in this diff Show more
Loading…
Add table
Reference in a new issue