feat(app): deal with peer/local addresses

This commit is contained in:
Ronan Abhamon 2018-08-21 16:48:15 +02:00
parent 578e1a2765
commit 3ea2478c23
74 changed files with 1146 additions and 690 deletions

View file

@ -142,7 +142,7 @@ set(SOURCES
src/components/contacts/ContactsListProxyModel.cpp
src/components/core/CoreHandlers.cpp
src/components/core/CoreManager.cpp
src/components/core/messages-count-notifier/AbstractMessagesCountNotifier.cpp
src/components/core/messages-count-notifier/AbstractMessageCountNotifier.cpp
src/components/file/FileDownloader.cpp
src/components/file/FileExtractor.cpp
src/components/notifier/Notifier.cpp
@ -200,7 +200,7 @@ set(HEADERS
src/components/contacts/ContactsListProxyModel.hpp
src/components/core/CoreHandlers.hpp
src/components/core/CoreManager.hpp
src/components/core/messages-count-notifier/AbstractMessagesCountNotifier.hpp
src/components/core/messages-count-notifier/AbstractMessageCountNotifier.hpp
src/components/file/FileDownloader.hpp
src/components/file/FileExtractor.hpp
src/components/notifier/Notifier.hpp
@ -230,37 +230,37 @@ set(MAIN_FILE src/app/main.cpp)
if (APPLE)
list(APPEND SOURCES
src/app/single-application/SingleApplication.cpp
src/components/core/messages-count-notifier/MessagesCountNotifierMacOs.m
src/components/core/messages-count-notifier/MessageCountNotifierMacOs.m
src/components/other/desktop-tools/DesktopToolsMacOs.cpp
src/components/other/desktop-tools/screen-saver/ScreenSaverMacOs.m
)
list(APPEND HEADERS
src/app/single-application/SingleApplicationPrivate.hpp
src/components/core/messages-count-notifier/MessagesCountNotifierMacOs.hpp
src/components/core/messages-count-notifier/MessageCountNotifierMacOs.hpp
src/components/other/desktop-tools/DesktopToolsMacOs.hpp
)
elseif (WIN32)
list(APPEND SOURCES
src/app/single-application/SingleApplication.cpp
src/components/core/messages-count-notifier/MessagesCountNotifierSystemTrayIcon.cpp
src/components/core/messages-count-notifier/MessageCountNotifierSystemTrayIcon.cpp
src/components/other/desktop-tools/DesktopToolsWindows.cpp
)
list(APPEND HEADERS
src/app/single-application/SingleApplicationPrivate.hpp
src/components/core/messages-count-notifier/MessagesCountNotifierSystemTrayIcon.hpp
src/components/core/messages-count-notifier/MessageCountNotifierSystemTrayIcon.hpp
src/components/other/desktop-tools/DesktopToolsWindows.hpp
)
else ()
list(APPEND SOURCES
src/app/single-application/SingleApplicationDBus.cpp
src/components/core/messages-count-notifier/MessagesCountNotifierSystemTrayIcon.cpp
src/components/core/messages-count-notifier/MessageCountNotifierSystemTrayIcon.cpp
src/components/other/desktop-tools/DesktopToolsLinux.cpp
src/components/other/desktop-tools/screen-saver/ScreenSaverDBus.cpp
src/components/other/desktop-tools/screen-saver/ScreenSaverXdg.cpp
)
list(APPEND HEADERS
src/app/single-application/SingleApplicationDBusPrivate.hpp
src/components/core/messages-count-notifier/MessagesCountNotifierSystemTrayIcon.hpp
src/components/core/messages-count-notifier/MessageCountNotifierSystemTrayIcon.hpp
src/components/other/desktop-tools/DesktopToolsLinux.hpp
src/components/other/desktop-tools/screen-saver/ScreenSaverDBus.hpp
src/components/other/desktop-tools/screen-saver/ScreenSaverXdg.hpp

View file

@ -1,13 +1,75 @@
<?xml version="1.0" encoding="UTF-8"?>
<svg width="12px" height="12px" viewBox="0 0 12 12" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
<!-- Generator: Sketch 40.3 (33839) - http://www.bohemiancoding.com/sketch -->
<title>call_lost</title>
<desc>Created with Sketch.</desc>
<defs></defs>
<g id="Symbols" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd" stroke-linecap="round">
<g id="call_lost" class="color-error-stroke" stroke="#FF0000" stroke-width="2">
<path d="M12.9852814,5.74407768 L-1.15685425,5.74407768" id="Line" transform="translate(6.266032, 5.768485) rotate(-45.000000) translate(-6.266032, -5.768485) "></path>
<path d="M11,11 L1,1" id="Line"></path>
</g>
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<svg
xmlns:dc="http://purl.org/dc/elements/1.1/"
xmlns:cc="http://creativecommons.org/ns#"
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:svg="http://www.w3.org/2000/svg"
xmlns="http://www.w3.org/2000/svg"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
width="18"
height="18"
viewBox="0 0 18 18"
version="1.1"
id="svg13"
sodipodi:docname="declined_incoming_call.svg"
inkscape:version="0.92.2 2405546, 2018-03-11">
<metadata
id="metadata17">
<rdf:RDF>
<cc:Work
rdf:about="">
<dc:format>image/svg+xml</dc:format>
<dc:type
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
<dc:title>call_lost</dc:title>
</cc:Work>
</rdf:RDF>
</metadata>
<sodipodi:namedview
pagecolor="#ffffff"
bordercolor="#666666"
borderopacity="1"
objecttolerance="10"
gridtolerance="10"
guidetolerance="10"
inkscape:pageopacity="0"
inkscape:pageshadow="2"
inkscape:window-width="1920"
inkscape:window-height="985"
id="namedview15"
showgrid="false"
inkscape:zoom="6.9532167"
inkscape:cx="1.925277"
inkscape:cy="3.533194"
inkscape:window-x="0"
inkscape:window-y="35"
inkscape:window-maximized="1"
inkscape:current-layer="svg13" />
<!-- Generator: Sketch 40.3 (33839) - http://www.bohemiancoding.com/sketch -->
<title
id="title2">call_lost</title>
<desc
id="desc4">Created with Sketch.</desc>
<defs
id="defs6" />
<g
id="Symbols"
style="fill:none;fill-rule:evenodd;stroke:none;stroke-width:1;stroke-linecap:round"
transform="translate(3,3)">
<g
id="call_lost"
class="color-error-stroke"
style="stroke:#ff0000;stroke-width:2">
<path
d="M 12.985281,5.7440777 H -1.1568543"
id="Line"
transform="rotate(-45,6.266032,5.768485)"
inkscape:connector-curvature="0" />
<path
d="M 11,11 1,1"
id="path9"
inkscape:connector-curvature="0" />
</g>
</svg>
</g>
</svg>

Before

Width:  |  Height:  |  Size: 808 B

After

Width:  |  Height:  |  Size: 2.2 KiB

View file

@ -1,13 +1,75 @@
<?xml version="1.0" encoding="UTF-8"?>
<svg width="12px" height="12px" viewBox="0 0 12 12" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
<!-- Generator: Sketch 40.3 (33839) - http://www.bohemiancoding.com/sketch -->
<title>call_lost</title>
<desc>Created with Sketch.</desc>
<defs></defs>
<g id="Symbols" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd" stroke-linecap="round">
<g id="call_lost" class="color-error-stroke" stroke="#FF0000" stroke-width="2">
<path d="M12.9852814,5.74407768 L-1.15685425,5.74407768" id="Line" transform="translate(6.266032, 5.768485) rotate(-45.000000) translate(-6.266032, -5.768485) "></path>
<path d="M11,11 L1,1" id="Line"></path>
</g>
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<svg
xmlns:dc="http://purl.org/dc/elements/1.1/"
xmlns:cc="http://creativecommons.org/ns#"
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:svg="http://www.w3.org/2000/svg"
xmlns="http://www.w3.org/2000/svg"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
width="18"
height="18"
viewBox="0 0 18 18"
version="1.1"
id="svg13"
sodipodi:docname="declined_incoming_call.svg"
inkscape:version="0.92.2 2405546, 2018-03-11">
<metadata
id="metadata17">
<rdf:RDF>
<cc:Work
rdf:about="">
<dc:format>image/svg+xml</dc:format>
<dc:type
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
<dc:title>call_lost</dc:title>
</cc:Work>
</rdf:RDF>
</metadata>
<sodipodi:namedview
pagecolor="#ffffff"
bordercolor="#666666"
borderopacity="1"
objecttolerance="10"
gridtolerance="10"
guidetolerance="10"
inkscape:pageopacity="0"
inkscape:pageshadow="2"
inkscape:window-width="1920"
inkscape:window-height="985"
id="namedview15"
showgrid="false"
inkscape:zoom="6.9532167"
inkscape:cx="1.925277"
inkscape:cy="3.533194"
inkscape:window-x="0"
inkscape:window-y="35"
inkscape:window-maximized="1"
inkscape:current-layer="svg13" />
<!-- Generator: Sketch 40.3 (33839) - http://www.bohemiancoding.com/sketch -->
<title
id="title2">call_lost</title>
<desc
id="desc4">Created with Sketch.</desc>
<defs
id="defs6" />
<g
id="Symbols"
style="fill:none;fill-rule:evenodd;stroke:none;stroke-width:1;stroke-linecap:round"
transform="translate(3,3)">
<g
id="call_lost"
class="color-error-stroke"
style="stroke:#ff0000;stroke-width:2">
<path
d="M 12.985281,5.7440777 H -1.1568543"
id="Line"
transform="rotate(-45,6.266032,5.768485)"
inkscape:connector-curvature="0" />
<path
d="M 11,11 1,1"
id="path9"
inkscape:connector-curvature="0" />
</g>
</svg>
</g>
</svg>

Before

Width:  |  Height:  |  Size: 808 B

After

Width:  |  Height:  |  Size: 2.2 KiB

View file

@ -1,13 +1,75 @@
<?xml version="1.0" encoding="UTF-8"?>
<svg width="12px" height="12px" viewBox="0 0 12 12" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
<!-- Generator: Sketch 40.3 (33839) - http://www.bohemiancoding.com/sketch -->
<title>call_lost</title>
<desc>Created with Sketch.</desc>
<defs></defs>
<g id="Symbols" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd" stroke-linecap="round">
<g id="call_lost" class="color-error-stroke" stroke="#FF0000" stroke-width="2">
<path d="M12.9852814,5.74407768 L-1.15685425,5.74407768" id="Line" transform="translate(6.266032, 5.768485) rotate(-45.000000) translate(-6.266032, -5.768485) "></path>
<path d="M11,11 L1,1" id="Line"></path>
</g>
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<svg
xmlns:dc="http://purl.org/dc/elements/1.1/"
xmlns:cc="http://creativecommons.org/ns#"
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:svg="http://www.w3.org/2000/svg"
xmlns="http://www.w3.org/2000/svg"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
width="18"
height="18"
viewBox="0 0 18 18"
version="1.1"
id="svg13"
sodipodi:docname="declined_incoming_call.svg"
inkscape:version="0.92.2 2405546, 2018-03-11">
<metadata
id="metadata17">
<rdf:RDF>
<cc:Work
rdf:about="">
<dc:format>image/svg+xml</dc:format>
<dc:type
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
<dc:title>call_lost</dc:title>
</cc:Work>
</rdf:RDF>
</metadata>
<sodipodi:namedview
pagecolor="#ffffff"
bordercolor="#666666"
borderopacity="1"
objecttolerance="10"
gridtolerance="10"
guidetolerance="10"
inkscape:pageopacity="0"
inkscape:pageshadow="2"
inkscape:window-width="1920"
inkscape:window-height="985"
id="namedview15"
showgrid="false"
inkscape:zoom="6.9532167"
inkscape:cx="1.925277"
inkscape:cy="3.533194"
inkscape:window-x="0"
inkscape:window-y="35"
inkscape:window-maximized="1"
inkscape:current-layer="svg13" />
<!-- Generator: Sketch 40.3 (33839) - http://www.bohemiancoding.com/sketch -->
<title
id="title2">call_lost</title>
<desc
id="desc4">Created with Sketch.</desc>
<defs
id="defs6" />
<g
id="Symbols"
style="fill:none;fill-rule:evenodd;stroke:none;stroke-width:1;stroke-linecap:round"
transform="translate(3,3)">
<g
id="call_lost"
class="color-error-stroke"
style="stroke:#ff0000;stroke-width:2">
<path
d="M 12.985281,5.7440777 H -1.1568543"
id="Line"
transform="rotate(-45,6.266032,5.768485)"
inkscape:connector-curvature="0" />
<path
d="M 11,11 1,1"
id="path9"
inkscape:connector-curvature="0" />
</g>
</svg>
</g>
</svg>

Before

Width:  |  Height:  |  Size: 808 B

After

Width:  |  Height:  |  Size: 2.2 KiB

View file

@ -1,13 +1,75 @@
<?xml version="1.0" encoding="UTF-8"?>
<svg width="12px" height="12px" viewBox="0 0 12 12" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
<!-- Generator: Sketch 40.3 (33839) - http://www.bohemiancoding.com/sketch -->
<title>call_lost</title>
<desc>Created with Sketch.</desc>
<defs></defs>
<g id="Symbols" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd" stroke-linecap="round">
<g id="call_lost" class="color-error-stroke" stroke="#FF0000" stroke-width="2">
<path d="M12.9852814,5.74407768 L-1.15685425,5.74407768" id="Line" transform="translate(6.266032, 5.768485) rotate(-45.000000) translate(-6.266032, -5.768485) "></path>
<path d="M11,11 L1,1" id="Line"></path>
</g>
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<svg
xmlns:dc="http://purl.org/dc/elements/1.1/"
xmlns:cc="http://creativecommons.org/ns#"
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:svg="http://www.w3.org/2000/svg"
xmlns="http://www.w3.org/2000/svg"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
width="18"
height="18"
viewBox="0 0 18 18"
version="1.1"
id="svg13"
sodipodi:docname="declined_incoming_call.svg"
inkscape:version="0.92.2 2405546, 2018-03-11">
<metadata
id="metadata17">
<rdf:RDF>
<cc:Work
rdf:about="">
<dc:format>image/svg+xml</dc:format>
<dc:type
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
<dc:title>call_lost</dc:title>
</cc:Work>
</rdf:RDF>
</metadata>
<sodipodi:namedview
pagecolor="#ffffff"
bordercolor="#666666"
borderopacity="1"
objecttolerance="10"
gridtolerance="10"
guidetolerance="10"
inkscape:pageopacity="0"
inkscape:pageshadow="2"
inkscape:window-width="1920"
inkscape:window-height="985"
id="namedview15"
showgrid="false"
inkscape:zoom="6.9532167"
inkscape:cx="1.925277"
inkscape:cy="3.533194"
inkscape:window-x="0"
inkscape:window-y="35"
inkscape:window-maximized="1"
inkscape:current-layer="svg13" />
<!-- Generator: Sketch 40.3 (33839) - http://www.bohemiancoding.com/sketch -->
<title
id="title2">call_lost</title>
<desc
id="desc4">Created with Sketch.</desc>
<defs
id="defs6" />
<g
id="Symbols"
style="fill:none;fill-rule:evenodd;stroke:none;stroke-width:1;stroke-linecap:round"
transform="translate(3,3)">
<g
id="call_lost"
class="color-error-stroke"
style="stroke:#ff0000;stroke-width:2">
<path
d="M 12.985281,5.7440777 H -1.1568543"
id="Line"
transform="rotate(-45,6.266032,5.768485)"
inkscape:connector-curvature="0" />
<path
d="M 11,11 1,1"
id="path9"
inkscape:connector-curvature="0" />
</g>
</svg>
</g>
</svg>

Before

Width:  |  Height:  |  Size: 808 B

After

Width:  |  Height:  |  Size: 2.2 KiB

View file

@ -22,7 +22,7 @@
lcb_define_target("linphoneqt" "linphone" "ms2plugins")
lcb_blacklist_dependencies("libxsd" "soci") # linphone do not need them for the moment.
lcb_blacklist_dependencies("libxsd") # linphone do not need them for the moment.
if (NOT WIN32 AND NOT APPLE)
lcb_blacklist_dependencies("turbo-jpeg") # turbo-jpeg is already provided by Qt5 so do not build it.

View file

@ -332,7 +332,7 @@
<file>ui/modules/Linphone/Contact/Avatar.qml</file>
<file>ui/modules/Linphone/Contact/ContactDescription.qml</file>
<file>ui/modules/Linphone/Contact/Contact.qml</file>
<file>ui/modules/Linphone/Contact/MessagesCounter.qml</file>
<file>ui/modules/Linphone/Contact/MessageCounter.qml</file>
<file>ui/modules/Linphone/Dialog/OnlineInstallerDialog.qml</file>
<file>ui/modules/Linphone/Menus/SipAddressesMenu.qml</file>
<file>ui/modules/Linphone/Notifications/NotificationBasic.qml</file>
@ -358,7 +358,7 @@
<file>ui/modules/Linphone/Styles/Contact/AvatarStyle.qml</file>
<file>ui/modules/Linphone/Styles/Contact/ContactDescriptionStyle.qml</file>
<file>ui/modules/Linphone/Styles/Contact/ContactStyle.qml</file>
<file>ui/modules/Linphone/Styles/Contact/MessagesCounterStyle.qml</file>
<file>ui/modules/Linphone/Styles/Contact/MessageCounterStyle.qml</file>
<file>ui/modules/Linphone/Styles/Dialog/OnlineInstallerDialogStyle.qml</file>
<file>ui/modules/Linphone/Styles/Menus/SipAddressesMenuStyle.qml</file>
<file>ui/modules/Linphone/Styles/Notifications/NotificationBasicStyle.qml</file>

View file

@ -87,22 +87,22 @@ private:
using LogLevel = linphone::LogLevel;
const char *format;
switch (level) {
case LogLevel::LogLevelDebug:
case LogLevel::Debug:
format = GREEN "[%s][Debug]" YELLOW "Core:%s: " RESET "%s\n";
break;
case LogLevel::LogLevelTrace:
case LogLevel::Trace:
format = BLUE "[%s][Trace]" YELLOW "Core:%s: " RESET "%s\n";
break;
case LogLevel::LogLevelMessage:
case LogLevel::Message:
format = BLUE "[%s][Info]" YELLOW "Core:%s: " RESET "%s\n";
break;
case LogLevel::LogLevelWarning:
case LogLevel::Warning:
format = RED "[%s][Warning]" YELLOW "Core:%s: " RESET "%s\n";
break;
case LogLevel::LogLevelError:
case LogLevel::Error:
format = RED "[%s][Error]" YELLOW "Core:%s: " RESET "%s\n";
break;
case LogLevel::LogLevelFatal:
case LogLevel::Fatal:
format = RED "[%s][Fatal]" YELLOW "Core:%s: " RESET "%s\n";
break;
}
@ -115,7 +115,7 @@ private:
message.c_str()
);
if (level == LogLevel::LogLevelFatal)
if (level == LogLevel::Fatal)
terminate();
};
@ -183,8 +183,8 @@ void Logger::log (QtMsgType type, const QMessageLogContext &context, const QStri
void Logger::enable (bool status) {
linphone::Core::enableLogCollection(
status
? linphone::LogCollectionStateEnabled
: linphone::LogCollectionStateDisabled
? linphone::LogCollectionState::Enabled
: linphone::LogCollectionState::Disabled
);
}
@ -201,7 +201,7 @@ void Logger::init (const shared_ptr<linphone::Config> &config) {
{
shared_ptr<linphone::LoggingService> loggingService = mInstance->mLoggingService = linphone::LoggingService::get();
loggingService->setLogLevel(linphone::LogLevel::LogLevelMessage);
loggingService->setLogLevel(linphone::LogLevel::Message);
loggingService->setListener(make_shared<LinphoneLogger>(mInstance));
}

View file

@ -52,15 +52,15 @@ private:
void onCreateAccount (
const shared_ptr<linphone::AccountCreator> &,
linphone::AccountCreatorStatus status,
linphone::AccountCreator::Status status,
const string &
) override {
if (status == linphone::AccountCreatorStatusAccountCreated)
if (status == linphone::AccountCreator::Status::AccountCreated)
emit mAssistant->createStatusChanged(QString(""));
else {
if (status == linphone::AccountCreatorStatusRequestFailed)
if (status == linphone::AccountCreator::Status::RequestFailed)
emit mAssistant->createStatusChanged(tr("requestFailed"));
else if (status == linphone::AccountCreatorStatusServerError)
else if (status == linphone::AccountCreator::Status::ServerError)
emit mAssistant->createStatusChanged(tr("cannotSendSms"));
else
emit mAssistant->createStatusChanged(tr("accountAlreadyExists"));
@ -69,14 +69,14 @@ private:
void onIsAccountExist (
const shared_ptr<linphone::AccountCreator> &creator,
linphone::AccountCreatorStatus status,
linphone::AccountCreator::Status status,
const string &
) override {
if (status == linphone::AccountCreatorStatusAccountExist || status == linphone::AccountCreatorStatusAccountExistWithAlias) {
if (status == linphone::AccountCreator::Status::AccountExist || status == linphone::AccountCreator::Status::AccountExistWithAlias) {
createProxyConfig(creator);
emit mAssistant->loginStatusChanged(QString(""));
} else {
if (status == linphone::AccountCreatorStatusRequestFailed)
if (status == linphone::AccountCreator::Status::RequestFailed)
emit mAssistant->loginStatusChanged(tr("requestFailed"));
else
emit mAssistant->loginStatusChanged(tr("loginWithUsernameFailed"));
@ -85,19 +85,19 @@ private:
void onActivateAccount (
const shared_ptr<linphone::AccountCreator> &creator,
linphone::AccountCreatorStatus status,
linphone::AccountCreator::Status status,
const string &
) override {
if (
status == linphone::AccountCreatorStatusAccountActivated ||
status == linphone::AccountCreatorStatusAccountAlreadyActivated
status == linphone::AccountCreator::Status::AccountActivated ||
status == linphone::AccountCreator::Status::AccountAlreadyActivated
) {
if (creator->getEmail().empty())
createProxyConfig(creator);
emit mAssistant->activateStatusChanged(QString(""));
} else {
if (status == linphone::AccountCreatorStatusRequestFailed)
if (status == linphone::AccountCreator::Status::RequestFailed)
emit mAssistant->activateStatusChanged(tr("requestFailed"));
else
emit mAssistant->activateStatusChanged(tr("smsActivationFailed"));
@ -106,14 +106,14 @@ private:
void onIsAccountActivated (
const shared_ptr<linphone::AccountCreator> &creator,
linphone::AccountCreatorStatus status,
linphone::AccountCreator::Status status,
const string &
) override {
if (status == linphone::AccountCreatorStatusAccountActivated) {
if (status == linphone::AccountCreator::Status::AccountActivated) {
createProxyConfig(creator);
emit mAssistant->activateStatusChanged(QString(""));
} else {
if (status == linphone::AccountCreatorStatusRequestFailed)
if (status == linphone::AccountCreator::Status::RequestFailed)
emit mAssistant->activateStatusChanged(tr("requestFailed"));
else
emit mAssistant->activateStatusChanged(tr("emailActivationFailed"));
@ -122,15 +122,15 @@ private:
void onRecoverAccount (
const shared_ptr<linphone::AccountCreator> &,
linphone::AccountCreatorStatus status,
linphone::AccountCreator::Status status,
const string &
) override {
if (status == linphone::AccountCreatorStatusRequestOk) {
if (status == linphone::AccountCreator::Status::RequestOk) {
emit mAssistant->recoverStatusChanged(QString(""));
} else {
if (status == linphone::AccountCreatorStatusRequestFailed)
if (status == linphone::AccountCreator::Status::RequestFailed)
emit mAssistant->recoverStatusChanged(tr("requestFailed"));
else if (status == linphone::AccountCreatorStatusServerError)
else if (status == linphone::AccountCreator::Status::ServerError)
emit mAssistant->recoverStatusChanged(tr("cannotSendSms"));
else
emit mAssistant->recoverStatusChanged(tr("loginWithPhoneNumberFailed"));
@ -268,12 +268,12 @@ void AssistantModel::setEmail (const QString &email) {
QString error;
switch (mAccountCreator->setEmail(Utils::appStringToCoreString(email))) {
case linphone::AccountCreatorEmailStatusOk:
case linphone::AccountCreator::EmailStatus::Ok:
break;
case linphone::AccountCreatorEmailStatusMalformed:
case linphone::AccountCreator::EmailStatus::Malformed:
error = tr("emailStatusMalformed");
break;
case linphone::AccountCreatorEmailStatusInvalidCharacters:
case linphone::AccountCreator::EmailStatus::InvalidCharacters:
error = tr("emailStatusMalformedInvalidCharacters");
break;
}
@ -292,19 +292,19 @@ void AssistantModel::setPassword (const QString &password) {
QString error;
switch (mAccountCreator->setPassword(Utils::appStringToCoreString(password))) {
case linphone::AccountCreatorPasswordStatusOk:
case linphone::AccountCreator::PasswordStatus::Ok:
break;
case linphone::AccountCreatorPasswordStatusTooShort:
case linphone::AccountCreator::PasswordStatus::TooShort:
error = tr("passwordStatusTooShort").arg(config->getInt("assistant", "password_min_length", 1));
break;
case linphone::AccountCreatorPasswordStatusTooLong:
case linphone::AccountCreator::PasswordStatus::TooLong:
error = tr("passwordStatusTooLong").arg(config->getInt("assistant", "password_max_length", -1));
break;
case linphone::AccountCreatorPasswordStatusInvalidCharacters:
case linphone::AccountCreator::PasswordStatus::InvalidCharacters:
error = tr("passwordStatusInvalidCharacters")
.arg(Utils::coreStringToAppString(config->getString("assistant", "password_regex", "")));
break;
case linphone::AccountCreatorPasswordStatusMissingCharacters:
case linphone::AccountCreator::PasswordStatus::MissingCharacters:
error = tr("passwordStatusMissingCharacters")
.arg(Utils::coreStringToAppString(config->getString("assistant", "missing_characters", "")));
break;
@ -334,19 +334,21 @@ void AssistantModel::setPhoneNumber (const QString &phoneNumber) {
shared_ptr<linphone::Config> config = CoreManager::getInstance()->getCore()->getConfig();
QString error;
switch (mAccountCreator->setPhoneNumber(Utils::appStringToCoreString(phoneNumber), Utils::appStringToCoreString(mCountryCode))) {
case linphone::AccountCreatorPhoneNumberStatusOk:
switch (static_cast<linphone::AccountCreator::PhoneNumberStatus>(
mAccountCreator->setPhoneNumber(Utils::appStringToCoreString(phoneNumber), Utils::appStringToCoreString(mCountryCode))
)) {
case linphone::AccountCreator::PhoneNumberStatus::Ok:
break;
case linphone::AccountCreatorPhoneNumberStatusInvalid:
case linphone::AccountCreator::PhoneNumberStatus::Invalid:
error = tr("phoneNumberStatusInvalid");
break;
case linphone::AccountCreatorPhoneNumberStatusTooShort:
case linphone::AccountCreator::PhoneNumberStatus::TooShort:
error = tr("phoneNumberStatusTooShort");
break;
case linphone::AccountCreatorPhoneNumberStatusTooLong:
case linphone::AccountCreator::PhoneNumberStatus::TooLong:
error = tr("phoneNumberStatusTooLong");
break;
case linphone::AccountCreatorPhoneNumberStatusInvalidCountryCode:
case linphone::AccountCreator::PhoneNumberStatus::InvalidCountryCode:
error = tr("phoneNumberStatusInvalidCountryCode");
break;
default:
@ -418,24 +420,24 @@ void AssistantModel::setConfigFilename (const QString &configFilename) {
// -----------------------------------------------------------------------------
QString AssistantModel::mapAccountCreatorUsernameStatusToString (linphone::AccountCreatorUsernameStatus status) const {
QString AssistantModel::mapAccountCreatorUsernameStatusToString (linphone::AccountCreator::UsernameStatus status) const {
shared_ptr<linphone::Config> config = CoreManager::getInstance()->getCore()->getConfig();
QString error;
switch (status) {
case linphone::AccountCreatorUsernameStatusOk:
case linphone::AccountCreator::UsernameStatus::Ok:
break;
case linphone::AccountCreatorUsernameStatusTooShort:
case linphone::AccountCreator::UsernameStatus::TooShort:
error = tr("usernameStatusTooShort").arg(config->getInt("assistant", "username_min_length", 1));
break;
case linphone::AccountCreatorUsernameStatusTooLong:
case linphone::AccountCreator::UsernameStatus::TooLong:
error = tr("usernameStatusTooLong").arg(config->getInt("assistant", "username_max_length", -1));
break;
case linphone::AccountCreatorUsernameStatusInvalidCharacters:
case linphone::AccountCreator::UsernameStatus::InvalidCharacters:
error = tr("usernameStatusInvalidCharacters")
.arg(Utils::coreStringToAppString(config->getString("assistant", "username_regex", "")));
break;
case linphone::AccountCreatorUsernameStatusInvalid:
case linphone::AccountCreator::UsernameStatus::Invalid:
error = tr("usernameStatusInvalid");
break;
}

View file

@ -94,7 +94,7 @@ private:
QString getConfigFilename () const;
void setConfigFilename (const QString &configFilename);
QString mapAccountCreatorUsernameStatusToString (linphone::AccountCreatorUsernameStatus status) const;
QString mapAccountCreatorUsernameStatusToString (linphone::AccountCreator::UsernameStatus status) const;
QString mCountryCode;
QString mConfigFilename;

View file

@ -87,10 +87,14 @@ CallModel::~CallModel () {
// -----------------------------------------------------------------------------
QString CallModel::getSipAddress () const {
QString CallModel::getPeerAddress () const {
return Utils::coreStringToAppString(mCall->getRemoteAddress()->asString());
}
QString CallModel::getLocalAddress () const {
return Utils::coreStringToAppString(mCall->getCallLog()->getFromAddress()->asString());
}
// -----------------------------------------------------------------------------
void CallModel::setRecordFile (const shared_ptr<linphone::CallParams> &callParams) {
@ -119,14 +123,14 @@ void CallModel::setRecordFile (const shared_ptr<linphone::CallParams> &callParam
void CallModel::updateStats (const shared_ptr<const linphone::CallStats> &callStats) {
switch (callStats->getType()) {
case linphone::StreamTypeText:
case linphone::StreamTypeUnknown:
case linphone::StreamType::Text:
case linphone::StreamType::Unknown:
break;
case linphone::StreamTypeAudio:
case linphone::StreamType::Audio:
updateStats(callStats, mAudioStats);
break;
case linphone::StreamTypeVideo:
case linphone::StreamType::Video:
updateStats(callStats, mVideoStats);
break;
}
@ -262,64 +266,64 @@ void CallModel::handleCallEncryptionChanged (const shared_ptr<linphone::Call> &c
emit securityUpdated();
}
void CallModel::handleCallStateChanged (const shared_ptr<linphone::Call> &call, linphone::CallState state) {
void CallModel::handleCallStateChanged (const shared_ptr<linphone::Call> &call, linphone::Call::State state) {
if (call != mCall)
return;
updateIsInConference();
switch (state) {
case linphone::CallStateError:
case linphone::CallStateEnd:
case linphone::Call::State::Error:
case linphone::Call::State::End:
setCallErrorFromReason(call->getReason());
stopAutoAnswerTimer();
stopRecording();
mPausedByRemote = false;
break;
case linphone::CallStateStreamsRunning:
case linphone::Call::State::StreamsRunning:
if (!mWasConnected && CoreManager::getInstance()->getSettingsModel()->getAutomaticallyRecordCalls()) {
startRecording();
mWasConnected = true;
} UTILS_NO_BREAK;
case linphone::CallStateConnected:
case linphone::CallStateRefered:
case linphone::CallStateReleased:
case linphone::Call::State::Connected:
case linphone::Call::State::Referred:
case linphone::Call::State::Released:
mPausedByRemote = false;
break;
case linphone::CallStatePausedByRemote:
case linphone::Call::State::PausedByRemote:
mNotifyCameraFirstFrameReceived = true;
mPausedByRemote = true;
break;
case linphone::CallStatePausing:
case linphone::Call::State::Pausing:
mNotifyCameraFirstFrameReceived = true;
mPausedByUser = true;
break;
case linphone::CallStateResuming:
case linphone::Call::State::Resuming:
mPausedByUser = false;
break;
case linphone::CallStateUpdatedByRemote:
case linphone::Call::State::UpdatedByRemote:
if (!mCall->getCurrentParams()->videoEnabled() && mCall->getRemoteParams()->videoEnabled()) {
mCall->deferUpdate();
emit videoRequested();
}
break;
case linphone::CallStateIdle:
case linphone::CallStateIncomingReceived:
case linphone::CallStateOutgoingInit:
case linphone::CallStateOutgoingProgress:
case linphone::CallStateOutgoingRinging:
case linphone::CallStateOutgoingEarlyMedia:
case linphone::CallStatePaused:
case linphone::CallStateIncomingEarlyMedia:
case linphone::CallStateUpdating:
case linphone::CallStateEarlyUpdatedByRemote:
case linphone::CallStateEarlyUpdating:
case linphone::Call::State::Idle:
case linphone::Call::State::IncomingReceived:
case linphone::Call::State::OutgoingInit:
case linphone::Call::State::OutgoingProgress:
case linphone::Call::State::OutgoingRinging:
case linphone::Call::State::OutgoingEarlyMedia:
case linphone::Call::State::Paused:
case linphone::Call::State::IncomingEarlyMedia:
case linphone::Call::State::Updating:
case linphone::Call::State::EarlyUpdatedByRemote:
case linphone::Call::State::EarlyUpdating:
break;
}
@ -372,39 +376,39 @@ void CallModel::stopAutoAnswerTimer () const {
CallModel::CallStatus CallModel::getStatus () const {
switch (mCall->getState()) {
case linphone::CallStateConnected:
case linphone::CallStateStreamsRunning:
case linphone::Call::State::Connected:
case linphone::Call::State::StreamsRunning:
return CallStatusConnected;
case linphone::CallStateEnd:
case linphone::CallStateError:
case linphone::CallStateRefered:
case linphone::CallStateReleased:
case linphone::Call::State::End:
case linphone::Call::State::Error:
case linphone::Call::State::Referred:
case linphone::Call::State::Released:
return CallStatusEnded;
case linphone::CallStatePaused:
case linphone::CallStatePausedByRemote:
case linphone::CallStatePausing:
case linphone::CallStateResuming:
case linphone::Call::State::Paused:
case linphone::Call::State::PausedByRemote:
case linphone::Call::State::Pausing:
case linphone::Call::State::Resuming:
return CallStatusPaused;
case linphone::CallStateUpdating:
case linphone::CallStateUpdatedByRemote:
case linphone::Call::State::Updating:
case linphone::Call::State::UpdatedByRemote:
return mPausedByRemote ? CallStatusPaused : CallStatusConnected;
case linphone::CallStateEarlyUpdatedByRemote:
case linphone::CallStateEarlyUpdating:
case linphone::CallStateIdle:
case linphone::CallStateIncomingEarlyMedia:
case linphone::CallStateIncomingReceived:
case linphone::CallStateOutgoingEarlyMedia:
case linphone::CallStateOutgoingInit:
case linphone::CallStateOutgoingProgress:
case linphone::CallStateOutgoingRinging:
case linphone::Call::State::EarlyUpdatedByRemote:
case linphone::Call::State::EarlyUpdating:
case linphone::Call::State::Idle:
case linphone::Call::State::IncomingEarlyMedia:
case linphone::Call::State::IncomingReceived:
case linphone::Call::State::OutgoingEarlyMedia:
case linphone::Call::State::OutgoingInit:
case linphone::Call::State::OutgoingProgress:
case linphone::Call::State::OutgoingRinging:
break;
}
return mCall->getDir() == linphone::CallDirIncoming ? CallStatusIncoming : CallStatusOutgoing;
return mCall->getDir() == linphone::Call::Dir::Incoming ? CallStatusIncoming : CallStatusOutgoing;
}
// -----------------------------------------------------------------------------
@ -430,16 +434,16 @@ QString CallModel::getCallError () const {
void CallModel::setCallErrorFromReason (linphone::Reason reason) {
switch (reason) {
case linphone::ReasonDeclined:
case linphone::Reason::Declined:
mCallError = tr("callErrorDeclined");
break;
case linphone::ReasonNotFound:
case linphone::Reason::NotFound:
mCallError = tr("callErrorNotFound");
break;
case linphone::ReasonBusy:
case linphone::Reason::Busy:
mCallError = tr("callErrorBusy");
break;
case linphone::ReasonNotAcceptable:
case linphone::Reason::NotAcceptable:
mCallError = tr("callErrorNotAcceptable");
break;
default:
@ -507,10 +511,10 @@ bool CallModel::getPausedByUser () const {
void CallModel::setPausedByUser (bool status) {
switch (mCall->getState()) {
case linphone::CallStateConnected:
case linphone::CallStateStreamsRunning:
case linphone::CallStatePaused:
case linphone::CallStatePausedByRemote:
case linphone::Call::State::Connected:
case linphone::Call::State::StreamsRunning:
case linphone::Call::State::Paused:
case linphone::Call::State::PausedByRemote:
break;
default: return;
}
@ -540,8 +544,8 @@ void CallModel::setVideoEnabled (bool status) {
}
switch (mCall->getState()) {
case linphone::CallStateConnected:
case linphone::CallStateStreamsRunning:
case linphone::Call::State::Connected:
case linphone::Call::State::StreamsRunning:
break;
default: return;
}
@ -559,10 +563,10 @@ void CallModel::setVideoEnabled (bool status) {
bool CallModel::getUpdating () const {
switch (mCall->getState()) {
case linphone::CallStateConnected:
case linphone::CallStateStreamsRunning:
case linphone::CallStatePaused:
case linphone::CallStatePausedByRemote:
case linphone::Call::State::Connected:
case linphone::Call::State::StreamsRunning:
case linphone::Call::State::Paused:
case linphone::Call::State::PausedByRemote:
return false;
default:
@ -602,33 +606,33 @@ bool CallModel::isSecured () const {
shared_ptr<const linphone::CallParams> params = mCall->getCurrentParams();
linphone::MediaEncryption encryption = params->getMediaEncryption();
return (
encryption == linphone::MediaEncryptionZRTP && mCall->getAuthenticationTokenVerified()
) || encryption == linphone::MediaEncryptionSRTP || encryption == linphone::MediaEncryptionDTLS;
encryption == linphone::MediaEncryption::ZRTP && mCall->getAuthenticationTokenVerified()
) || encryption == linphone::MediaEncryption::SRTP || encryption == linphone::MediaEncryption::DTLS;
}
// -----------------------------------------------------------------------------
QString CallModel::getLocalSas () const {
QString token = Utils::coreStringToAppString(mCall->getAuthenticationToken());
return mCall->getDir() == linphone::CallDirIncoming ? token.left(2).toUpper() : token.right(2).toUpper();
return mCall->getDir() == linphone::Call::Dir::Incoming ? token.left(2).toUpper() : token.right(2).toUpper();
}
QString CallModel::getRemoteSas () const {
QString token = Utils::coreStringToAppString(mCall->getAuthenticationToken());
return mCall->getDir() != linphone::CallDirIncoming ? token.left(2).toUpper() : token.right(2).toUpper();
return mCall->getDir() != linphone::Call::Dir::Incoming ? token.left(2).toUpper() : token.right(2).toUpper();
}
// -----------------------------------------------------------------------------
QString CallModel::getSecuredString () const {
switch (mCall->getCurrentParams()->getMediaEncryption()) {
case linphone::MediaEncryptionSRTP:
case linphone::MediaEncryption::SRTP:
return QStringLiteral("SRTP");
case linphone::MediaEncryptionZRTP:
case linphone::MediaEncryption::ZRTP:
return QStringLiteral("ZRTP");
case linphone::MediaEncryptionDTLS:
case linphone::MediaEncryption::DTLS:
return QStringLiteral("DTLS");
case linphone::MediaEncryptionNone:
case linphone::MediaEncryption::None:
break;
}
@ -659,10 +663,10 @@ void CallModel::updateStats (const shared_ptr<const linphone::CallStats> &callSt
shared_ptr<const linphone::PayloadType> payloadType;
switch (callStats->getType()) {
case linphone::StreamTypeAudio:
case linphone::StreamType::Audio:
payloadType = params->getUsedAudioPayloadType();
break;
case linphone::StreamTypeVideo:
case linphone::StreamType::Video:
payloadType = params->getUsedVideoPayloadType();
break;
default:
@ -671,10 +675,10 @@ void CallModel::updateStats (const shared_ptr<const linphone::CallStats> &callSt
QString family;
switch (callStats->getIpFamilyOfRemote()) {
case linphone::AddressFamilyInet:
case linphone::AddressFamily::Inet:
family = QStringLiteral("IPv4");
break;
case linphone::AddressFamilyInet6:
case linphone::AddressFamily::Inet6:
family = QStringLiteral("IPv6");
break;
default:
@ -695,10 +699,10 @@ void CallModel::updateStats (const shared_ptr<const linphone::CallStats> &callSt
statsList << createStat(tr("callStatsReceiverLossRate"), QStringLiteral("%1 %").arg(callStats->getReceiverLossRate()));
switch (callStats->getType()) {
case linphone::StreamTypeAudio:
case linphone::StreamType::Audio:
statsList << createStat(tr("callStatsJitterBuffer"), QStringLiteral("%1 ms").arg(callStats->getJitterBufferSizeMs()));
break;
case linphone::StreamTypeVideo: {
case linphone::StreamType::Video: {
statsList << createStat(tr("callStatsEstimatedDownloadBandwidth"), QStringLiteral("%1 kbits/s").arg(int(callStats->getEstimatedDownloadBandwidth())));
const QString sentVideoDefinitionName = Utils::coreStringToAppString(params->getSentVideoDefinition()->getName());
const QString sentVideoDefinition = QStringLiteral("%1x%2")
@ -731,17 +735,17 @@ void CallModel::updateStats (const shared_ptr<const linphone::CallStats> &callSt
QString CallModel::iceStateToString (linphone::IceState state) const {
switch (state) {
case linphone::IceStateNotActivated:
case linphone::IceState::NotActivated:
return tr("iceStateNotActivated");
case linphone::IceStateFailed:
case linphone::IceState::Failed:
return tr("iceStateFailed");
case linphone::IceStateInProgress:
case linphone::IceState::InProgress:
return tr("iceStateInProgress");
case linphone::IceStateReflexiveConnection:
case linphone::IceState::ReflexiveConnection:
return tr("iceStateReflexiveConnection");
case linphone::IceStateHostConnection:
case linphone::IceState::HostConnection:
return tr("iceStateHostConnection");
case linphone::IceStateRelayConnection:
case linphone::IceState::RelayConnection:
return tr("iceStateRelayConnection");
}

View file

@ -31,7 +31,9 @@
class CallModel : public QObject {
Q_OBJECT;
Q_PROPERTY(QString sipAddress READ getSipAddress CONSTANT);
Q_PROPERTY(QString peerAddress READ getPeerAddress CONSTANT);
Q_PROPERTY(QString localAddress READ getLocalAddress CONSTANT);
Q_PROPERTY(CallStatus status READ getStatus NOTIFY statusChanged);
Q_PROPERTY(QString callError READ getCallError NOTIFY callErrorChanged);
@ -77,10 +79,10 @@ public:
Q_ENUM(CallStatus);
enum CallEncryption {
CallEncryptionNone = linphone::MediaEncryptionNone,
CallEncryptionDtls = linphone::MediaEncryptionDTLS,
CallEncryptionSrtp = linphone::MediaEncryptionSRTP,
CallEncryptionZrtp = linphone::MediaEncryptionZRTP
CallEncryptionNone = int(linphone::MediaEncryption::None),
CallEncryptionDtls = int(linphone::MediaEncryption::DTLS),
CallEncryptionSrtp = int(linphone::MediaEncryption::SRTP),
CallEncryptionZrtp = int(linphone::MediaEncryption::ZRTP)
};
Q_ENUM(CallEncryption);
@ -91,7 +93,8 @@ public:
return mCall;
}
QString getSipAddress () const;
QString getPeerAddress () const;
QString getLocalAddress () const;
bool isInConference () const {
return mIsInConference;
@ -140,7 +143,7 @@ signals:
private:
void handleCallEncryptionChanged (const std::shared_ptr<linphone::Call> &call);
void handleCallStateChanged (const std::shared_ptr<linphone::Call> &call, linphone::CallState state);
void handleCallStateChanged (const std::shared_ptr<linphone::Call> &call, linphone::Call::State state);
void accept (bool withVideo);
@ -149,7 +152,7 @@ private:
CallStatus getStatus () const;
bool isOutgoing () const {
return mCall->getDir() == linphone::CallDirOutgoing;
return mCall->getDir() == linphone::Call::Dir::Outgoing;
}
void updateIsInConference ();

View file

@ -179,23 +179,23 @@ static void joinConference (const shared_ptr<linphone::Call> &call) {
addModel->update();
}
void CallsListModel::handleCallStateChanged (const shared_ptr<linphone::Call> &call, linphone::CallState state) {
void CallsListModel::handleCallStateChanged (const shared_ptr<linphone::Call> &call, linphone::Call::State state) {
switch (state) {
case linphone::CallStateIncomingReceived:
case linphone::Call::State::IncomingReceived:
addCall(call);
joinConference(call);
break;
case linphone::CallStateOutgoingInit:
case linphone::Call::State::OutgoingInit:
addCall(call);
break;
case linphone::CallStateEnd:
case linphone::CallStateError:
case linphone::Call::State::End:
case linphone::Call::State::Error:
removeCall(call);
break;
case linphone::CallStateStreamsRunning: {
case linphone::Call::State::StreamsRunning: {
int index = findCallIndex(mList, call);
emit callRunning(index, &call->getData<CallModel>("call-model"));
} break;
@ -228,7 +228,7 @@ bool CallsListModel::removeRows (int row, int count, const QModelIndex &parent)
// -----------------------------------------------------------------------------
void CallsListModel::addCall (const shared_ptr<linphone::Call> &call) {
if (call->getDir() == linphone::CallDirOutgoing) {
if (call->getDir() == linphone::Call::Dir::Outgoing) {
QQuickWindow *callsWindow = App::getInstance()->getCallsWindow();
if (callsWindow) {
if (CoreManager::getInstance()->getSettingsModel()->getKeepCallsWindowInBackground()) {

View file

@ -59,7 +59,7 @@ private:
bool removeRow (int row, const QModelIndex &parent = QModelIndex());
bool removeRows (int row, int count, const QModelIndex &parent = QModelIndex()) override;
void handleCallStateChanged (const std::shared_ptr<linphone::Call> &call, linphone::CallState state);
void handleCallStateChanged (const std::shared_ptr<linphone::Call> &call, linphone::Call::State state);
void addCall (const std::shared_ptr<linphone::Call> &call);
void removeCall (const std::shared_ptr<linphone::Call> &call);

View file

@ -178,7 +178,7 @@ private:
signalDataChanged(it);
}
void onMsgStateChanged (const shared_ptr<linphone::ChatMessage> &message, linphone::ChatMessageState state) override {
void onMsgStateChanged (const shared_ptr<linphone::ChatMessage> &message, linphone::ChatMessage::State state) override {
if (!mChatModel)
return;
@ -187,7 +187,7 @@ private:
return;
// File message downloaded.
if (state == linphone::ChatMessageStateFileTransferDone && !message->isOutgoing()) {
if (state == linphone::ChatMessage::State::FileTransferDone && !message->isOutgoing()) {
createThumbnail(message);
fillThumbnailProperty((*it).first, message);
@ -199,7 +199,7 @@ private:
App::getInstance()->getNotifier()->notifyReceivedFileMessage(message);
}
(*it).first["status"] = state;
(*it).first["status"] = static_cast<MessageStatus>(state);
signalDataChanged(it);
}
@ -209,13 +209,13 @@ private:
// -----------------------------------------------------------------------------
ChatModel::ChatModel (const QString &sipAddress) {
ChatModel::ChatModel (const QString &peerAddress, const QString &localAddress) {
CoreManager *coreManager = CoreManager::getInstance();
mCoreHandlers = coreManager->getHandlers();
mMessageHandlers = make_shared<MessageHandlers>(this);
setSipAddress(sipAddress);
setSipAddresses(peerAddress, localAddress);
{
CoreHandlers *coreHandlers = mCoreHandlers.get();
@ -283,17 +283,27 @@ bool ChatModel::removeRows (int row, int count, const QModelIndex &parent) {
return true;
}
QString ChatModel::getSipAddress () const {
QString ChatModel::getPeerAddress () const {
return Utils::coreStringToAppString(
mChatRoom->getPeerAddress()->asStringUriOnly()
);
}
void ChatModel::setSipAddress (const QString &sipAddress) {
shared_ptr<linphone::Core> core = CoreManager::getInstance()->getCore();
QString ChatModel::getLocalAddress () const {
return Utils::coreStringToAppString(
mChatRoom->getLocalAddress()->asStringUriOnly()
);
}
mChatRoom = core->getChatRoomFromUri(Utils::appStringToCoreString(sipAddress));
Q_CHECK_PTR(mChatRoom.get());
void ChatModel::setSipAddresses (const QString &peerAddress, const QString &localAddress) {
shared_ptr<linphone::Core> core = CoreManager::getInstance()->getCore();
shared_ptr<linphone::Factory> factory(linphone::Factory::get());
mChatRoom = core->getChatRoom(
factory->createAddress(Utils::appStringToCoreString(peerAddress)),
factory->createAddress(Utils::appStringToCoreString(localAddress))
);
Q_ASSERT(mChatRoom);
handleIsComposingChanged(mChatRoom);
@ -306,15 +316,17 @@ void ChatModel::setSipAddress (const QString &sipAddress) {
// Old workaround.
// It can exist messages with a not delivered status. It's a linphone core bug.
if (message->getState() == linphone::ChatMessageStateInProgress)
map["status"] = linphone::ChatMessageStateNotDelivered;
if (message->getState() == linphone::ChatMessage::State::InProgress)
map["status"] = MessageStatusNotDelivered;
mEntries << qMakePair(map, static_pointer_cast<void>(message));
}
// Get calls.
// TODO: Add an API to find with local and peer addresses.
for (auto &callLog : core->getCallHistoryForAddress(mChatRoom->getPeerAddress()))
insertCall(callLog);
if (mChatRoom->getLocalAddress()->weakEqual(callLog->getLocalAddress()))
insertCall(callLog);
}
bool ChatModel::getIsRemoteComposing () const {
@ -324,15 +336,16 @@ bool ChatModel::getIsRemoteComposing () const {
// -----------------------------------------------------------------------------
void ChatModel::removeEntry (int id) {
qInfo() << QStringLiteral("Removing chat entry: %1 of %2.")
.arg(id).arg(getSipAddress());
qInfo() << QStringLiteral("Removing chat entry: %1 of (%2, %3).")
.arg(id).arg(getPeerAddress()).arg(getLocalAddress());
if (!removeRow(id))
qWarning() << QStringLiteral("Unable to remove chat entry: %1").arg(id);
}
void ChatModel::removeAllEntries () {
qInfo() << QStringLiteral("Removing all chat entries of: %1.").arg(getSipAddress());
qInfo() << QStringLiteral("Removing all chat entries of: (%1, %2).")
.arg(getPeerAddress()).arg(getLocalAddress());
beginResetModel();
@ -433,7 +446,7 @@ void ChatModel::downloadFile (int id) {
shared_ptr<linphone::ChatMessage> message = static_pointer_cast<linphone::ChatMessage>(entry.second);
switch (message->getState()) {
switch (static_cast<MessageStatus>(message->getState())) {
case MessageStatusDelivered:
case MessageStatusDeliveredToUser:
case MessageStatusDisplayed:
@ -491,10 +504,10 @@ void ChatModel::compose () {
mChatRoom->compose();
}
void ChatModel::resetMessagesCount () {
void ChatModel::resetMessageCount () {
if (mChatRoom->getUnreadMessagesCount() > 0) {
mChatRoom->markAsRead();
emit messagesCountReset();
emit messageCountReset();
}
}
@ -527,8 +540,8 @@ void ChatModel::fillMessageEntry (QVariantMap &dest, const shared_ptr<linphone::
dest["type"] = EntryType::MessageEntry;
dest["timestamp"] = QDateTime::fromMSecsSinceEpoch(message->getTime() * 1000);
dest["content"] = Utils::coreStringToAppString(message->getText());
dest["isOutgoing"] = message->isOutgoing() || message->getState() == linphone::ChatMessageStateIdle;
dest["status"] = message->getState();
dest["isOutgoing"] = message->isOutgoing() || message->getState() == linphone::ChatMessage::State::Idle;
dest["status"] = static_cast<MessageStatus>(message->getState());
shared_ptr<const linphone::Content> content = message->getFileTransferInformation();
if (content) {
@ -545,8 +558,8 @@ void ChatModel::fillCallStartEntry (QVariantMap &dest, const shared_ptr<linphone
dest["type"] = EntryType::CallEntry;
dest["timestamp"] = timestamp;
dest["isOutgoing"] = callLog->getDir() == linphone::CallDirOutgoing;
dest["status"] = callLog->getStatus();
dest["isOutgoing"] = callLog->getDir() == linphone::Call::Dir::Outgoing;
dest["status"] = static_cast<CallStatus>(callLog->getStatus());
dest["isStart"] = true;
}
@ -555,8 +568,8 @@ void ChatModel::fillCallEndEntry (QVariantMap &dest, const shared_ptr<linphone::
dest["type"] = EntryType::CallEntry;
dest["timestamp"] = timestamp;
dest["isOutgoing"] = callLog->getDir() == linphone::CallDirOutgoing;
dest["status"] = callLog->getStatus();
dest["isOutgoing"] = callLog->getDir() == linphone::Call::Dir::Outgoing;
dest["status"] = static_cast<CallStatus>(callLog->getStatus());
dest["isStart"] = false;
}
@ -574,7 +587,7 @@ void ChatModel::removeEntry (ChatEntryData &entry) {
}
case ChatModel::CallEntry: {
if (entry.first["status"].toInt() == linphone::CallStatusSuccess) {
if (entry.first["status"].toInt() == CallStatusSuccess) {
// WARNING: Unable to remove symmetric call here. (start/end)
// We are between `beginRemoveRows` and `endRemoveRows`.
// A solution is to schedule a `removeEntry` call in the Qt main loop.
@ -599,20 +612,20 @@ void ChatModel::removeEntry (ChatEntryData &entry) {
}
void ChatModel::insertCall (const shared_ptr<linphone::CallLog> &callLog) {
linphone::CallStatus status = callLog->getStatus();
linphone::Call::Status status = callLog->getStatus();
switch (status) {
case linphone::CallStatusAborted:
case linphone::CallStatusEarlyAborted:
case linphone::Call::Status::Aborted:
case linphone::Call::Status::EarlyAborted:
return; // Ignore aborted calls.
case linphone::CallStatusAcceptedElsewhere:
case linphone::CallStatusDeclinedElsewhere:
case linphone::Call::Status::AcceptedElsewhere:
case linphone::Call::Status::DeclinedElsewhere:
return; // Ignore accepted calls on other device.
case linphone::CallStatusSuccess:
case linphone::CallStatusMissed:
case linphone::CallStatusDeclined:
case linphone::Call::Status::Success:
case linphone::Call::Status::Missed:
case linphone::Call::Status::Declined:
break;
}
@ -639,7 +652,7 @@ void ChatModel::insertCall (const shared_ptr<linphone::CallLog> &callLog) {
auto it = insertEntry(qMakePair(start, static_pointer_cast<void>(callLog)));
// Add end call. (if necessary)
if (status == linphone::CallStatusSuccess) {
if (status == linphone::Call::Status::Success) {
QVariantMap end;
fillCallEndEntry(end, callLog);
insertEntry(qMakePair(end, static_pointer_cast<void>(callLog)), &it);
@ -660,10 +673,10 @@ void ChatModel::insertMessageAtEnd (const shared_ptr<linphone::ChatMessage> &mes
// -----------------------------------------------------------------------------
void ChatModel::handleCallStateChanged (const shared_ptr<linphone::Call> &call, linphone::CallState state) {
void ChatModel::handleCallStateChanged (const shared_ptr<linphone::Call> &call, linphone::Call::State state) {
if (
(state == linphone::CallStateEnd || state == linphone::CallStateError) &&
mChatRoom == CoreManager::getInstance()->getCore()->getChatRoom(call->getRemoteAddress())
(state == linphone::Call::State::End || state == linphone::Call::State::Error) &&
mChatRoom == CoreManager::getInstance()->getCore()->findChatRoom(call->getRemoteAddress(), mChatRoom->getLocalAddress())
)
insertCall(call->getCallLog());
}

View file

@ -51,25 +51,25 @@ public:
Q_ENUM(EntryType);
enum CallStatus {
CallStatusDeclined = linphone::CallStatusDeclined,
CallStatusMissed = linphone::CallStatusMissed,
CallStatusSuccess = linphone::CallStatusSuccess
CallStatusDeclined = int(linphone::Call::Status::Declined),
CallStatusMissed = int(linphone::Call::Status::Missed),
CallStatusSuccess = int(linphone::Call::Status::Success)
};
Q_ENUM(CallStatus);
enum MessageStatus {
MessageStatusDelivered = linphone::ChatMessageStateDelivered,
MessageStatusDeliveredToUser = linphone::ChatMessageStateDeliveredToUser,
MessageStatusDisplayed = linphone::ChatMessageStateDisplayed,
MessageStatusFileTransferDone = linphone::ChatMessageStateFileTransferDone,
MessageStatusFileTransferError = linphone::ChatMessageStateFileTransferError,
MessageStatusIdle = linphone::ChatMessageStateIdle,
MessageStatusInProgress = linphone::ChatMessageStateInProgress,
MessageStatusNotDelivered = linphone::ChatMessageStateNotDelivered
MessageStatusDelivered = int(linphone::ChatMessage::State::Delivered),
MessageStatusDeliveredToUser = int(linphone::ChatMessage::State::DeliveredToUser),
MessageStatusDisplayed = int(linphone::ChatMessage::State::Displayed),
MessageStatusFileTransferDone = int(linphone::ChatMessage::State::FileTransferDone),
MessageStatusFileTransferError = int(linphone::ChatMessage::State::FileTransferError),
MessageStatusIdle = int(linphone::ChatMessage::State::Idle),
MessageStatusInProgress = int(linphone::ChatMessage::State::InProgress),
MessageStatusNotDelivered = int(linphone::ChatMessage::State::NotDelivered)
};
Q_ENUM(MessageStatus);
ChatModel (const QString &sipAddress);
ChatModel (const QString &peerAddress, const QString &localAddress);
~ChatModel ();
int rowCount (const QModelIndex &index = QModelIndex()) const override;
@ -80,7 +80,8 @@ public:
bool removeRow (int row, const QModelIndex &parent = QModelIndex());
bool removeRows (int row, int count, const QModelIndex &parent = QModelIndex()) override;
QString getSipAddress () const;
QString getPeerAddress () const;
QString getLocalAddress () const;
bool getIsRemoteComposing () const;
@ -103,7 +104,7 @@ public:
void compose ();
void resetMessagesCount ();
void resetMessageCount ();
signals:
bool isRemoteComposingChanged (bool status);
@ -114,12 +115,12 @@ signals:
void messageSent (const std::shared_ptr<linphone::ChatMessage> &message);
void messageReceived (const std::shared_ptr<linphone::ChatMessage> &message);
void messagesCountReset ();
void messageCountReset ();
private:
typedef QPair<QVariantMap, std::shared_ptr<void>> ChatEntryData;
void setSipAddress (const QString &sipAddress);
void setSipAddresses (const QString &peerAddress, const QString &localAddress);
const ChatEntryData getFileMessageEntry (int id);
@ -132,7 +133,7 @@ private:
void insertCall (const std::shared_ptr<linphone::CallLog> &callLog);
void insertMessageAtEnd (const std::shared_ptr<linphone::ChatMessage> &message);
void handleCallStateChanged (const std::shared_ptr<linphone::Call> &call, linphone::CallState state);
void handleCallStateChanged (const std::shared_ptr<linphone::Call> &call, linphone::Call::State state);
void handleIsComposingChanged (const std::shared_ptr<linphone::ChatRoom> &chatRoom);
void handleMessageReceived (const std::shared_ptr<linphone::ChatMessage> &message);

View file

@ -85,17 +85,17 @@ ChatProxyModel::ChatProxyModel (QObject *parent) : QSortFilterProxyModel(parent)
mChatModel
#define CREATE_PARENT_MODEL_FUNCTION(METHOD) \
void ChatProxyModel::METHOD() { \
void ChatProxyModel::METHOD () { \
GET_CHAT_MODEL()->METHOD(); \
}
#define CREATE_PARENT_MODEL_FUNCTION_WITH_PARAM(METHOD, ARG_TYPE) \
void ChatProxyModel::METHOD(ARG_TYPE value) { \
void ChatProxyModel::METHOD (ARG_TYPE value) { \
GET_CHAT_MODEL()->METHOD(value); \
}
#define CREATE_PARENT_MODEL_FUNCTION_WITH_ID(METHOD) \
void ChatProxyModel::METHOD(int id) { \
void ChatProxyModel::METHOD (int id) { \
QModelIndex sourceIndex = mapToSource(index(id, 0)); \
GET_CHAT_MODEL()->METHOD( \
static_cast<ChatModelFilter *>(sourceModel())->mapToSource(sourceIndex).row() \
@ -156,11 +156,31 @@ bool ChatProxyModel::filterAcceptsRow (int sourceRow, const QModelIndex &) const
// -----------------------------------------------------------------------------
QString ChatProxyModel::getSipAddress () const {
return mChatModel ? mChatModel->getSipAddress() : QString("");
QString ChatProxyModel::getPeerAddress () const {
return mChatModel ? mChatModel->getPeerAddress() : QString("");
}
void ChatProxyModel::setSipAddress (const QString &sipAddress) {
void ChatProxyModel::setPeerAddress (const QString &peerAddress) {
mPeerAddress = peerAddress;
reload();
}
QString ChatProxyModel::getLocalAddress () const {
return mChatModel ? mChatModel->getLocalAddress() : QString("");
}
void ChatProxyModel::setLocalAddress (const QString &localAddress) {
mLocalAddress = localAddress;
reload();
}
bool ChatProxyModel::getIsRemoteComposing () const {
return mChatModel ? mChatModel->getIsRemoteComposing() : false;
}
// -----------------------------------------------------------------------------
void ChatProxyModel::reload () {
mMaxDisplayedEntries = EntriesChunkSize;
if (mChatModel) {
@ -170,10 +190,10 @@ void ChatProxyModel::setSipAddress (const QString &sipAddress) {
QObject::disconnect(chatModel, &ChatModel::messageSent, this, &ChatProxyModel::handleMessageSent);
}
mChatModel = CoreManager::getInstance()->getChatModelFromSipAddress(sipAddress);
mChatModel = CoreManager::getInstance()->getChatModel(mPeerAddress, mLocalAddress);
if (mChatModel) {
mChatModel->resetMessagesCount();
mChatModel->resetMessageCount();
ChatModel *chatModel = mChatModel.get();
QObject::connect(chatModel, &ChatModel::isRemoteComposingChanged, this, &ChatProxyModel::handleIsRemoteComposingChanged);
@ -184,10 +204,6 @@ void ChatProxyModel::setSipAddress (const QString &sipAddress) {
static_cast<ChatModelFilter *>(sourceModel())->setSourceModel(mChatModel.get());
}
bool ChatProxyModel::getIsRemoteComposing () const {
return mChatModel ? mChatModel->getIsRemoteComposing() : false;
}
// -----------------------------------------------------------------------------
static inline QWindow *getParentWindow (QObject *object) {
@ -201,8 +217,8 @@ static inline QWindow *getParentWindow (QObject *object) {
}
void ChatProxyModel::handleIsActiveChanged (QWindow *window) {
if (window->isActive() && getParentWindow(this) == window)
mChatModel->resetMessagesCount();
if (mChatModel && window->isActive() && getParentWindow(this) == window)
mChatModel->resetMessageCount();
}
void ChatProxyModel::handleIsRemoteComposingChanged (bool status) {
@ -214,7 +230,7 @@ void ChatProxyModel::handleMessageReceived (const shared_ptr<linphone::ChatMessa
QWindow *window = getParentWindow(this);
if (window && window->isActive())
mChatModel->resetMessagesCount();
mChatModel->resetMessageCount();
}
void ChatProxyModel::handleMessageSent (const shared_ptr<linphone::ChatMessage> &) {

View file

@ -36,7 +36,8 @@ class ChatProxyModel : public QSortFilterProxyModel {
Q_OBJECT;
Q_PROPERTY(QString sipAddress READ getSipAddress WRITE setSipAddress NOTIFY sipAddressChanged);
Q_PROPERTY(QString peerAddress READ getPeerAddress WRITE setPeerAddress NOTIFY peerAddressChanged);
Q_PROPERTY(QString localAddress READ getLocalAddress WRITE setLocalAddress NOTIFY localAddressChanged);
Q_PROPERTY(bool isRemoteComposing READ getIsRemoteComposing NOTIFY isRemoteComposingChanged);
public:
@ -60,7 +61,8 @@ public:
Q_INVOKABLE void compose ();
signals:
void sipAddressChanged (const QString &sipAddress);
void peerAddressChanged (const QString &peerAddress);
void localAddressChanged (const QString &localAddress);
bool isRemoteComposingChanged (bool status);
void moreEntriesLoaded (int n);
@ -71,11 +73,16 @@ protected:
bool filterAcceptsRow (int sourceRow, const QModelIndex &sourceParent) const override;
private:
QString getSipAddress () const;
void setSipAddress (const QString &sipAddress);
QString getPeerAddress () const;
void setPeerAddress (const QString &peerAddress);
QString getLocalAddress () const;
void setLocalAddress (const QString &localAddress);
bool getIsRemoteComposing () const;
void reload ();
void handleIsActiveChanged (QWindow *window);
void handleIsRemoteComposingChanged (bool status);
@ -84,6 +91,9 @@ private:
int mMaxDisplayedEntries = EntriesChunkSize;
QString mPeerAddress;
QString mLocalAddress;
std::shared_ptr<ChatModel> mChatModel;
static constexpr int EntriesChunkSize = 50;

View file

@ -140,10 +140,7 @@ ContactModel *ContactsListModel::addContact (VcardModel *vcardModel) {
contact = new ContactModel(this, vcardModel);
App::getInstance()->getEngine()->setObjectOwnership(contact, QQmlEngine::CppOwnership);
if (
mLinphoneFriends->addFriend(contact->mLinphoneFriend) !=
linphone::FriendListStatus::FriendListStatusOK
) {
if (mLinphoneFriends->addFriend(contact->mLinphoneFriend) != linphone::FriendList::Status::OK) {
qWarning() << QStringLiteral("Unable to add contact from vcard:") << vcardModel;
delete contact;
return nullptr;

View file

@ -101,14 +101,14 @@ void CoreHandlers::onCallEncryptionChanged (
void CoreHandlers::onCallStateChanged (
const shared_ptr<linphone::Core> &,
const shared_ptr<linphone::Call> &call,
linphone::CallState state,
linphone::Call::State state,
const string &
) {
emit callStateChanged(call, state);
SettingsModel *settingsModel = CoreManager::getInstance()->getSettingsModel();
if (
call->getState() == linphone::CallStateIncomingReceived && (
call->getState() == linphone::Call::State::IncomingReceived && (
!settingsModel->getAutoAnswerStatus() ||
settingsModel->getAutoAnswerDelay() > 0
)
@ -129,7 +129,7 @@ void CoreHandlers::onGlobalStateChanged (
linphone::GlobalState gstate,
const string &
) {
if (gstate == linphone::GlobalStateOn) {
if (gstate == linphone::GlobalState::On) {
mCoreStartedLock->lock();
Q_ASSERT(mCoreStarted == false);
@ -149,7 +149,7 @@ void CoreHandlers::onIsComposingReceived (
void CoreHandlers::onLogCollectionUploadStateChanged (
const shared_ptr<linphone::Core> &,
linphone::CoreLogCollectionUploadState state,
linphone::Core::LogCollectionUploadState state,
const string &info
) {
emit logsUploadStateChanged(state, info);
@ -165,7 +165,7 @@ void CoreHandlers::onLogCollectionUploadProgressIndication (
void CoreHandlers::onMessageReceived (
const shared_ptr<linphone::Core> &core,
const shared_ptr<linphone::ChatRoom> &,
const shared_ptr<linphone::ChatRoom> &chatRoom,
const shared_ptr<linphone::ChatMessage> &message
) {
const string contentType = message->getContentType();
@ -190,7 +190,8 @@ void CoreHandlers::onMessageReceived (
if (
!app->hasFocus() ||
!CoreManager::getInstance()->chatModelExists(
Utils::coreStringToAppString(message->getFromAddress()->asStringUriOnly())
Utils::coreStringToAppString(chatRoom->getPeerAddress()->asStringUriOnly()),
Utils::coreStringToAppString(chatRoom->getLocalAddress()->asStringUriOnly())
)
)
core->playLocal(Utils::appStringToCoreString(settingsModel->getChatNotificationSoundPath()));
@ -227,46 +228,46 @@ void CoreHandlers::onRegistrationStateChanged (
void CoreHandlers::onTransferStateChanged (
const shared_ptr<linphone::Core> &,
const shared_ptr<linphone::Call> &call,
linphone::CallState state
linphone::Call::State state
) {
switch (state) {
case linphone::CallStateEarlyUpdatedByRemote:
case linphone::CallStateEarlyUpdating:
case linphone::CallStateIdle:
case linphone::CallStateIncomingEarlyMedia:
case linphone::CallStateIncomingReceived:
case linphone::CallStateOutgoingEarlyMedia:
case linphone::CallStateOutgoingRinging:
case linphone::CallStatePaused:
case linphone::CallStatePausedByRemote:
case linphone::CallStatePausing:
case linphone::CallStateRefered:
case linphone::CallStateReleased:
case linphone::CallStateResuming:
case linphone::CallStateStreamsRunning:
case linphone::CallStateUpdatedByRemote:
case linphone::CallStateUpdating:
case linphone::Call::State::EarlyUpdatedByRemote:
case linphone::Call::State::EarlyUpdating:
case linphone::Call::State::Idle:
case linphone::Call::State::IncomingEarlyMedia:
case linphone::Call::State::IncomingReceived:
case linphone::Call::State::OutgoingEarlyMedia:
case linphone::Call::State::OutgoingRinging:
case linphone::Call::State::Paused:
case linphone::Call::State::PausedByRemote:
case linphone::Call::State::Pausing:
case linphone::Call::State::Referred:
case linphone::Call::State::Released:
case linphone::Call::State::Resuming:
case linphone::Call::State::StreamsRunning:
case linphone::Call::State::UpdatedByRemote:
case linphone::Call::State::Updating:
break; // Nothing.
// 1. Init.
case linphone::CallStateOutgoingInit:
case linphone::Call::State::OutgoingInit:
qInfo() << QStringLiteral("Call transfer init.");
break;
// 2. In progress.
case linphone::CallStateOutgoingProgress:
case linphone::Call::State::OutgoingProgress:
qInfo() << QStringLiteral("Call transfer in progress.");
break;
// 3. Done.
case linphone::CallStateConnected:
case linphone::Call::State::Connected:
qInfo() << QStringLiteral("Call transfer succeeded.");
emit callTransferSucceeded(call);
break;
// 4. Error.
case linphone::CallStateEnd:
case linphone::CallStateError:
case linphone::Call::State::End:
case linphone::Call::State::Error:
qWarning() << QStringLiteral("Call transfer failed.");
emit callTransferFailed(call);
break;
@ -279,7 +280,7 @@ void CoreHandlers::onVersionUpdateCheckResultReceived (
const string &version,
const string &url
) {
if (result == linphone::VersionUpdateCheckResultNewVersionAvailable)
if (result == linphone::VersionUpdateCheckResult::NewVersionAvailable)
App::getInstance()->getNotifier()->notifyNewVersionAvailable(
Utils::coreStringToAppString(version),
Utils::coreStringToAppString(url)

View file

@ -43,12 +43,12 @@ public:
signals:
void authenticationRequested (const std::shared_ptr<linphone::AuthInfo> &authInfo);
void callEncryptionChanged (const std::shared_ptr<linphone::Call> &call);
void callStateChanged (const std::shared_ptr<linphone::Call> &call, linphone::CallState state);
void callStateChanged (const std::shared_ptr<linphone::Call> &call, linphone::Call::State state);
void callTransferFailed (const std::shared_ptr<linphone::Call> &call);
void callTransferSucceeded (const std::shared_ptr<linphone::Call> &call);
void coreStarted ();
void isComposingChanged (const std::shared_ptr<linphone::ChatRoom> &chatRoom);
void logsUploadStateChanged (linphone::CoreLogCollectionUploadState state, const std::string &info);
void logsUploadStateChanged (linphone::Core::LogCollectionUploadState state, const std::string &info);
void messageReceived (const std::shared_ptr<linphone::ChatMessage> &message);
void presenceReceived (const QString &sipAddress, const std::shared_ptr<const linphone::PresenceModel> &presenceModel);
void registrationStateChanged (const std::shared_ptr<linphone::ProxyConfig> &proxyConfig, linphone::RegistrationState state);
@ -77,7 +77,7 @@ private:
void onCallStateChanged (
const std::shared_ptr<linphone::Core> &core,
const std::shared_ptr<linphone::Call> &call,
linphone::CallState state,
linphone::Call::State state,
const std::string &message
) override;
@ -100,7 +100,7 @@ private:
void onLogCollectionUploadStateChanged (
const std::shared_ptr<linphone::Core> &core,
linphone::CoreLogCollectionUploadState state,
linphone::Core::LogCollectionUploadState state,
const std::string &info
) override;
@ -138,7 +138,7 @@ private:
void onTransferStateChanged (
const std::shared_ptr<linphone::Core> &core,
const std::shared_ptr<linphone::Call> &call,
linphone::CallState state
linphone::Call::State state
) override;
void onVersionUpdateCheckResultReceived (

View file

@ -38,9 +38,9 @@
#include "utils/Utils.hpp"
#if defined(Q_OS_MACOS)
#include "messages-count-notifier/MessagesCountNotifierMacOs.hpp"
#include "messages-count-notifier/MessageCountNotifierMacOs.hpp"
#else
#include "messages-count-notifier/MessagesCountNotifierSystemTrayIcon.hpp"
#include "messages-count-notifier/MessageCountNotifierSystemTrayIcon.hpp"
#endif // if defined(Q_OS_MACOS)
#include "CoreHandlers.hpp"
@ -81,15 +81,16 @@ CoreManager::CoreManager (QObject *parent, const QString &configPath) :
CoreHandlers *coreHandlers = mHandlers.get();
QObject::connect(coreHandlers, &CoreHandlers::coreStarted, this, [] {
// Do not change this order. :) (Or pray.)
mInstance->mCallsListModel = new CallsListModel(mInstance);
mInstance->mContactsListModel = new ContactsListModel(mInstance);
mInstance->mSipAddressesModel = new SipAddressesModel(mInstance);
mInstance->mSettingsModel = new SettingsModel(mInstance);
mInstance->mAccountSettingsModel = new AccountSettingsModel(mInstance);
mInstance->mSettingsModel = new SettingsModel(mInstance);
mInstance->mSipAddressesModel = new SipAddressesModel(mInstance);
{
MessagesCountNotifier *messagesCountNotifier = new MessagesCountNotifier(mInstance);
messagesCountNotifier->updateUnreadMessagesCount();
MessageCountNotifier *messageCountNotifier = new MessageCountNotifier(mInstance);
messageCountNotifier->updateUnreadMessageCount();
}
mInstance->migrate();
@ -108,21 +109,23 @@ CoreManager::CoreManager (QObject *parent, const QString &configPath) :
// -----------------------------------------------------------------------------
shared_ptr<ChatModel> CoreManager::getChatModelFromSipAddress (const QString &sipAddress) {
if (!sipAddress.length())
shared_ptr<ChatModel> CoreManager::getChatModel (const QString &peerAddress, const QString &localAddress) {
if (peerAddress.isEmpty() || localAddress.isEmpty())
return nullptr;
// Create a new chat model.
if (!mChatModels.contains(sipAddress)) {
Q_ASSERT(mCore->createAddress(Utils::appStringToCoreString(sipAddress)) != nullptr);
QPair<QString, QString> chatModelId{ peerAddress, localAddress };
if (!mChatModels.contains(chatModelId)) {
Q_ASSERT(mCore->createAddress(Utils::appStringToCoreString(peerAddress)));
Q_ASSERT(mCore->createAddress(Utils::appStringToCoreString(localAddress)));
auto deleter = [this](ChatModel *chatModel) {
mChatModels.remove(chatModel->getSipAddress());
auto deleter = [this, chatModelId](ChatModel *chatModel) {
mChatModels.remove(chatModelId);
delete chatModel;
};
shared_ptr<ChatModel> chatModel(new ChatModel(sipAddress), deleter);
mChatModels[chatModel->getSipAddress()] = chatModel;
shared_ptr<ChatModel> chatModel(new ChatModel(peerAddress, localAddress), deleter);
mChatModels[chatModelId] = chatModel;
emit chatModelCreated(chatModel);
@ -130,13 +133,13 @@ shared_ptr<ChatModel> CoreManager::getChatModelFromSipAddress (const QString &si
}
// Returns an existing chat model.
shared_ptr<ChatModel> chatModel = mChatModels[sipAddress].lock();
shared_ptr<ChatModel> chatModel = mChatModels[chatModelId].lock();
Q_CHECK_PTR(chatModel.get());
return chatModel;
}
bool CoreManager::chatModelExists (const QString &sipAddress) {
return mChatModels.contains(sipAddress);
bool CoreManager::chatModelExists (const QString &peerAddress, const QString &localAddress) {
return mChatModels.contains({ peerAddress, localAddress });
}
// -----------------------------------------------------------------------------
@ -204,7 +207,6 @@ void CoreManager::cleanLogs () const {
void CoreManager::setDatabasesPaths () {
SET_DATABASE_PATH(Friends, Paths::getFriendsListFilePath());
SET_DATABASE_PATH(CallLogs, Paths::getCallHistoryFilePath());
SET_DATABASE_PATH(Chat, Paths::getMessageHistoryFilePath());
}
#undef SET_DATABASE_PATH
@ -237,10 +239,11 @@ void CoreManager::createLinphoneCore (const QString &configPath) {
setResourcesPaths();
mCore = linphone::Factory::get()->createCore(
mHandlers,
Paths::getConfigFilePath(configPath),
Paths::getFactoryConfigFilePath()
Paths::getFactoryConfigFilePath(),
nullptr
);
mCore->addListener(mHandlers);
mCore->setVideoDisplayFilter("MSOGL");
mCore->usePreviewWindow(true);
@ -258,6 +261,8 @@ void CoreManager::createLinphoneCore (const QString &configPath) {
config->setInt("video", "display", 1);
}
mCore->start();
setDatabasesPaths();
setOtherPaths();
}
@ -303,13 +308,13 @@ void CoreManager::iterate () {
// -----------------------------------------------------------------------------
void CoreManager::handleLogsUploadStateChanged (linphone::CoreLogCollectionUploadState state, const string &info) {
void CoreManager::handleLogsUploadStateChanged (linphone::Core::LogCollectionUploadState state, const string &info) {
switch (state) {
case linphone::CoreLogCollectionUploadStateInProgress:
case linphone::Core::LogCollectionUploadState::InProgress:
break;
case linphone::CoreLogCollectionUploadStateDelivered:
case linphone::CoreLogCollectionUploadStateNotDelivered:
case linphone::Core::LogCollectionUploadState::Delivered:
case linphone::Core::LogCollectionUploadState::NotDelivered:
emit logsUploaded(Utils::coreStringToAppString(info));
break;
}

View file

@ -60,8 +60,8 @@ public:
return mHandlers;
}
std::shared_ptr<ChatModel> getChatModelFromSipAddress (const QString &sipAddress);
bool chatModelExists (const QString &sipAddress);
std::shared_ptr<ChatModel> getChatModel (const QString &peerAddress, const QString &localAddress);
bool chatModelExists (const QString &sipAddress, const QString &localAddress);
// ---------------------------------------------------------------------------
// Video render lock.
@ -149,7 +149,7 @@ private:
void iterate ();
void handleLogsUploadStateChanged (linphone::CoreLogCollectionUploadState state, const std::string &info);
void handleLogsUploadStateChanged (linphone::Core::LogCollectionUploadState state, const std::string &info);
static QString getDownloadUrl ();
@ -164,7 +164,7 @@ private:
SettingsModel *mSettingsModel = nullptr;
AccountSettingsModel *mAccountSettingsModel = nullptr;
QHash<QString, std::weak_ptr<ChatModel>> mChatModels;
QHash<QPair<QString, QString>, std::weak_ptr<ChatModel>> mChatModels;
QTimer *mCbsTimer = nullptr;

View file

@ -1,5 +1,5 @@
/*
* AbstractMessagesCountNotifier.cpp
* AbstractMessageCountNotifier.cpp
* Copyright (C) 2017-2018 Belledonne Communications, Grenoble, France
*
* This program is free software; you can redistribute it and/or
@ -25,55 +25,55 @@
#include "components/core/CoreManager.hpp"
#include "components/settings/SettingsModel.hpp"
#include "AbstractMessagesCountNotifier.hpp"
#include "AbstractMessageCountNotifier.hpp"
// =============================================================================
using namespace std;
AbstractMessagesCountNotifier::AbstractMessagesCountNotifier (QObject *parent) : QObject(parent) {
AbstractMessageCountNotifier::AbstractMessageCountNotifier (QObject *parent) : QObject(parent) {
CoreManager *coreManager = CoreManager::getInstance();
QObject::connect(
coreManager, &CoreManager::chatModelCreated,
this, &AbstractMessagesCountNotifier::handleChatModelCreated
this, &AbstractMessageCountNotifier::handleChatModelCreated
);
QObject::connect(
coreManager->getHandlers().get(), &CoreHandlers::messageReceived,
this, &AbstractMessagesCountNotifier::handleMessageReceived
this, &AbstractMessageCountNotifier::handleMessageReceived
);
QObject::connect(
coreManager->getSettingsModel(), &SettingsModel::chatEnabledChanged,
this, &AbstractMessagesCountNotifier::internalNotifyUnreadMessagesCount
this, &AbstractMessageCountNotifier::internalNotifyUnreadMessageCount
);
}
// -----------------------------------------------------------------------------
void AbstractMessagesCountNotifier::updateUnreadMessagesCount () {
mUnreadMessagesCount = 0;
void AbstractMessageCountNotifier::updateUnreadMessageCount () {
mUnreadMessageCount = 0;
for (const auto &chatRoom : CoreManager::getInstance()->getCore()->getChatRooms())
mUnreadMessagesCount += chatRoom->getUnreadMessagesCount();
mUnreadMessageCount += chatRoom->getUnreadMessagesCount();
internalNotifyUnreadMessagesCount();
internalNotifyUnreadMessageCount();
}
void AbstractMessagesCountNotifier::internalNotifyUnreadMessagesCount () {
qInfo() << QStringLiteral("Notify unread messages count: %1.").arg(mUnreadMessagesCount);
int n = mUnreadMessagesCount > 99 ? 99 : mUnreadMessagesCount;
void AbstractMessageCountNotifier::internalNotifyUnreadMessageCount () {
qInfo() << QStringLiteral("Notify unread messages count: %1.").arg(mUnreadMessageCount);
int n = mUnreadMessageCount > 99 ? 99 : mUnreadMessageCount;
notifyUnreadMessagesCount(CoreManager::getInstance()->getSettingsModel()->getChatEnabled() ? n : 0);
notifyUnreadMessageCount(CoreManager::getInstance()->getSettingsModel()->getChatEnabled() ? n : 0);
}
// -----------------------------------------------------------------------------
void AbstractMessagesCountNotifier::handleChatModelCreated (const shared_ptr<ChatModel> &chatModel) {
void AbstractMessageCountNotifier::handleChatModelCreated (const shared_ptr<ChatModel> &chatModel) {
QObject::connect(
chatModel.get(), &ChatModel::messagesCountReset,
this, &AbstractMessagesCountNotifier::updateUnreadMessagesCount
chatModel.get(), &ChatModel::messageCountReset,
this, &AbstractMessageCountNotifier::updateUnreadMessageCount
);
}
void AbstractMessagesCountNotifier::handleMessageReceived (const shared_ptr<linphone::ChatMessage> &) {
mUnreadMessagesCount++;
internalNotifyUnreadMessagesCount();
void AbstractMessageCountNotifier::handleMessageReceived (const shared_ptr<linphone::ChatMessage> &) {
mUnreadMessageCount++;
internalNotifyUnreadMessageCount();
}

View file

@ -1,5 +1,5 @@
/*
* AbstractMessagesCountNotifier.hpp
* AbstractMessageCountNotifier.hpp
* Copyright (C) 2017-2018 Belledonne Communications, Grenoble, France
*
* This program is free software; you can redistribute it and/or
@ -20,8 +20,8 @@
* Author: Ronan Abhamon
*/
#ifndef ABSTRACT_MESSAGES_COUNT_NOTIFIER_H_
#define ABSTRACT_MESSAGES_COUNT_NOTIFIER_H_
#ifndef ABSTRACT_MESSAGE_COUNT_NOTIFIER_H_
#define ABSTRACT_MESSAGE_COUNT_NOTIFIER_H_
#include <memory>
@ -35,24 +35,24 @@ namespace linphone {
class ChatModel;
class AbstractMessagesCountNotifier : public QObject {
class AbstractMessageCountNotifier : public QObject {
Q_OBJECT;
public:
AbstractMessagesCountNotifier (QObject *parent = Q_NULLPTR);
AbstractMessageCountNotifier (QObject *parent = Q_NULLPTR);
void updateUnreadMessagesCount ();
void updateUnreadMessageCount ();
protected:
virtual void notifyUnreadMessagesCount (int n) = 0;
virtual void notifyUnreadMessageCount (int n) = 0;
private:
void internalNotifyUnreadMessagesCount ();
void internalNotifyUnreadMessageCount ();
void handleChatModelCreated (const std::shared_ptr<ChatModel> &chatModel);
void handleMessageReceived (const std::shared_ptr<linphone::ChatMessage> &message);
int mUnreadMessagesCount = 0;
int mUnreadMessageCount = 0;
};
#endif // ABSTRACT_MESSAGES_COUNT_NOTIFIER_H_
#endif // ABSTRACT_MESSAGE_COUNT_NOTIFIER_H_

View file

@ -1,5 +1,5 @@
/*
* MessagesCountNotifierMacOs.hpp
* MessageCountNotifierMacOs.hpp
* Copyright (C) 2017-2018 Belledonne Communications, Grenoble, France
*
* This program is free software; you can redistribute it and/or
@ -20,22 +20,22 @@
* Author: Ghislain MARY
*/
#ifndef MESSAGES_COUNT_NOTIFIER_MAC_OS_H_
#define MESSAGES_COUNT_NOTIFIER_MAC_OS_H_
#ifndef MESSAGE_COUNT_NOTIFIER_MAC_OS_H_
#define MESSAGE_COUNT_NOTIFIER_MAC_OS_H_
#include "AbstractMessagesCountNotifier.hpp"
#include "AbstractMessageCountNotifier.hpp"
// =============================================================================
extern "C" void notifyUnreadMessagesCountMacOs (int n);
extern "C" void notifyUnreadMessageCountMacOs (int n);
class MessagesCountNotifier : public AbstractMessagesCountNotifier {
class MessageCountNotifier : public AbstractMessageCountNotifier {
public:
MessagesCountNotifier (QObject *parent = Q_NULLPTR) : AbstractMessagesCountNotifier(parent) {}
MessageCountNotifier (QObject *parent = Q_NULLPTR) : AbstractMessageCountNotifier(parent) {}
void notifyUnreadMessagesCount (int n) override {
notifyUnreadMessagesCountMacOs(n);
void notifyUnreadMessageCount (int n) override {
notifyUnreadMessageCountMacOs(n);
}
};
#endif // MESSAGES_COUNT_NOTIFIER_MAC_OS_H_
#endif // MESSAGE_COUNT_NOTIFIER_MAC_OS_H_

View file

@ -1,5 +1,5 @@
/*
* MessagesCountNotifierMacOS.m
* MessageCountNotifierMacOS.m
* Copyright (C) 2017-2018 Belledonne Communications, Grenoble, France
*
* This program is free software; you can redistribute it and/or
@ -24,7 +24,7 @@
// =============================================================================
void notifyUnreadMessagesCountMacOs (int n) {
void notifyUnreadMessageCountMacOs (int n) {
NSString *badgeStr = (n > 0) ? [NSString stringWithFormat:@"%d", n] : @"";
[[NSApp dockTile] setBadgeLabel:badgeStr];
}

View file

@ -1,5 +1,5 @@
/*
* MessagesCountNotifierSystemTrayIcon.hpp
* MessageCountNotifierSystemTrayIcon.hpp
* Copyright (C) 2017-2018 Belledonne Communications, Grenoble, France
*
* This program is free software; you can redistribute it and/or
@ -31,7 +31,7 @@
#include "utils/LinphoneUtils.hpp"
#include "utils/Utils.hpp"
#include "MessagesCountNotifierSystemTrayIcon.hpp"
#include "MessageCountNotifierSystemTrayIcon.hpp"
// =============================================================================
@ -46,7 +46,7 @@ namespace {
constexpr int IconCounterTextPixelSize = 144;
}
MessagesCountNotifier::MessagesCountNotifier (QObject *parent) : AbstractMessagesCountNotifier(parent) {
MessageCountNotifier::MessageCountNotifier (QObject *parent) : AbstractMessageCountNotifier(parent) {
QSvgRenderer renderer((QString(LinphoneUtils::WindowIconPath)));
if (!renderer.isValid())
qFatal("Invalid SVG Image.");
@ -62,20 +62,20 @@ MessagesCountNotifier::MessagesCountNotifier (QObject *parent) : AbstractMessage
mBlinkTimer = new QTimer(this);
mBlinkTimer->setInterval(IconCounterBlinkInterval);
QObject::connect(mBlinkTimer, &QTimer::timeout, this, &MessagesCountNotifier::update);
QObject::connect(mBlinkTimer, &QTimer::timeout, this, &MessageCountNotifier::update);
Utils::connectOnce(
App::getInstance(), &App::focusWindowChanged,
this, &MessagesCountNotifier::updateUnreadMessagesCount
this, &MessageCountNotifier::updateUnreadMessageCount
);
}
MessagesCountNotifier::~MessagesCountNotifier () {
MessageCountNotifier::~MessageCountNotifier () {
delete mBuf;
delete mBufWithCounter;
}
void MessagesCountNotifier::notifyUnreadMessagesCount (int n) {
void MessageCountNotifier::notifyUnreadMessageCount (int n) {
QSystemTrayIcon *sysTrayIcon = App::getInstance()->getSystemTrayIcon();
if (!sysTrayIcon)
return;
@ -115,7 +115,7 @@ void MessagesCountNotifier::notifyUnreadMessagesCount (int n) {
update();
}
void MessagesCountNotifier::update () {
void MessageCountNotifier::update () {
QSystemTrayIcon *sysTrayIcon = App::getInstance()->getSystemTrayIcon();
Q_CHECK_PTR(sysTrayIcon);
sysTrayIcon->setIcon(QIcon(mDisplayCounter ? *mBufWithCounter : *mBuf));

View file

@ -1,5 +1,5 @@
/*
* MessagesCountNotifierSystemTrayIcon.hpp
* MessageCountNotifierSystemTrayIcon.hpp
* Copyright (C) 2017-2018 Belledonne Communications, Grenoble, France
*
* This program is free software; you can redistribute it and/or
@ -20,22 +20,22 @@
* Author: Ronan Abhamon
*/
#ifndef MESSAGES_COUNT_NOTIFIER_SYSTEM_TRAY_ICON_H_
#define MESSAGES_COUNT_NOTIFIER_SYSTEM_TRAY_ICON_H_
#ifndef MESSAGE_COUNT_NOTIFIER_SYSTEM_TRAY_ICON_H_
#define MESSAGE_COUNT_NOTIFIER_SYSTEM_TRAY_ICON_H_
#include "AbstractMessagesCountNotifier.hpp"
#include "AbstractMessageCountNotifier.hpp"
// =============================================================================
class QTimer;
class MessagesCountNotifier : public AbstractMessagesCountNotifier {
class MessageCountNotifier : public AbstractMessageCountNotifier {
public:
MessagesCountNotifier (QObject *parent = Q_NULLPTR);
~MessagesCountNotifier ();
MessageCountNotifier (QObject *parent = Q_NULLPTR);
~MessageCountNotifier ();
protected:
void notifyUnreadMessagesCount (int n) override;
void notifyUnreadMessageCount (int n) override;
private:
void update ();
@ -46,4 +46,4 @@ private:
bool mDisplayCounter = false;
};
#endif // MESSAGES_COUNT_NOTIFIER_SYSTEM_TRAY_ICON_H_
#endif // MESSAGE_COUNT_NOTIFIER_SYSTEM_TRAY_ICON_H_

View file

@ -237,7 +237,9 @@ void Notifier::notifyReceivedMessage (const shared_ptr<linphone::ChatMessage> &m
? tr("newFileMessage")
: Utils::coreStringToAppString(message->getText());
map["sipAddress"] = Utils::coreStringToAppString(message->getFromAddress()->asStringUriOnly());
shared_ptr<linphone::ChatRoom> chatRoom(message->getChatRoom());
map["peerAddress"] = Utils::coreStringToAppString(chatRoom->getPeerAddress()->asStringUriOnly());
map["localAddress"] = Utils::coreStringToAppString(chatRoom->getLocalAddress()->asStringUriOnly());
map["window"].setValue(App::getInstance()->getMainWindow());
SHOW_NOTIFICATION(map);

View file

@ -36,10 +36,10 @@ class Presence : public QObject {
public:
enum PresenceStatus {
Online = linphone::ConsolidatedPresenceOnline,
Busy = linphone::ConsolidatedPresenceBusy,
DoNotDisturb = linphone::ConsolidatedPresenceDoNotDisturb,
Offline = linphone::ConsolidatedPresenceOffline
Online = int(linphone::ConsolidatedPresence::Online),
Busy = int(linphone::ConsolidatedPresence::Busy),
DoNotDisturb = int(linphone::ConsolidatedPresence::DoNotDisturb),
Offline = int(linphone::ConsolidatedPresence::Offline)
};
Q_ENUM(PresenceStatus);

View file

@ -36,15 +36,15 @@ using namespace std;
static inline AccountSettingsModel::RegistrationState mapLinphoneRegistrationStateToUi (linphone::RegistrationState state) {
switch (state) {
case linphone::RegistrationStateNone:
case linphone::RegistrationStateCleared:
case linphone::RegistrationStateFailed:
case linphone::RegistrationState::None:
case linphone::RegistrationState::Cleared:
case linphone::RegistrationState::Failed:
return AccountSettingsModel::RegistrationStateNotRegistered;
case linphone::RegistrationStateProgress:
case linphone::RegistrationState::Progress:
return AccountSettingsModel::RegistrationStateInProgress;
case linphone::RegistrationStateOk:
case linphone::RegistrationState::Ok:
break;
}
@ -76,6 +76,10 @@ void AccountSettingsModel::setUsedSipAddress (const shared_ptr<const linphone::A
proxyConfig ? proxyConfig->setIdentityAddress(address) : core->setPrimaryContact(address->asString());
}
QString AccountSettingsModel::getUsedSipAddressAsString () const {
return Utils::coreStringToAppString(getUsedSipAddress()->asStringUriOnly());
}
// -----------------------------------------------------------------------------
bool AccountSettingsModel::addOrUpdateProxyConfig (const shared_ptr<linphone::ProxyConfig> &proxyConfig) {
@ -124,7 +128,7 @@ QVariantMap AccountSettingsModel::getProxyConfigDescription (const shared_ptr<li
map["avpfInterval"] = proxyConfig->getAvpfRrInterval();
map["registerEnabled"] = proxyConfig->registerEnabled();
map["publishPresence"] = proxyConfig->publishEnabled();
map["avpfEnabled"] = proxyConfig->getAvpfMode() == linphone::AVPFMode::AVPFModeEnabled;
map["avpfEnabled"] = proxyConfig->getAvpfMode() == linphone::AVPFMode::Enabled;
map["registrationState"] = mapLinphoneRegistrationStateToUi(proxyConfig->getState());
shared_ptr<linphone::NatPolicy> natPolicy = proxyConfig->getNatPolicy();
@ -135,7 +139,7 @@ QVariantMap AccountSettingsModel::getProxyConfigDescription (const shared_ptr<li
map["stunServer"] = Utils::coreStringToAppString(natPolicy->getStunServer());
map["turnUser"] = Utils::coreStringToAppString(natPolicy->getStunServerUsername());
shared_ptr<const linphone::AuthInfo> authInfo = proxyConfig->findAuthInfo();
map["turnPassword"] = authInfo ? Utils::coreStringToAppString(authInfo->getPasswd()) : QString("");
map["turnPassword"] = authInfo ? Utils::coreStringToAppString(authInfo->getPassword()) : QString("");
return map;
}
@ -197,8 +201,8 @@ bool AccountSettingsModel::addOrUpdateProxyConfig (
proxyConfig->enableRegister(data["registerEnabled"].toBool());
proxyConfig->enablePublish(data["publishPresence"].toBool());
proxyConfig->setAvpfMode(data["avpfEnabled"].toBool()
? linphone::AVPFMode::AVPFModeEnabled
: linphone::AVPFMode::AVPFModeDefault
? linphone::AVPFMode::Enabled
: linphone::AVPFMode::Default
);
shared_ptr<linphone::NatPolicy> natPolicy = proxyConfig->getNatPolicy();
@ -214,7 +218,7 @@ bool AccountSettingsModel::addOrUpdateProxyConfig (
shared_ptr<linphone::Core> core = proxyConfig->getCore();
if (authInfo) {
shared_ptr<linphone::AuthInfo> clonedAuthInfo = authInfo->clone();
clonedAuthInfo->setPasswd(Utils::appStringToCoreString(data["turnPassword"].toString()));
clonedAuthInfo->setPassword(Utils::appStringToCoreString(data["turnPassword"].toString()));
core->removeAuthInfo(authInfo);
core->addAuthInfo(clonedAuthInfo);
@ -248,7 +252,7 @@ void AccountSettingsModel::addAuthInfo (
const QString &password,
const QString &userId
) {
authInfo->setPasswd(Utils::appStringToCoreString(password));
authInfo->setPassword(Utils::appStringToCoreString(password));
authInfo->setUserid(Utils::appStringToCoreString(userId));
CoreManager::getInstance()->getCore()->addAuthInfo(authInfo);
@ -283,10 +287,6 @@ void AccountSettingsModel::setUsername (const QString &username) {
emit accountSettingsUpdated();
}
QString AccountSettingsModel::getSipAddress () const {
return Utils::coreStringToAppString(getUsedSipAddress()->asStringUriOnly());
}
AccountSettingsModel::RegistrationState AccountSettingsModel::getRegistrationState () const {
shared_ptr<linphone::ProxyConfig> proxyConfig = CoreManager::getInstance()->getCore()->getDefaultProxyConfig();
return proxyConfig ? mapLinphoneRegistrationStateToUi(proxyConfig->getState()) : RegistrationStateNotRegistered;

View file

@ -33,7 +33,7 @@ class AccountSettingsModel : public QObject {
// Selected proxy config.
Q_PROPERTY(QString username READ getUsername WRITE setUsername NOTIFY accountSettingsUpdated);
Q_PROPERTY(QString sipAddress READ getSipAddress NOTIFY accountSettingsUpdated);
Q_PROPERTY(QString sipAddress READ getUsedSipAddressAsString NOTIFY accountSettingsUpdated);
Q_PROPERTY(RegistrationState registrationState READ getRegistrationState NOTIFY accountSettingsUpdated);
// Default info.
@ -56,6 +56,8 @@ public:
std::shared_ptr<const linphone::Address> getUsedSipAddress () const;
void setUsedSipAddress (const std::shared_ptr<const linphone::Address> &address);
QString getUsedSipAddressAsString () const;
bool addOrUpdateProxyConfig (const std::shared_ptr<linphone::ProxyConfig> &proxyConfig);
Q_INVOKABLE QVariantMap getProxyConfigDescription (const std::shared_ptr<linphone::ProxyConfig> &proxyConfig);
@ -82,8 +84,6 @@ private:
QString getUsername () const;
void setUsername (const QString &username);
QString getSipAddress () const;
RegistrationState getRegistrationState () const;
// ---------------------------------------------------------------------------

View file

@ -104,7 +104,7 @@ QStringList SettingsModel::getCaptureDevices () const {
shared_ptr<linphone::Core> core = CoreManager::getInstance()->getCore();
QStringList list;
for (const auto &device : core->getSoundDevices()) {
for (const auto &device : core->getSoundDevicesList()) {
if (core->soundDeviceCanCapture(device))
list << Utils::coreStringToAppString(device);
}
@ -116,7 +116,7 @@ QStringList SettingsModel::getPlaybackDevices () const {
shared_ptr<linphone::Core> core = CoreManager::getInstance()->getCore();
QStringList list;
for (const auto &device : core->getSoundDevices())
for (const auto &device : core->getSoundDevicesList())
if (core->soundDeviceCanPlayback(device))
list << Utils::coreStringToAppString(device);
@ -213,7 +213,7 @@ void SettingsModel::setShowAudioCodecs (bool status) {
QStringList SettingsModel::getVideoDevices () const {
QStringList list;
for (const auto &device : CoreManager::getInstance()->getCore()->getVideoDevices())
for (const auto &device : CoreManager::getInstance()->getCore()->getVideoDevicesList())
list << Utils::coreStringToAppString(device);
return list;
@ -504,13 +504,13 @@ QVariantList SettingsModel::getSupportedMediaEncryptions () const {
shared_ptr<linphone::Core> core = CoreManager::getInstance()->getCore();
QVariantList list;
if (core->mediaEncryptionSupported(linphone::MediaEncryptionDTLS))
if (core->mediaEncryptionSupported(linphone::MediaEncryption::DTLS))
list << buildEncryptionDescription(MediaEncryptionDtls, "DTLS");
if (core->mediaEncryptionSupported(linphone::MediaEncryptionSRTP))
if (core->mediaEncryptionSupported(linphone::MediaEncryption::SRTP))
list << buildEncryptionDescription(MediaEncryptionSrtp, "SRTP");
if (core->mediaEncryptionSupported(linphone::MediaEncryptionZRTP))
if (core->mediaEncryptionSupported(linphone::MediaEncryption::ZRTP))
list << buildEncryptionDescription(MediaEncryptionZrtp, "ZRTP");
return list;
@ -803,7 +803,7 @@ QString SettingsModel::getTurnPassword () const {
shared_ptr<linphone::NatPolicy> natPolicy = core->getNatPolicy();
shared_ptr<const linphone::AuthInfo> authInfo = core->findAuthInfo(natPolicy->getStunServerUsername(), "", "");
return authInfo ? Utils::coreStringToAppString(authInfo->getPasswd()) : QString("");
return authInfo ? Utils::coreStringToAppString(authInfo->getPassword()) : QString("");
}
void SettingsModel::setTurnPassword (const QString &password) {
@ -815,7 +815,7 @@ void SettingsModel::setTurnPassword (const QString &password) {
if (authInfo) {
shared_ptr<linphone::AuthInfo> clonedAuthInfo = authInfo->clone();
clonedAuthInfo->setPasswd(Utils::appStringToCoreString(password));
clonedAuthInfo->setPassword(Utils::appStringToCoreString(password));
core->removeAuthInfo(authInfo);
core->addAuthInfo(clonedAuthInfo);

View file

@ -171,17 +171,17 @@ class SettingsModel : public QObject {
public:
enum MediaEncryption {
MediaEncryptionNone = linphone::MediaEncryptionNone,
MediaEncryptionDtls = linphone::MediaEncryptionDTLS,
MediaEncryptionSrtp = linphone::MediaEncryptionSRTP,
MediaEncryptionZrtp = linphone::MediaEncryptionZRTP
MediaEncryptionNone = int(linphone::MediaEncryption::None),
MediaEncryptionDtls = int(linphone::MediaEncryption::DTLS),
MediaEncryptionSrtp = int(linphone::MediaEncryption::SRTP),
MediaEncryptionZrtp = int(linphone::MediaEncryption::ZRTP)
};
Q_ENUM(MediaEncryption);
enum LimeState {
LimeStateDisabled = linphone::LimeStateDisabled,
LimeStateMandatory = linphone::LimeStateMandatory,
LimeStatePreferred = linphone::LimeStatePreferred
LimeStateDisabled = int(linphone::LimeState::Disabled),
LimeStateMandatory = int(linphone::LimeState::Mandatory),
LimeStatePreferred = int(linphone::LimeState::Preferred)
};
Q_ENUM(LimeState);

View file

@ -24,8 +24,9 @@
// =============================================================================
SipAddressObserver::SipAddressObserver (const QString &sipAddress) {
mSipAddress = sipAddress;
SipAddressObserver::SipAddressObserver (const QString &peerAddress, const QString &localAddress) {
mPeerAddress = peerAddress;
mLocalAddress = localAddress;
}
void SipAddressObserver::setContact (ContactModel *contact) {
@ -44,10 +45,10 @@ void SipAddressObserver::setPresenceStatus (const Presence::PresenceStatus &pres
emit presenceStatusChanged(presenceStatus);
}
void SipAddressObserver::setUnreadMessagesCount (int unreadMessagesCount) {
if (unreadMessagesCount == mUnreadMessagesCount)
void SipAddressObserver::setUnreadMessageCount (int unreadMessageCount) {
if (unreadMessageCount == mUnreadMessageCount)
return;
mUnreadMessagesCount = unreadMessagesCount;
emit unreadMessagesCountChanged(unreadMessagesCount);
mUnreadMessageCount = unreadMessageCount;
emit unreadMessageCountChanged(unreadMessageCount);
}

View file

@ -34,23 +34,28 @@ class SipAddressObserver : public QObject {
Q_OBJECT;
Q_PROPERTY(QString sipAddress READ getSipAddress CONSTANT);
Q_PROPERTY(QString peerAddress READ getPeerAddress CONSTANT);
Q_PROPERTY(QString localAddress READ getLocalAddress CONSTANT);
Q_PROPERTY(ContactModel * contact READ getContact NOTIFY contactChanged);
Q_PROPERTY(ContactModel *contact READ getContact NOTIFY contactChanged);
Q_PROPERTY(Presence::PresenceStatus presenceStatus READ getPresenceStatus NOTIFY presenceStatusChanged);
Q_PROPERTY(int unreadMessagesCount READ getUnreadMessagesCount NOTIFY unreadMessagesCountChanged);
Q_PROPERTY(int unreadMessageCount READ getUnreadMessageCount NOTIFY unreadMessageCountChanged);
public:
SipAddressObserver (const QString &sipAddress);
SipAddressObserver (const QString &peerAddress, const QString &localAddress);
signals:
void contactChanged (ContactModel *contact);
void presenceStatusChanged (const Presence::PresenceStatus &presenceStatus);
void unreadMessagesCountChanged (int unreadMessagesCount);
void unreadMessageCountChanged (int unreadMessageCount);
private:
QString getSipAddress () const {
return mSipAddress;
QString getPeerAddress () const {
return mPeerAddress;
}
QString getLocalAddress () const {
return mLocalAddress;
}
// ---------------------------------------------------------------------------
@ -71,17 +76,18 @@ private:
// ---------------------------------------------------------------------------
int getUnreadMessagesCount () const {
return mUnreadMessagesCount;
int getUnreadMessageCount () const {
return mUnreadMessageCount;
}
void setUnreadMessagesCount (int unreadMessagesCount);
void setUnreadMessageCount (int unreadMessageCount);
QString mSipAddress;
QString mPeerAddress;
QString mLocalAddress;
ContactModel *mContact = nullptr;
Presence::PresenceStatus mPresenceStatus = Presence::PresenceStatus::Offline;
int mUnreadMessagesCount = 0;
int mUnreadMessageCount = 0;
};
Q_DECLARE_METATYPE(SipAddressObserver *);

View file

@ -21,6 +21,7 @@
*/
#include <QDateTime>
#include <QElapsedTimer>
#include <QUrl>
#include "components/call/CallModel.hpp"
@ -30,6 +31,7 @@
#include "components/contacts/ContactsListModel.hpp"
#include "components/core/CoreHandlers.hpp"
#include "components/core/CoreManager.hpp"
#include "components/settings/AccountSettingsModel.hpp"
#include "utils/LinphoneUtils.hpp"
#include "utils/Utils.hpp"
@ -39,6 +41,17 @@
using namespace std;
// -----------------------------------------------------------------------------
static inline QVariantMap buildVariantMap (const SipAddressesModel::SipAddressEntry &sipAddressEntry) {
return QVariantMap{
{ "sipAddress", sipAddressEntry.sipAddress },
{ "contact", QVariant::fromValue(sipAddressEntry.contact) },
{ "presenceStatus", sipAddressEntry.presenceStatus },
{ "__localToConferenceEntry", QVariant::fromValue(&sipAddressEntry.localAddressToConferenceEntry) }
};
}
SipAddressesModel::SipAddressesModel (QObject *parent) : QAbstractListModel(parent) {
initSipAddresses();
@ -80,7 +93,7 @@ QVariant SipAddressesModel::data (const QModelIndex &index, int role) const {
return QVariant();
if (role == Qt::DisplayRole)
return QVariant::fromValue(*mRefs[row]);
return buildVariantMap(*mRefs[row]);
return QVariant();
}
@ -88,44 +101,43 @@ QVariant SipAddressesModel::data (const QModelIndex &index, int role) const {
// -----------------------------------------------------------------------------
QVariantMap SipAddressesModel::find (const QString &sipAddress) const {
auto it = mSipAddresses.find(sipAddress);
return it == mSipAddresses.end() ? QVariantMap() : *it;
auto it = mPeerAddressToSipAddressEntry.find(sipAddress);
if (it == mPeerAddressToSipAddressEntry.end())
return QVariantMap();
return buildVariantMap(*it);
}
// -----------------------------------------------------------------------------
ContactModel *SipAddressesModel::mapSipAddressToContact (const QString &sipAddress) const {
auto it = mSipAddresses.find(sipAddress);
if (it == mSipAddresses.end())
return nullptr;
return it->value("contact").value<ContactModel *>();
auto it = mPeerAddressToSipAddressEntry.find(sipAddress);
return it == mPeerAddressToSipAddressEntry.end() ? nullptr : it->contact;
}
// -----------------------------------------------------------------------------
SipAddressObserver *SipAddressesModel::getSipAddressObserver (const QString &sipAddress) {
SipAddressObserver *model = new SipAddressObserver(sipAddress);
const QString cleanedSipAddress = cleanSipAddress(sipAddress);
SipAddressObserver *SipAddressesModel::getSipAddressObserver (const QString &peerAddress, const QString &localAddress) {
SipAddressObserver *model = new SipAddressObserver(peerAddress, localAddress);
const QString cleanedPeerAddress = cleanSipAddress(peerAddress);
const QString cleanedLocalAddress = cleanSipAddress(localAddress);
{
auto it = mSipAddresses.find(cleanedSipAddress);
if (it != mSipAddresses.end()) {
model->setContact(it->value("contact").value<ContactModel *>());
model->setPresenceStatus(
it->value("presenceStatus", Presence::PresenceStatus::Offline).value<Presence::PresenceStatus>()
);
model->setUnreadMessagesCount(
it->value("unreadMessagesCount", 0).toInt()
);
}
auto it = mPeerAddressToSipAddressEntry.find(cleanedPeerAddress);
if (it != mPeerAddressToSipAddressEntry.end()) {
model->setContact(it->contact);
model->setPresenceStatus(it->presenceStatus);
auto it2 = it->localAddressToConferenceEntry.find(cleanedLocalAddress);
if (it2 != it->localAddressToConferenceEntry.end())
model->setUnreadMessageCount(it2->unreadMessageCount);
}
mObservers.insert(cleanedSipAddress, model);
QObject::connect(model, &SipAddressObserver::destroyed, this, [this, model, cleanedSipAddress]() {
// Do not use `model` methods here. `model` is partially destroyed here!
if (mObservers.remove(cleanedSipAddress, model) == 0)
qWarning() << QStringLiteral("Unable to remove sip address `%1` from observers.").arg(cleanedSipAddress);
mObservers.insert(cleanedPeerAddress, model);
QObject::connect(model, &SipAddressObserver::destroyed, this, [this, model, cleanedPeerAddress, cleanedLocalAddress]() {
// Do not use `model` methods. `model` is partially destroyed here!
if (mObservers.remove(cleanedPeerAddress, model) == 0)
qWarning() << QStringLiteral("Unable to remove (%1, %2) from observers.")
.arg(cleanedPeerAddress).arg(cleanedLocalAddress);
});
return model;
@ -133,7 +145,7 @@ SipAddressObserver *SipAddressesModel::getSipAddressObserver (const QString &sip
// -----------------------------------------------------------------------------
QString SipAddressesModel::getTransportFromSipAddress (const QString &sipAddress) const {
QString SipAddressesModel::getTransportFromSipAddress (const QString &sipAddress) {
const shared_ptr<const linphone::Address> address = linphone::Factory::get()->createAddress(
Utils::appStringToCoreString(sipAddress)
);
@ -142,20 +154,20 @@ QString SipAddressesModel::getTransportFromSipAddress (const QString &sipAddress
return QString("");
switch (address->getTransport()) {
case linphone::TransportTypeUdp:
case linphone::TransportType::Udp:
return QStringLiteral("UDP");
case linphone::TransportTypeTcp:
case linphone::TransportType::Tcp:
return QStringLiteral("TCP");
case linphone::TransportTypeTls:
case linphone::TransportType::Tls:
return QStringLiteral("TLS");
case linphone::TransportTypeDtls:
case linphone::TransportType::Dtls:
return QStringLiteral("DTLS");
}
return QString("");
}
QString SipAddressesModel::addTransportToSipAddress (const QString &sipAddress, const QString &transport) const {
QString SipAddressesModel::addTransportToSipAddress (const QString &sipAddress, const QString &transport) {
shared_ptr<linphone::Address> address = linphone::Factory::get()->createAddress(
Utils::appStringToCoreString(sipAddress)
);
@ -213,18 +225,13 @@ bool SipAddressesModel::removeRow (int row, const QModelIndex &parent) {
bool SipAddressesModel::removeRows (int row, int count, const QModelIndex &parent) {
int limit = row + count - 1;
if (row < 0 || count < 0 || limit >= mSipAddresses.count())
if (row < 0 || count < 0 || limit >= mRefs.count())
return false;
beginRemoveRows(parent, row, limit);
for (int i = 0; i < count; ++i) {
const QVariantMap *map = mRefs.takeAt(row);
QString sipAddress = (*map)["sipAddress"].toString();
qInfo() << QStringLiteral("Remove sip address: `%1`.").arg(sipAddress);
mSipAddresses.remove(sipAddress);
}
for (int i = 0; i < count; ++i)
mPeerAddressToSipAddressEntry.remove(mRefs.takeAt(row)->sipAddress);
endRemoveRows();
@ -242,8 +249,8 @@ void SipAddressesModel::handleChatModelCreated (const shared_ptr<ChatModel> &cha
QObject::connect(ptr, &ChatModel::lastEntryRemoved, this, [this, ptr] {
handleLastEntryRemoved(ptr);
});
QObject::connect(ptr, &ChatModel::messagesCountReset, this, [this, ptr] {
handleMessagesCountReset(ptr);
QObject::connect(ptr, &ChatModel::messageCountReset, this, [this, ptr] {
handleMessageCountReset(ptr);
});
QObject::connect(ptr, &ChatModel::messageSent, this, &SipAddressesModel::handleMessageSent);
@ -286,13 +293,13 @@ void SipAddressesModel::handleMessageReceived (const shared_ptr<linphone::ChatMe
void SipAddressesModel::handleCallStateChanged (
const shared_ptr<linphone::Call> &call,
linphone::CallState state
linphone::Call::State state
) {
// Ignore aborted calls.
if (call->getCallLog()->getStatus() == linphone::CallStatus::CallStatusAborted)
if (call->getCallLog()->getStatus() == linphone::Call::Status::Aborted)
return;
if (state == linphone::CallStateEnd || state == linphone::CallStateError)
if (state == linphone::Call::State::End || state == linphone::Call::State::Error)
addOrUpdateSipAddress(
Utils::coreStringToAppString(call->getRemoteAddress()->asStringUriOnly()), call
);
@ -305,24 +312,24 @@ void SipAddressesModel::handlePresenceReceived (
Presence::PresenceStatus status;
switch (presenceModel->getConsolidatedPresence()) {
case linphone::ConsolidatedPresenceOnline:
case linphone::ConsolidatedPresence::Online:
status = Presence::PresenceStatus::Online;
break;
case linphone::ConsolidatedPresenceBusy:
case linphone::ConsolidatedPresence::Busy:
status = Presence::PresenceStatus::Busy;
break;
case linphone::ConsolidatedPresenceDoNotDisturb:
case linphone::ConsolidatedPresence::DoNotDisturb:
status = Presence::PresenceStatus::DoNotDisturb;
break;
case linphone::ConsolidatedPresenceOffline:
case linphone::ConsolidatedPresence::Offline:
status = Presence::PresenceStatus::Offline;
break;
}
auto it = mSipAddresses.find(sipAddress);
if (it != mSipAddresses.end()) {
auto it = mPeerAddressToSipAddressEntry.find(sipAddress);
if (it != mPeerAddressToSipAddressEntry.end()) {
qInfo() << QStringLiteral("Update presence of `%1`: %2.").arg(sipAddress).arg(status);
(*it)["presenceStatus"] = status;
it->presenceStatus = status;
int row = mRefs.indexOf(&(*it));
Q_ASSERT(row != -1);
@ -333,26 +340,34 @@ void SipAddressesModel::handlePresenceReceived (
}
void SipAddressesModel::handleAllEntriesRemoved (ChatModel *chatModel) {
auto it = mSipAddresses.find(chatModel->getSipAddress());
if (it == mSipAddresses.end())
auto it = mPeerAddressToSipAddressEntry.find(chatModel->getPeerAddress());
if (it == mPeerAddressToSipAddressEntry.end())
return;
auto it2 = it->localAddressToConferenceEntry.find(chatModel->getLocalAddress());
if (it2 == it->localAddressToConferenceEntry.end())
return;
it->localAddressToConferenceEntry.erase(it2);
int row = mRefs.indexOf(&(*it));
Q_ASSERT(row != -1);
// No history, no contact => Remove sip address from list.
if (!it->contains("contact")) {
if (!it->contact && it->localAddressToConferenceEntry.empty()) {
removeRow(row);
return;
}
it->remove("timestamp");
emit dataChanged(index(row, 0), index(row, 0));
}
void SipAddressesModel::handleLastEntryRemoved (ChatModel *chatModel) {
auto it = mSipAddresses.find(chatModel->getSipAddress());
if (it == mSipAddresses.end())
auto it = mPeerAddressToSipAddressEntry.find(chatModel->getPeerAddress());
if (it == mPeerAddressToSipAddressEntry.end())
return;
auto it2 = it->localAddressToConferenceEntry.find(chatModel->getLocalAddress());
if (it2 == it->localAddressToConferenceEntry.end())
return;
int row = mRefs.indexOf(&(*it));
@ -365,22 +380,28 @@ void SipAddressesModel::handleLastEntryRemoved (ChatModel *chatModel) {
).toMap();
// Update the timestamp with the new last chat message timestamp.
(*it)["timestamp"] = map["timestamp"];
it2->timestamp = map["timestamp"].toDateTime();
emit dataChanged(index(row, 0), index(row, 0));
}
void SipAddressesModel::handleMessagesCountReset (ChatModel *chatModel) {
const QString &sipAddress = chatModel->getSipAddress();
auto it = mSipAddresses.find(sipAddress);
if (it != mSipAddresses.end()) {
(*it)["unreadMessagesCount"] = 0;
void SipAddressesModel::handleMessageCountReset (ChatModel *chatModel) {
const QString &peerAddress = chatModel->getPeerAddress();
auto it = mPeerAddressToSipAddressEntry.find(peerAddress);
if (it == mPeerAddressToSipAddressEntry.end())
return;
int row = mRefs.indexOf(&(*it));
Q_ASSERT(row != -1);
emit dataChanged(index(row, 0), index(row, 0));
}
const QString &localAddress = chatModel->getLocalAddress();
auto it2 = it->localAddressToConferenceEntry.find(localAddress);
if (it2 == it->localAddressToConferenceEntry.end())
return;
updateObservers(sipAddress, 0);
it2->unreadMessageCount = 0;
int row = mRefs.indexOf(&(*it));
Q_ASSERT(row != -1);
emit dataChanged(index(row, 0), index(row, 0));
updateObservers(peerAddress, localAddress, 0);
}
void SipAddressesModel::handleMessageSent (const shared_ptr<linphone::ChatMessage> &message) {
@ -391,50 +412,62 @@ void SipAddressesModel::handleMessageSent (const shared_ptr<linphone::ChatMessag
}
void SipAddressesModel::handlerIsComposingChanged (const shared_ptr<linphone::ChatRoom> &chatRoom) {
auto it = mSipAddresses.find(Utils::coreStringToAppString(chatRoom->getPeerAddress()->asStringUriOnly()));
if (it != mSipAddresses.end()) {
(*it)["isComposing"] = chatRoom->isRemoteComposing();
auto it = mPeerAddressToSipAddressEntry.find(
Utils::coreStringToAppString(chatRoom->getPeerAddress()->asStringUriOnly())
);
if (it == mPeerAddressToSipAddressEntry.end())
return;
int row = mRefs.indexOf(&(*it));
Q_ASSERT(row != -1);
emit dataChanged(index(row, 0), index(row, 0));
}
auto it2 = it->localAddressToConferenceEntry.find(
Utils::coreStringToAppString(chatRoom->getLocalAddress()->asStringUriOnly())
);
if (it2 == it->localAddressToConferenceEntry.end())
return;
it2->isComposing = chatRoom->isRemoteComposing();
int row = mRefs.indexOf(&(*it));
Q_ASSERT(row != -1);
emit dataChanged(index(row, 0), index(row, 0));
}
// -----------------------------------------------------------------------------
void SipAddressesModel::addOrUpdateSipAddress (QVariantMap &map, ContactModel *contact) {
QString sipAddress = map["sipAddress"].toString();
void SipAddressesModel::addOrUpdateSipAddress (SipAddressEntry &sipAddressEntry, ContactModel *contact) {
const QString &sipAddress = sipAddressEntry.sipAddress;
if (contact)
map["contact"] = QVariant::fromValue(contact);
else if (map.remove("contact") == 0)
sipAddressEntry.contact = contact;
else if (!sipAddressEntry.contact)
qWarning() << QStringLiteral("`contact` field is empty on sip address: `%1`.").arg(sipAddress);
updateObservers(sipAddress, contact);
}
void SipAddressesModel::addOrUpdateSipAddress (QVariantMap &map, const shared_ptr<linphone::Call> &call) {
void SipAddressesModel::addOrUpdateSipAddress (SipAddressEntry &sipAddressEntry, const shared_ptr<linphone::Call> &call) {
const shared_ptr<linphone::CallLog> callLog = call->getCallLog();
map["timestamp"] = callLog->getStatus() == linphone::CallStatus::CallStatusSuccess
sipAddressEntry.localAddressToConferenceEntry[
Utils::coreStringToAppString(callLog->getLocalAddress()->asStringUriOnly())
].timestamp = callLog->getStatus() == linphone::Call::Status::Success
? QDateTime::fromMSecsSinceEpoch((callLog->getStartDate() + callLog->getDuration()) * 1000)
: QDateTime::fromMSecsSinceEpoch(callLog->getStartDate() * 1000);
}
void SipAddressesModel::addOrUpdateSipAddress (QVariantMap &map, const shared_ptr<linphone::ChatMessage> &message) {
void SipAddressesModel::addOrUpdateSipAddress (SipAddressEntry &sipAddressEntry, const shared_ptr<linphone::ChatMessage> &message) {
int count = message->getChatRoom()->getUnreadMessagesCount();
map["timestamp"] = QDateTime::fromMSecsSinceEpoch(message->getTime() * 1000);
map["unreadMessagesCount"] = count;
QString localAddress(Utils::coreStringToAppString(message->getLocalAddress()->asStringUriOnly()));
ConferenceEntry &conferenceEntry = sipAddressEntry.localAddressToConferenceEntry[localAddress];
conferenceEntry.timestamp = QDateTime::fromMSecsSinceEpoch(message->getTime() * 1000);
conferenceEntry.unreadMessageCount = count;
updateObservers(map["sipAddress"].toString(), count);
updateObservers(sipAddressEntry.sipAddress, localAddress, count);
}
template<typename T>
void SipAddressesModel::addOrUpdateSipAddress (const QString &sipAddress, T data) {
auto it = mSipAddresses.find(sipAddress);
if (it != mSipAddresses.end()) {
auto it = mPeerAddressToSipAddressEntry.find(sipAddress);
if (it != mPeerAddressToSipAddressEntry.end()) {
addOrUpdateSipAddress(*it, data);
int row = mRefs.indexOf(&(*it));
@ -444,18 +477,15 @@ void SipAddressesModel::addOrUpdateSipAddress (const QString &sipAddress, T data
return;
}
QVariantMap map;
map["sipAddress"] = sipAddress;
addOrUpdateSipAddress(map, data);
SipAddressEntry sipAddressEntry{ sipAddress, nullptr, Presence::Offline, {} };
addOrUpdateSipAddress(sipAddressEntry, data);
int row = mRefs.count();
beginInsertRows(QModelIndex(), row, row);
qInfo() << QStringLiteral("Add sip address: `%1`.").arg(sipAddress);
mSipAddresses[sipAddress] = map;
mRefs << &mSipAddresses[sipAddress];
mPeerAddressToSipAddressEntry[sipAddress] = move(sipAddressEntry);
mRefs << &mPeerAddressToSipAddressEntry[sipAddress];
endInsertRows();
}
@ -463,8 +493,8 @@ void SipAddressesModel::addOrUpdateSipAddress (const QString &sipAddress, T data
// -----------------------------------------------------------------------------
void SipAddressesModel::removeContactOfSipAddress (const QString &sipAddress) {
auto it = mSipAddresses.find(sipAddress);
if (it == mSipAddresses.end()) {
auto it = mPeerAddressToSipAddressEntry.find(sipAddress);
if (it == mPeerAddressToSipAddressEntry.end()) {
qWarning() << QStringLiteral("Unable to remove unavailable sip address: `%1`.").arg(sipAddress);
return;
}
@ -479,8 +509,8 @@ void SipAddressesModel::removeContactOfSipAddress (const QString &sipAddress) {
int row = mRefs.indexOf(&(*it));
Q_ASSERT(row != -1);
// History exists, signal changes.
if (it->contains("timestamp") || contactModel) {
// History or contact exists, signal changes.
if (!it->localAddressToConferenceEntry.empty() || contactModel) {
emit dataChanged(index(row, 0), index(row, 0));
return;
}
@ -492,53 +522,60 @@ void SipAddressesModel::removeContactOfSipAddress (const QString &sipAddress) {
// -----------------------------------------------------------------------------
void SipAddressesModel::initSipAddresses () {
QElapsedTimer timer;
timer.start();
initSipAddressesFromChat();
initSipAddressesFromCalls();
initRefs();
initSipAddressesFromContacts();
qInfo() << "Sip addresses model initialized in:" << timer.elapsed() << "ms.";
}
void SipAddressesModel::initSipAddressesFromChat () {
for (const auto &chatRoom : CoreManager::getInstance()->getCore()->getChatRooms()) {
list<shared_ptr<linphone::ChatMessage>> history = chatRoom->getHistory(1);
list<shared_ptr<linphone::ChatMessage>> history(chatRoom->getHistory(1));
if (history.empty())
continue;
QString sipAddress = Utils::coreStringToAppString(chatRoom->getPeerAddress()->asStringUriOnly());
QString peerAddress(Utils::coreStringToAppString(chatRoom->getPeerAddress()->asStringUriOnly()));
QString localAddress(Utils::coreStringToAppString(chatRoom->getLocalAddress()->asStringUriOnly()));
QVariantMap map;
map["sipAddress"] = sipAddress;
map["timestamp"] = QDateTime::fromMSecsSinceEpoch(history.back()->getTime() * 1000);
map["unreadMessagesCount"] = chatRoom->getUnreadMessagesCount();
mSipAddresses[sipAddress] = map;
getSipAddressEntry(peerAddress)->localAddressToConferenceEntry[localAddress] = {
chatRoom->getUnreadMessagesCount(),
false,
QDateTime::fromMSecsSinceEpoch(history.back()->getTime() * 1000)
};
}
}
void SipAddressesModel::initSipAddressesFromCalls () {
QSet<QString> addressDone;
using ConferenceId = QPair<QString, QString>;
QSet<ConferenceId> conferenceDone;
for (const auto &callLog : CoreManager::getInstance()->getCore()->getCallLogs()) {
const QString sipAddress = Utils::coreStringToAppString(callLog->getRemoteAddress()->asStringUriOnly());
const QString peerAddress(Utils::coreStringToAppString(callLog->getRemoteAddress()->asStringUriOnly()));
const QString localAddress(Utils::coreStringToAppString(callLog->getLocalAddress()->asStringUriOnly()));
if (addressDone.contains(sipAddress))
continue; // Already used.
if (callLog->getStatus() == linphone::CallStatusAborted)
if (callLog->getStatus() == linphone::Call::Status::Aborted)
continue; // Ignore aborted calls.
addressDone << sipAddress;
QVariantMap map;
map["sipAddress"] = sipAddress;
ConferenceId conferenceId{ peerAddress, localAddress };
if (conferenceDone.contains(conferenceId))
continue; // Already used.
conferenceDone << conferenceId;
// The duration can be wrong if status is not success.
map["timestamp"] = callLog->getStatus() == linphone::CallStatus::CallStatusSuccess
QDateTime timestamp(callLog->getStatus() == linphone::Call::Status::Success
? QDateTime::fromMSecsSinceEpoch((callLog->getStartDate() + callLog->getDuration()) * 1000)
: QDateTime::fromMSecsSinceEpoch(callLog->getStartDate() * 1000);
: QDateTime::fromMSecsSinceEpoch(callLog->getStartDate() * 1000));
auto it = mSipAddresses.find(sipAddress);
if (it == mSipAddresses.end() || map["timestamp"] > (*it)["timestamp"])
mSipAddresses[sipAddress] = map;
auto &localToConferenceEntry = getSipAddressEntry(peerAddress)->localAddressToConferenceEntry;
auto it = localToConferenceEntry.find(localAddress);
if (it == localToConferenceEntry.end())
localToConferenceEntry[localAddress] = { 0, false, move(timestamp) };
else if (it->timestamp.isNull() || timestamp > it->timestamp)
it->timestamp = move(timestamp);
}
}
@ -548,8 +585,8 @@ void SipAddressesModel::initSipAddressesFromContacts () {
}
void SipAddressesModel::initRefs () {
for (const auto &map : mSipAddresses)
mRefs << &map;
for (const auto &sipAddressEntry : mPeerAddressToSipAddressEntry)
mRefs << &sipAddressEntry;
}
// -----------------------------------------------------------------------------
@ -564,7 +601,10 @@ void SipAddressesModel::updateObservers (const QString &sipAddress, const Presen
observer->setPresenceStatus(presenceStatus);
}
void SipAddressesModel::updateObservers (const QString &sipAddress, int messagesCount) {
for (auto &observer : mObservers.values(sipAddress))
observer->setUnreadMessagesCount(messagesCount);
void SipAddressesModel::updateObservers (const QString &peerAddress, const QString &localAddress, int messageCount) {
for (auto &observer : mObservers.values(peerAddress))
if (observer->getLocalAddress() == localAddress) {
observer->setUnreadMessageCount(messageCount);
return;
}
}

View file

@ -24,6 +24,7 @@
#define SIP_ADDRESSES_MODEL_H_
#include <QAbstractListModel>
#include <QDateTime>
#include "SipAddressObserver.hpp"
@ -38,6 +39,19 @@ class SipAddressesModel : public QAbstractListModel {
Q_OBJECT;
public:
struct ConferenceEntry {
int unreadMessageCount;
bool isComposing;
QDateTime timestamp;
};
struct SipAddressEntry {
QString sipAddress;
ContactModel *contact;
Presence::PresenceStatus presenceStatus;
QHash<QString, ConferenceEntry> localAddressToConferenceEntry;
};
SipAddressesModel (QObject *parent = Q_NULLPTR);
int rowCount (const QModelIndex &index = QModelIndex()) const override;
@ -47,14 +61,14 @@ public:
Q_INVOKABLE QVariantMap find (const QString &sipAddress) const;
Q_INVOKABLE ContactModel *mapSipAddressToContact (const QString &sipAddress) const;
Q_INVOKABLE SipAddressObserver *getSipAddressObserver (const QString &sipAddress);
Q_INVOKABLE SipAddressObserver *getSipAddressObserver (const QString &peerAddress, const QString &localAddress);
// ---------------------------------------------------------------------------
// Sip addresses helpers.
// ---------------------------------------------------------------------------
Q_INVOKABLE QString getTransportFromSipAddress (const QString &sipAddress) const;
Q_INVOKABLE QString addTransportToSipAddress (const QString &sipAddress, const QString &transport) const;
Q_INVOKABLE static QString getTransportFromSipAddress (const QString &sipAddress);
Q_INVOKABLE static QString addTransportToSipAddress (const QString &sipAddress, const QString &transport);
Q_INVOKABLE static QString interpretSipAddress (const QString &sipAddress, bool checkUsername = true);
Q_INVOKABLE static QString interpretSipAddress (const QUrl &sipAddress);
@ -81,12 +95,12 @@ private:
void handleSipAddressRemoved (ContactModel *contact, const QString &sipAddress);
void handleMessageReceived (const std::shared_ptr<linphone::ChatMessage> &message);
void handleCallStateChanged (const std::shared_ptr<linphone::Call> &call, linphone::CallState state);
void handleCallStateChanged (const std::shared_ptr<linphone::Call> &call, linphone::Call::State state);
void handlePresenceReceived (const QString &sipAddress, const std::shared_ptr<const linphone::PresenceModel> &presenceModel);
void handleAllEntriesRemoved (ChatModel *chatModel);
void handleLastEntryRemoved (ChatModel *chatModel);
void handleMessagesCountReset (ChatModel *chatModel);
void handleMessageCountReset (ChatModel *chatModel);
void handleMessageSent (const std::shared_ptr<linphone::ChatMessage> &message);
@ -96,9 +110,9 @@ private:
// A sip address exists in this list if a contact is linked to it, or a call, or a message.
void addOrUpdateSipAddress (QVariantMap &map, ContactModel *contact);
void addOrUpdateSipAddress (QVariantMap &map, const std::shared_ptr<linphone::Call> &call);
void addOrUpdateSipAddress (QVariantMap &map, const std::shared_ptr<linphone::ChatMessage> &message);
void addOrUpdateSipAddress (SipAddressEntry &sipAddressEntry, ContactModel *contact);
void addOrUpdateSipAddress (SipAddressEntry &sipAddressEntry, const std::shared_ptr<linphone::Call> &call);
void addOrUpdateSipAddress (SipAddressEntry &sipAddressEntry, const std::shared_ptr<linphone::ChatMessage> &message);
template<class T>
void addOrUpdateSipAddress (const QString &sipAddress, T data);
@ -117,14 +131,26 @@ private:
void updateObservers (const QString &sipAddress, ContactModel *contact);
void updateObservers (const QString &sipAddress, const Presence::PresenceStatus &presenceStatus);
void updateObservers (const QString &sipAddress, int messagesCount);
void updateObservers (const QString &peerAddress, const QString &localAddress, int messageCount);
QHash<QString, QVariantMap> mSipAddresses;
QList<const QVariantMap *> mRefs;
// ---------------------------------------------------------------------------
SipAddressEntry *getSipAddressEntry (const QString &peerAddress) {
auto it = mPeerAddressToSipAddressEntry.find(peerAddress);
if (it == mPeerAddressToSipAddressEntry.end())
it = mPeerAddressToSipAddressEntry.insert(peerAddress, { peerAddress, nullptr, Presence::Offline, {} });
return &(*it);
}
QHash<QString, SipAddressEntry> mPeerAddressToSipAddressEntry;
QList<const SipAddressEntry *> mRefs;
QMultiHash<QString, SipAddressObserver *> mObservers;
std::shared_ptr<CoreHandlers> mCoreHandlers;
};
using LocalAddressToConferenceEntry = QHash<QString, SipAddressesModel::ConferenceEntry>;
Q_DECLARE_METATYPE(const LocalAddressToConferenceEntry *);
#endif // SIP_ADDRESSES_MODEL_H_

View file

@ -21,6 +21,7 @@
*/
#include "components/core/CoreManager.hpp"
#include "components/settings/AccountSettingsModel.hpp"
#include "components/sip-addresses/SipAddressesModel.hpp"
#include "TimelineModel.hpp"
@ -28,7 +29,15 @@
// =============================================================================
TimelineModel::TimelineModel (QObject *parent) : QSortFilterProxyModel(parent) {
setSourceModel(CoreManager::getInstance()->getSipAddressesModel());
CoreManager *coreManager = CoreManager::getInstance();
AccountSettingsModel *accountSettingsModel = coreManager->getAccountSettingsModel();
QObject::connect(accountSettingsModel, &AccountSettingsModel::accountSettingsUpdated, this, [this]() {
handleLocalAddressChanged(CoreManager::getInstance()->getAccountSettingsModel()->getUsedSipAddressAsString());
});
mLocalAddress = accountSettingsModel->getUsedSipAddressAsString();
setSourceModel(coreManager->getSipAddressesModel());
sort(0);
}
@ -40,11 +49,40 @@ QHash<int, QByteArray> TimelineModel::roleNames () const {
// -----------------------------------------------------------------------------
static inline const QHash<QString, SipAddressesModel::ConferenceEntry> *getLocalToConferenceEntry (const QVariantMap &map) {
return map.value("__localToConferenceEntry").value<decltype(getLocalToConferenceEntry({}))>();
}
QVariant TimelineModel::data (const QModelIndex &index, int role) const {
QVariantMap map(QSortFilterProxyModel::data(index, role).toMap());
auto localToConferenceEntry = getLocalToConferenceEntry(map);
auto it = localToConferenceEntry->find(mLocalAddress);
if (it != localToConferenceEntry->end()) {
map["timestamp"] = it->timestamp;
map["isComposing"] = it->isComposing;
map["unreadMessageCount"] = it->unreadMessageCount;
}
return map;
}
bool TimelineModel::filterAcceptsRow (int sourceRow, const QModelIndex &sourceParent) const {
const QModelIndex index = sourceModel()->index(sourceRow, 0, sourceParent);
return index.data().toMap().contains("timestamp");
return getLocalToConferenceEntry(index.data().toMap())->contains(mLocalAddress);
}
bool TimelineModel::lessThan (const QModelIndex &left, const QModelIndex &right) const {
return sourceModel()->data(left).toMap()["timestamp"] > sourceModel()->data(right).toMap()["timestamp"];
const QDateTime &a(getLocalToConferenceEntry(sourceModel()->data(left).toMap())->find(mLocalAddress)->timestamp);
const QDateTime &b(getLocalToConferenceEntry(sourceModel()->data(right).toMap())->find(mLocalAddress)->timestamp);
return a > b;
}
// -----------------------------------------------------------------------------
void TimelineModel::handleLocalAddressChanged (const QString &localAddress) {
if (mLocalAddress != localAddress) {
mLocalAddress = localAddress;
invalidate();
}
}

View file

@ -30,14 +30,30 @@
class TimelineModel : public QSortFilterProxyModel {
Q_OBJECT;
Q_PROPERTY(QString localAddress READ getLocalAddress NOTIFY localAddressChanged);
public:
TimelineModel (QObject *parent = Q_NULLPTR);
QHash<int, QByteArray> roleNames () const override;
signals:
void localAddressChanged (const QString &localAddress);
protected:
QVariant data (const QModelIndex &index, int role = Qt::DisplayRole) const override;
bool filterAcceptsRow (int sourceRow, const QModelIndex &sourceParent) const override;
bool lessThan (const QModelIndex &left, const QModelIndex &right) const override;
QString getLocalAddress () const {
return mLocalAddress;
}
void handleLocalAddressChanged (const QString &localAddress);
private:
QString mLocalAddress;
};
#endif // TIMELINE_MODEL_H_

View file

@ -28,11 +28,11 @@
linphone::TransportType LinphoneUtils::stringToTransportType (const QString &transport) {
if (transport == QLatin1String("TCP"))
return linphone::TransportType::TransportTypeTcp;
return linphone::TransportType::Tcp;
if (transport == QLatin1String("UDP"))
return linphone::TransportType::TransportTypeUdp;
return linphone::TransportType::Udp;
if (transport == QLatin1String("TLS"))
return linphone::TransportType::TransportTypeTls;
return linphone::TransportType::Tls;
return linphone::TransportType::TransportTypeDtls;
return linphone::TransportType::Dtls;
}

@ -1 +1 @@
Subproject commit 28b8552948d653bbe9b37f5f08473bb9e325829e
Subproject commit 914558009a3013e53745344c359d3621c5e9d4e6

@ -1 +1 @@
Subproject commit a26a7854efb6b3c25f3bc3213851ef69cc999aa6
Subproject commit d1fc622b2cbe5fe9b55959b32af054c7ae75e1a1

@ -1 +1 @@
Subproject commit dacbddbd19a5b81df66c97e4c99b71dc99120228
Subproject commit f3856c456d88859839e4bab93bb5524d793dd719

@ -1 +1 @@
Subproject commit 9add24c2041e1bcf7b51ae580575ef56aa408f3e
Subproject commit acb4a5641f74500ac17df43ced7ffa5d71999574

@ -1 +1 @@
Subproject commit ad3c3fc7ee789baaf9075a6ecdb9de8e585a088d
Subproject commit 17be28e9d0b8e50b89ff9fba75990a51f03f111e

View file

@ -57,7 +57,7 @@ Item {
var count = 0
exclusiveButtons.clicked.connect(function (_button) {
button = _button;
button = _button
count += 1
})

View file

@ -17,7 +17,9 @@ Rectangle {
property alias signIcon: signIcon.icon
property alias sipAddressColor: contact.sipAddressColor
property alias usernameColor: contact.usernameColor
property string sipAddress
property string peerAddress
property string localAddress
// ---------------------------------------------------------------------------
@ -60,9 +62,9 @@ Rectangle {
Layout.fillHeight: true
Layout.fillWidth: true
displayUnreadMessagesCount: true
displayUnreadMessageCount: true
entry: SipAddressesModel.getSipAddressObserver(sipAddress)
entry: SipAddressesModel.getSipAddressObserver(peerAddress, localAddress)
}
Item {

View file

@ -142,7 +142,9 @@ ListView {
return params ? 'call_sign_' + params.string : ''
}
sipAddress: $call.sipAddress
peerAddress: $call.peerAddress
localAddress: $call.localAddress
width: parent.width
onClicked: {

View file

@ -34,7 +34,7 @@ Rectangle {
property bool bindToEnd: false
property bool tryToLoadMoreEntries: true
property var sipAddressObserver: SipAddressesModel.getSipAddressObserver(proxyModel.sipAddress)
property var sipAddressObserver: SipAddressesModel.getSipAddressObserver(proxyModel.peerAddress, proxyModel.localAddress)
// -----------------------------------------------------------------------

View file

@ -15,9 +15,9 @@ Rectangle {
property alias sipAddressColor: description.sipAddressColor
property alias usernameColor: description.usernameColor
property bool displayUnreadMessagesCount: false
property bool displayUnreadMessageCount: false
// A entry from `SipAddressesModel`.
// A entry from `SipAddressesModel` or an `SipAddressObserver`.
property var entry
readonly property var _contact: entry.contact
@ -47,7 +47,7 @@ Rectangle {
? Presence.getPresenceLevel(entry.presenceStatus)
: -1
username: LinphoneUtils.getContactUsername(_contact || entry.sipAddress)
username: LinphoneUtils.getContactUsername(_contact || entry.sipAddress || entry.peerAddress || '')
}
ContactDescription {
@ -57,17 +57,17 @@ Rectangle {
Layout.fillWidth: true
Layout.leftMargin: ContactStyle.spacing
sipAddress: entry.sipAddress
sipAddress: entry.sipAddress || entry.peerAddress || ''
username: avatar.username
}
MessagesCounter {
MessageCounter {
Layout.alignment: Qt.AlignTop
count: Number(entry.unreadMessagesCount)
count: Number(entry.unreadMessageCount)
isComposing: Boolean(entry.isComposing)
visible: item.displayUnreadMessagesCount
visible: item.displayUnreadMessageCount
}
}
}

View file

@ -7,13 +7,13 @@ import Linphone.Styles 1.0
// =============================================================================
Item {
id: messagesCounter
id: messageCounter
property int count
property bool isComposing
implicitHeight: counterIcon.height + MessagesCounterStyle.verticalMargins * 2
implicitWidth: counterIcon.width + MessagesCounterStyle.horizontalMargins * 2
implicitHeight: counterIcon.height + MessageCounterStyle.verticalMargins * 2
implicitWidth: counterIcon.width + MessageCounterStyle.horizontalMargins * 2
Icon {
id: counterIcon
@ -22,11 +22,11 @@ Item {
anchors.centerIn: parent
icon: messagesCounter.isComposing
icon: messageCounter.isComposing
? ('chat_is_composing_' + counterIcon.composingIndex)
: 'chat_count'
iconSize: MessagesCounterStyle.iconSize.message
visible: messagesCounter.count > 0 || messagesCounter.isComposing
iconSize: MessageCounterStyle.iconSize.message
visible: messageCounter.count > 0 || messageCounter.isComposing
Icon {
anchors {
@ -35,21 +35,21 @@ Item {
}
icon: 'chat_amount'
iconSize: MessagesCounterStyle.iconSize.amount
visible: messagesCounter.count > 0
iconSize: MessageCounterStyle.iconSize.amount
visible: messageCounter.count > 0
Text {
anchors.centerIn: parent
color: MessagesCounterStyle.text.color
font.pointSize: MessagesCounterStyle.text.pointSize
text: messagesCounter.count
color: MessageCounterStyle.text.color
font.pointSize: MessageCounterStyle.text.pointSize
text: messageCounter.count
}
}
Timer {
interval: 500
repeat: true
running: messagesCounter.isComposing
running: messageCounter.isComposing
onRunningChanged: {
if (running) {

View file

@ -36,7 +36,7 @@ Notification {
entry: {
var call = notification.call
return SipAddressesModel.getSipAddressObserver(call ? call.sipAddress : '')
return SipAddressesModel.getSipAddressObserver(call ? call.peerAddress : '', call ? call.localAddress : '')
}
}

View file

@ -14,12 +14,13 @@ Notification {
// ---------------------------------------------------------------------------
readonly property string sipAddress: notificationData && notificationData.sipAddress || ''
readonly property string peerAddress: notificationData && notificationData.peerAddress || ''
readonly property string localAddress: notificationData && notificationData.localAddress || ''
// ---------------------------------------------------------------------------
Loader {
active: Boolean(notification.sipAddress)
active: Boolean(notification.peerAddress) && Boolean(notification.localAddress)
anchors {
fill: parent
@ -34,7 +35,7 @@ Notification {
Contact {
Layout.fillWidth: true
entry: SipAddressesModel.getSipAddressObserver(notification.sipAddress)
entry: SipAddressesModel.getSipAddressObserver(notification.peerAddress, notification.localAddress)
}
Rectangle {
@ -73,7 +74,8 @@ Notification {
onClicked: notification._close(function () {
notification.notificationData.window.setView('Conversation', {
sipAddress: notification.sipAddress
peerAddress: notification.peerAddress,
localAddress: notification.localAddress
})
})
}

View file

@ -21,7 +21,7 @@ singleton CodecsViewerStyle 1.0 Codecs/CodecsViewerStyle.qml
singleton AvatarStyle 1.0 Contact/AvatarStyle.qml
singleton ContactDescriptionStyle 1.0 Contact/ContactDescriptionStyle.qml
singleton ContactStyle 1.0 Contact/ContactStyle.qml
singleton MessagesCounterStyle 1.0 Contact/MessagesCounterStyle.qml
singleton MessageCounterStyle 1.0 Contact/MessageCounterStyle.qml
singleton OnlineInstallerDialogStyle 1.0 Dialog/OnlineInstallerDialogStyle.qml

View file

@ -27,7 +27,7 @@ Rectangle {
Keys.onPressed: {
var index = Logic.mapKeyToButtonIndex(event.key)
if (index != null) {
event.accepted = true;
event.accepted = true
Logic.sendDtmf(index)
}
}

View file

@ -2,14 +2,23 @@
// `Timeline.qml` Logic.
// =============================================================================
function setSelectedEntry (sipAddress) {
.import Linphone 1.0 as Linphone
// =============================================================================
function setSelectedEntry (peerAddress, localAddress) {
if (localAddress !== Linphone.AccountSettingsModel.sipAddress) {
resetSelectedEntry()
return
}
var model = timeline.model
var n = view.count
timeline._selectedSipAddress = sipAddress
timeline._selectedSipAddress = peerAddress
for (var i = 0; i < n; i++) {
if (sipAddress === model.data(model.index(i, 0)).sipAddress) {
if (peerAddress === model.data(model.index(i, 0)).sipAddress) {
view.currentIndex = i
return
}

View file

@ -17,16 +17,14 @@ Rectangle {
property alias model: view.model
property string _selectedSipAddress
property var _newInsertedItem
// ---------------------------------------------------------------------------
signal entrySelected (var entry)
// ---------------------------------------------------------------------------
function setSelectedEntry (sipAddress) {
Logic.setSelectedEntry(sipAddress)
function setSelectedEntry (peerAddress, localAddress) {
Logic.setSelectedEntry(peerAddress, localAddress)
}
function resetSelectedEntry () {
@ -109,7 +107,7 @@ Rectangle {
? TimelineStyle.contact.backgroundColor.a
: TimelineStyle.contact.backgroundColor.b
)
displayUnreadMessagesCount: SettingsModel.chatEnabled
displayUnreadMessageCount: SettingsModel.chatEnabled
entry: $timelineEntry
sipAddressColor: isSelected
? TimelineStyle.contact.sipAddress.color.selected

View file

@ -74,8 +74,8 @@ function getContactUsername (contact) {
}
// 2. `object` is just a string.
object = Utils.isString(contact.sipAddress)
? contact.sipAddress // String from `SipAddressObserver`.
object = Utils.isString(contact.peerAddress)
? contact.peerAddress // String from `SipAddressObserver`.
: contact // Just a String.
// Use display name.

View file

@ -647,7 +647,7 @@ function unscapeHtml (str) {
function write (fileName, text) {
// TODO: Deal with async.
var request = new XMLHttpRequest();
request.open('PUT', getUriFromSystemPath(fileName), false);
request.send(text);
var request = new XMLHttpRequest()
request.open('PUT', getUriFromSystemPath(fileName), false)
request.send(text)
}

View file

@ -13,7 +13,7 @@ Rectangle {
property var call
default property alias _actionArea: actionArea.data
property var _sipAddressObserver: SipAddressesModel.getSipAddressObserver(sipAddress)
property var _sipAddressObserver: SipAddressesModel.getSipAddressObserver(call.peerAddress, call.localAddress)
// ---------------------------------------------------------------------------
@ -40,7 +40,7 @@ Rectangle {
height: CallStyle.header.contactDescription.height
horizontalTextAlignment: Text.AlignHCenter
sipAddress: call.sipAddress
sipAddress: call.peerAddress
username: LinphoneUtils.getContactUsername(_sipAddressObserver)
width: parent.width
}

View file

@ -23,7 +23,8 @@ Window {
isOutgoing: true,
recording: false,
localSas: '',
sipAddress: '',
peerAddress: '',
localAddress: '',
type: false,
updating: true,
videoEnabled: false
@ -31,8 +32,6 @@ Window {
readonly property bool chatIsOpened: !rightPaned.isClosed()
property string sipAddress: call ? call.sipAddress : ''
// ---------------------------------------------------------------------------
function openChat () {
@ -198,7 +197,8 @@ Window {
}
}
sipAddress: window.sipAddress
peerAddress: call.peerAddress
localAddress: call.localAddress
}
Connections {
@ -225,7 +225,7 @@ Window {
childB: Loader {
anchors.fill: parent
sourceComponent: window.sipAddress ? chat : null
sourceComponent: call.peerAddress && call.localAddress ? chat : null
}
}
}

View file

@ -46,7 +46,7 @@ DialogPlus {
Contact {
Layout.fillWidth: true
entry: SipAddressesModel.getSipAddressObserver(call ? call.sipAddress : '')
entry: SipAddressesModel.getSipAddressObserver(call ? call.peerAddress : '', call ? call.localAddress : '')
}
// -------------------------------------------------------------------------

View file

@ -16,7 +16,7 @@ Rectangle {
property var call
property var _sipAddressObserver: SipAddressesModel.getSipAddressObserver(sipAddress)
property var _sipAddressObserver: SipAddressesModel.getSipAddressObserver(call ? call.peerAddress : '', call ? call.localAddress : '')
// ---------------------------------------------------------------------------
@ -37,7 +37,7 @@ Rectangle {
Layout.preferredHeight: CallStyle.header.contactDescription.height
horizontalTextAlignment: Text.AlignHCenter
sipAddress: _sipAddressObserver.sipAddress
sipAddress: _sipAddressObserver.peerAddress
username: LinphoneUtils.getContactUsername(_sipAddressObserver)
}

View file

@ -26,7 +26,7 @@ Rectangle {
property var call
property var _sipAddressObserver: SipAddressesModel.getSipAddressObserver(sipAddress)
property var _sipAddressObserver: SipAddressesModel.getSipAddressObserver(call.peerAddress, call.localAddress)
property var _fullscreen: null
// ---------------------------------------------------------------------------

View file

@ -10,7 +10,7 @@ import App.Styles 1.0
Avatar {
property var call
readonly property var _sipAddressObserver: SipAddressesModel.getSipAddressObserver(call.sipAddress)
readonly property var _sipAddressObserver: SipAddressesModel.getSipAddressObserver(call.peerAddress, call.localAddress)
readonly property var _username: LinphoneUtils.getContactUsername(_sipAddressObserver)
backgroundColor: CallStyle.container.avatar.backgroundColor

View file

@ -137,7 +137,7 @@ ColumnLayout {
SettingsModel.assistantSupportsPhoneNumbers ?
'CreateAppSipAccount' :
'CreateAppSipAccountWithEmail'
);
)
}
}
}

View file

@ -166,7 +166,8 @@ ColumnLayout {
sipAddresses: _contact ? _contact.vcard.sipAddresses : [ contactEdit.sipAddress ]
onSipAddressClicked: window.setView('Conversation', {
sipAddress: sipAddress
peerAddress: sipAddress,
localAddress: AccountSettingsModel.sipAddress
})
}

View file

@ -173,7 +173,8 @@ ColumnLayout {
CallsListModel.launchAudioCall,
function (sipAddress) {
window.setView('Conversation', {
sipAddress: sipAddress
peerAddress: sipAddress,
localAddress: AccountSettingsModel.sipAddress
})
}
]

View file

@ -13,9 +13,10 @@ import 'Conversation.js' as Logic
ColumnLayout {
id: conversation
property string sipAddress
property string peerAddress
property string localAddress
readonly property var _sipAddressObserver: SipAddressesModel.getSipAddressObserver(sipAddress)
readonly property var _sipAddressObserver: SipAddressesModel.getSipAddressObserver(peerAddress, localAddress)
// ---------------------------------------------------------------------------
@ -58,7 +59,7 @@ ColumnLayout {
Layout.fillHeight: true
Layout.fillWidth: true
sipAddress: conversation.sipAddress
sipAddress: conversation.peerAddress
sipAddressColor: ConversationStyle.bar.description.sipAddressColor
username: avatar.username
usernameColor: ConversationStyle.bar.description.usernameColor
@ -77,14 +78,14 @@ ColumnLayout {
icon: 'video_call'
visible: SettingsModel.videoSupported && SettingsModel.outgoingCallsEnabled
onClicked: CallsListModel.launchVideoCall(conversation.sipAddress)
onClicked: CallsListModel.launchVideoCall(conversation.peerAddress)
}
ActionButton {
icon: 'call'
visible: SettingsModel.outgoingCallsEnabled
onClicked: CallsListModel.launchAudioCall(conversation.sipAddress)
onClicked: CallsListModel.launchAudioCall(conversation.peerAddress)
}
}
@ -97,7 +98,7 @@ ColumnLayout {
visible: SettingsModel.contactsEnabled
onClicked: window.setView('ContactEdit', {
sipAddress: conversation.sipAddress
sipAddress: conversation.peerAddress
})
}
@ -160,7 +161,8 @@ ColumnLayout {
}
}
sipAddress: conversation.sipAddress
peerAddress: conversation.peerAddress
localAddress: conversation.localAddress
}
}

View file

@ -100,7 +100,7 @@ function updateSelectedEntry (view, props) {
menu.resetSelectedEntry()
if (view === 'Conversation') {
timeline.setSelectedEntry(props.sipAddress)
timeline.setSelectedEntry(props.peerAddress, props.localAddress)
} else if (view === 'ContactEdit') {
timeline.resetSelectedEntry()
}

View file

@ -146,15 +146,21 @@ ApplicationWindow {
sipAddress: sipAddress
})
onEntryClicked: window.setView(entry.contact && SettingsModel.contactsEnabled
? 'ContactEdit'
: 'Conversation', {
sipAddress: entry.sipAddress
})
onEntryClicked: {
if (entry.contact && SettingsModel.contactsEnabled) {
window.setView('ContactEdit', { sipAddress: entry.sipAddress })
} else {
window.setView('Conversation', {
peerAddress: entry.sipAddress,
localAddress: AccountSettingsModel.sipAddress
})
}
}
onLaunchCall: CallsListModel.launchAudioCall(sipAddress)
onLaunchChat: window.setView('Conversation', {
sipAddress: sipAddress
peerAddress: sipAddress,
localAddress: AccountSettingsModel.sipAddress
})
onLaunchVideoCall: CallsListModel.launchVideoCall(sipAddress)
@ -240,7 +246,10 @@ ApplicationWindow {
Layout.fillWidth: true
model: TimelineModel
onEntrySelected: setView('Conversation', { sipAddress: entry })
onEntrySelected: setView('Conversation', {
peerAddress: entry,
localAddress: AccountSettingsModel.sipAddress
})
}
}
@ -289,7 +298,8 @@ ApplicationWindow {
target: UrlHandlers
onSip: window.setView('Conversation', {
sipAddress: sipAddress
peerAddress: sipAddress,
localAddress: AccountSettingsModel.sipAddress
})
}
}