Change icons (notification, menus).

Simplify main menu.
Display call history by account.
Allow to remove reactions from chat.
Fix crash on conference creation.
This commit is contained in:
Julien Wadel 2023-09-08 11:44:13 +02:00
parent 820a34fd50
commit 369bc765e4
108 changed files with 3378 additions and 2679 deletions

View file

@ -9,9 +9,17 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
### Fixed ### Fixed
- Download path and emojis size settings - Download path and emojis size settings
- Mac emoji font. - Mac emoji font.
- Better SVG preview in thumbnails.
- Unstable forward message menu.
### Added ### Added
- Dedicated call history view.
- Chat reactions - Chat reactions
- Update UI layouts.
## Removed
- Call events from chats.
- Missed call count in application side (done by SDK).
## 5.1.3 - Undefined ## 5.1.3 - Undefined

View file

@ -282,6 +282,9 @@ set(SOURCES
src/components/file/TemporaryFile.cpp src/components/file/TemporaryFile.cpp
src/components/file/FileMediaModel.cpp src/components/file/FileMediaModel.cpp
src/components/friend/FriendListListener.cpp src/components/friend/FriendListListener.cpp
src/components/history/CallHistoryModel.cpp
src/components/history/CallHistoryListModel.cpp
src/components/history/CallHistoryProxyModel.cpp
src/components/history/HistoryModel.cpp src/components/history/HistoryModel.cpp
src/components/history/HistoryProxyModel.cpp src/components/history/HistoryProxyModel.cpp
src/components/ldap/LdapModel.cpp src/components/ldap/LdapModel.cpp
@ -429,6 +432,9 @@ set(HEADERS
src/components/file/TemporaryFile.hpp src/components/file/TemporaryFile.hpp
src/components/file/FileMediaModel.hpp src/components/file/FileMediaModel.hpp
src/components/friend/FriendListListener.hpp src/components/friend/FriendListListener.hpp
src/components/history/CallHistoryModel.hpp
src/components/history/CallHistoryListModel.hpp
src/components/history/CallHistoryProxyModel.hpp
src/components/history/HistoryModel.hpp src/components/history/HistoryModel.hpp
src/components/history/HistoryProxyModel.hpp src/components/history/HistoryProxyModel.hpp
src/components/ldap/LdapModel.hpp src/components/ldap/LdapModel.hpp

View file

@ -4,7 +4,7 @@
height="80" height="80"
version="1.1" version="1.1"
id="svg4" id="svg4"
sodipodi:docname="call_history_custom2.svg" sodipodi:docname="call_custom.svg"
inkscape:version="1.1 (c68e22c387, 2021-05-23)" inkscape:version="1.1 (c68e22c387, 2021-05-23)"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape" xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd" xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
@ -21,11 +21,11 @@
inkscape:pageopacity="0.0" inkscape:pageopacity="0.0"
inkscape:pagecheckerboard="0" inkscape:pagecheckerboard="0"
showgrid="false" showgrid="false"
inkscape:zoom="6.7098284" inkscape:zoom="4.7445652"
inkscape:cx="2.6081144" inkscape:cx="-20.760596"
inkscape:cy="59.763078" inkscape:cy="12.013746"
inkscape:window-width="1920" inkscape:window-width="1920"
inkscape:window-height="1131" inkscape:window-height="1043"
inkscape:window-x="0" inkscape:window-x="0"
inkscape:window-y="0" inkscape:window-y="0"
inkscape:window-maximized="1" inkscape:window-maximized="1"
@ -33,21 +33,10 @@
<path <path
d="m 20.032548,25.306346 c -2.922789,8.273156 1.173621,20.093116 7.803662,26.723927 l 0.139279,0.137194 c 6.627993,6.628763 18.450233,10.726431 26.718838,7.802159 l 6.271605,-8.22196 -8.541016,-8.539373 -7.815954,6.608287 -7.14209,-7.142763 -0.13723,-0.137195 -7.142092,-7.14276 6.607512,-7.818542 -8.53897,-8.53937 z" d="m 20.032548,25.306346 c -2.922789,8.273156 1.173621,20.093116 7.803662,26.723927 l 0.139279,0.137194 c 6.627993,6.628763 18.450233,10.726431 26.718838,7.802159 l 6.271605,-8.22196 -8.541016,-8.539373 -7.815954,6.608287 -7.14209,-7.142763 -0.13723,-0.137195 -7.142092,-7.14276 6.607512,-7.818542 -8.53897,-8.53937 z"
stroke="#000000" stroke="#000000"
stroke-width="5.072" stroke-width="3.072"
fill="none" fill="none"
fill-rule="evenodd" fill-rule="evenodd"
stroke-linecap="round" stroke-linecap="round"
stroke-linejoin="round" stroke-linejoin="round"
id="path2" id="path2" />
style="stroke-width:5.2119685;stroke-miterlimit:4;stroke-dasharray:none;paint-order:normal" />
<path
d="m 63.999928,25.141826 a 9.230749,9.2313207 0 1 1 -18.461498,0 9.2307491,9.2313205 0 0 1 18.461498,0 z m -9.232801,-4.989014 v 5.060814 H 60.0625"
stroke="#000000"
stroke-width="3.03851"
fill="none"
fill-rule="evenodd"
stroke-linecap="round"
stroke-linejoin="round"
id="path2-5"
style="stroke-width:3.17784;stroke-miterlimit:4;stroke-dasharray:none" />
</svg> </svg>

Before

Width:  |  Height:  |  Size: 1.9 KiB

After

Width:  |  Height:  |  Size: 1.4 KiB

View file

@ -11,7 +11,7 @@
</defs> </defs>
<g id="Symbols" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd"> <g id="Symbols" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
<g id="statut_avatar_busy_l"> <g id="statut_avatar_busy_l">
<path d="M7.9995,16 C3.581,16 0,12.4185 0,8 C0,3.582 3.581,0 7.9995,0 C12.418,0 16,3.582 16,8 C16,12.4185 12.418,16 7.9995,16 Z" id="statut_avatar_busy_s" class="color-i-fill" fill="#FE5E00"></path> <path d="M7.9995,16 C3.581,16 0,12.4185 0,8 C0,3.582 3.581,0 7.9995,0 C12.418,0 16,3.582 16,8 C16,12.4185 12.418,16 7.9995,16 Z" id="statut_avatar_busy_s" fill="#FF0000"></path>
<use id="statut_avatar_busy_s" stroke="#00FFFFFF" mask="url(#mask-2)" stroke-width="4" xlink:href="#path-1"></use> <use id="statut_avatar_busy_s" stroke="#00FFFFFF" mask="url(#mask-2)" stroke-width="4" xlink:href="#path-1"></use>
</g> </g>
</g> </g>

Before

Width:  |  Height:  |  Size: 1.2 KiB

After

Width:  |  Height:  |  Size: 1.2 KiB

View file

@ -1,105 +1,112 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?> <?xml version="1.0" encoding="UTF-8" standalone="no"?>
<svg <svg
version="1.1"
id="Layer_1"
x="0px"
y="0px"
width="80" width="80"
height="80" height="80"
viewBox="0 0 80 80" viewBox="0 0 80 80"
xml:space="preserve" fill="none"
version="1.1"
id="svg27"
sodipodi:docname="filter_params_custom.svg" sodipodi:docname="filter_params_custom.svg"
inkscape:version="1.1 (c68e22c387, 2021-05-23)" inkscape:version="1.2.2 (b0a8486541, 2022-12-01)"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape" xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd" xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns="http://www.w3.org/2000/svg" xmlns="http://www.w3.org/2000/svg"
xmlns:svg="http://www.w3.org/2000/svg"><defs xmlns:svg="http://www.w3.org/2000/svg">
id="defs25" /><sodipodi:namedview <sodipodi:namedview
id="namedview23" id="namedview29"
pagecolor="#ffffff" pagecolor="#ffffff"
bordercolor="#666666" bordercolor="#666666"
borderopacity="1.0" borderopacity="1.0"
inkscape:pageshadow="2" inkscape:showpageshadow="2"
inkscape:pageopacity="0.0" inkscape:pageopacity="0.0"
inkscape:pagecheckerboard="0" inkscape:pagecheckerboard="0"
showgrid="false" inkscape:deskcolor="#d1d1d1"
inkscape:zoom="13.640625" showgrid="false"
inkscape:cx="33.319588" inkscape:zoom="4.9104638"
inkscape:cy="40.687286" inkscape:cx="88.077221"
inkscape:window-width="1920" inkscape:cy="32.176187"
inkscape:window-height="1131" inkscape:window-width="1963"
inkscape:window-x="0" inkscape:window-height="1209"
inkscape:window-y="0" inkscape:window-x="26"
inkscape:window-maximized="1" inkscape:window-y="23"
inkscape:current-layer="Layer_1" /> inkscape:window-maximized="0"
<style inkscape:current-layer="svg27" />
type="text/css" <g
id="style2"> filter="url(#filter0_b_26_3850)"
.st0{fill:#000000;} id="g14"
</style> transform="matrix(2.7586207,0,0,2.7586207,11.034483,16.034483)">
<path
d="M 5,2 V 16.3347"
stroke="#000000"
stroke-width="1.5"
stroke-linecap="round"
id="path2" />
<path
d="M 15,2 V 16.3347"
<g stroke="#000000"
id="g870" stroke-width="1.5"
transform="matrix(0,0.20833333,-0.22727273,0,69.090912,13.333333)"><rect stroke-linecap="round"
x="108" id="path4" />
y="64" <path
class="st0" d="M 10,2 V 16.3347"
width="116" stroke="#000000"
height="16" stroke-width="1.5"
id="rect4" /><rect stroke-linecap="round"
x="32" id="path6" />
y="64" <circle
class="st0" cx="5"
width="24" cy="5.72189"
height="16" r="1.25"
id="rect6" /><path fill="#000000"
class="st0" stroke="#000000"
d="m 84,56 c 8.8,0 16,7.2 16,16 0,8.8 -7.2,16 -16,16 -8.8,0 -16,-7.2 -16,-16 0,-8.8 7.2,-16 16,-16 m 0,-16 c -17.7,0 -32,14.3 -32,32 0,17.7 14.3,32 32,32 17.7,0 32,-14.3 32,-32 0,-17.7 -14.3,-32 -32,-32 z" stroke-width="1.5"
id="path8" /><rect id="circle8" />
x="132" <circle
y="176" cx="15"
class="st0" cy="5.72189"
width="92" r="1.25"
height="16" fill="#000000"
id="rect10" /><rect stroke="#000000"
x="32" stroke-width="1.5"
y="176" id="circle10" />
class="st0" <circle
width="48" cx="10"
height="16" cy="12.7219"
id="rect12" /><path r="1.25"
class="st0" fill="#000000"
d="m 108,168 c 8.8,0 16,7.2 16,16 0,8.8 -7.2,16 -16,16 -8.8,0 -16,-7.2 -16,-16 0,-8.8 7.2,-16 16,-16 m 0,-16 c -17.7,0 -32,14.3 -32,32 0,17.7 14.3,32 32,32 17.7,0 32,-14.3 32,-32 0,-17.7 -14.3,-32 -32,-32 z" stroke="#000000"
id="path14" /><rect stroke-width="1.5"
x="32" id="circle12" />
y="120" </g>
class="st0" <defs
width="116" id="defs25">
height="16" <filter
id="rect16" /><rect id="filter0_b_26_3850"
x="200" x="-4"
y="120" y="-4"
class="st0" width="29"
width="24" height="26"
height="16" filterUnits="userSpaceOnUse"
id="rect18" /><path color-interpolation-filters="sRGB">
class="st0" <feFlood
d="m 172,112 c 8.8,0 16,7.2 16,16 0,8.8 -7.2,16 -16,16 -8.8,0 -16,-7.2 -16,-16 0,-8.8 7.2,-16 16,-16 m 0,-16 c -17.7,0 -32,14.3 -32,32 0,17.7 14.3,32 32,32 17.7,0 32,-14.3 32,-32 0,-17.7 -14.3,-32 -32,-32 z" flood-opacity="0"
id="path20" /></g> result="BackgroundImageFix"
<path id="feFlood16" />
style="fill:#000000;stroke-width:1.24628" <feGaussianBlur
d="m 26.480571,39.100741 c -1.240541,-0.237768 -2.354137,-1.20884 -2.70286,-2.356933 -0.35178,-1.158159 -0.01556,-2.390762 0.876927,-3.214894 0.771356,-0.712275 1.553169,-1.015741 2.61684,-1.015741 1.471109,0 2.706656,0.729807 3.313172,1.95701 0.236125,0.477766 0.275153,0.632062 0.302022,1.194042 0.02517,0.526467 0.0012,0.734641 -0.130367,1.129851 -0.556222,1.671447 -2.400071,2.666163 -4.275734,2.306665 z" in="BackgroundImageFix"
id="path905" /><path stdDeviation="2"
style="fill:#000000;stroke-width:1.24628" id="feGaussianBlur18" />
d="m 39.130367,52.415919 c -1.751718,-0.380575 -3.023331,-2.107078 -2.740129,-3.720347 0.318831,-1.816233 2.097722,-3.045769 4.097474,-2.832096 1.959774,0.209401 3.422761,1.981513 3.115711,3.774055 -0.33496,1.955482 -2.388809,3.231208 -4.473056,2.778388 z" <feComposite
id="path944" /><path in2="SourceAlpha"
style="fill:#000000;stroke-width:1.24628" operator="in"
d="m 51.897251,34.09053 c -1.291519,-0.28101 -2.396632,-1.29209 -2.713659,-2.482754 -0.438408,-1.646541 0.609221,-3.377901 2.385004,-3.941568 0.683573,-0.216979 1.70512,-0.214333 2.351222,0.0061 2.486916,0.848431 3.243723,3.649845 1.466208,5.42736 -0.882409,0.882409 -2.229224,1.264928 -3.488775,0.990873 z" result="effect1_backgroundBlur_26_3850"
id="path983" /></svg> id="feComposite20" />
<feBlend
mode="normal"
in="SourceGraphic"
in2="effect1_backgroundBlur_26_3850"
result="shape"
id="feBlend22" />
</filter>
</defs>
</svg>

Before

Width:  |  Height:  |  Size: 3.7 KiB

After

Width:  |  Height:  |  Size: 2.8 KiB

View file

@ -4,8 +4,8 @@
height="80" height="80"
version="1.1" version="1.1"
id="svg4" id="svg4"
sodipodi:docname="close_custom.svg" sodipodi:docname="missed_incoming_call_custom.svg"
inkscape:version="1.1 (c68e22c387, 2021-05-23)" inkscape:version="1.2.2 (b0a8486541, 2022-12-01)"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape" xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd" xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns="http://www.w3.org/2000/svg" xmlns="http://www.w3.org/2000/svg"
@ -24,16 +24,18 @@
inkscape:zoom="4.1971154" inkscape:zoom="4.1971154"
inkscape:cx="-29.66323" inkscape:cx="-29.66323"
inkscape:cy="23.34937" inkscape:cy="23.34937"
inkscape:window-width="1920" inkscape:window-width="1499"
inkscape:window-height="1131" inkscape:window-height="1111"
inkscape:window-x="0" inkscape:window-x="26"
inkscape:window-y="0" inkscape:window-y="23"
inkscape:window-maximized="1" inkscape:window-maximized="0"
inkscape:current-layer="svg4" /> inkscape:current-layer="svg4"
inkscape:showpageshadow="2"
inkscape:deskcolor="#d1d1d1" />
<path <path
d="M 27.255215,52.745704 51.112191,28.89804 52.772276,27.233933 27.255215,52.743448 Z m -0.01579,-25.511771 23.85472,23.849921 1.664598,1.659594 z" d="M 23.08194,57.916804 55.684473,25.326996 57.953116,23.052856 23.08194,57.913721 Z m -0.02158,-34.863948 32.59945,32.592892 2.274811,2.267973 z"
stroke="#000000" stroke="#000000"
stroke-width="4.51043" stroke-width="6.16388"
fill="none" fill="none"
fill-rule="evenodd" fill-rule="evenodd"
stroke-linecap="round" stroke-linecap="round"

Before

Width:  |  Height:  |  Size: 1.3 KiB

After

Width:  |  Height:  |  Size: 1.4 KiB

View file

@ -4,8 +4,8 @@
height="80" height="80"
version="1.1" version="1.1"
id="svg4" id="svg4"
sodipodi:docname="close_custom.svg" sodipodi:docname="missed_outgoing_call_custom.svg"
inkscape:version="1.1 (c68e22c387, 2021-05-23)" inkscape:version="1.2.2 (b0a8486541, 2022-12-01)"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape" xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd" xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns="http://www.w3.org/2000/svg" xmlns="http://www.w3.org/2000/svg"
@ -22,18 +22,20 @@
inkscape:pagecheckerboard="0" inkscape:pagecheckerboard="0"
showgrid="false" showgrid="false"
inkscape:zoom="4.1971154" inkscape:zoom="4.1971154"
inkscape:cx="-29.66323" inkscape:cx="-29.305842"
inkscape:cy="23.34937" inkscape:cy="23.34937"
inkscape:window-width="1920" inkscape:window-width="1920"
inkscape:window-height="1131" inkscape:window-height="1011"
inkscape:window-x="0" inkscape:window-x="0"
inkscape:window-y="0" inkscape:window-y="0"
inkscape:window-maximized="1" inkscape:window-maximized="1"
inkscape:current-layer="svg4" /> inkscape:current-layer="svg4"
inkscape:showpageshadow="2"
inkscape:deskcolor="#d1d1d1" />
<path <path
d="M 27.255215,52.745704 51.112191,28.89804 52.772276,27.233933 27.255215,52.743448 Z m -0.01579,-25.511771 23.85472,23.849921 1.664598,1.659594 z" d="M 23.081774,57.918657 55.678996,25.326969 57.94727,23.052697 23.081774,57.915574 Z m -0.02158,-34.86596 32.594137,32.594771 2.274441,2.268106 z"
stroke="#000000" stroke="#000000"
stroke-width="4.51043" stroke-width="6.16356"
fill="none" fill="none"
fill-rule="evenodd" fill-rule="evenodd"
stroke-linecap="round" stroke-linecap="round"

Before

Width:  |  Height:  |  Size: 1.3 KiB

After

Width:  |  Height:  |  Size: 1.4 KiB

View file

@ -451,6 +451,34 @@
<translation>Šifrování médií</translation> <translation>Šifrování médií</translation>
</message> </message>
</context> </context>
<context>
<name>CallTimeline</name>
<message>
<source>callListTitle</source>
<extracomment>&apos;Call list&apos; : Call histories title</extracomment>
<translation type="unfinished"></translation>
</message>
<message>
<source>incomingFilter</source>
<extracomment>&apos;Incoming&apos; : Filter label for incoming call</extracomment>
<translation type="unfinished"></translation>
</message>
<message>
<source>outgoingFilter</source>
<extracomment>&apos;Outgoing&apos; : Filter label for outgoing call</extracomment>
<translation type="unfinished"></translation>
</message>
<message>
<source>missedFilter</source>
<extracomment>&apos;Missed&apos; : Filter label for missed call</extracomment>
<translation type="unfinished"></translation>
</message>
<message>
<source>searchListPlaceholderText</source>
<extracomment>&apos;Search in the list&apos; : ths is a placeholder when searching something in a list</extracomment>
<translation type="unfinished"></translation>
</message>
</context>
<context> <context>
<name>CallTransfer</name> <name>CallTransfer</name>
<message> <message>
@ -920,6 +948,11 @@ Adresa URL není nakonfigurována.</translation>
<extracomment>&apos;The meeting has been deleted&apos; : Message text in a banner to warn the user that the meeting has been deleted.</extracomment> <extracomment>&apos;The meeting has been deleted&apos; : Message text in a banner to warn the user that the meeting has been deleted.</extracomment>
<translation>Schůzka byla smazána</translation> <translation>Schůzka byla smazána</translation>
</message> </message>
<message>
<source>createMeeting</source>
<extracomment>&apos;Create Meeting&apos; : Button label to create a meeting</extracomment>
<translation type="unfinished"></translation>
</message>
</context> </context>
<context> <context>
<name>ConfirmDialog</name> <name>ConfirmDialog</name>
@ -1030,12 +1063,9 @@ Adresa URL není nakonfigurována.</translation>
</message> </message>
<message> <message>
<source>selectAllContacts</source> <source>selectAllContacts</source>
<extracomment>&apos;All&apos; : Filter label to display all items.</extracomment>
<translation>Vše</translation> <translation>Vše</translation>
</message> </message>
<message>
<source>selectConnectedContacts</source>
<translation>Připojeno</translation>
</message>
<message> <message>
<source>addContact</source> <source>addContact</source>
<translation>PŘIDAT KONTAKT</translation> <translation>PŘIDAT KONTAKT</translation>
@ -1049,21 +1079,24 @@ Adresa URL není nakonfigurována.</translation>
<extracomment>&apos;You need to set the conference URI in your account settings to create a conference based chat room.&apos; : Tooltip to warn the user that a setting is missing in its configuration.</extracomment> <extracomment>&apos;You need to set the conference URI in your account settings to create a conference based chat room.&apos; : Tooltip to warn the user that a setting is missing in its configuration.</extracomment>
<translation>Chcete-li vytvořit chatovací místnost založenou na konferenci, musíte v nastavení účtu nastavit URI konference.</translation> <translation>Chcete-li vytvořit chatovací místnost založenou na konferenci, musíte v nastavení účtu nastavit URI konference.</translation>
</message> </message>
<message>
<source>localContactsEntry</source>
<extracomment>&apos;Local contacts&apos; : Contacts section label in main window when we have to specify that they are local to the application.</extracomment>
<translation type="unfinished">Místní kontakty</translation>
</message>
<message>
<source>contactsEntry</source>
<extracomment>&apos;Contacts&apos; : Contacts section label in main waindow.</extracomment>
<translation type="unfinished">KONTAKTY</translation>
</message>
<message>
<source>selectOnlineContacts</source>
<extracomment>&apos;Online&apos; : Filter label to display only online contacts.</extracomment>
<translation type="unfinished"></translation>
</message>
</context> </context>
<context> <context>
<name>Conversation</name> <name>Conversation</name>
<message>
<source>displayCallsAndMessages</source>
<translation>VŠE</translation>
</message>
<message>
<source>displayCalls</source>
<translation>HOVORY</translation>
</message>
<message>
<source>displayMessages</source>
<translation>ZPRÁVY</translation>
</message>
<message> <message>
<source>removeAllEntriesDescription</source> <source>removeAllEntriesDescription</source>
<translation>Jste si jisti, že chcete tuto historii vymazat?</translation> <translation>Jste si jisti, že chcete tuto historii vymazat?</translation>
@ -1855,11 +1888,6 @@ Klikněte zde: &lt;a href=&quot;%1&quot;&gt;%1&lt;/a&gt;
<source>mainSearchBarPlaceholder</source> <source>mainSearchBarPlaceholder</source>
<translation>Vyhledejte kontakt, začněte hovor nebo chat</translation> <translation>Vyhledejte kontakt, začněte hovor nebo chat</translation>
</message> </message>
<message>
<source>contactsEntry</source>
<extracomment>&apos;Contacts&apos; : Contacts section label in main waindow.</extracomment>
<translation>KONTAKTY</translation>
</message>
<message> <message>
<source>autoAnswerStatus</source> <source>autoAnswerStatus</source>
<translation>automaticky</translation> <translation>automaticky</translation>
@ -1877,26 +1905,11 @@ Klikněte zde: &lt;a href=&quot;%1&quot;&gt;%1&lt;/a&gt;
<extracomment>&apos;Start a chat room&apos; : Tooltip to illustrate a button</extracomment> <extracomment>&apos;Start a chat room&apos; : Tooltip to illustrate a button</extracomment>
<translation>Založit chatovací místnost</translation> <translation>Založit chatovací místnost</translation>
</message> </message>
<message>
<source>hideTimeline</source>
<extracomment>&apos;Hide Timeline&apos; : Tooltip for a button that hide the timeline</extracomment>
<translation>Skrýt události</translation>
</message>
<message>
<source>openTimeline</source>
<extracomment>&apos;Open Timeline&apos; : Tooltip for a button that open the timeline</extracomment>
<translation>Otevřít časovou osu</translation>
</message>
<message> <message>
<source>openHome</source> <source>openHome</source>
<extracomment>&apos;Open Home&apos; : Tooltip for a button that open the home view</extracomment> <extracomment>&apos;Open Home&apos; : Tooltip for a button that open the home view</extracomment>
<translation>Domů</translation> <translation>Domů</translation>
</message> </message>
<message>
<source>mainWindowConferencesTitle</source>
<extracomment>&apos;Meetings&apos; : Meeting title for main window.</extracomment>
<translation>Schůzky</translation>
</message>
<message> <message>
<source>newChatRoomUriMissing</source> <source>newChatRoomUriMissing</source>
<extracomment>&apos;Conference URI is not set. You have to change it in your account settings in order to create new group chats.&apos; : Tooltip to warn the user to change a setting to activate an action.</extracomment> <extracomment>&apos;Conference URI is not set. You have to change it in your account settings in order to create new group chats.&apos; : Tooltip to warn the user to change a setting to activate an action.</extracomment>
@ -1913,9 +1926,24 @@ Klikněte zde: &lt;a href=&quot;%1&quot;&gt;%1&lt;/a&gt;
<translation>Chcete stáhnout a použít konfiguraci z této adresy URL?</translation> <translation>Chcete stáhnout a použít konfiguraci z této adresy URL?</translation>
</message> </message>
<message> <message>
<source>localContactsEntry</source> <source>openCalls</source>
<extracomment>&apos;Local contacts&apos; : Contacts section label in main window when we have to specify that they are local to the application.</extracomment> <extracomment>&apos;Open call history&apos; : Tooltip for a button that open the call history view</extracomment>
<translation>Místní kontakty</translation> <translation type="unfinished"></translation>
</message>
<message>
<source>openChats</source>
<extracomment>&apos;Open chats&apos; : Tooltip for a button that open the conversations view</extracomment>
<translation type="unfinished"></translation>
</message>
<message>
<source>openContacts</source>
<extracomment>&apos;Open contacts&apos; : Tooltip for a button that open the contacts view</extracomment>
<translation type="unfinished"></translation>
</message>
<message>
<source>openMeetings</source>
<extracomment>&apos;Open meetings&apos; : Tooltip for a button that open the meetings list</extracomment>
<translation type="unfinished"></translation>
</message> </message>
</context> </context>
<context> <context>
@ -3944,26 +3972,6 @@ Klikněte zde: &lt;a href=&quot;%1&quot;&gt;%1&lt;/a&gt;
</context> </context>
<context> <context>
<name>Timeline</name> <name>Timeline</name>
<message>
<source>timelineFilter</source>
<extracomment>A title for filtering mode.</extracomment>
<translation>Filtr</translation>
</message>
<message>
<source>timelineFilterAll</source>
<extracomment>&apos;All&apos; The mode for timelines filtering.</extracomment>
<translation>Vše</translation>
</message>
<message>
<source>timelineFilterCustom</source>
<extracomment>&apos;Custom&apos; The mode for timelines filtering.</extracomment>
<translation>Vlastní</translation>
</message>
<message>
<source>timelineFilterSimpleRooms</source>
<extracomment>&apos;Simple rooms&apos; : Filter item. Selecting it will show all secure chat groups (with more than one participant).</extracomment>
<translation>Místnosti s 1 a více účastníky</translation>
</message>
<message> <message>
<source>timelineFilterSecureRooms</source> <source>timelineFilterSecureRooms</source>
<extracomment>&apos;Secure rooms&apos; : Filter item. Selecting it will show all secure rooms.</extracomment> <extracomment>&apos;Secure rooms&apos; : Filter item. Selecting it will show all secure rooms.</extracomment>
@ -3974,45 +3982,15 @@ Klikněte zde: &lt;a href=&quot;%1&quot;&gt;%1&lt;/a&gt;
<extracomment>&apos;Chat groups&apos; : Filter item. Selecting it will show all chat groups (with more than one participant).</extracomment> <extracomment>&apos;Chat groups&apos; : Filter item. Selecting it will show all chat groups (with more than one participant).</extracomment>
<translation>Skupiny chatu</translation> <translation>Skupiny chatu</translation>
</message> </message>
<message>
<source>timelineFilterEphemerals</source>
<extracomment>&apos;Ephemerals&apos; : Filter item. Selecting it will show all chat rooms where the ephemeral mode has been enabled.</extracomment>
<translation>Povoleny mizející zprávy</translation>
</message>
<message> <message>
<source>timelineSearchPlaceholderText</source> <source>timelineSearchPlaceholderText</source>
<extracomment>&apos;Search in the list&apos; : ths is a placeholder when searching something in the timeline list</extracomment> <extracomment>&apos;Search in the list&apos; : ths is a placeholder when searching something in the timeline list</extracomment>
<translation>Hledat v seznamu</translation> <translation>Hledat v seznamu</translation>
</message> </message>
<message> <message>
<source>timelineFilterAllSecureLevelRooms</source> <source>chatsTitle</source>
<extracomment>&apos;All security levels&apos; : Filter item. Selecting it will not do any filter on security level.</extracomment> <extracomment>&apos;Messages&apos; : Title for conversations</extracomment>
<translation>Všechny úrovně zabezpečení</translation> <translation type="unfinished"></translation>
</message>
<message>
<source>timelineFilterStandardRooms</source>
<extracomment>&apos;Standard rooms&apos; : Filter item. Selecting it will show all simple rooms.</extracomment>
<translation>Standardní místnosti</translation>
</message>
<message>
<source>timelineFilterAnyChatRooms</source>
<extracomment>&apos;Any conversations&apos; : Filter item. Selecting it will not do any filter on the type of conversations.</extracomment>
<translation>Jakékoli konverzace</translation>
</message>
<message>
<source>timelineFilterAnyEphemerals</source>
<extracomment>&apos;Ephemerals on/off&apos; : Filter item. Selecting it will not do any filter on ephemerals activation.</extracomment>
<translation>Mizející zap/vyp</translation>
</message>
<message>
<source>timelineFilterNoEphemerals</source>
<extracomment>&apos;No Ephemerals&apos; : Filter item. Selecting it will hide all chat rooms where the ephemeral mode has been enabled.</extracomment>
<translation>Bez mizejících</translation>
</message>
<message>
<source>timelineFilterConferences</source>
<extracomment>&apos;Conferences&apos; : Filter item. Selecting it will show all conferences.</extracomment>
<translation>Konference</translation>
</message> </message>
</context> </context>
<context> <context>

View file

@ -451,6 +451,34 @@
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
</context> </context>
<context>
<name>CallTimeline</name>
<message>
<source>callListTitle</source>
<extracomment>&apos;Call list&apos; : Call histories title</extracomment>
<translation type="unfinished"></translation>
</message>
<message>
<source>incomingFilter</source>
<extracomment>&apos;Incoming&apos; : Filter label for incoming call</extracomment>
<translation type="unfinished"></translation>
</message>
<message>
<source>outgoingFilter</source>
<extracomment>&apos;Outgoing&apos; : Filter label for outgoing call</extracomment>
<translation type="unfinished"></translation>
</message>
<message>
<source>missedFilter</source>
<extracomment>&apos;Missed&apos; : Filter label for missed call</extracomment>
<translation type="unfinished"></translation>
</message>
<message>
<source>searchListPlaceholderText</source>
<extracomment>&apos;Search in the list&apos; : ths is a placeholder when searching something in a list</extracomment>
<translation type="unfinished"></translation>
</message>
</context>
<context> <context>
<name>CallTransfer</name> <name>CallTransfer</name>
<message> <message>
@ -913,6 +941,11 @@ Server url ikke konfigureret.</translation>
<extracomment>&apos;The meeting has been deleted&apos; : Message text in a banner to warn the user that the meeting has been deleted.</extracomment> <extracomment>&apos;The meeting has been deleted&apos; : Message text in a banner to warn the user that the meeting has been deleted.</extracomment>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
<message>
<source>createMeeting</source>
<extracomment>&apos;Create Meeting&apos; : Button label to create a meeting</extracomment>
<translation type="unfinished"></translation>
</message>
</context> </context>
<context> <context>
<name>ConfirmDialog</name> <name>ConfirmDialog</name>
@ -1023,12 +1056,9 @@ Server url ikke konfigureret.</translation>
</message> </message>
<message> <message>
<source>selectAllContacts</source> <source>selectAllContacts</source>
<extracomment>&apos;All&apos; : Filter label to display all items.</extracomment>
<translation>Alle</translation> <translation>Alle</translation>
</message> </message>
<message>
<source>selectConnectedContacts</source>
<translation>Forbundet</translation>
</message>
<message> <message>
<source>addContact</source> <source>addContact</source>
<translation>OPRET KONTAKT</translation> <translation>OPRET KONTAKT</translation>
@ -1042,21 +1072,24 @@ Server url ikke konfigureret.</translation>
<extracomment>&apos;You need to set the conference URI in your account settings to create a conference based chat room.&apos; : Tooltip to warn the user that a setting is missing in its configuration.</extracomment> <extracomment>&apos;You need to set the conference URI in your account settings to create a conference based chat room.&apos; : Tooltip to warn the user that a setting is missing in its configuration.</extracomment>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
<message>
<source>localContactsEntry</source>
<extracomment>&apos;Local contacts&apos; : Contacts section label in main window when we have to specify that they are local to the application.</extracomment>
<translation type="unfinished"></translation>
</message>
<message>
<source>contactsEntry</source>
<extracomment>&apos;Contacts&apos; : Contacts section label in main waindow.</extracomment>
<translation type="unfinished">KONTAKTER</translation>
</message>
<message>
<source>selectOnlineContacts</source>
<extracomment>&apos;Online&apos; : Filter label to display only online contacts.</extracomment>
<translation type="unfinished"></translation>
</message>
</context> </context>
<context> <context>
<name>Conversation</name> <name>Conversation</name>
<message>
<source>displayCallsAndMessages</source>
<translation>ALLE</translation>
</message>
<message>
<source>displayCalls</source>
<translation>OPKALD</translation>
</message>
<message>
<source>displayMessages</source>
<translation>BESKEDER</translation>
</message>
<message> <message>
<source>removeAllEntriesDescription</source> <source>removeAllEntriesDescription</source>
<translation>Er du sikker at du vil rydde op historikken?</translation> <translation>Er du sikker at du vil rydde op historikken?</translation>
@ -1844,11 +1877,6 @@ Klik her: &lt;a href=&quot;%1&quot;&gt;%1&lt;/a&gt;
<source>mainSearchBarPlaceholder</source> <source>mainSearchBarPlaceholder</source>
<translation>Søg en kontakt, start en samtale eller en chat</translation> <translation>Søg en kontakt, start en samtale eller en chat</translation>
</message> </message>
<message>
<source>contactsEntry</source>
<extracomment>&apos;Contacts&apos; : Contacts section label in main waindow.</extracomment>
<translation>KONTAKTER</translation>
</message>
<message> <message>
<source>autoAnswerStatus</source> <source>autoAnswerStatus</source>
<translation>auto</translation> <translation>auto</translation>
@ -1866,26 +1894,11 @@ Klik her: &lt;a href=&quot;%1&quot;&gt;%1&lt;/a&gt;
<extracomment>&apos;Start a chat room&apos; : Tooltip to illustrate a button</extracomment> <extracomment>&apos;Start a chat room&apos; : Tooltip to illustrate a button</extracomment>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
<message>
<source>hideTimeline</source>
<extracomment>&apos;Hide Timeline&apos; : Tooltip for a button that hide the timeline</extracomment>
<translation type="unfinished"></translation>
</message>
<message>
<source>openTimeline</source>
<extracomment>&apos;Open Timeline&apos; : Tooltip for a button that open the timeline</extracomment>
<translation type="unfinished"></translation>
</message>
<message> <message>
<source>openHome</source> <source>openHome</source>
<extracomment>&apos;Open Home&apos; : Tooltip for a button that open the home view</extracomment> <extracomment>&apos;Open Home&apos; : Tooltip for a button that open the home view</extracomment>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
<message>
<source>mainWindowConferencesTitle</source>
<extracomment>&apos;Meetings&apos; : Meeting title for main window.</extracomment>
<translation type="unfinished"></translation>
</message>
<message> <message>
<source>newChatRoomUriMissing</source> <source>newChatRoomUriMissing</source>
<extracomment>&apos;Conference URI is not set. You have to change it in your account settings in order to create new group chats.&apos; : Tooltip to warn the user to change a setting to activate an action.</extracomment> <extracomment>&apos;Conference URI is not set. You have to change it in your account settings in order to create new group chats.&apos; : Tooltip to warn the user to change a setting to activate an action.</extracomment>
@ -1902,8 +1915,23 @@ Klik her: &lt;a href=&quot;%1&quot;&gt;%1&lt;/a&gt;
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
<message> <message>
<source>localContactsEntry</source> <source>openCalls</source>
<extracomment>&apos;Local contacts&apos; : Contacts section label in main window when we have to specify that they are local to the application.</extracomment> <extracomment>&apos;Open call history&apos; : Tooltip for a button that open the call history view</extracomment>
<translation type="unfinished"></translation>
</message>
<message>
<source>openChats</source>
<extracomment>&apos;Open chats&apos; : Tooltip for a button that open the conversations view</extracomment>
<translation type="unfinished"></translation>
</message>
<message>
<source>openContacts</source>
<extracomment>&apos;Open contacts&apos; : Tooltip for a button that open the contacts view</extracomment>
<translation type="unfinished"></translation>
</message>
<message>
<source>openMeetings</source>
<extracomment>&apos;Open meetings&apos; : Tooltip for a button that open the meetings list</extracomment>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
</context> </context>
@ -3906,26 +3934,6 @@ Klik her: &lt;a href=&quot;%1&quot;&gt;%1&lt;/a&gt;
</context> </context>
<context> <context>
<name>Timeline</name> <name>Timeline</name>
<message>
<source>timelineFilter</source>
<extracomment>A title for filtering mode.</extracomment>
<translation type="unfinished"></translation>
</message>
<message>
<source>timelineFilterAll</source>
<extracomment>&apos;All&apos; The mode for timelines filtering.</extracomment>
<translation type="unfinished"></translation>
</message>
<message>
<source>timelineFilterCustom</source>
<extracomment>&apos;Custom&apos; The mode for timelines filtering.</extracomment>
<translation type="unfinished"></translation>
</message>
<message>
<source>timelineFilterSimpleRooms</source>
<extracomment>&apos;Simple rooms&apos; : Filter item. Selecting it will show all secure chat groups (with more than one participant).</extracomment>
<translation type="unfinished"></translation>
</message>
<message> <message>
<source>timelineFilterSecureRooms</source> <source>timelineFilterSecureRooms</source>
<extracomment>&apos;Secure rooms&apos; : Filter item. Selecting it will show all secure rooms.</extracomment> <extracomment>&apos;Secure rooms&apos; : Filter item. Selecting it will show all secure rooms.</extracomment>
@ -3936,44 +3944,14 @@ Klik her: &lt;a href=&quot;%1&quot;&gt;%1&lt;/a&gt;
<extracomment>&apos;Chat groups&apos; : Filter item. Selecting it will show all chat groups (with more than one participant).</extracomment> <extracomment>&apos;Chat groups&apos; : Filter item. Selecting it will show all chat groups (with more than one participant).</extracomment>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
<message>
<source>timelineFilterEphemerals</source>
<extracomment>&apos;Ephemerals&apos; : Filter item. Selecting it will show all chat rooms where the ephemeral mode has been enabled.</extracomment>
<translation type="unfinished"></translation>
</message>
<message> <message>
<source>timelineSearchPlaceholderText</source> <source>timelineSearchPlaceholderText</source>
<extracomment>&apos;Search in the list&apos; : ths is a placeholder when searching something in the timeline list</extracomment> <extracomment>&apos;Search in the list&apos; : ths is a placeholder when searching something in the timeline list</extracomment>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
<message> <message>
<source>timelineFilterAllSecureLevelRooms</source> <source>chatsTitle</source>
<extracomment>&apos;All security levels&apos; : Filter item. Selecting it will not do any filter on security level.</extracomment> <extracomment>&apos;Messages&apos; : Title for conversations</extracomment>
<translation type="unfinished"></translation>
</message>
<message>
<source>timelineFilterStandardRooms</source>
<extracomment>&apos;Standard rooms&apos; : Filter item. Selecting it will show all simple rooms.</extracomment>
<translation type="unfinished"></translation>
</message>
<message>
<source>timelineFilterAnyChatRooms</source>
<extracomment>&apos;Any conversations&apos; : Filter item. Selecting it will not do any filter on the type of conversations.</extracomment>
<translation type="unfinished"></translation>
</message>
<message>
<source>timelineFilterAnyEphemerals</source>
<extracomment>&apos;Ephemerals on/off&apos; : Filter item. Selecting it will not do any filter on ephemerals activation.</extracomment>
<translation type="unfinished"></translation>
</message>
<message>
<source>timelineFilterNoEphemerals</source>
<extracomment>&apos;No Ephemerals&apos; : Filter item. Selecting it will hide all chat rooms where the ephemeral mode has been enabled.</extracomment>
<translation type="unfinished"></translation>
</message>
<message>
<source>timelineFilterConferences</source>
<extracomment>&apos;Conferences&apos; : Filter item. Selecting it will show all conferences.</extracomment>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
</context> </context>

View file

@ -451,6 +451,34 @@
<translation>Medienverschlüsselung</translation> <translation>Medienverschlüsselung</translation>
</message> </message>
</context> </context>
<context>
<name>CallTimeline</name>
<message>
<source>callListTitle</source>
<extracomment>&apos;Call list&apos; : Call histories title</extracomment>
<translation type="unfinished"></translation>
</message>
<message>
<source>incomingFilter</source>
<extracomment>&apos;Incoming&apos; : Filter label for incoming call</extracomment>
<translation type="unfinished"></translation>
</message>
<message>
<source>outgoingFilter</source>
<extracomment>&apos;Outgoing&apos; : Filter label for outgoing call</extracomment>
<translation type="unfinished"></translation>
</message>
<message>
<source>missedFilter</source>
<extracomment>&apos;Missed&apos; : Filter label for missed call</extracomment>
<translation type="unfinished"></translation>
</message>
<message>
<source>searchListPlaceholderText</source>
<extracomment>&apos;Search in the list&apos; : ths is a placeholder when searching something in a list</extracomment>
<translation type="unfinished"></translation>
</message>
</context>
<context> <context>
<name>CallTransfer</name> <name>CallTransfer</name>
<message> <message>
@ -913,6 +941,11 @@ Server URL ist nicht konfiguriert.</translation>
<extracomment>&apos;The meeting has been deleted&apos; : Message text in a banner to warn the user that the meeting has been deleted.</extracomment> <extracomment>&apos;The meeting has been deleted&apos; : Message text in a banner to warn the user that the meeting has been deleted.</extracomment>
<translation>Diese Besprechungen wurde gelöscht</translation> <translation>Diese Besprechungen wurde gelöscht</translation>
</message> </message>
<message>
<source>createMeeting</source>
<extracomment>&apos;Create Meeting&apos; : Button label to create a meeting</extracomment>
<translation type="unfinished"></translation>
</message>
</context> </context>
<context> <context>
<name>ConfirmDialog</name> <name>ConfirmDialog</name>
@ -1023,12 +1056,9 @@ Server URL ist nicht konfiguriert.</translation>
</message> </message>
<message> <message>
<source>selectAllContacts</source> <source>selectAllContacts</source>
<extracomment>&apos;All&apos; : Filter label to display all items.</extracomment>
<translation>Alle</translation> <translation>Alle</translation>
</message> </message>
<message>
<source>selectConnectedContacts</source>
<translation>Verbunden</translation>
</message>
<message> <message>
<source>addContact</source> <source>addContact</source>
<translation>KONTAKT HINZUFÜGEN</translation> <translation>KONTAKT HINZUFÜGEN</translation>
@ -1042,21 +1072,24 @@ Server URL ist nicht konfiguriert.</translation>
<extracomment>&apos;You need to set the conference URI in your account settings to create a conference based chat room.&apos; : Tooltip to warn the user that a setting is missing in its configuration.</extracomment> <extracomment>&apos;You need to set the conference URI in your account settings to create a conference based chat room.&apos; : Tooltip to warn the user that a setting is missing in its configuration.</extracomment>
<translation>Sie müssen eine Konferenz-URI in den Kontoeinstellungen festlegen um einen konferenzbasierten Chatraum zu erstellen.</translation> <translation>Sie müssen eine Konferenz-URI in den Kontoeinstellungen festlegen um einen konferenzbasierten Chatraum zu erstellen.</translation>
</message> </message>
<message>
<source>localContactsEntry</source>
<extracomment>&apos;Local contacts&apos; : Contacts section label in main window when we have to specify that they are local to the application.</extracomment>
<translation type="unfinished"></translation>
</message>
<message>
<source>contactsEntry</source>
<extracomment>&apos;Contacts&apos; : Contacts section label in main waindow.</extracomment>
<translation type="unfinished">KONTAKTE</translation>
</message>
<message>
<source>selectOnlineContacts</source>
<extracomment>&apos;Online&apos; : Filter label to display only online contacts.</extracomment>
<translation type="unfinished"></translation>
</message>
</context> </context>
<context> <context>
<name>Conversation</name> <name>Conversation</name>
<message>
<source>displayCallsAndMessages</source>
<translation>ALLE</translation>
</message>
<message>
<source>displayCalls</source>
<translation>ANRUFE</translation>
</message>
<message>
<source>displayMessages</source>
<translation>NACHRICHTEN</translation>
</message>
<message> <message>
<source>removeAllEntriesDescription</source> <source>removeAllEntriesDescription</source>
<translation>Möchten Sie diese Historie wirklich löschen?</translation> <translation>Möchten Sie diese Historie wirklich löschen?</translation>
@ -1844,11 +1877,6 @@ Klicken Sie hier: &lt;a href=&quot;%1&quot;&gt;%1&lt;/a&gt;
<source>mainSearchBarPlaceholder</source> <source>mainSearchBarPlaceholder</source>
<translation>Suche Kontakte, starte einen Anruf oder Chat</translation> <translation>Suche Kontakte, starte einen Anruf oder Chat</translation>
</message> </message>
<message>
<source>contactsEntry</source>
<extracomment>&apos;Contacts&apos; : Contacts section label in main waindow.</extracomment>
<translation>KONTAKTE</translation>
</message>
<message> <message>
<source>autoAnswerStatus</source> <source>autoAnswerStatus</source>
<translation>automatisch</translation> <translation>automatisch</translation>
@ -1866,26 +1894,11 @@ Klicken Sie hier: &lt;a href=&quot;%1&quot;&gt;%1&lt;/a&gt;
<extracomment>&apos;Start a chat room&apos; : Tooltip to illustrate a button</extracomment> <extracomment>&apos;Start a chat room&apos; : Tooltip to illustrate a button</extracomment>
<translation>Starte einen Chatraum</translation> <translation>Starte einen Chatraum</translation>
</message> </message>
<message>
<source>hideTimeline</source>
<extracomment>&apos;Hide Timeline&apos; : Tooltip for a button that hide the timeline</extracomment>
<translation>Verlauf verstecken</translation>
</message>
<message>
<source>openTimeline</source>
<extracomment>&apos;Open Timeline&apos; : Tooltip for a button that open the timeline</extracomment>
<translation>Verlauf öffnen</translation>
</message>
<message> <message>
<source>openHome</source> <source>openHome</source>
<extracomment>&apos;Open Home&apos; : Tooltip for a button that open the home view</extracomment> <extracomment>&apos;Open Home&apos; : Tooltip for a button that open the home view</extracomment>
<translation>Startseite öffnen</translation> <translation>Startseite öffnen</translation>
</message> </message>
<message>
<source>mainWindowConferencesTitle</source>
<extracomment>&apos;Meetings&apos; : Meeting title for main window.</extracomment>
<translation>Besprechungen</translation>
</message>
<message> <message>
<source>newChatRoomUriMissing</source> <source>newChatRoomUriMissing</source>
<extracomment>&apos;Conference URI is not set. You have to change it in your account settings in order to create new group chats.&apos; : Tooltip to warn the user to change a setting to activate an action.</extracomment> <extracomment>&apos;Conference URI is not set. You have to change it in your account settings in order to create new group chats.&apos; : Tooltip to warn the user to change a setting to activate an action.</extracomment>
@ -1902,8 +1915,23 @@ Klicken Sie hier: &lt;a href=&quot;%1&quot;&gt;%1&lt;/a&gt;
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
<message> <message>
<source>localContactsEntry</source> <source>openCalls</source>
<extracomment>&apos;Local contacts&apos; : Contacts section label in main window when we have to specify that they are local to the application.</extracomment> <extracomment>&apos;Open call history&apos; : Tooltip for a button that open the call history view</extracomment>
<translation type="unfinished"></translation>
</message>
<message>
<source>openChats</source>
<extracomment>&apos;Open chats&apos; : Tooltip for a button that open the conversations view</extracomment>
<translation type="unfinished"></translation>
</message>
<message>
<source>openContacts</source>
<extracomment>&apos;Open contacts&apos; : Tooltip for a button that open the contacts view</extracomment>
<translation type="unfinished"></translation>
</message>
<message>
<source>openMeetings</source>
<extracomment>&apos;Open meetings&apos; : Tooltip for a button that open the meetings list</extracomment>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
</context> </context>
@ -3906,26 +3934,6 @@ Klicken Sie hier: &lt;a href=&quot;%1&quot;&gt;%1&lt;/a&gt;
</context> </context>
<context> <context>
<name>Timeline</name> <name>Timeline</name>
<message>
<source>timelineFilter</source>
<extracomment>A title for filtering mode.</extracomment>
<translation>Filter</translation>
</message>
<message>
<source>timelineFilterAll</source>
<extracomment>&apos;All&apos; The mode for timelines filtering.</extracomment>
<translation>Alle</translation>
</message>
<message>
<source>timelineFilterCustom</source>
<extracomment>&apos;Custom&apos; The mode for timelines filtering.</extracomment>
<translation>Individuell</translation>
</message>
<message>
<source>timelineFilterSimpleRooms</source>
<extracomment>&apos;Simple rooms&apos; : Filter item. Selecting it will show all secure chat groups (with more than one participant).</extracomment>
<translation>Einfache Räume</translation>
</message>
<message> <message>
<source>timelineFilterSecureRooms</source> <source>timelineFilterSecureRooms</source>
<extracomment>&apos;Secure rooms&apos; : Filter item. Selecting it will show all secure rooms.</extracomment> <extracomment>&apos;Secure rooms&apos; : Filter item. Selecting it will show all secure rooms.</extracomment>
@ -3936,44 +3944,14 @@ Klicken Sie hier: &lt;a href=&quot;%1&quot;&gt;%1&lt;/a&gt;
<extracomment>&apos;Chat groups&apos; : Filter item. Selecting it will show all chat groups (with more than one participant).</extracomment> <extracomment>&apos;Chat groups&apos; : Filter item. Selecting it will show all chat groups (with more than one participant).</extracomment>
<translation>Chatgruppen</translation> <translation>Chatgruppen</translation>
</message> </message>
<message>
<source>timelineFilterEphemerals</source>
<extracomment>&apos;Ephemerals&apos; : Filter item. Selecting it will show all chat rooms where the ephemeral mode has been enabled.</extracomment>
<translation>Kurzlebiges</translation>
</message>
<message> <message>
<source>timelineSearchPlaceholderText</source> <source>timelineSearchPlaceholderText</source>
<extracomment>&apos;Search in the list&apos; : ths is a placeholder when searching something in the timeline list</extracomment> <extracomment>&apos;Search in the list&apos; : ths is a placeholder when searching something in the timeline list</extracomment>
<translation>In der Liste suchen</translation> <translation>In der Liste suchen</translation>
</message> </message>
<message> <message>
<source>timelineFilterAllSecureLevelRooms</source> <source>chatsTitle</source>
<extracomment>&apos;All security levels&apos; : Filter item. Selecting it will not do any filter on security level.</extracomment> <extracomment>&apos;Messages&apos; : Title for conversations</extracomment>
<translation type="unfinished"></translation>
</message>
<message>
<source>timelineFilterStandardRooms</source>
<extracomment>&apos;Standard rooms&apos; : Filter item. Selecting it will show all simple rooms.</extracomment>
<translation type="unfinished"></translation>
</message>
<message>
<source>timelineFilterAnyChatRooms</source>
<extracomment>&apos;Any conversations&apos; : Filter item. Selecting it will not do any filter on the type of conversations.</extracomment>
<translation type="unfinished"></translation>
</message>
<message>
<source>timelineFilterAnyEphemerals</source>
<extracomment>&apos;Ephemerals on/off&apos; : Filter item. Selecting it will not do any filter on ephemerals activation.</extracomment>
<translation type="unfinished"></translation>
</message>
<message>
<source>timelineFilterNoEphemerals</source>
<extracomment>&apos;No Ephemerals&apos; : Filter item. Selecting it will hide all chat rooms where the ephemeral mode has been enabled.</extracomment>
<translation type="unfinished"></translation>
</message>
<message>
<source>timelineFilterConferences</source>
<extracomment>&apos;Conferences&apos; : Filter item. Selecting it will show all conferences.</extracomment>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
</context> </context>

View file

@ -451,6 +451,34 @@
<translation>Media encryption</translation> <translation>Media encryption</translation>
</message> </message>
</context> </context>
<context>
<name>CallTimeline</name>
<message>
<source>callListTitle</source>
<extracomment>&apos;Call list&apos; : Call histories title</extracomment>
<translation>Call list</translation>
</message>
<message>
<source>incomingFilter</source>
<extracomment>&apos;Incoming&apos; : Filter label for incoming call</extracomment>
<translation>Incoming</translation>
</message>
<message>
<source>outgoingFilter</source>
<extracomment>&apos;Outgoing&apos; : Filter label for outgoing call</extracomment>
<translation>Outgoing</translation>
</message>
<message>
<source>missedFilter</source>
<extracomment>&apos;Missed&apos; : Filter label for missed call</extracomment>
<translation>Missed</translation>
</message>
<message>
<source>searchListPlaceholderText</source>
<extracomment>&apos;Search in the list&apos; : ths is a placeholder when searching something in a list</extracomment>
<translation>Search in the list</translation>
</message>
</context>
<context> <context>
<name>CallTransfer</name> <name>CallTransfer</name>
<message> <message>
@ -913,6 +941,11 @@ Server URL not configured.</translation>
<extracomment>&apos;The meeting has been deleted&apos; : Message text in a banner to warn the user that the meeting has been deleted.</extracomment> <extracomment>&apos;The meeting has been deleted&apos; : Message text in a banner to warn the user that the meeting has been deleted.</extracomment>
<translation>The meeting has been deleted</translation> <translation>The meeting has been deleted</translation>
</message> </message>
<message>
<source>createMeeting</source>
<extracomment>&apos;Create Meeting&apos; : Button label to create a meeting</extracomment>
<translation>Create Meeting</translation>
</message>
</context> </context>
<context> <context>
<name>ConfirmDialog</name> <name>ConfirmDialog</name>
@ -1023,12 +1056,9 @@ Server URL not configured.</translation>
</message> </message>
<message> <message>
<source>selectAllContacts</source> <source>selectAllContacts</source>
<extracomment>&apos;All&apos; : Filter label to display all items.</extracomment>
<translation>All</translation> <translation>All</translation>
</message> </message>
<message>
<source>selectConnectedContacts</source>
<translation>Connected</translation>
</message>
<message> <message>
<source>addContact</source> <source>addContact</source>
<translation>ADD CONTACT</translation> <translation>ADD CONTACT</translation>
@ -1042,21 +1072,24 @@ Server URL not configured.</translation>
<extracomment>&apos;You need to set the conference URI in your account settings to create a conference based chat room.&apos; : Tooltip to warn the user that a setting is missing in its configuration.</extracomment> <extracomment>&apos;You need to set the conference URI in your account settings to create a conference based chat room.&apos; : Tooltip to warn the user that a setting is missing in its configuration.</extracomment>
<translation>You need to set the conference URI in your account settings to create a conference based chat room.</translation> <translation>You need to set the conference URI in your account settings to create a conference based chat room.</translation>
</message> </message>
<message>
<source>localContactsEntry</source>
<extracomment>&apos;Local contacts&apos; : Contacts section label in main window when we have to specify that they are local to the application.</extracomment>
<translation>Local contacts</translation>
</message>
<message>
<source>contactsEntry</source>
<extracomment>&apos;Contacts&apos; : Contacts section label in main waindow.</extracomment>
<translation>Contacts</translation>
</message>
<message>
<source>selectOnlineContacts</source>
<extracomment>&apos;Online&apos; : Filter label to display only online contacts.</extracomment>
<translation>Online</translation>
</message>
</context> </context>
<context> <context>
<name>Conversation</name> <name>Conversation</name>
<message>
<source>displayCallsAndMessages</source>
<translation>ALL</translation>
</message>
<message>
<source>displayCalls</source>
<translation>CALLS</translation>
</message>
<message>
<source>displayMessages</source>
<translation>MESSAGES</translation>
</message>
<message> <message>
<source>removeAllEntriesDescription</source> <source>removeAllEntriesDescription</source>
<translation>Are you sure you want to clear this history?</translation> <translation>Are you sure you want to clear this history?</translation>
@ -1844,11 +1877,6 @@ Click here: &lt;a href=&quot;%1&quot;&gt;%1&lt;/a&gt;
<source>mainSearchBarPlaceholder</source> <source>mainSearchBarPlaceholder</source>
<translation>Search contact, start a call or a chat</translation> <translation>Search contact, start a call or a chat</translation>
</message> </message>
<message>
<source>contactsEntry</source>
<extracomment>&apos;Contacts&apos; : Contacts section label in main waindow.</extracomment>
<translation>CONTACTS</translation>
</message>
<message> <message>
<source>autoAnswerStatus</source> <source>autoAnswerStatus</source>
<translation>auto</translation> <translation>auto</translation>
@ -1866,26 +1894,11 @@ Click here: &lt;a href=&quot;%1&quot;&gt;%1&lt;/a&gt;
<extracomment>&apos;Start a chat room&apos; : Tooltip to illustrate a button</extracomment> <extracomment>&apos;Start a chat room&apos; : Tooltip to illustrate a button</extracomment>
<translation>Start a chat room</translation> <translation>Start a chat room</translation>
</message> </message>
<message>
<source>hideTimeline</source>
<extracomment>&apos;Hide Timeline&apos; : Tooltip for a button that hide the timeline</extracomment>
<translation>Hide Timeline</translation>
</message>
<message>
<source>openTimeline</source>
<extracomment>&apos;Open Timeline&apos; : Tooltip for a button that open the timeline</extracomment>
<translation>Open Timeline</translation>
</message>
<message> <message>
<source>openHome</source> <source>openHome</source>
<extracomment>&apos;Open Home&apos; : Tooltip for a button that open the home view</extracomment> <extracomment>&apos;Open Home&apos; : Tooltip for a button that open the home view</extracomment>
<translation>Open Home</translation> <translation>Open Home</translation>
</message> </message>
<message>
<source>mainWindowConferencesTitle</source>
<extracomment>&apos;Meetings&apos; : Meeting title for main window.</extracomment>
<translation>Meetings</translation>
</message>
<message> <message>
<source>newChatRoomUriMissing</source> <source>newChatRoomUriMissing</source>
<extracomment>&apos;Conference URI is not set. You have to change it in your account settings in order to create new group chats.&apos; : Tooltip to warn the user to change a setting to activate an action.</extracomment> <extracomment>&apos;Conference URI is not set. You have to change it in your account settings in order to create new group chats.&apos; : Tooltip to warn the user to change a setting to activate an action.</extracomment>
@ -1902,9 +1915,24 @@ Click here: &lt;a href=&quot;%1&quot;&gt;%1&lt;/a&gt;
<translation>Do you want to download and apply configuration from this URL?</translation> <translation>Do you want to download and apply configuration from this URL?</translation>
</message> </message>
<message> <message>
<source>localContactsEntry</source> <source>openCalls</source>
<extracomment>&apos;Local contacts&apos; : Contacts section label in main window when we have to specify that they are local to the application.</extracomment> <extracomment>&apos;Open call history&apos; : Tooltip for a button that open the call history view</extracomment>
<translation>Local contacts</translation> <translation>Open call history</translation>
</message>
<message>
<source>openChats</source>
<extracomment>&apos;Open chats&apos; : Tooltip for a button that open the conversations view</extracomment>
<translation>Open chats</translation>
</message>
<message>
<source>openContacts</source>
<extracomment>&apos;Open contacts&apos; : Tooltip for a button that open the contacts view</extracomment>
<translation>Open contacts</translation>
</message>
<message>
<source>openMeetings</source>
<extracomment>&apos;Open meetings&apos; : Tooltip for a button that open the meetings list</extracomment>
<translation>Open meetings</translation>
</message> </message>
</context> </context>
<context> <context>
@ -3931,26 +3959,6 @@ Click here: &lt;a href=&quot;%1&quot;&gt;%1&lt;/a&gt;
</context> </context>
<context> <context>
<name>Timeline</name> <name>Timeline</name>
<message>
<source>timelineFilter</source>
<extracomment>A title for filtering mode.</extracomment>
<translation>Filter</translation>
</message>
<message>
<source>timelineFilterAll</source>
<extracomment>&apos;All&apos; The mode for timelines filtering.</extracomment>
<translation>All</translation>
</message>
<message>
<source>timelineFilterCustom</source>
<extracomment>&apos;Custom&apos; The mode for timelines filtering.</extracomment>
<translation>Custom</translation>
</message>
<message>
<source>timelineFilterSimpleRooms</source>
<extracomment>&apos;Simple rooms&apos; : Filter item. Selecting it will show all secure chat groups (with more than one participant).</extracomment>
<translation>Simple rooms</translation>
</message>
<message> <message>
<source>timelineFilterSecureRooms</source> <source>timelineFilterSecureRooms</source>
<extracomment>&apos;Secure rooms&apos; : Filter item. Selecting it will show all secure rooms.</extracomment> <extracomment>&apos;Secure rooms&apos; : Filter item. Selecting it will show all secure rooms.</extracomment>
@ -3961,45 +3969,15 @@ Click here: &lt;a href=&quot;%1&quot;&gt;%1&lt;/a&gt;
<extracomment>&apos;Chat groups&apos; : Filter item. Selecting it will show all chat groups (with more than one participant).</extracomment> <extracomment>&apos;Chat groups&apos; : Filter item. Selecting it will show all chat groups (with more than one participant).</extracomment>
<translation>Chat groups</translation> <translation>Chat groups</translation>
</message> </message>
<message>
<source>timelineFilterEphemerals</source>
<extracomment>&apos;Ephemerals&apos; : Filter item. Selecting it will show all chat rooms where the ephemeral mode has been enabled.</extracomment>
<translation>Ephemerals</translation>
</message>
<message> <message>
<source>timelineSearchPlaceholderText</source> <source>timelineSearchPlaceholderText</source>
<extracomment>&apos;Search in the list&apos; : ths is a placeholder when searching something in the timeline list</extracomment> <extracomment>&apos;Search in the list&apos; : ths is a placeholder when searching something in the timeline list</extracomment>
<translation>Search in the list</translation> <translation>Search in the list</translation>
</message> </message>
<message> <message>
<source>timelineFilterAllSecureLevelRooms</source> <source>chatsTitle</source>
<extracomment>&apos;All security levels&apos; : Filter item. Selecting it will not do any filter on security level.</extracomment> <extracomment>&apos;Messages&apos; : Title for conversations</extracomment>
<translation>All security levels</translation> <translation>Messages</translation>
</message>
<message>
<source>timelineFilterStandardRooms</source>
<extracomment>&apos;Standard rooms&apos; : Filter item. Selecting it will show all simple rooms.</extracomment>
<translation>Standard rooms</translation>
</message>
<message>
<source>timelineFilterAnyChatRooms</source>
<extracomment>&apos;Any conversations&apos; : Filter item. Selecting it will not do any filter on the type of conversations.</extracomment>
<translation>Any conversations</translation>
</message>
<message>
<source>timelineFilterAnyEphemerals</source>
<extracomment>&apos;Ephemerals on/off&apos; : Filter item. Selecting it will not do any filter on ephemerals activation.</extracomment>
<translation>Ephemerals on/off</translation>
</message>
<message>
<source>timelineFilterNoEphemerals</source>
<extracomment>&apos;No Ephemerals&apos; : Filter item. Selecting it will hide all chat rooms where the ephemeral mode has been enabled.</extracomment>
<translation>Without ephemerals</translation>
</message>
<message>
<source>timelineFilterConferences</source>
<extracomment>&apos;Conferences&apos; : Filter item. Selecting it will show all conferences.</extracomment>
<translation>Conferences</translation>
</message> </message>
</context> </context>
<context> <context>

View file

@ -451,6 +451,34 @@
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
</context> </context>
<context>
<name>CallTimeline</name>
<message>
<source>callListTitle</source>
<extracomment>&apos;Call list&apos; : Call histories title</extracomment>
<translation type="unfinished"></translation>
</message>
<message>
<source>incomingFilter</source>
<extracomment>&apos;Incoming&apos; : Filter label for incoming call</extracomment>
<translation type="unfinished"></translation>
</message>
<message>
<source>outgoingFilter</source>
<extracomment>&apos;Outgoing&apos; : Filter label for outgoing call</extracomment>
<translation type="unfinished"></translation>
</message>
<message>
<source>missedFilter</source>
<extracomment>&apos;Missed&apos; : Filter label for missed call</extracomment>
<translation type="unfinished"></translation>
</message>
<message>
<source>searchListPlaceholderText</source>
<extracomment>&apos;Search in the list&apos; : ths is a placeholder when searching something in a list</extracomment>
<translation type="unfinished"></translation>
</message>
</context>
<context> <context>
<name>CallTransfer</name> <name>CallTransfer</name>
<message> <message>
@ -913,6 +941,11 @@ URL del servidor no configurada.</translation>
<extracomment>&apos;The meeting has been deleted&apos; : Message text in a banner to warn the user that the meeting has been deleted.</extracomment> <extracomment>&apos;The meeting has been deleted&apos; : Message text in a banner to warn the user that the meeting has been deleted.</extracomment>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
<message>
<source>createMeeting</source>
<extracomment>&apos;Create Meeting&apos; : Button label to create a meeting</extracomment>
<translation type="unfinished"></translation>
</message>
</context> </context>
<context> <context>
<name>ConfirmDialog</name> <name>ConfirmDialog</name>
@ -1023,12 +1056,9 @@ URL del servidor no configurada.</translation>
</message> </message>
<message> <message>
<source>selectAllContacts</source> <source>selectAllContacts</source>
<extracomment>&apos;All&apos; : Filter label to display all items.</extracomment>
<translation>Todo</translation> <translation>Todo</translation>
</message> </message>
<message>
<source>selectConnectedContacts</source>
<translation>Conectado</translation>
</message>
<message> <message>
<source>addContact</source> <source>addContact</source>
<translation>AÑADIR CONTACTO</translation> <translation>AÑADIR CONTACTO</translation>
@ -1042,21 +1072,24 @@ URL del servidor no configurada.</translation>
<extracomment>&apos;You need to set the conference URI in your account settings to create a conference based chat room.&apos; : Tooltip to warn the user that a setting is missing in its configuration.</extracomment> <extracomment>&apos;You need to set the conference URI in your account settings to create a conference based chat room.&apos; : Tooltip to warn the user that a setting is missing in its configuration.</extracomment>
<translation>Debe configurar el URL de la conferencia en la configuración de su cuenta para crear una conferencia basada en una sala de chat.</translation> <translation>Debe configurar el URL de la conferencia en la configuración de su cuenta para crear una conferencia basada en una sala de chat.</translation>
</message> </message>
<message>
<source>localContactsEntry</source>
<extracomment>&apos;Local contacts&apos; : Contacts section label in main window when we have to specify that they are local to the application.</extracomment>
<translation type="unfinished"></translation>
</message>
<message>
<source>contactsEntry</source>
<extracomment>&apos;Contacts&apos; : Contacts section label in main waindow.</extracomment>
<translation type="unfinished">CONTACTOS</translation>
</message>
<message>
<source>selectOnlineContacts</source>
<extracomment>&apos;Online&apos; : Filter label to display only online contacts.</extracomment>
<translation type="unfinished"></translation>
</message>
</context> </context>
<context> <context>
<name>Conversation</name> <name>Conversation</name>
<message>
<source>displayCallsAndMessages</source>
<translation>TODO</translation>
</message>
<message>
<source>displayCalls</source>
<translation>LLAMADAS</translation>
</message>
<message>
<source>displayMessages</source>
<translation>MENSAJES</translation>
</message>
<message> <message>
<source>removeAllEntriesDescription</source> <source>removeAllEntriesDescription</source>
<translation>¿Estás seguro de que quieres limpiar este historial?</translation> <translation>¿Estás seguro de que quieres limpiar este historial?</translation>
@ -1844,11 +1877,6 @@ Haga clic aquí: &lt;a href=&quot;%1&quot;&gt;%1 &lt;/a&gt;
<source>mainSearchBarPlaceholder</source> <source>mainSearchBarPlaceholder</source>
<translation>Buscar contacto, empezar una llamada o un chat</translation> <translation>Buscar contacto, empezar una llamada o un chat</translation>
</message> </message>
<message>
<source>contactsEntry</source>
<extracomment>&apos;Contacts&apos; : Contacts section label in main waindow.</extracomment>
<translation>CONTACTOS</translation>
</message>
<message> <message>
<source>autoAnswerStatus</source> <source>autoAnswerStatus</source>
<translation>automático</translation> <translation>automático</translation>
@ -1866,26 +1894,11 @@ Haga clic aquí: &lt;a href=&quot;%1&quot;&gt;%1 &lt;/a&gt;
<extracomment>&apos;Start a chat room&apos; : Tooltip to illustrate a button</extracomment> <extracomment>&apos;Start a chat room&apos; : Tooltip to illustrate a button</extracomment>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
<message>
<source>hideTimeline</source>
<extracomment>&apos;Hide Timeline&apos; : Tooltip for a button that hide the timeline</extracomment>
<translation type="unfinished"></translation>
</message>
<message>
<source>openTimeline</source>
<extracomment>&apos;Open Timeline&apos; : Tooltip for a button that open the timeline</extracomment>
<translation type="unfinished"></translation>
</message>
<message> <message>
<source>openHome</source> <source>openHome</source>
<extracomment>&apos;Open Home&apos; : Tooltip for a button that open the home view</extracomment> <extracomment>&apos;Open Home&apos; : Tooltip for a button that open the home view</extracomment>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
<message>
<source>mainWindowConferencesTitle</source>
<extracomment>&apos;Meetings&apos; : Meeting title for main window.</extracomment>
<translation type="unfinished"></translation>
</message>
<message> <message>
<source>newChatRoomUriMissing</source> <source>newChatRoomUriMissing</source>
<extracomment>&apos;Conference URI is not set. You have to change it in your account settings in order to create new group chats.&apos; : Tooltip to warn the user to change a setting to activate an action.</extracomment> <extracomment>&apos;Conference URI is not set. You have to change it in your account settings in order to create new group chats.&apos; : Tooltip to warn the user to change a setting to activate an action.</extracomment>
@ -1902,8 +1915,23 @@ Haga clic aquí: &lt;a href=&quot;%1&quot;&gt;%1 &lt;/a&gt;
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
<message> <message>
<source>localContactsEntry</source> <source>openCalls</source>
<extracomment>&apos;Local contacts&apos; : Contacts section label in main window when we have to specify that they are local to the application.</extracomment> <extracomment>&apos;Open call history&apos; : Tooltip for a button that open the call history view</extracomment>
<translation type="unfinished"></translation>
</message>
<message>
<source>openChats</source>
<extracomment>&apos;Open chats&apos; : Tooltip for a button that open the conversations view</extracomment>
<translation type="unfinished"></translation>
</message>
<message>
<source>openContacts</source>
<extracomment>&apos;Open contacts&apos; : Tooltip for a button that open the contacts view</extracomment>
<translation type="unfinished"></translation>
</message>
<message>
<source>openMeetings</source>
<extracomment>&apos;Open meetings&apos; : Tooltip for a button that open the meetings list</extracomment>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
</context> </context>
@ -3906,26 +3934,6 @@ Haga clic aquí: &lt;a href=&quot;%1&quot;&gt;%1 &lt;/a&gt;
</context> </context>
<context> <context>
<name>Timeline</name> <name>Timeline</name>
<message>
<source>timelineFilter</source>
<extracomment>A title for filtering mode.</extracomment>
<translation type="unfinished"></translation>
</message>
<message>
<source>timelineFilterAll</source>
<extracomment>&apos;All&apos; The mode for timelines filtering.</extracomment>
<translation type="unfinished"></translation>
</message>
<message>
<source>timelineFilterCustom</source>
<extracomment>&apos;Custom&apos; The mode for timelines filtering.</extracomment>
<translation type="unfinished"></translation>
</message>
<message>
<source>timelineFilterSimpleRooms</source>
<extracomment>&apos;Simple rooms&apos; : Filter item. Selecting it will show all secure chat groups (with more than one participant).</extracomment>
<translation type="unfinished"></translation>
</message>
<message> <message>
<source>timelineFilterSecureRooms</source> <source>timelineFilterSecureRooms</source>
<extracomment>&apos;Secure rooms&apos; : Filter item. Selecting it will show all secure rooms.</extracomment> <extracomment>&apos;Secure rooms&apos; : Filter item. Selecting it will show all secure rooms.</extracomment>
@ -3936,44 +3944,14 @@ Haga clic aquí: &lt;a href=&quot;%1&quot;&gt;%1 &lt;/a&gt;
<extracomment>&apos;Chat groups&apos; : Filter item. Selecting it will show all chat groups (with more than one participant).</extracomment> <extracomment>&apos;Chat groups&apos; : Filter item. Selecting it will show all chat groups (with more than one participant).</extracomment>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
<message>
<source>timelineFilterEphemerals</source>
<extracomment>&apos;Ephemerals&apos; : Filter item. Selecting it will show all chat rooms where the ephemeral mode has been enabled.</extracomment>
<translation type="unfinished"></translation>
</message>
<message> <message>
<source>timelineSearchPlaceholderText</source> <source>timelineSearchPlaceholderText</source>
<extracomment>&apos;Search in the list&apos; : ths is a placeholder when searching something in the timeline list</extracomment> <extracomment>&apos;Search in the list&apos; : ths is a placeholder when searching something in the timeline list</extracomment>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
<message> <message>
<source>timelineFilterAllSecureLevelRooms</source> <source>chatsTitle</source>
<extracomment>&apos;All security levels&apos; : Filter item. Selecting it will not do any filter on security level.</extracomment> <extracomment>&apos;Messages&apos; : Title for conversations</extracomment>
<translation type="unfinished"></translation>
</message>
<message>
<source>timelineFilterStandardRooms</source>
<extracomment>&apos;Standard rooms&apos; : Filter item. Selecting it will show all simple rooms.</extracomment>
<translation type="unfinished"></translation>
</message>
<message>
<source>timelineFilterAnyChatRooms</source>
<extracomment>&apos;Any conversations&apos; : Filter item. Selecting it will not do any filter on the type of conversations.</extracomment>
<translation type="unfinished"></translation>
</message>
<message>
<source>timelineFilterAnyEphemerals</source>
<extracomment>&apos;Ephemerals on/off&apos; : Filter item. Selecting it will not do any filter on ephemerals activation.</extracomment>
<translation type="unfinished"></translation>
</message>
<message>
<source>timelineFilterNoEphemerals</source>
<extracomment>&apos;No Ephemerals&apos; : Filter item. Selecting it will hide all chat rooms where the ephemeral mode has been enabled.</extracomment>
<translation type="unfinished"></translation>
</message>
<message>
<source>timelineFilterConferences</source>
<extracomment>&apos;Conferences&apos; : Filter item. Selecting it will show all conferences.</extracomment>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
</context> </context>

View file

@ -451,6 +451,34 @@
<translation>Chiffrement du média</translation> <translation>Chiffrement du média</translation>
</message> </message>
</context> </context>
<context>
<name>CallTimeline</name>
<message>
<source>callListTitle</source>
<extracomment>&apos;Call list&apos; : Call histories title</extracomment>
<translation type="unfinished"></translation>
</message>
<message>
<source>incomingFilter</source>
<extracomment>&apos;Incoming&apos; : Filter label for incoming call</extracomment>
<translation type="unfinished"></translation>
</message>
<message>
<source>outgoingFilter</source>
<extracomment>&apos;Outgoing&apos; : Filter label for outgoing call</extracomment>
<translation type="unfinished"></translation>
</message>
<message>
<source>missedFilter</source>
<extracomment>&apos;Missed&apos; : Filter label for missed call</extracomment>
<translation type="unfinished"></translation>
</message>
<message>
<source>searchListPlaceholderText</source>
<extracomment>&apos;Search in the list&apos; : ths is a placeholder when searching something in a list</extracomment>
<translation type="unfinished"></translation>
</message>
</context>
<context> <context>
<name>CallTransfer</name> <name>CallTransfer</name>
<message> <message>
@ -913,6 +941,11 @@ URL du serveur non configurée.</translation>
<extracomment>&apos;The meeting has been deleted&apos; : Message text in a banner to warn the user that the meeting has been deleted.</extracomment> <extracomment>&apos;The meeting has been deleted&apos; : Message text in a banner to warn the user that the meeting has been deleted.</extracomment>
<translation>La réunion a é supprimée</translation> <translation>La réunion a é supprimée</translation>
</message> </message>
<message>
<source>createMeeting</source>
<extracomment>&apos;Create Meeting&apos; : Button label to create a meeting</extracomment>
<translation type="unfinished"></translation>
</message>
</context> </context>
<context> <context>
<name>ConfirmDialog</name> <name>ConfirmDialog</name>
@ -1023,12 +1056,9 @@ URL du serveur non configurée.</translation>
</message> </message>
<message> <message>
<source>selectAllContacts</source> <source>selectAllContacts</source>
<extracomment>&apos;All&apos; : Filter label to display all items.</extracomment>
<translation>Tous</translation> <translation>Tous</translation>
</message> </message>
<message>
<source>selectConnectedContacts</source>
<translation>Connectés</translation>
</message>
<message> <message>
<source>addContact</source> <source>addContact</source>
<translation>AJOUTER UN CONTACT</translation> <translation>AJOUTER UN CONTACT</translation>
@ -1042,21 +1072,24 @@ URL du serveur non configurée.</translation>
<extracomment>&apos;You need to set the conference URI in your account settings to create a conference based chat room.&apos; : Tooltip to warn the user that a setting is missing in its configuration.</extracomment> <extracomment>&apos;You need to set the conference URI in your account settings to create a conference based chat room.&apos; : Tooltip to warn the user that a setting is missing in its configuration.</extracomment>
<translation>Vous devez définir l&apos;URI de la conférence dans les paramètres de votre compte pour créer une conférence.</translation> <translation>Vous devez définir l&apos;URI de la conférence dans les paramètres de votre compte pour créer une conférence.</translation>
</message> </message>
<message>
<source>localContactsEntry</source>
<extracomment>&apos;Local contacts&apos; : Contacts section label in main window when we have to specify that they are local to the application.</extracomment>
<translation type="unfinished">Contacts locaux</translation>
</message>
<message>
<source>contactsEntry</source>
<extracomment>&apos;Contacts&apos; : Contacts section label in main waindow.</extracomment>
<translation type="unfinished">CONTACTS</translation>
</message>
<message>
<source>selectOnlineContacts</source>
<extracomment>&apos;Online&apos; : Filter label to display only online contacts.</extracomment>
<translation type="unfinished"></translation>
</message>
</context> </context>
<context> <context>
<name>Conversation</name> <name>Conversation</name>
<message>
<source>displayCallsAndMessages</source>
<translation>TOUT</translation>
</message>
<message>
<source>displayCalls</source>
<translation>APPELS</translation>
</message>
<message>
<source>displayMessages</source>
<translation>MESSAGES</translation>
</message>
<message> <message>
<source>removeAllEntriesDescription</source> <source>removeAllEntriesDescription</source>
<translation>Êtes-vous sûr de vouloir supprimer cet historique ?</translation> <translation>Êtes-vous sûr de vouloir supprimer cet historique ?</translation>
@ -1844,11 +1877,6 @@ Cliquez ici : &lt;a href=&quot;%1&quot;&gt;%1&lt;/a&gt;
<source>mainSearchBarPlaceholder</source> <source>mainSearchBarPlaceholder</source>
<translation>Chercher un contact, appeler ou envoyer un message</translation> <translation>Chercher un contact, appeler ou envoyer un message</translation>
</message> </message>
<message>
<source>contactsEntry</source>
<extracomment>&apos;Contacts&apos; : Contacts section label in main waindow.</extracomment>
<translation>CONTACTS</translation>
</message>
<message> <message>
<source>autoAnswerStatus</source> <source>autoAnswerStatus</source>
<translation>auto</translation> <translation>auto</translation>
@ -1866,26 +1894,11 @@ Cliquez ici : &lt;a href=&quot;%1&quot;&gt;%1&lt;/a&gt;
<extracomment>&apos;Start a chat room&apos; : Tooltip to illustrate a button</extracomment> <extracomment>&apos;Start a chat room&apos; : Tooltip to illustrate a button</extracomment>
<translation>Commencer une conversation</translation> <translation>Commencer une conversation</translation>
</message> </message>
<message>
<source>hideTimeline</source>
<extracomment>&apos;Hide Timeline&apos; : Tooltip for a button that hide the timeline</extracomment>
<translation>Masquer la chronologie</translation>
</message>
<message>
<source>openTimeline</source>
<extracomment>&apos;Open Timeline&apos; : Tooltip for a button that open the timeline</extracomment>
<translation>Afficher la chronologie</translation>
</message>
<message> <message>
<source>openHome</source> <source>openHome</source>
<extracomment>&apos;Open Home&apos; : Tooltip for a button that open the home view</extracomment> <extracomment>&apos;Open Home&apos; : Tooltip for a button that open the home view</extracomment>
<translation>Ouvrir la page d&apos;accueil</translation> <translation>Ouvrir la page d&apos;accueil</translation>
</message> </message>
<message>
<source>mainWindowConferencesTitle</source>
<extracomment>&apos;Meetings&apos; : Meeting title for main window.</extracomment>
<translation>Réunions</translation>
</message>
<message> <message>
<source>newChatRoomUriMissing</source> <source>newChatRoomUriMissing</source>
<extracomment>&apos;Conference URI is not set. You have to change it in your account settings in order to create new group chats.&apos; : Tooltip to warn the user to change a setting to activate an action.</extracomment> <extracomment>&apos;Conference URI is not set. You have to change it in your account settings in order to create new group chats.&apos; : Tooltip to warn the user to change a setting to activate an action.</extracomment>
@ -1902,9 +1915,24 @@ Cliquez ici : &lt;a href=&quot;%1&quot;&gt;%1&lt;/a&gt;
<translation>Voulez-vous télécharger et appliquer la configuration depuis cette adresse ?</translation> <translation>Voulez-vous télécharger et appliquer la configuration depuis cette adresse ?</translation>
</message> </message>
<message> <message>
<source>localContactsEntry</source> <source>openCalls</source>
<extracomment>&apos;Local contacts&apos; : Contacts section label in main window when we have to specify that they are local to the application.</extracomment> <extracomment>&apos;Open call history&apos; : Tooltip for a button that open the call history view</extracomment>
<translation>Contacts locaux</translation> <translation type="unfinished"></translation>
</message>
<message>
<source>openChats</source>
<extracomment>&apos;Open chats&apos; : Tooltip for a button that open the conversations view</extracomment>
<translation type="unfinished"></translation>
</message>
<message>
<source>openContacts</source>
<extracomment>&apos;Open contacts&apos; : Tooltip for a button that open the contacts view</extracomment>
<translation type="unfinished"></translation>
</message>
<message>
<source>openMeetings</source>
<extracomment>&apos;Open meetings&apos; : Tooltip for a button that open the meetings list</extracomment>
<translation type="unfinished"></translation>
</message> </message>
</context> </context>
<context> <context>
@ -3906,26 +3934,6 @@ Cliquez ici : &lt;a href=&quot;%1&quot;&gt;%1&lt;/a&gt;
</context> </context>
<context> <context>
<name>Timeline</name> <name>Timeline</name>
<message>
<source>timelineFilter</source>
<extracomment>A title for filtering mode.</extracomment>
<translation>Filtre</translation>
</message>
<message>
<source>timelineFilterAll</source>
<extracomment>&apos;All&apos; The mode for timelines filtering.</extracomment>
<translation>Tous</translation>
</message>
<message>
<source>timelineFilterCustom</source>
<extracomment>&apos;Custom&apos; The mode for timelines filtering.</extracomment>
<translation>Personnalisé</translation>
</message>
<message>
<source>timelineFilterSimpleRooms</source>
<extracomment>&apos;Simple rooms&apos; : Filter item. Selecting it will show all secure chat groups (with more than one participant).</extracomment>
<translation>Standards</translation>
</message>
<message> <message>
<source>timelineFilterSecureRooms</source> <source>timelineFilterSecureRooms</source>
<extracomment>&apos;Secure rooms&apos; : Filter item. Selecting it will show all secure rooms.</extracomment> <extracomment>&apos;Secure rooms&apos; : Filter item. Selecting it will show all secure rooms.</extracomment>
@ -3936,45 +3944,15 @@ Cliquez ici : &lt;a href=&quot;%1&quot;&gt;%1&lt;/a&gt;
<extracomment>&apos;Chat groups&apos; : Filter item. Selecting it will show all chat groups (with more than one participant).</extracomment> <extracomment>&apos;Chat groups&apos; : Filter item. Selecting it will show all chat groups (with more than one participant).</extracomment>
<translation>Groupes standards</translation> <translation>Groupes standards</translation>
</message> </message>
<message>
<source>timelineFilterEphemerals</source>
<extracomment>&apos;Ephemerals&apos; : Filter item. Selecting it will show all chat rooms where the ephemeral mode has been enabled.</extracomment>
<translation>Éphémères</translation>
</message>
<message> <message>
<source>timelineSearchPlaceholderText</source> <source>timelineSearchPlaceholderText</source>
<extracomment>&apos;Search in the list&apos; : ths is a placeholder when searching something in the timeline list</extracomment> <extracomment>&apos;Search in the list&apos; : ths is a placeholder when searching something in the timeline list</extracomment>
<translation>Rechercher dans la chronologie</translation> <translation>Rechercher dans la chronologie</translation>
</message> </message>
<message> <message>
<source>timelineFilterAllSecureLevelRooms</source> <source>chatsTitle</source>
<extracomment>&apos;All security levels&apos; : Filter item. Selecting it will not do any filter on security level.</extracomment> <extracomment>&apos;Messages&apos; : Title for conversations</extracomment>
<translation>Tous les niveaux de sécurité</translation> <translation type="unfinished"></translation>
</message>
<message>
<source>timelineFilterStandardRooms</source>
<extracomment>&apos;Standard rooms&apos; : Filter item. Selecting it will show all simple rooms.</extracomment>
<translation>Standards</translation>
</message>
<message>
<source>timelineFilterAnyChatRooms</source>
<extracomment>&apos;Any conversations&apos; : Filter item. Selecting it will not do any filter on the type of conversations.</extracomment>
<translation>Tous les types</translation>
</message>
<message>
<source>timelineFilterAnyEphemerals</source>
<extracomment>&apos;Ephemerals on/off&apos; : Filter item. Selecting it will not do any filter on ephemerals activation.</extracomment>
<translation>Éphémères on/off</translation>
</message>
<message>
<source>timelineFilterNoEphemerals</source>
<extracomment>&apos;No Ephemerals&apos; : Filter item. Selecting it will hide all chat rooms where the ephemeral mode has been enabled.</extracomment>
<translation>Sans éphémères</translation>
</message>
<message>
<source>timelineFilterConferences</source>
<extracomment>&apos;Conferences&apos; : Filter item. Selecting it will show all conferences.</extracomment>
<translation>Conférences</translation>
</message> </message>
</context> </context>
<context> <context>

View file

@ -451,6 +451,34 @@
<translation>Média titkosítás</translation> <translation>Média titkosítás</translation>
</message> </message>
</context> </context>
<context>
<name>CallTimeline</name>
<message>
<source>callListTitle</source>
<extracomment>&apos;Call list&apos; : Call histories title</extracomment>
<translation type="unfinished"></translation>
</message>
<message>
<source>incomingFilter</source>
<extracomment>&apos;Incoming&apos; : Filter label for incoming call</extracomment>
<translation type="unfinished"></translation>
</message>
<message>
<source>outgoingFilter</source>
<extracomment>&apos;Outgoing&apos; : Filter label for outgoing call</extracomment>
<translation type="unfinished"></translation>
</message>
<message>
<source>missedFilter</source>
<extracomment>&apos;Missed&apos; : Filter label for missed call</extracomment>
<translation type="unfinished"></translation>
</message>
<message>
<source>searchListPlaceholderText</source>
<extracomment>&apos;Search in the list&apos; : ths is a placeholder when searching something in a list</extracomment>
<translation type="unfinished"></translation>
</message>
</context>
<context> <context>
<name>CallTransfer</name> <name>CallTransfer</name>
<message> <message>
@ -906,6 +934,11 @@ A kiszolgáló URL-je nincs konfigurálva.</translation>
<extracomment>&apos;The meeting has been deleted&apos; : Message text in a banner to warn the user that the meeting has been deleted.</extracomment> <extracomment>&apos;The meeting has been deleted&apos; : Message text in a banner to warn the user that the meeting has been deleted.</extracomment>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
<message>
<source>createMeeting</source>
<extracomment>&apos;Create Meeting&apos; : Button label to create a meeting</extracomment>
<translation type="unfinished"></translation>
</message>
</context> </context>
<context> <context>
<name>ConfirmDialog</name> <name>ConfirmDialog</name>
@ -1016,12 +1049,9 @@ A kiszolgáló URL-je nincs konfigurálva.</translation>
</message> </message>
<message> <message>
<source>selectAllContacts</source> <source>selectAllContacts</source>
<extracomment>&apos;All&apos; : Filter label to display all items.</extracomment>
<translation>Összes</translation> <translation>Összes</translation>
</message> </message>
<message>
<source>selectConnectedContacts</source>
<translation>Kapcsolódva</translation>
</message>
<message> <message>
<source>addContact</source> <source>addContact</source>
<translation>Névjegy hozzáadása</translation> <translation>Névjegy hozzáadása</translation>
@ -1035,21 +1065,24 @@ A kiszolgáló URL-je nincs konfigurálva.</translation>
<extracomment>&apos;You need to set the conference URI in your account settings to create a conference based chat room.&apos; : Tooltip to warn the user that a setting is missing in its configuration.</extracomment> <extracomment>&apos;You need to set the conference URI in your account settings to create a conference based chat room.&apos; : Tooltip to warn the user that a setting is missing in its configuration.</extracomment>
<translation>Konferenciaalapú csevegőszoba létrehozásához be kell állítania a konferencia URI-címét a fiókbeállításokban.</translation> <translation>Konferenciaalapú csevegőszoba létrehozásához be kell állítania a konferencia URI-címét a fiókbeállításokban.</translation>
</message> </message>
<message>
<source>localContactsEntry</source>
<extracomment>&apos;Local contacts&apos; : Contacts section label in main window when we have to specify that they are local to the application.</extracomment>
<translation type="unfinished"></translation>
</message>
<message>
<source>contactsEntry</source>
<extracomment>&apos;Contacts&apos; : Contacts section label in main waindow.</extracomment>
<translation type="unfinished">Névjegyek</translation>
</message>
<message>
<source>selectOnlineContacts</source>
<extracomment>&apos;Online&apos; : Filter label to display only online contacts.</extracomment>
<translation type="unfinished"></translation>
</message>
</context> </context>
<context> <context>
<name>Conversation</name> <name>Conversation</name>
<message>
<source>displayCallsAndMessages</source>
<translation>Összes</translation>
</message>
<message>
<source>displayCalls</source>
<translation>Hívások</translation>
</message>
<message>
<source>displayMessages</source>
<translation>Üzenetek</translation>
</message>
<message> <message>
<source>removeAllEntriesDescription</source> <source>removeAllEntriesDescription</source>
<translation>Biztosan törölni kívánja ezt az előzményt?</translation> <translation>Biztosan törölni kívánja ezt az előzményt?</translation>
@ -1833,11 +1866,6 @@ Kattintson ide: &lt;a href=&quot;%1&quot;&gt;%1&lt;/a&gt;
<source>mainSearchBarPlaceholder</source> <source>mainSearchBarPlaceholder</source>
<translation>Névjegy keresése, hívás indítása vagy csevegés kezdése</translation> <translation>Névjegy keresése, hívás indítása vagy csevegés kezdése</translation>
</message> </message>
<message>
<source>contactsEntry</source>
<extracomment>&apos;Contacts&apos; : Contacts section label in main waindow.</extracomment>
<translation>Névjegyek</translation>
</message>
<message> <message>
<source>autoAnswerStatus</source> <source>autoAnswerStatus</source>
<translation>önműködő</translation> <translation>önműködő</translation>
@ -1855,26 +1883,11 @@ Kattintson ide: &lt;a href=&quot;%1&quot;&gt;%1&lt;/a&gt;
<extracomment>&apos;Start a chat room&apos; : Tooltip to illustrate a button</extracomment> <extracomment>&apos;Start a chat room&apos; : Tooltip to illustrate a button</extracomment>
<translation>Csevegőszoba indítása</translation> <translation>Csevegőszoba indítása</translation>
</message> </message>
<message>
<source>hideTimeline</source>
<extracomment>&apos;Hide Timeline&apos; : Tooltip for a button that hide the timeline</extracomment>
<translation>Idővonal elrejtése</translation>
</message>
<message>
<source>openTimeline</source>
<extracomment>&apos;Open Timeline&apos; : Tooltip for a button that open the timeline</extracomment>
<translation>Idővonal megnyitása</translation>
</message>
<message> <message>
<source>openHome</source> <source>openHome</source>
<extracomment>&apos;Open Home&apos; : Tooltip for a button that open the home view</extracomment> <extracomment>&apos;Open Home&apos; : Tooltip for a button that open the home view</extracomment>
<translation>Kezdőlap megnyitása</translation> <translation>Kezdőlap megnyitása</translation>
</message> </message>
<message>
<source>mainWindowConferencesTitle</source>
<extracomment>&apos;Meetings&apos; : Meeting title for main window.</extracomment>
<translation type="unfinished"></translation>
</message>
<message> <message>
<source>newChatRoomUriMissing</source> <source>newChatRoomUriMissing</source>
<extracomment>&apos;Conference URI is not set. You have to change it in your account settings in order to create new group chats.&apos; : Tooltip to warn the user to change a setting to activate an action.</extracomment> <extracomment>&apos;Conference URI is not set. You have to change it in your account settings in order to create new group chats.&apos; : Tooltip to warn the user to change a setting to activate an action.</extracomment>
@ -1891,8 +1904,23 @@ Kattintson ide: &lt;a href=&quot;%1&quot;&gt;%1&lt;/a&gt;
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
<message> <message>
<source>localContactsEntry</source> <source>openCalls</source>
<extracomment>&apos;Local contacts&apos; : Contacts section label in main window when we have to specify that they are local to the application.</extracomment> <extracomment>&apos;Open call history&apos; : Tooltip for a button that open the call history view</extracomment>
<translation type="unfinished"></translation>
</message>
<message>
<source>openChats</source>
<extracomment>&apos;Open chats&apos; : Tooltip for a button that open the conversations view</extracomment>
<translation type="unfinished"></translation>
</message>
<message>
<source>openContacts</source>
<extracomment>&apos;Open contacts&apos; : Tooltip for a button that open the contacts view</extracomment>
<translation type="unfinished"></translation>
</message>
<message>
<source>openMeetings</source>
<extracomment>&apos;Open meetings&apos; : Tooltip for a button that open the meetings list</extracomment>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
</context> </context>
@ -3892,26 +3920,6 @@ Kattintson ide: &lt;a href=&quot;%1&quot;&gt;%1&lt;/a&gt;
</context> </context>
<context> <context>
<name>Timeline</name> <name>Timeline</name>
<message>
<source>timelineFilter</source>
<extracomment>A title for filtering mode.</extracomment>
<translation>Szűrő</translation>
</message>
<message>
<source>timelineFilterAll</source>
<extracomment>&apos;All&apos; The mode for timelines filtering.</extracomment>
<translation>Összes</translation>
</message>
<message>
<source>timelineFilterCustom</source>
<extracomment>&apos;Custom&apos; The mode for timelines filtering.</extracomment>
<translation>Egyéni</translation>
</message>
<message>
<source>timelineFilterSimpleRooms</source>
<extracomment>&apos;Simple rooms&apos; : Filter item. Selecting it will show all secure chat groups (with more than one participant).</extracomment>
<translation>Egyszerű szobák</translation>
</message>
<message> <message>
<source>timelineFilterSecureRooms</source> <source>timelineFilterSecureRooms</source>
<extracomment>&apos;Secure rooms&apos; : Filter item. Selecting it will show all secure rooms.</extracomment> <extracomment>&apos;Secure rooms&apos; : Filter item. Selecting it will show all secure rooms.</extracomment>
@ -3922,44 +3930,14 @@ Kattintson ide: &lt;a href=&quot;%1&quot;&gt;%1&lt;/a&gt;
<extracomment>&apos;Chat groups&apos; : Filter item. Selecting it will show all chat groups (with more than one participant).</extracomment> <extracomment>&apos;Chat groups&apos; : Filter item. Selecting it will show all chat groups (with more than one participant).</extracomment>
<translation>Csevegőcsoportok</translation> <translation>Csevegőcsoportok</translation>
</message> </message>
<message>
<source>timelineFilterEphemerals</source>
<extracomment>&apos;Ephemerals&apos; : Filter item. Selecting it will show all chat rooms where the ephemeral mode has been enabled.</extracomment>
<translation>Elmúlók</translation>
</message>
<message> <message>
<source>timelineSearchPlaceholderText</source> <source>timelineSearchPlaceholderText</source>
<extracomment>&apos;Search in the list&apos; : ths is a placeholder when searching something in the timeline list</extracomment> <extracomment>&apos;Search in the list&apos; : ths is a placeholder when searching something in the timeline list</extracomment>
<translation>Keresés a listában</translation> <translation>Keresés a listában</translation>
</message> </message>
<message> <message>
<source>timelineFilterAllSecureLevelRooms</source> <source>chatsTitle</source>
<extracomment>&apos;All security levels&apos; : Filter item. Selecting it will not do any filter on security level.</extracomment> <extracomment>&apos;Messages&apos; : Title for conversations</extracomment>
<translation>Minden biztonsági szint</translation>
</message>
<message>
<source>timelineFilterStandardRooms</source>
<extracomment>&apos;Standard rooms&apos; : Filter item. Selecting it will show all simple rooms.</extracomment>
<translation>Szabványos szobák</translation>
</message>
<message>
<source>timelineFilterAnyChatRooms</source>
<extracomment>&apos;Any conversations&apos; : Filter item. Selecting it will not do any filter on the type of conversations.</extracomment>
<translation>Minden beszélgetés</translation>
</message>
<message>
<source>timelineFilterAnyEphemerals</source>
<extracomment>&apos;Ephemerals on/off&apos; : Filter item. Selecting it will not do any filter on ephemerals activation.</extracomment>
<translation>Elmúlók be/ki</translation>
</message>
<message>
<source>timelineFilterNoEphemerals</source>
<extracomment>&apos;No Ephemerals&apos; : Filter item. Selecting it will hide all chat rooms where the ephemeral mode has been enabled.</extracomment>
<translation>Elmúlók nélkül</translation>
</message>
<message>
<source>timelineFilterConferences</source>
<extracomment>&apos;Conferences&apos; : Filter item. Selecting it will show all conferences.</extracomment>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
</context> </context>

View file

@ -451,6 +451,34 @@
<translation>Criptaggio dei dati multimediali</translation> <translation>Criptaggio dei dati multimediali</translation>
</message> </message>
</context> </context>
<context>
<name>CallTimeline</name>
<message>
<source>callListTitle</source>
<extracomment>&apos;Call list&apos; : Call histories title</extracomment>
<translation type="unfinished"></translation>
</message>
<message>
<source>incomingFilter</source>
<extracomment>&apos;Incoming&apos; : Filter label for incoming call</extracomment>
<translation type="unfinished"></translation>
</message>
<message>
<source>outgoingFilter</source>
<extracomment>&apos;Outgoing&apos; : Filter label for outgoing call</extracomment>
<translation type="unfinished"></translation>
</message>
<message>
<source>missedFilter</source>
<extracomment>&apos;Missed&apos; : Filter label for missed call</extracomment>
<translation type="unfinished"></translation>
</message>
<message>
<source>searchListPlaceholderText</source>
<extracomment>&apos;Search in the list&apos; : ths is a placeholder when searching something in a list</extracomment>
<translation type="unfinished"></translation>
</message>
</context>
<context> <context>
<name>CallTransfer</name> <name>CallTransfer</name>
<message> <message>
@ -913,6 +941,11 @@ URL del server non configurato.</translation>
<extracomment>&apos;The meeting has been deleted&apos; : Message text in a banner to warn the user that the meeting has been deleted.</extracomment> <extracomment>&apos;The meeting has been deleted&apos; : Message text in a banner to warn the user that the meeting has been deleted.</extracomment>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
<message>
<source>createMeeting</source>
<extracomment>&apos;Create Meeting&apos; : Button label to create a meeting</extracomment>
<translation type="unfinished"></translation>
</message>
</context> </context>
<context> <context>
<name>ConfirmDialog</name> <name>ConfirmDialog</name>
@ -1023,12 +1056,9 @@ URL del server non configurato.</translation>
</message> </message>
<message> <message>
<source>selectAllContacts</source> <source>selectAllContacts</source>
<extracomment>&apos;All&apos; : Filter label to display all items.</extracomment>
<translation>Tutti</translation> <translation>Tutti</translation>
</message> </message>
<message>
<source>selectConnectedContacts</source>
<translation>Connesso</translation>
</message>
<message> <message>
<source>addContact</source> <source>addContact</source>
<translation>AGGIUNGI UN CONTATTO</translation> <translation>AGGIUNGI UN CONTATTO</translation>
@ -1042,21 +1072,24 @@ URL del server non configurato.</translation>
<extracomment>&apos;You need to set the conference URI in your account settings to create a conference based chat room.&apos; : Tooltip to warn the user that a setting is missing in its configuration.</extracomment> <extracomment>&apos;You need to set the conference URI in your account settings to create a conference based chat room.&apos; : Tooltip to warn the user that a setting is missing in its configuration.</extracomment>
<translation>Per creare una chat di gruppo è necessario impostare la URI del gruppo nelle impostazioni del tuo account.</translation> <translation>Per creare una chat di gruppo è necessario impostare la URI del gruppo nelle impostazioni del tuo account.</translation>
</message> </message>
<message>
<source>localContactsEntry</source>
<extracomment>&apos;Local contacts&apos; : Contacts section label in main window when we have to specify that they are local to the application.</extracomment>
<translation type="unfinished"></translation>
</message>
<message>
<source>contactsEntry</source>
<extracomment>&apos;Contacts&apos; : Contacts section label in main waindow.</extracomment>
<translation type="unfinished">CONTATTI</translation>
</message>
<message>
<source>selectOnlineContacts</source>
<extracomment>&apos;Online&apos; : Filter label to display only online contacts.</extracomment>
<translation type="unfinished"></translation>
</message>
</context> </context>
<context> <context>
<name>Conversation</name> <name>Conversation</name>
<message>
<source>displayCallsAndMessages</source>
<translation>TUTTI</translation>
</message>
<message>
<source>displayCalls</source>
<translation>CHIAMATE</translation>
</message>
<message>
<source>displayMessages</source>
<translation>MESSAGGI</translation>
</message>
<message> <message>
<source>removeAllEntriesDescription</source> <source>removeAllEntriesDescription</source>
<translation>Sei sicuro di voler cancellare questa cronologia?</translation> <translation>Sei sicuro di voler cancellare questa cronologia?</translation>
@ -1844,11 +1877,6 @@ Clicca: &lt;a href=&quot;%1&quot;&gt;%1&lt;/a&gt;
<source>mainSearchBarPlaceholder</source> <source>mainSearchBarPlaceholder</source>
<translation>Cerca un contatto, avvia una chiamata o una chat</translation> <translation>Cerca un contatto, avvia una chiamata o una chat</translation>
</message> </message>
<message>
<source>contactsEntry</source>
<extracomment>&apos;Contacts&apos; : Contacts section label in main waindow.</extracomment>
<translation>CONTATTI</translation>
</message>
<message> <message>
<source>autoAnswerStatus</source> <source>autoAnswerStatus</source>
<translation>auto</translation> <translation>auto</translation>
@ -1866,26 +1894,11 @@ Clicca: &lt;a href=&quot;%1&quot;&gt;%1&lt;/a&gt;
<extracomment>&apos;Start a chat room&apos; : Tooltip to illustrate a button</extracomment> <extracomment>&apos;Start a chat room&apos; : Tooltip to illustrate a button</extracomment>
<translation>Crea una chat di gruppo</translation> <translation>Crea una chat di gruppo</translation>
</message> </message>
<message>
<source>hideTimeline</source>
<extracomment>&apos;Hide Timeline&apos; : Tooltip for a button that hide the timeline</extracomment>
<translation>Nascondi Timeline</translation>
</message>
<message>
<source>openTimeline</source>
<extracomment>&apos;Open Timeline&apos; : Tooltip for a button that open the timeline</extracomment>
<translation>Apri Timeline</translation>
</message>
<message> <message>
<source>openHome</source> <source>openHome</source>
<extracomment>&apos;Open Home&apos; : Tooltip for a button that open the home view</extracomment> <extracomment>&apos;Open Home&apos; : Tooltip for a button that open the home view</extracomment>
<translation>Apri Home</translation> <translation>Apri Home</translation>
</message> </message>
<message>
<source>mainWindowConferencesTitle</source>
<extracomment>&apos;Meetings&apos; : Meeting title for main window.</extracomment>
<translation>Riunioni</translation>
</message>
<message> <message>
<source>newChatRoomUriMissing</source> <source>newChatRoomUriMissing</source>
<extracomment>&apos;Conference URI is not set. You have to change it in your account settings in order to create new group chats.&apos; : Tooltip to warn the user to change a setting to activate an action.</extracomment> <extracomment>&apos;Conference URI is not set. You have to change it in your account settings in order to create new group chats.&apos; : Tooltip to warn the user to change a setting to activate an action.</extracomment>
@ -1902,8 +1915,23 @@ Clicca: &lt;a href=&quot;%1&quot;&gt;%1&lt;/a&gt;
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
<message> <message>
<source>localContactsEntry</source> <source>openCalls</source>
<extracomment>&apos;Local contacts&apos; : Contacts section label in main window when we have to specify that they are local to the application.</extracomment> <extracomment>&apos;Open call history&apos; : Tooltip for a button that open the call history view</extracomment>
<translation type="unfinished"></translation>
</message>
<message>
<source>openChats</source>
<extracomment>&apos;Open chats&apos; : Tooltip for a button that open the conversations view</extracomment>
<translation type="unfinished"></translation>
</message>
<message>
<source>openContacts</source>
<extracomment>&apos;Open contacts&apos; : Tooltip for a button that open the contacts view</extracomment>
<translation type="unfinished"></translation>
</message>
<message>
<source>openMeetings</source>
<extracomment>&apos;Open meetings&apos; : Tooltip for a button that open the meetings list</extracomment>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
</context> </context>
@ -3906,26 +3934,6 @@ Clicca: &lt;a href=&quot;%1&quot;&gt;%1&lt;/a&gt;
</context> </context>
<context> <context>
<name>Timeline</name> <name>Timeline</name>
<message>
<source>timelineFilter</source>
<extracomment>A title for filtering mode.</extracomment>
<translation type="unfinished"></translation>
</message>
<message>
<source>timelineFilterAll</source>
<extracomment>&apos;All&apos; The mode for timelines filtering.</extracomment>
<translation type="unfinished"></translation>
</message>
<message>
<source>timelineFilterCustom</source>
<extracomment>&apos;Custom&apos; The mode for timelines filtering.</extracomment>
<translation type="unfinished"></translation>
</message>
<message>
<source>timelineFilterSimpleRooms</source>
<extracomment>&apos;Simple rooms&apos; : Filter item. Selecting it will show all secure chat groups (with more than one participant).</extracomment>
<translation type="unfinished"></translation>
</message>
<message> <message>
<source>timelineFilterSecureRooms</source> <source>timelineFilterSecureRooms</source>
<extracomment>&apos;Secure rooms&apos; : Filter item. Selecting it will show all secure rooms.</extracomment> <extracomment>&apos;Secure rooms&apos; : Filter item. Selecting it will show all secure rooms.</extracomment>
@ -3936,44 +3944,14 @@ Clicca: &lt;a href=&quot;%1&quot;&gt;%1&lt;/a&gt;
<extracomment>&apos;Chat groups&apos; : Filter item. Selecting it will show all chat groups (with more than one participant).</extracomment> <extracomment>&apos;Chat groups&apos; : Filter item. Selecting it will show all chat groups (with more than one participant).</extracomment>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
<message>
<source>timelineFilterEphemerals</source>
<extracomment>&apos;Ephemerals&apos; : Filter item. Selecting it will show all chat rooms where the ephemeral mode has been enabled.</extracomment>
<translation type="unfinished"></translation>
</message>
<message> <message>
<source>timelineSearchPlaceholderText</source> <source>timelineSearchPlaceholderText</source>
<extracomment>&apos;Search in the list&apos; : ths is a placeholder when searching something in the timeline list</extracomment> <extracomment>&apos;Search in the list&apos; : ths is a placeholder when searching something in the timeline list</extracomment>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
<message> <message>
<source>timelineFilterAllSecureLevelRooms</source> <source>chatsTitle</source>
<extracomment>&apos;All security levels&apos; : Filter item. Selecting it will not do any filter on security level.</extracomment> <extracomment>&apos;Messages&apos; : Title for conversations</extracomment>
<translation type="unfinished"></translation>
</message>
<message>
<source>timelineFilterStandardRooms</source>
<extracomment>&apos;Standard rooms&apos; : Filter item. Selecting it will show all simple rooms.</extracomment>
<translation type="unfinished"></translation>
</message>
<message>
<source>timelineFilterAnyChatRooms</source>
<extracomment>&apos;Any conversations&apos; : Filter item. Selecting it will not do any filter on the type of conversations.</extracomment>
<translation type="unfinished"></translation>
</message>
<message>
<source>timelineFilterAnyEphemerals</source>
<extracomment>&apos;Ephemerals on/off&apos; : Filter item. Selecting it will not do any filter on ephemerals activation.</extracomment>
<translation type="unfinished"></translation>
</message>
<message>
<source>timelineFilterNoEphemerals</source>
<extracomment>&apos;No Ephemerals&apos; : Filter item. Selecting it will hide all chat rooms where the ephemeral mode has been enabled.</extracomment>
<translation type="unfinished"></translation>
</message>
<message>
<source>timelineFilterConferences</source>
<extracomment>&apos;Conferences&apos; : Filter item. Selecting it will show all conferences.</extracomment>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
</context> </context>

View file

@ -451,6 +451,34 @@
<translation></translation> <translation></translation>
</message> </message>
</context> </context>
<context>
<name>CallTimeline</name>
<message>
<source>callListTitle</source>
<extracomment>&apos;Call list&apos; : Call histories title</extracomment>
<translation type="unfinished"></translation>
</message>
<message>
<source>incomingFilter</source>
<extracomment>&apos;Incoming&apos; : Filter label for incoming call</extracomment>
<translation type="unfinished"></translation>
</message>
<message>
<source>outgoingFilter</source>
<extracomment>&apos;Outgoing&apos; : Filter label for outgoing call</extracomment>
<translation type="unfinished"></translation>
</message>
<message>
<source>missedFilter</source>
<extracomment>&apos;Missed&apos; : Filter label for missed call</extracomment>
<translation type="unfinished"></translation>
</message>
<message>
<source>searchListPlaceholderText</source>
<extracomment>&apos;Search in the list&apos; : ths is a placeholder when searching something in a list</extracomment>
<translation type="unfinished"></translation>
</message>
</context>
<context> <context>
<name>CallTransfer</name> <name>CallTransfer</name>
<message> <message>
@ -906,6 +934,11 @@
<extracomment>&apos;The meeting has been deleted&apos; : Message text in a banner to warn the user that the meeting has been deleted.</extracomment> <extracomment>&apos;The meeting has been deleted&apos; : Message text in a banner to warn the user that the meeting has been deleted.</extracomment>
<translation></translation> <translation></translation>
</message> </message>
<message>
<source>createMeeting</source>
<extracomment>&apos;Create Meeting&apos; : Button label to create a meeting</extracomment>
<translation type="unfinished"></translation>
</message>
</context> </context>
<context> <context>
<name>ConfirmDialog</name> <name>ConfirmDialog</name>
@ -1016,12 +1049,9 @@
</message> </message>
<message> <message>
<source>selectAllContacts</source> <source>selectAllContacts</source>
<extracomment>&apos;All&apos; : Filter label to display all items.</extracomment>
<translation></translation> <translation></translation>
</message> </message>
<message>
<source>selectConnectedContacts</source>
<translation></translation>
</message>
<message> <message>
<source>addContact</source> <source>addContact</source>
<translation></translation> <translation></translation>
@ -1035,21 +1065,24 @@
<extracomment>&apos;You need to set the conference URI in your account settings to create a conference based chat room.&apos; : Tooltip to warn the user that a setting is missing in its configuration.</extracomment> <extracomment>&apos;You need to set the conference URI in your account settings to create a conference based chat room.&apos; : Tooltip to warn the user that a setting is missing in its configuration.</extracomment>
<translation type="unfinished">URIを設定する必要があります</translation> <translation type="unfinished">URIを設定する必要があります</translation>
</message> </message>
<message>
<source>localContactsEntry</source>
<extracomment>&apos;Local contacts&apos; : Contacts section label in main window when we have to specify that they are local to the application.</extracomment>
<translation type="unfinished"></translation>
</message>
<message>
<source>contactsEntry</source>
<extracomment>&apos;Contacts&apos; : Contacts section label in main waindow.</extracomment>
<translation type="unfinished"></translation>
</message>
<message>
<source>selectOnlineContacts</source>
<extracomment>&apos;Online&apos; : Filter label to display only online contacts.</extracomment>
<translation type="unfinished"></translation>
</message>
</context> </context>
<context> <context>
<name>Conversation</name> <name>Conversation</name>
<message>
<source>displayCallsAndMessages</source>
<translation></translation>
</message>
<message>
<source>displayCalls</source>
<translation></translation>
</message>
<message>
<source>displayMessages</source>
<translation></translation>
</message>
<message> <message>
<source>removeAllEntriesDescription</source> <source>removeAllEntriesDescription</source>
<translation></translation> <translation></translation>
@ -1833,11 +1866,6 @@
<source>mainSearchBarPlaceholder</source> <source>mainSearchBarPlaceholder</source>
<translation></translation> <translation></translation>
</message> </message>
<message>
<source>contactsEntry</source>
<extracomment>&apos;Contacts&apos; : Contacts section label in main waindow.</extracomment>
<translation></translation>
</message>
<message> <message>
<source>autoAnswerStatus</source> <source>autoAnswerStatus</source>
<translation></translation> <translation></translation>
@ -1855,26 +1883,11 @@
<extracomment>&apos;Start a chat room&apos; : Tooltip to illustrate a button</extracomment> <extracomment>&apos;Start a chat room&apos; : Tooltip to illustrate a button</extracomment>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
<message>
<source>hideTimeline</source>
<extracomment>&apos;Hide Timeline&apos; : Tooltip for a button that hide the timeline</extracomment>
<translation></translation>
</message>
<message>
<source>openTimeline</source>
<extracomment>&apos;Open Timeline&apos; : Tooltip for a button that open the timeline</extracomment>
<translation></translation>
</message>
<message> <message>
<source>openHome</source> <source>openHome</source>
<extracomment>&apos;Open Home&apos; : Tooltip for a button that open the home view</extracomment> <extracomment>&apos;Open Home&apos; : Tooltip for a button that open the home view</extracomment>
<translation></translation> <translation></translation>
</message> </message>
<message>
<source>mainWindowConferencesTitle</source>
<extracomment>&apos;Meetings&apos; : Meeting title for main window.</extracomment>
<translation></translation>
</message>
<message> <message>
<source>newChatRoomUriMissing</source> <source>newChatRoomUriMissing</source>
<extracomment>&apos;Conference URI is not set. You have to change it in your account settings in order to create new group chats.&apos; : Tooltip to warn the user to change a setting to activate an action.</extracomment> <extracomment>&apos;Conference URI is not set. You have to change it in your account settings in order to create new group chats.&apos; : Tooltip to warn the user to change a setting to activate an action.</extracomment>
@ -1891,9 +1904,24 @@
<translation>URLから設定をダウンロードして適用しますか</translation> <translation>URLから設定をダウンロードして適用しますか</translation>
</message> </message>
<message> <message>
<source>localContactsEntry</source> <source>openCalls</source>
<extracomment>&apos;Local contacts&apos; : Contacts section label in main window when we have to specify that they are local to the application.</extracomment> <extracomment>&apos;Open call history&apos; : Tooltip for a button that open the call history view</extracomment>
<translation></translation> <translation type="unfinished"></translation>
</message>
<message>
<source>openChats</source>
<extracomment>&apos;Open chats&apos; : Tooltip for a button that open the conversations view</extracomment>
<translation type="unfinished"></translation>
</message>
<message>
<source>openContacts</source>
<extracomment>&apos;Open contacts&apos; : Tooltip for a button that open the contacts view</extracomment>
<translation type="unfinished"></translation>
</message>
<message>
<source>openMeetings</source>
<extracomment>&apos;Open meetings&apos; : Tooltip for a button that open the meetings list</extracomment>
<translation type="unfinished"></translation>
</message> </message>
</context> </context>
<context> <context>
@ -3892,26 +3920,6 @@
</context> </context>
<context> <context>
<name>Timeline</name> <name>Timeline</name>
<message>
<source>timelineFilter</source>
<extracomment>A title for filtering mode.</extracomment>
<translation></translation>
</message>
<message>
<source>timelineFilterAll</source>
<extracomment>&apos;All&apos; The mode for timelines filtering.</extracomment>
<translation></translation>
</message>
<message>
<source>timelineFilterCustom</source>
<extracomment>&apos;Custom&apos; The mode for timelines filtering.</extracomment>
<translation></translation>
</message>
<message>
<source>timelineFilterSimpleRooms</source>
<extracomment>&apos;Simple rooms&apos; : Filter item. Selecting it will show all secure chat groups (with more than one participant).</extracomment>
<translation></translation>
</message>
<message> <message>
<source>timelineFilterSecureRooms</source> <source>timelineFilterSecureRooms</source>
<extracomment>&apos;Secure rooms&apos; : Filter item. Selecting it will show all secure rooms.</extracomment> <extracomment>&apos;Secure rooms&apos; : Filter item. Selecting it will show all secure rooms.</extracomment>
@ -3922,46 +3930,16 @@
<extracomment>&apos;Chat groups&apos; : Filter item. Selecting it will show all chat groups (with more than one participant).</extracomment> <extracomment>&apos;Chat groups&apos; : Filter item. Selecting it will show all chat groups (with more than one participant).</extracomment>
<translation></translation> <translation></translation>
</message> </message>
<message>
<source>timelineFilterEphemerals</source>
<extracomment>&apos;Ephemerals&apos; : Filter item. Selecting it will show all chat rooms where the ephemeral mode has been enabled.</extracomment>
<translation></translation>
</message>
<message> <message>
<source>timelineSearchPlaceholderText</source> <source>timelineSearchPlaceholderText</source>
<extracomment>&apos;Search in the list&apos; : ths is a placeholder when searching something in the timeline list</extracomment> <extracomment>&apos;Search in the list&apos; : ths is a placeholder when searching something in the timeline list</extracomment>
<translation></translation> <translation></translation>
</message> </message>
<message> <message>
<source>timelineFilterAllSecureLevelRooms</source> <source>chatsTitle</source>
<extracomment>&apos;All security levels&apos; : Filter item. Selecting it will not do any filter on security level.</extracomment> <extracomment>&apos;Messages&apos; : Title for conversations</extracomment>
<translation></translation>
</message>
<message>
<source>timelineFilterStandardRooms</source>
<extracomment>&apos;Standard rooms&apos; : Filter item. Selecting it will show all simple rooms.</extracomment>
<translation></translation>
</message>
<message>
<source>timelineFilterAnyChatRooms</source>
<extracomment>&apos;Any conversations&apos; : Filter item. Selecting it will not do any filter on the type of conversations.</extracomment>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
<message>
<source>timelineFilterAnyEphemerals</source>
<extracomment>&apos;Ephemerals on/off&apos; : Filter item. Selecting it will not do any filter on ephemerals activation.</extracomment>
<translation type="unfinished"> ON/OFF</translation>
</message>
<message>
<source>timelineFilterNoEphemerals</source>
<extracomment>&apos;No Ephemerals&apos; : Filter item. Selecting it will hide all chat rooms where the ephemeral mode has been enabled.</extracomment>
<translation></translation>
</message>
<message>
<source>timelineFilterConferences</source>
<extracomment>&apos;Conferences&apos; : Filter item. Selecting it will show all conferences.</extracomment>
<translation></translation>
</message>
</context> </context>
<context> <context>
<name>TimelineItem</name> <name>TimelineItem</name>

View file

@ -451,6 +451,34 @@
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
</context> </context>
<context>
<name>CallTimeline</name>
<message>
<source>callListTitle</source>
<extracomment>&apos;Call list&apos; : Call histories title</extracomment>
<translation type="unfinished"></translation>
</message>
<message>
<source>incomingFilter</source>
<extracomment>&apos;Incoming&apos; : Filter label for incoming call</extracomment>
<translation type="unfinished"></translation>
</message>
<message>
<source>outgoingFilter</source>
<extracomment>&apos;Outgoing&apos; : Filter label for outgoing call</extracomment>
<translation type="unfinished"></translation>
</message>
<message>
<source>missedFilter</source>
<extracomment>&apos;Missed&apos; : Filter label for missed call</extracomment>
<translation type="unfinished"></translation>
</message>
<message>
<source>searchListPlaceholderText</source>
<extracomment>&apos;Search in the list&apos; : ths is a placeholder when searching something in a list</extracomment>
<translation type="unfinished"></translation>
</message>
</context>
<context> <context>
<name>CallTransfer</name> <name>CallTransfer</name>
<message> <message>
@ -920,6 +948,11 @@ Nesukonfigūruotas serverio url.</translation>
<extracomment>&apos;The meeting has been deleted&apos; : Message text in a banner to warn the user that the meeting has been deleted.</extracomment> <extracomment>&apos;The meeting has been deleted&apos; : Message text in a banner to warn the user that the meeting has been deleted.</extracomment>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
<message>
<source>createMeeting</source>
<extracomment>&apos;Create Meeting&apos; : Button label to create a meeting</extracomment>
<translation type="unfinished"></translation>
</message>
</context> </context>
<context> <context>
<name>ConfirmDialog</name> <name>ConfirmDialog</name>
@ -1030,12 +1063,9 @@ Nesukonfigūruotas serverio url.</translation>
</message> </message>
<message> <message>
<source>selectAllContacts</source> <source>selectAllContacts</source>
<extracomment>&apos;All&apos; : Filter label to display all items.</extracomment>
<translation>Visi</translation> <translation>Visi</translation>
</message> </message>
<message>
<source>selectConnectedContacts</source>
<translation>Prisijungę</translation>
</message>
<message> <message>
<source>addContact</source> <source>addContact</source>
<translation>PRIDĖTI KONTAKTĄ</translation> <translation>PRIDĖTI KONTAKTĄ</translation>
@ -1049,21 +1079,24 @@ Nesukonfigūruotas serverio url.</translation>
<extracomment>&apos;You need to set the conference URI in your account settings to create a conference based chat room.&apos; : Tooltip to warn the user that a setting is missing in its configuration.</extracomment> <extracomment>&apos;You need to set the conference URI in your account settings to create a conference based chat room.&apos; : Tooltip to warn the user that a setting is missing in its configuration.</extracomment>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
<message>
<source>localContactsEntry</source>
<extracomment>&apos;Local contacts&apos; : Contacts section label in main window when we have to specify that they are local to the application.</extracomment>
<translation type="unfinished"></translation>
</message>
<message>
<source>contactsEntry</source>
<extracomment>&apos;Contacts&apos; : Contacts section label in main waindow.</extracomment>
<translation type="unfinished">KONTAKTAI</translation>
</message>
<message>
<source>selectOnlineContacts</source>
<extracomment>&apos;Online&apos; : Filter label to display only online contacts.</extracomment>
<translation type="unfinished"></translation>
</message>
</context> </context>
<context> <context>
<name>Conversation</name> <name>Conversation</name>
<message>
<source>displayCallsAndMessages</source>
<translation>VISKAS</translation>
</message>
<message>
<source>displayCalls</source>
<translation>SKAMBUČIAI</translation>
</message>
<message>
<source>displayMessages</source>
<translation>ŽINUTĖS</translation>
</message>
<message> <message>
<source>removeAllEntriesDescription</source> <source>removeAllEntriesDescription</source>
<translation>Ar tikrai norite išvalyti š istoriją?</translation> <translation>Ar tikrai norite išvalyti š istoriją?</translation>
@ -1855,11 +1888,6 @@ Spustelėkite čia: &lt;a href=&quot;%1&quot;&gt;%1&lt;/a&gt;
<source>mainSearchBarPlaceholder</source> <source>mainSearchBarPlaceholder</source>
<translation>Ieškoti kontaktų, pradėti skambutį ar pokalbį</translation> <translation>Ieškoti kontaktų, pradėti skambutį ar pokalbį</translation>
</message> </message>
<message>
<source>contactsEntry</source>
<extracomment>&apos;Contacts&apos; : Contacts section label in main waindow.</extracomment>
<translation>KONTAKTAI</translation>
</message>
<message> <message>
<source>autoAnswerStatus</source> <source>autoAnswerStatus</source>
<translation>automatinis</translation> <translation>automatinis</translation>
@ -1877,26 +1905,11 @@ Spustelėkite čia: &lt;a href=&quot;%1&quot;&gt;%1&lt;/a&gt;
<extracomment>&apos;Start a chat room&apos; : Tooltip to illustrate a button</extracomment> <extracomment>&apos;Start a chat room&apos; : Tooltip to illustrate a button</extracomment>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
<message>
<source>hideTimeline</source>
<extracomment>&apos;Hide Timeline&apos; : Tooltip for a button that hide the timeline</extracomment>
<translation type="unfinished"></translation>
</message>
<message>
<source>openTimeline</source>
<extracomment>&apos;Open Timeline&apos; : Tooltip for a button that open the timeline</extracomment>
<translation type="unfinished"></translation>
</message>
<message> <message>
<source>openHome</source> <source>openHome</source>
<extracomment>&apos;Open Home&apos; : Tooltip for a button that open the home view</extracomment> <extracomment>&apos;Open Home&apos; : Tooltip for a button that open the home view</extracomment>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
<message>
<source>mainWindowConferencesTitle</source>
<extracomment>&apos;Meetings&apos; : Meeting title for main window.</extracomment>
<translation type="unfinished"></translation>
</message>
<message> <message>
<source>newChatRoomUriMissing</source> <source>newChatRoomUriMissing</source>
<extracomment>&apos;Conference URI is not set. You have to change it in your account settings in order to create new group chats.&apos; : Tooltip to warn the user to change a setting to activate an action.</extracomment> <extracomment>&apos;Conference URI is not set. You have to change it in your account settings in order to create new group chats.&apos; : Tooltip to warn the user to change a setting to activate an action.</extracomment>
@ -1913,8 +1926,23 @@ Spustelėkite čia: &lt;a href=&quot;%1&quot;&gt;%1&lt;/a&gt;
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
<message> <message>
<source>localContactsEntry</source> <source>openCalls</source>
<extracomment>&apos;Local contacts&apos; : Contacts section label in main window when we have to specify that they are local to the application.</extracomment> <extracomment>&apos;Open call history&apos; : Tooltip for a button that open the call history view</extracomment>
<translation type="unfinished"></translation>
</message>
<message>
<source>openChats</source>
<extracomment>&apos;Open chats&apos; : Tooltip for a button that open the conversations view</extracomment>
<translation type="unfinished"></translation>
</message>
<message>
<source>openContacts</source>
<extracomment>&apos;Open contacts&apos; : Tooltip for a button that open the contacts view</extracomment>
<translation type="unfinished"></translation>
</message>
<message>
<source>openMeetings</source>
<extracomment>&apos;Open meetings&apos; : Tooltip for a button that open the meetings list</extracomment>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
</context> </context>
@ -3920,26 +3948,6 @@ Spustelėkite čia: &lt;a href=&quot;%1&quot;&gt;%1&lt;/a&gt;
</context> </context>
<context> <context>
<name>Timeline</name> <name>Timeline</name>
<message>
<source>timelineFilter</source>
<extracomment>A title for filtering mode.</extracomment>
<translation type="unfinished"></translation>
</message>
<message>
<source>timelineFilterAll</source>
<extracomment>&apos;All&apos; The mode for timelines filtering.</extracomment>
<translation type="unfinished"></translation>
</message>
<message>
<source>timelineFilterCustom</source>
<extracomment>&apos;Custom&apos; The mode for timelines filtering.</extracomment>
<translation type="unfinished"></translation>
</message>
<message>
<source>timelineFilterSimpleRooms</source>
<extracomment>&apos;Simple rooms&apos; : Filter item. Selecting it will show all secure chat groups (with more than one participant).</extracomment>
<translation type="unfinished"></translation>
</message>
<message> <message>
<source>timelineFilterSecureRooms</source> <source>timelineFilterSecureRooms</source>
<extracomment>&apos;Secure rooms&apos; : Filter item. Selecting it will show all secure rooms.</extracomment> <extracomment>&apos;Secure rooms&apos; : Filter item. Selecting it will show all secure rooms.</extracomment>
@ -3950,44 +3958,14 @@ Spustelėkite čia: &lt;a href=&quot;%1&quot;&gt;%1&lt;/a&gt;
<extracomment>&apos;Chat groups&apos; : Filter item. Selecting it will show all chat groups (with more than one participant).</extracomment> <extracomment>&apos;Chat groups&apos; : Filter item. Selecting it will show all chat groups (with more than one participant).</extracomment>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
<message>
<source>timelineFilterEphemerals</source>
<extracomment>&apos;Ephemerals&apos; : Filter item. Selecting it will show all chat rooms where the ephemeral mode has been enabled.</extracomment>
<translation type="unfinished"></translation>
</message>
<message> <message>
<source>timelineSearchPlaceholderText</source> <source>timelineSearchPlaceholderText</source>
<extracomment>&apos;Search in the list&apos; : ths is a placeholder when searching something in the timeline list</extracomment> <extracomment>&apos;Search in the list&apos; : ths is a placeholder when searching something in the timeline list</extracomment>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
<message> <message>
<source>timelineFilterAllSecureLevelRooms</source> <source>chatsTitle</source>
<extracomment>&apos;All security levels&apos; : Filter item. Selecting it will not do any filter on security level.</extracomment> <extracomment>&apos;Messages&apos; : Title for conversations</extracomment>
<translation type="unfinished"></translation>
</message>
<message>
<source>timelineFilterStandardRooms</source>
<extracomment>&apos;Standard rooms&apos; : Filter item. Selecting it will show all simple rooms.</extracomment>
<translation type="unfinished"></translation>
</message>
<message>
<source>timelineFilterAnyChatRooms</source>
<extracomment>&apos;Any conversations&apos; : Filter item. Selecting it will not do any filter on the type of conversations.</extracomment>
<translation type="unfinished"></translation>
</message>
<message>
<source>timelineFilterAnyEphemerals</source>
<extracomment>&apos;Ephemerals on/off&apos; : Filter item. Selecting it will not do any filter on ephemerals activation.</extracomment>
<translation type="unfinished"></translation>
</message>
<message>
<source>timelineFilterNoEphemerals</source>
<extracomment>&apos;No Ephemerals&apos; : Filter item. Selecting it will hide all chat rooms where the ephemeral mode has been enabled.</extracomment>
<translation type="unfinished"></translation>
</message>
<message>
<source>timelineFilterConferences</source>
<extracomment>&apos;Conferences&apos; : Filter item. Selecting it will show all conferences.</extracomment>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
</context> </context>

View file

@ -451,6 +451,34 @@
<translation>Encriptação da media</translation> <translation>Encriptação da media</translation>
</message> </message>
</context> </context>
<context>
<name>CallTimeline</name>
<message>
<source>callListTitle</source>
<extracomment>&apos;Call list&apos; : Call histories title</extracomment>
<translation type="unfinished"></translation>
</message>
<message>
<source>incomingFilter</source>
<extracomment>&apos;Incoming&apos; : Filter label for incoming call</extracomment>
<translation type="unfinished"></translation>
</message>
<message>
<source>outgoingFilter</source>
<extracomment>&apos;Outgoing&apos; : Filter label for outgoing call</extracomment>
<translation type="unfinished"></translation>
</message>
<message>
<source>missedFilter</source>
<extracomment>&apos;Missed&apos; : Filter label for missed call</extracomment>
<translation type="unfinished"></translation>
</message>
<message>
<source>searchListPlaceholderText</source>
<extracomment>&apos;Search in the list&apos; : ths is a placeholder when searching something in a list</extracomment>
<translation type="unfinished"></translation>
</message>
</context>
<context> <context>
<name>CallTransfer</name> <name>CallTransfer</name>
<message> <message>
@ -913,6 +941,11 @@ URL do servidor não configurado.</translation>
<extracomment>&apos;The meeting has been deleted&apos; : Message text in a banner to warn the user that the meeting has been deleted.</extracomment> <extracomment>&apos;The meeting has been deleted&apos; : Message text in a banner to warn the user that the meeting has been deleted.</extracomment>
<translation>A reunião foi excluída</translation> <translation>A reunião foi excluída</translation>
</message> </message>
<message>
<source>createMeeting</source>
<extracomment>&apos;Create Meeting&apos; : Button label to create a meeting</extracomment>
<translation type="unfinished"></translation>
</message>
</context> </context>
<context> <context>
<name>ConfirmDialog</name> <name>ConfirmDialog</name>
@ -1023,12 +1056,9 @@ URL do servidor não configurado.</translation>
</message> </message>
<message> <message>
<source>selectAllContacts</source> <source>selectAllContacts</source>
<extracomment>&apos;All&apos; : Filter label to display all items.</extracomment>
<translation>Todos</translation> <translation>Todos</translation>
</message> </message>
<message>
<source>selectConnectedContacts</source>
<translation>Conectado</translation>
</message>
<message> <message>
<source>addContact</source> <source>addContact</source>
<translation>ADICIONAR CONTATO</translation> <translation>ADICIONAR CONTATO</translation>
@ -1042,21 +1072,24 @@ URL do servidor não configurado.</translation>
<extracomment>&apos;You need to set the conference URI in your account settings to create a conference based chat room.&apos; : Tooltip to warn the user that a setting is missing in its configuration.</extracomment> <extracomment>&apos;You need to set the conference URI in your account settings to create a conference based chat room.&apos; : Tooltip to warn the user that a setting is missing in its configuration.</extracomment>
<translation>Você precisa definir o URI da conferência nas configurações da sua conta para criar uma sala de bate-papo baseada em conferência.</translation> <translation>Você precisa definir o URI da conferência nas configurações da sua conta para criar uma sala de bate-papo baseada em conferência.</translation>
</message> </message>
<message>
<source>localContactsEntry</source>
<extracomment>&apos;Local contacts&apos; : Contacts section label in main window when we have to specify that they are local to the application.</extracomment>
<translation type="unfinished"></translation>
</message>
<message>
<source>contactsEntry</source>
<extracomment>&apos;Contacts&apos; : Contacts section label in main waindow.</extracomment>
<translation type="unfinished">CONTATOS</translation>
</message>
<message>
<source>selectOnlineContacts</source>
<extracomment>&apos;Online&apos; : Filter label to display only online contacts.</extracomment>
<translation type="unfinished"></translation>
</message>
</context> </context>
<context> <context>
<name>Conversation</name> <name>Conversation</name>
<message>
<source>displayCallsAndMessages</source>
<translation>TODOS</translation>
</message>
<message>
<source>displayCalls</source>
<translation>CHAMADAS</translation>
</message>
<message>
<source>displayMessages</source>
<translation>MENSAGENS</translation>
</message>
<message> <message>
<source>removeAllEntriesDescription</source> <source>removeAllEntriesDescription</source>
<translation>Tem certeza de que deseja limpar esse histórico?</translation> <translation>Tem certeza de que deseja limpar esse histórico?</translation>
@ -1844,11 +1877,6 @@ Clique aqui: &lt;a href=&quot;%1&quot;&gt;%1 &lt;/a&gt;
<source>mainSearchBarPlaceholder</source> <source>mainSearchBarPlaceholder</source>
<translation>Pesquisar contato, iniciar uma chamada ou um bate-papo</translation> <translation>Pesquisar contato, iniciar uma chamada ou um bate-papo</translation>
</message> </message>
<message>
<source>contactsEntry</source>
<extracomment>&apos;Contacts&apos; : Contacts section label in main waindow.</extracomment>
<translation>CONTATOS</translation>
</message>
<message> <message>
<source>autoAnswerStatus</source> <source>autoAnswerStatus</source>
<translation>Automático</translation> <translation>Automático</translation>
@ -1866,26 +1894,11 @@ Clique aqui: &lt;a href=&quot;%1&quot;&gt;%1 &lt;/a&gt;
<extracomment>&apos;Start a chat room&apos; : Tooltip to illustrate a button</extracomment> <extracomment>&apos;Start a chat room&apos; : Tooltip to illustrate a button</extracomment>
<translation>Iniciar uma sala de chat</translation> <translation>Iniciar uma sala de chat</translation>
</message> </message>
<message>
<source>hideTimeline</source>
<extracomment>&apos;Hide Timeline&apos; : Tooltip for a button that hide the timeline</extracomment>
<translation>Ocultar linha do tempo</translation>
</message>
<message>
<source>openTimeline</source>
<extracomment>&apos;Open Timeline&apos; : Tooltip for a button that open the timeline</extracomment>
<translation>Abrir linha do tempo</translation>
</message>
<message> <message>
<source>openHome</source> <source>openHome</source>
<extracomment>&apos;Open Home&apos; : Tooltip for a button that open the home view</extracomment> <extracomment>&apos;Open Home&apos; : Tooltip for a button that open the home view</extracomment>
<translation>Abrir a página inicial</translation> <translation>Abrir a página inicial</translation>
</message> </message>
<message>
<source>mainWindowConferencesTitle</source>
<extracomment>&apos;Meetings&apos; : Meeting title for main window.</extracomment>
<translation>Reuniões</translation>
</message>
<message> <message>
<source>newChatRoomUriMissing</source> <source>newChatRoomUriMissing</source>
<extracomment>&apos;Conference URI is not set. You have to change it in your account settings in order to create new group chats.&apos; : Tooltip to warn the user to change a setting to activate an action.</extracomment> <extracomment>&apos;Conference URI is not set. You have to change it in your account settings in order to create new group chats.&apos; : Tooltip to warn the user to change a setting to activate an action.</extracomment>
@ -1902,8 +1915,23 @@ Clique aqui: &lt;a href=&quot;%1&quot;&gt;%1 &lt;/a&gt;
<translation>Você deseja fazer o download e aplicar a configuração a partir desta URL?</translation> <translation>Você deseja fazer o download e aplicar a configuração a partir desta URL?</translation>
</message> </message>
<message> <message>
<source>localContactsEntry</source> <source>openCalls</source>
<extracomment>&apos;Local contacts&apos; : Contacts section label in main window when we have to specify that they are local to the application.</extracomment> <extracomment>&apos;Open call history&apos; : Tooltip for a button that open the call history view</extracomment>
<translation type="unfinished"></translation>
</message>
<message>
<source>openChats</source>
<extracomment>&apos;Open chats&apos; : Tooltip for a button that open the conversations view</extracomment>
<translation type="unfinished"></translation>
</message>
<message>
<source>openContacts</source>
<extracomment>&apos;Open contacts&apos; : Tooltip for a button that open the contacts view</extracomment>
<translation type="unfinished"></translation>
</message>
<message>
<source>openMeetings</source>
<extracomment>&apos;Open meetings&apos; : Tooltip for a button that open the meetings list</extracomment>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
</context> </context>
@ -3906,26 +3934,6 @@ Clique aqui: &lt;a href=&quot;%1&quot;&gt;%1 &lt;/a&gt;
</context> </context>
<context> <context>
<name>Timeline</name> <name>Timeline</name>
<message>
<source>timelineFilter</source>
<extracomment>A title for filtering mode.</extracomment>
<translation>Filtro</translation>
</message>
<message>
<source>timelineFilterAll</source>
<extracomment>&apos;All&apos; The mode for timelines filtering.</extracomment>
<translation>Todos</translation>
</message>
<message>
<source>timelineFilterCustom</source>
<extracomment>&apos;Custom&apos; The mode for timelines filtering.</extracomment>
<translation>Personalização</translation>
</message>
<message>
<source>timelineFilterSimpleRooms</source>
<extracomment>&apos;Simple rooms&apos; : Filter item. Selecting it will show all secure chat groups (with more than one participant).</extracomment>
<translation>Salas simples</translation>
</message>
<message> <message>
<source>timelineFilterSecureRooms</source> <source>timelineFilterSecureRooms</source>
<extracomment>&apos;Secure rooms&apos; : Filter item. Selecting it will show all secure rooms.</extracomment> <extracomment>&apos;Secure rooms&apos; : Filter item. Selecting it will show all secure rooms.</extracomment>
@ -3936,45 +3944,15 @@ Clique aqui: &lt;a href=&quot;%1&quot;&gt;%1 &lt;/a&gt;
<extracomment>&apos;Chat groups&apos; : Filter item. Selecting it will show all chat groups (with more than one participant).</extracomment> <extracomment>&apos;Chat groups&apos; : Filter item. Selecting it will show all chat groups (with more than one participant).</extracomment>
<translation>Grupo de chat</translation> <translation>Grupo de chat</translation>
</message> </message>
<message>
<source>timelineFilterEphemerals</source>
<extracomment>&apos;Ephemerals&apos; : Filter item. Selecting it will show all chat rooms where the ephemeral mode has been enabled.</extracomment>
<translation>Efêmeros</translation>
</message>
<message> <message>
<source>timelineSearchPlaceholderText</source> <source>timelineSearchPlaceholderText</source>
<extracomment>&apos;Search in the list&apos; : ths is a placeholder when searching something in the timeline list</extracomment> <extracomment>&apos;Search in the list&apos; : ths is a placeholder when searching something in the timeline list</extracomment>
<translation>Pesquisar na lista</translation> <translation>Pesquisar na lista</translation>
</message> </message>
<message> <message>
<source>timelineFilterAllSecureLevelRooms</source> <source>chatsTitle</source>
<extracomment>&apos;All security levels&apos; : Filter item. Selecting it will not do any filter on security level.</extracomment> <extracomment>&apos;Messages&apos; : Title for conversations</extracomment>
<translation>Todos níveis de segurança</translation> <translation type="unfinished"></translation>
</message>
<message>
<source>timelineFilterStandardRooms</source>
<extracomment>&apos;Standard rooms&apos; : Filter item. Selecting it will show all simple rooms.</extracomment>
<translation>Salas padrão</translation>
</message>
<message>
<source>timelineFilterAnyChatRooms</source>
<extracomment>&apos;Any conversations&apos; : Filter item. Selecting it will not do any filter on the type of conversations.</extracomment>
<translation>Todas conversas</translation>
</message>
<message>
<source>timelineFilterAnyEphemerals</source>
<extracomment>&apos;Ephemerals on/off&apos; : Filter item. Selecting it will not do any filter on ephemerals activation.</extracomment>
<translation>Efêmeros ligado/desligado</translation>
</message>
<message>
<source>timelineFilterNoEphemerals</source>
<extracomment>&apos;No Ephemerals&apos; : Filter item. Selecting it will hide all chat rooms where the ephemeral mode has been enabled.</extracomment>
<translation>Sem efêmeros</translation>
</message>
<message>
<source>timelineFilterConferences</source>
<extracomment>&apos;Conferences&apos; : Filter item. Selecting it will show all conferences.</extracomment>
<translation>Conferências</translation>
</message> </message>
</context> </context>
<context> <context>

View file

@ -451,6 +451,34 @@
<translation>Шифрование потока</translation> <translation>Шифрование потока</translation>
</message> </message>
</context> </context>
<context>
<name>CallTimeline</name>
<message>
<source>callListTitle</source>
<extracomment>&apos;Call list&apos; : Call histories title</extracomment>
<translation type="unfinished"></translation>
</message>
<message>
<source>incomingFilter</source>
<extracomment>&apos;Incoming&apos; : Filter label for incoming call</extracomment>
<translation type="unfinished"></translation>
</message>
<message>
<source>outgoingFilter</source>
<extracomment>&apos;Outgoing&apos; : Filter label for outgoing call</extracomment>
<translation type="unfinished"></translation>
</message>
<message>
<source>missedFilter</source>
<extracomment>&apos;Missed&apos; : Filter label for missed call</extracomment>
<translation type="unfinished"></translation>
</message>
<message>
<source>searchListPlaceholderText</source>
<extracomment>&apos;Search in the list&apos; : ths is a placeholder when searching something in a list</extracomment>
<translation type="unfinished"></translation>
</message>
</context>
<context> <context>
<name>CallTransfer</name> <name>CallTransfer</name>
<message> <message>
@ -920,6 +948,11 @@
<extracomment>&apos;The meeting has been deleted&apos; : Message text in a banner to warn the user that the meeting has been deleted.</extracomment> <extracomment>&apos;The meeting has been deleted&apos; : Message text in a banner to warn the user that the meeting has been deleted.</extracomment>
<translation>Встреча была удалена</translation> <translation>Встреча была удалена</translation>
</message> </message>
<message>
<source>createMeeting</source>
<extracomment>&apos;Create Meeting&apos; : Button label to create a meeting</extracomment>
<translation type="unfinished"></translation>
</message>
</context> </context>
<context> <context>
<name>ConfirmDialog</name> <name>ConfirmDialog</name>
@ -1030,12 +1063,9 @@
</message> </message>
<message> <message>
<source>selectAllContacts</source> <source>selectAllContacts</source>
<extracomment>&apos;All&apos; : Filter label to display all items.</extracomment>
<translation>Все</translation> <translation>Все</translation>
</message> </message>
<message>
<source>selectConnectedContacts</source>
<translation>Подключенные</translation>
</message>
<message> <message>
<source>addContact</source> <source>addContact</source>
<translation>ДОБАВИТЬ КОНТАКТ</translation> <translation>ДОБАВИТЬ КОНТАКТ</translation>
@ -1049,21 +1079,24 @@
<extracomment>&apos;You need to set the conference URI in your account settings to create a conference based chat room.&apos; : Tooltip to warn the user that a setting is missing in its configuration.</extracomment> <extracomment>&apos;You need to set the conference URI in your account settings to create a conference based chat room.&apos; : Tooltip to warn the user that a setting is missing in its configuration.</extracomment>
<translation>Вам необходимо установить URI конференции в настройках вашего аккаунта, чтобы создать чат-комнату на основе конференции.</translation> <translation>Вам необходимо установить URI конференции в настройках вашего аккаунта, чтобы создать чат-комнату на основе конференции.</translation>
</message> </message>
<message>
<source>localContactsEntry</source>
<extracomment>&apos;Local contacts&apos; : Contacts section label in main window when we have to specify that they are local to the application.</extracomment>
<translation type="unfinished"></translation>
</message>
<message>
<source>contactsEntry</source>
<extracomment>&apos;Contacts&apos; : Contacts section label in main waindow.</extracomment>
<translation type="unfinished">КОНТАКТЫ</translation>
</message>
<message>
<source>selectOnlineContacts</source>
<extracomment>&apos;Online&apos; : Filter label to display only online contacts.</extracomment>
<translation type="unfinished"></translation>
</message>
</context> </context>
<context> <context>
<name>Conversation</name> <name>Conversation</name>
<message>
<source>displayCallsAndMessages</source>
<translation>ВСЕ</translation>
</message>
<message>
<source>displayCalls</source>
<translation>ЗВОНКИ</translation>
</message>
<message>
<source>displayMessages</source>
<translation>СООБЩЕНИЯ</translation>
</message>
<message> <message>
<source>removeAllEntriesDescription</source> <source>removeAllEntriesDescription</source>
<translation>Вы уверены, что хотите очистить эту историю?</translation> <translation>Вы уверены, что хотите очистить эту историю?</translation>
@ -1855,11 +1888,6 @@
<source>mainSearchBarPlaceholder</source> <source>mainSearchBarPlaceholder</source>
<translation>Найти контакт, начать звонок или чат</translation> <translation>Найти контакт, начать звонок или чат</translation>
</message> </message>
<message>
<source>contactsEntry</source>
<extracomment>&apos;Contacts&apos; : Contacts section label in main waindow.</extracomment>
<translation>КОНТАКТЫ</translation>
</message>
<message> <message>
<source>autoAnswerStatus</source> <source>autoAnswerStatus</source>
<translation>авто</translation> <translation>авто</translation>
@ -1877,26 +1905,11 @@
<extracomment>&apos;Start a chat room&apos; : Tooltip to illustrate a button</extracomment> <extracomment>&apos;Start a chat room&apos; : Tooltip to illustrate a button</extracomment>
<translation>Начать чат-комнату</translation> <translation>Начать чат-комнату</translation>
</message> </message>
<message>
<source>hideTimeline</source>
<extracomment>&apos;Hide Timeline&apos; : Tooltip for a button that hide the timeline</extracomment>
<translation>Скрыть шкалу времени</translation>
</message>
<message>
<source>openTimeline</source>
<extracomment>&apos;Open Timeline&apos; : Tooltip for a button that open the timeline</extracomment>
<translation>Открыть шкалу времени</translation>
</message>
<message> <message>
<source>openHome</source> <source>openHome</source>
<extracomment>&apos;Open Home&apos; : Tooltip for a button that open the home view</extracomment> <extracomment>&apos;Open Home&apos; : Tooltip for a button that open the home view</extracomment>
<translation>Открыть главную</translation> <translation>Открыть главную</translation>
</message> </message>
<message>
<source>mainWindowConferencesTitle</source>
<extracomment>&apos;Meetings&apos; : Meeting title for main window.</extracomment>
<translation>Встречи</translation>
</message>
<message> <message>
<source>newChatRoomUriMissing</source> <source>newChatRoomUriMissing</source>
<extracomment>&apos;Conference URI is not set. You have to change it in your account settings in order to create new group chats.&apos; : Tooltip to warn the user to change a setting to activate an action.</extracomment> <extracomment>&apos;Conference URI is not set. You have to change it in your account settings in order to create new group chats.&apos; : Tooltip to warn the user to change a setting to activate an action.</extracomment>
@ -1913,8 +1926,23 @@
<translation>Вы хотите загрузить и применить конфигурацию с этого URL-адреса?</translation> <translation>Вы хотите загрузить и применить конфигурацию с этого URL-адреса?</translation>
</message> </message>
<message> <message>
<source>localContactsEntry</source> <source>openCalls</source>
<extracomment>&apos;Local contacts&apos; : Contacts section label in main window when we have to specify that they are local to the application.</extracomment> <extracomment>&apos;Open call history&apos; : Tooltip for a button that open the call history view</extracomment>
<translation type="unfinished"></translation>
</message>
<message>
<source>openChats</source>
<extracomment>&apos;Open chats&apos; : Tooltip for a button that open the conversations view</extracomment>
<translation type="unfinished"></translation>
</message>
<message>
<source>openContacts</source>
<extracomment>&apos;Open contacts&apos; : Tooltip for a button that open the contacts view</extracomment>
<translation type="unfinished"></translation>
</message>
<message>
<source>openMeetings</source>
<extracomment>&apos;Open meetings&apos; : Tooltip for a button that open the meetings list</extracomment>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
</context> </context>
@ -3920,26 +3948,6 @@
</context> </context>
<context> <context>
<name>Timeline</name> <name>Timeline</name>
<message>
<source>timelineFilter</source>
<extracomment>A title for filtering mode.</extracomment>
<translation>Фильтр</translation>
</message>
<message>
<source>timelineFilterAll</source>
<extracomment>&apos;All&apos; The mode for timelines filtering.</extracomment>
<translation>Все</translation>
</message>
<message>
<source>timelineFilterCustom</source>
<extracomment>&apos;Custom&apos; The mode for timelines filtering.</extracomment>
<translation>Пользовательский</translation>
</message>
<message>
<source>timelineFilterSimpleRooms</source>
<extracomment>&apos;Simple rooms&apos; : Filter item. Selecting it will show all secure chat groups (with more than one participant).</extracomment>
<translation>Простые комнаты</translation>
</message>
<message> <message>
<source>timelineFilterSecureRooms</source> <source>timelineFilterSecureRooms</source>
<extracomment>&apos;Secure rooms&apos; : Filter item. Selecting it will show all secure rooms.</extracomment> <extracomment>&apos;Secure rooms&apos; : Filter item. Selecting it will show all secure rooms.</extracomment>
@ -3950,45 +3958,15 @@
<extracomment>&apos;Chat groups&apos; : Filter item. Selecting it will show all chat groups (with more than one participant).</extracomment> <extracomment>&apos;Chat groups&apos; : Filter item. Selecting it will show all chat groups (with more than one participant).</extracomment>
<translation>Чат-группы</translation> <translation>Чат-группы</translation>
</message> </message>
<message>
<source>timelineFilterEphemerals</source>
<extracomment>&apos;Ephemerals&apos; : Filter item. Selecting it will show all chat rooms where the ephemeral mode has been enabled.</extracomment>
<translation>Недолговечные</translation>
</message>
<message> <message>
<source>timelineSearchPlaceholderText</source> <source>timelineSearchPlaceholderText</source>
<extracomment>&apos;Search in the list&apos; : ths is a placeholder when searching something in the timeline list</extracomment> <extracomment>&apos;Search in the list&apos; : ths is a placeholder when searching something in the timeline list</extracomment>
<translation>Поиск в списке</translation> <translation>Поиск в списке</translation>
</message> </message>
<message> <message>
<source>timelineFilterAllSecureLevelRooms</source> <source>chatsTitle</source>
<extracomment>&apos;All security levels&apos; : Filter item. Selecting it will not do any filter on security level.</extracomment> <extracomment>&apos;Messages&apos; : Title for conversations</extracomment>
<translation>Все уровни безопасности</translation> <translation type="unfinished"></translation>
</message>
<message>
<source>timelineFilterStandardRooms</source>
<extracomment>&apos;Standard rooms&apos; : Filter item. Selecting it will show all simple rooms.</extracomment>
<translation>Стандартные комнаты</translation>
</message>
<message>
<source>timelineFilterAnyChatRooms</source>
<extracomment>&apos;Any conversations&apos; : Filter item. Selecting it will not do any filter on the type of conversations.</extracomment>
<translation>Любые разговоры</translation>
</message>
<message>
<source>timelineFilterAnyEphemerals</source>
<extracomment>&apos;Ephemerals on/off&apos; : Filter item. Selecting it will not do any filter on ephemerals activation.</extracomment>
<translation>Недолговечные вкл/выкл</translation>
</message>
<message>
<source>timelineFilterNoEphemerals</source>
<extracomment>&apos;No Ephemerals&apos; : Filter item. Selecting it will hide all chat rooms where the ephemeral mode has been enabled.</extracomment>
<translation>Без недолговечных</translation>
</message>
<message>
<source>timelineFilterConferences</source>
<extracomment>&apos;Conferences&apos; : Filter item. Selecting it will show all conferences.</extracomment>
<translation>Конференции</translation>
</message> </message>
</context> </context>
<context> <context>

View file

@ -451,6 +451,34 @@
<translation>Mediekryptering</translation> <translation>Mediekryptering</translation>
</message> </message>
</context> </context>
<context>
<name>CallTimeline</name>
<message>
<source>callListTitle</source>
<extracomment>&apos;Call list&apos; : Call histories title</extracomment>
<translation type="unfinished"></translation>
</message>
<message>
<source>incomingFilter</source>
<extracomment>&apos;Incoming&apos; : Filter label for incoming call</extracomment>
<translation type="unfinished"></translation>
</message>
<message>
<source>outgoingFilter</source>
<extracomment>&apos;Outgoing&apos; : Filter label for outgoing call</extracomment>
<translation type="unfinished"></translation>
</message>
<message>
<source>missedFilter</source>
<extracomment>&apos;Missed&apos; : Filter label for missed call</extracomment>
<translation type="unfinished"></translation>
</message>
<message>
<source>searchListPlaceholderText</source>
<extracomment>&apos;Search in the list&apos; : ths is a placeholder when searching something in a list</extracomment>
<translation type="unfinished"></translation>
</message>
</context>
<context> <context>
<name>CallTransfer</name> <name>CallTransfer</name>
<message> <message>
@ -913,6 +941,11 @@ Serverwebbadressen är inte konfigurerad.</translation>
<extracomment>&apos;The meeting has been deleted&apos; : Message text in a banner to warn the user that the meeting has been deleted.</extracomment> <extracomment>&apos;The meeting has been deleted&apos; : Message text in a banner to warn the user that the meeting has been deleted.</extracomment>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
<message>
<source>createMeeting</source>
<extracomment>&apos;Create Meeting&apos; : Button label to create a meeting</extracomment>
<translation type="unfinished"></translation>
</message>
</context> </context>
<context> <context>
<name>ConfirmDialog</name> <name>ConfirmDialog</name>
@ -1023,12 +1056,9 @@ Serverwebbadressen är inte konfigurerad.</translation>
</message> </message>
<message> <message>
<source>selectAllContacts</source> <source>selectAllContacts</source>
<extracomment>&apos;All&apos; : Filter label to display all items.</extracomment>
<translation>Alla</translation> <translation>Alla</translation>
</message> </message>
<message>
<source>selectConnectedContacts</source>
<translation>Ansluten</translation>
</message>
<message> <message>
<source>addContact</source> <source>addContact</source>
<translation>LÄGG TILL KONTAKT</translation> <translation>LÄGG TILL KONTAKT</translation>
@ -1042,21 +1072,24 @@ Serverwebbadressen är inte konfigurerad.</translation>
<extracomment>&apos;You need to set the conference URI in your account settings to create a conference based chat room.&apos; : Tooltip to warn the user that a setting is missing in its configuration.</extracomment> <extracomment>&apos;You need to set the conference URI in your account settings to create a conference based chat room.&apos; : Tooltip to warn the user that a setting is missing in its configuration.</extracomment>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
<message>
<source>localContactsEntry</source>
<extracomment>&apos;Local contacts&apos; : Contacts section label in main window when we have to specify that they are local to the application.</extracomment>
<translation type="unfinished"></translation>
</message>
<message>
<source>contactsEntry</source>
<extracomment>&apos;Contacts&apos; : Contacts section label in main waindow.</extracomment>
<translation type="unfinished">KONTAKTER</translation>
</message>
<message>
<source>selectOnlineContacts</source>
<extracomment>&apos;Online&apos; : Filter label to display only online contacts.</extracomment>
<translation type="unfinished"></translation>
</message>
</context> </context>
<context> <context>
<name>Conversation</name> <name>Conversation</name>
<message>
<source>displayCallsAndMessages</source>
<translation>ALLA</translation>
</message>
<message>
<source>displayCalls</source>
<translation>SAMTAL</translation>
</message>
<message>
<source>displayMessages</source>
<translation>MEDDELANDEN</translation>
</message>
<message> <message>
<source>removeAllEntriesDescription</source> <source>removeAllEntriesDescription</source>
<translation>Är du säker att du vill rensa den här historiken?</translation> <translation>Är du säker att du vill rensa den här historiken?</translation>
@ -1844,11 +1877,6 @@ Klicka här: &lt;a href=&quot;%1&quot;&gt;%1&lt;/a&gt;
<source>mainSearchBarPlaceholder</source> <source>mainSearchBarPlaceholder</source>
<translation>Sök kontakt, starta ett samtal eller en chatt</translation> <translation>Sök kontakt, starta ett samtal eller en chatt</translation>
</message> </message>
<message>
<source>contactsEntry</source>
<extracomment>&apos;Contacts&apos; : Contacts section label in main waindow.</extracomment>
<translation>KONTAKTER</translation>
</message>
<message> <message>
<source>autoAnswerStatus</source> <source>autoAnswerStatus</source>
<translation>automatiskt</translation> <translation>automatiskt</translation>
@ -1866,26 +1894,11 @@ Klicka här: &lt;a href=&quot;%1&quot;&gt;%1&lt;/a&gt;
<extracomment>&apos;Start a chat room&apos; : Tooltip to illustrate a button</extracomment> <extracomment>&apos;Start a chat room&apos; : Tooltip to illustrate a button</extracomment>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
<message>
<source>hideTimeline</source>
<extracomment>&apos;Hide Timeline&apos; : Tooltip for a button that hide the timeline</extracomment>
<translation type="unfinished"></translation>
</message>
<message>
<source>openTimeline</source>
<extracomment>&apos;Open Timeline&apos; : Tooltip for a button that open the timeline</extracomment>
<translation type="unfinished"></translation>
</message>
<message> <message>
<source>openHome</source> <source>openHome</source>
<extracomment>&apos;Open Home&apos; : Tooltip for a button that open the home view</extracomment> <extracomment>&apos;Open Home&apos; : Tooltip for a button that open the home view</extracomment>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
<message>
<source>mainWindowConferencesTitle</source>
<extracomment>&apos;Meetings&apos; : Meeting title for main window.</extracomment>
<translation type="unfinished"></translation>
</message>
<message> <message>
<source>newChatRoomUriMissing</source> <source>newChatRoomUriMissing</source>
<extracomment>&apos;Conference URI is not set. You have to change it in your account settings in order to create new group chats.&apos; : Tooltip to warn the user to change a setting to activate an action.</extracomment> <extracomment>&apos;Conference URI is not set. You have to change it in your account settings in order to create new group chats.&apos; : Tooltip to warn the user to change a setting to activate an action.</extracomment>
@ -1902,8 +1915,23 @@ Klicka här: &lt;a href=&quot;%1&quot;&gt;%1&lt;/a&gt;
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
<message> <message>
<source>localContactsEntry</source> <source>openCalls</source>
<extracomment>&apos;Local contacts&apos; : Contacts section label in main window when we have to specify that they are local to the application.</extracomment> <extracomment>&apos;Open call history&apos; : Tooltip for a button that open the call history view</extracomment>
<translation type="unfinished"></translation>
</message>
<message>
<source>openChats</source>
<extracomment>&apos;Open chats&apos; : Tooltip for a button that open the conversations view</extracomment>
<translation type="unfinished"></translation>
</message>
<message>
<source>openContacts</source>
<extracomment>&apos;Open contacts&apos; : Tooltip for a button that open the contacts view</extracomment>
<translation type="unfinished"></translation>
</message>
<message>
<source>openMeetings</source>
<extracomment>&apos;Open meetings&apos; : Tooltip for a button that open the meetings list</extracomment>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
</context> </context>
@ -3906,26 +3934,6 @@ Klicka här: &lt;a href=&quot;%1&quot;&gt;%1&lt;/a&gt;
</context> </context>
<context> <context>
<name>Timeline</name> <name>Timeline</name>
<message>
<source>timelineFilter</source>
<extracomment>A title for filtering mode.</extracomment>
<translation type="unfinished"></translation>
</message>
<message>
<source>timelineFilterAll</source>
<extracomment>&apos;All&apos; The mode for timelines filtering.</extracomment>
<translation type="unfinished"></translation>
</message>
<message>
<source>timelineFilterCustom</source>
<extracomment>&apos;Custom&apos; The mode for timelines filtering.</extracomment>
<translation type="unfinished"></translation>
</message>
<message>
<source>timelineFilterSimpleRooms</source>
<extracomment>&apos;Simple rooms&apos; : Filter item. Selecting it will show all secure chat groups (with more than one participant).</extracomment>
<translation type="unfinished"></translation>
</message>
<message> <message>
<source>timelineFilterSecureRooms</source> <source>timelineFilterSecureRooms</source>
<extracomment>&apos;Secure rooms&apos; : Filter item. Selecting it will show all secure rooms.</extracomment> <extracomment>&apos;Secure rooms&apos; : Filter item. Selecting it will show all secure rooms.</extracomment>
@ -3936,44 +3944,14 @@ Klicka här: &lt;a href=&quot;%1&quot;&gt;%1&lt;/a&gt;
<extracomment>&apos;Chat groups&apos; : Filter item. Selecting it will show all chat groups (with more than one participant).</extracomment> <extracomment>&apos;Chat groups&apos; : Filter item. Selecting it will show all chat groups (with more than one participant).</extracomment>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
<message>
<source>timelineFilterEphemerals</source>
<extracomment>&apos;Ephemerals&apos; : Filter item. Selecting it will show all chat rooms where the ephemeral mode has been enabled.</extracomment>
<translation type="unfinished"></translation>
</message>
<message> <message>
<source>timelineSearchPlaceholderText</source> <source>timelineSearchPlaceholderText</source>
<extracomment>&apos;Search in the list&apos; : ths is a placeholder when searching something in the timeline list</extracomment> <extracomment>&apos;Search in the list&apos; : ths is a placeholder when searching something in the timeline list</extracomment>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
<message> <message>
<source>timelineFilterAllSecureLevelRooms</source> <source>chatsTitle</source>
<extracomment>&apos;All security levels&apos; : Filter item. Selecting it will not do any filter on security level.</extracomment> <extracomment>&apos;Messages&apos; : Title for conversations</extracomment>
<translation type="unfinished"></translation>
</message>
<message>
<source>timelineFilterStandardRooms</source>
<extracomment>&apos;Standard rooms&apos; : Filter item. Selecting it will show all simple rooms.</extracomment>
<translation type="unfinished"></translation>
</message>
<message>
<source>timelineFilterAnyChatRooms</source>
<extracomment>&apos;Any conversations&apos; : Filter item. Selecting it will not do any filter on the type of conversations.</extracomment>
<translation type="unfinished"></translation>
</message>
<message>
<source>timelineFilterAnyEphemerals</source>
<extracomment>&apos;Ephemerals on/off&apos; : Filter item. Selecting it will not do any filter on ephemerals activation.</extracomment>
<translation type="unfinished"></translation>
</message>
<message>
<source>timelineFilterNoEphemerals</source>
<extracomment>&apos;No Ephemerals&apos; : Filter item. Selecting it will hide all chat rooms where the ephemeral mode has been enabled.</extracomment>
<translation type="unfinished"></translation>
</message>
<message>
<source>timelineFilterConferences</source>
<extracomment>&apos;Conferences&apos; : Filter item. Selecting it will show all conferences.</extracomment>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
</context> </context>

View file

@ -451,6 +451,34 @@
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
</context> </context>
<context>
<name>CallTimeline</name>
<message>
<source>callListTitle</source>
<extracomment>&apos;Call list&apos; : Call histories title</extracomment>
<translation type="unfinished"></translation>
</message>
<message>
<source>incomingFilter</source>
<extracomment>&apos;Incoming&apos; : Filter label for incoming call</extracomment>
<translation type="unfinished"></translation>
</message>
<message>
<source>outgoingFilter</source>
<extracomment>&apos;Outgoing&apos; : Filter label for outgoing call</extracomment>
<translation type="unfinished"></translation>
</message>
<message>
<source>missedFilter</source>
<extracomment>&apos;Missed&apos; : Filter label for missed call</extracomment>
<translation type="unfinished"></translation>
</message>
<message>
<source>searchListPlaceholderText</source>
<extracomment>&apos;Search in the list&apos; : ths is a placeholder when searching something in a list</extracomment>
<translation type="unfinished"></translation>
</message>
</context>
<context> <context>
<name>CallTransfer</name> <name>CallTransfer</name>
<message> <message>
@ -906,6 +934,11 @@ Sunucu url&apos;si yapılandırılmadı.</translation>
<extracomment>&apos;The meeting has been deleted&apos; : Message text in a banner to warn the user that the meeting has been deleted.</extracomment> <extracomment>&apos;The meeting has been deleted&apos; : Message text in a banner to warn the user that the meeting has been deleted.</extracomment>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
<message>
<source>createMeeting</source>
<extracomment>&apos;Create Meeting&apos; : Button label to create a meeting</extracomment>
<translation type="unfinished"></translation>
</message>
</context> </context>
<context> <context>
<name>ConfirmDialog</name> <name>ConfirmDialog</name>
@ -1016,12 +1049,9 @@ Sunucu url&apos;si yapılandırılmadı.</translation>
</message> </message>
<message> <message>
<source>selectAllContacts</source> <source>selectAllContacts</source>
<extracomment>&apos;All&apos; : Filter label to display all items.</extracomment>
<translation>Tümü</translation> <translation>Tümü</translation>
</message> </message>
<message>
<source>selectConnectedContacts</source>
<translation>Bağlı</translation>
</message>
<message> <message>
<source>addContact</source> <source>addContact</source>
<translation>KİŞİ EKLE</translation> <translation>KİŞİ EKLE</translation>
@ -1035,21 +1065,24 @@ Sunucu url&apos;si yapılandırılmadı.</translation>
<extracomment>&apos;You need to set the conference URI in your account settings to create a conference based chat room.&apos; : Tooltip to warn the user that a setting is missing in its configuration.</extracomment> <extracomment>&apos;You need to set the conference URI in your account settings to create a conference based chat room.&apos; : Tooltip to warn the user that a setting is missing in its configuration.</extracomment>
<translation>Toplantı tabanlı konuşma odası oluşturmak için hesap ayarlarınızda toplantı URI&apos;si belirlemelisiniz.</translation> <translation>Toplantı tabanlı konuşma odası oluşturmak için hesap ayarlarınızda toplantı URI&apos;si belirlemelisiniz.</translation>
</message> </message>
<message>
<source>localContactsEntry</source>
<extracomment>&apos;Local contacts&apos; : Contacts section label in main window when we have to specify that they are local to the application.</extracomment>
<translation type="unfinished"></translation>
</message>
<message>
<source>contactsEntry</source>
<extracomment>&apos;Contacts&apos; : Contacts section label in main waindow.</extracomment>
<translation type="unfinished">KİŞİLER</translation>
</message>
<message>
<source>selectOnlineContacts</source>
<extracomment>&apos;Online&apos; : Filter label to display only online contacts.</extracomment>
<translation type="unfinished"></translation>
</message>
</context> </context>
<context> <context>
<name>Conversation</name> <name>Conversation</name>
<message>
<source>displayCallsAndMessages</source>
<translation>TÜMÜ</translation>
</message>
<message>
<source>displayCalls</source>
<translation>ÇAĞRILAR</translation>
</message>
<message>
<source>displayMessages</source>
<translation>İLETİLER</translation>
</message>
<message> <message>
<source>removeAllEntriesDescription</source> <source>removeAllEntriesDescription</source>
<translation>Bu geçmişi temizlemek istediğinize emin misiniz?</translation> <translation>Bu geçmişi temizlemek istediğinize emin misiniz?</translation>
@ -1833,11 +1866,6 @@ Buraya tıklayın: &lt;a href=&quot;%1&quot;&gt;%1&lt;/a&gt;
<source>mainSearchBarPlaceholder</source> <source>mainSearchBarPlaceholder</source>
<translation>Kişi ara, çağrı veya sohbet başlat</translation> <translation>Kişi ara, çağrı veya sohbet başlat</translation>
</message> </message>
<message>
<source>contactsEntry</source>
<extracomment>&apos;Contacts&apos; : Contacts section label in main waindow.</extracomment>
<translation>KİŞİLER</translation>
</message>
<message> <message>
<source>autoAnswerStatus</source> <source>autoAnswerStatus</source>
<translation>kendiliğinden</translation> <translation>kendiliğinden</translation>
@ -1855,26 +1883,11 @@ Buraya tıklayın: &lt;a href=&quot;%1&quot;&gt;%1&lt;/a&gt;
<extracomment>&apos;Start a chat room&apos; : Tooltip to illustrate a button</extracomment> <extracomment>&apos;Start a chat room&apos; : Tooltip to illustrate a button</extracomment>
<translation>Konuşma odası başlat</translation> <translation>Konuşma odası başlat</translation>
</message> </message>
<message>
<source>hideTimeline</source>
<extracomment>&apos;Hide Timeline&apos; : Tooltip for a button that hide the timeline</extracomment>
<translation>Zaman Çizelgesini Gizle</translation>
</message>
<message>
<source>openTimeline</source>
<extracomment>&apos;Open Timeline&apos; : Tooltip for a button that open the timeline</extracomment>
<translation>Zaman Çizelgesini </translation>
</message>
<message> <message>
<source>openHome</source> <source>openHome</source>
<extracomment>&apos;Open Home&apos; : Tooltip for a button that open the home view</extracomment> <extracomment>&apos;Open Home&apos; : Tooltip for a button that open the home view</extracomment>
<translation>Evi </translation> <translation>Evi </translation>
</message> </message>
<message>
<source>mainWindowConferencesTitle</source>
<extracomment>&apos;Meetings&apos; : Meeting title for main window.</extracomment>
<translation type="unfinished"></translation>
</message>
<message> <message>
<source>newChatRoomUriMissing</source> <source>newChatRoomUriMissing</source>
<extracomment>&apos;Conference URI is not set. You have to change it in your account settings in order to create new group chats.&apos; : Tooltip to warn the user to change a setting to activate an action.</extracomment> <extracomment>&apos;Conference URI is not set. You have to change it in your account settings in order to create new group chats.&apos; : Tooltip to warn the user to change a setting to activate an action.</extracomment>
@ -1891,8 +1904,23 @@ Buraya tıklayın: &lt;a href=&quot;%1&quot;&gt;%1&lt;/a&gt;
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
<message> <message>
<source>localContactsEntry</source> <source>openCalls</source>
<extracomment>&apos;Local contacts&apos; : Contacts section label in main window when we have to specify that they are local to the application.</extracomment> <extracomment>&apos;Open call history&apos; : Tooltip for a button that open the call history view</extracomment>
<translation type="unfinished"></translation>
</message>
<message>
<source>openChats</source>
<extracomment>&apos;Open chats&apos; : Tooltip for a button that open the conversations view</extracomment>
<translation type="unfinished"></translation>
</message>
<message>
<source>openContacts</source>
<extracomment>&apos;Open contacts&apos; : Tooltip for a button that open the contacts view</extracomment>
<translation type="unfinished"></translation>
</message>
<message>
<source>openMeetings</source>
<extracomment>&apos;Open meetings&apos; : Tooltip for a button that open the meetings list</extracomment>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
</context> </context>
@ -3892,26 +3920,6 @@ Buraya tıklayın: &lt;a href=&quot;%1&quot;&gt;%1&lt;/a&gt;
</context> </context>
<context> <context>
<name>Timeline</name> <name>Timeline</name>
<message>
<source>timelineFilter</source>
<extracomment>A title for filtering mode.</extracomment>
<translation>Süzgeç</translation>
</message>
<message>
<source>timelineFilterAll</source>
<extracomment>&apos;All&apos; The mode for timelines filtering.</extracomment>
<translation>Tümü</translation>
</message>
<message>
<source>timelineFilterCustom</source>
<extracomment>&apos;Custom&apos; The mode for timelines filtering.</extracomment>
<translation>Özel</translation>
</message>
<message>
<source>timelineFilterSimpleRooms</source>
<extracomment>&apos;Simple rooms&apos; : Filter item. Selecting it will show all secure chat groups (with more than one participant).</extracomment>
<translation>Basit odalar</translation>
</message>
<message> <message>
<source>timelineFilterSecureRooms</source> <source>timelineFilterSecureRooms</source>
<extracomment>&apos;Secure rooms&apos; : Filter item. Selecting it will show all secure rooms.</extracomment> <extracomment>&apos;Secure rooms&apos; : Filter item. Selecting it will show all secure rooms.</extracomment>
@ -3922,45 +3930,15 @@ Buraya tıklayın: &lt;a href=&quot;%1&quot;&gt;%1&lt;/a&gt;
<extracomment>&apos;Chat groups&apos; : Filter item. Selecting it will show all chat groups (with more than one participant).</extracomment> <extracomment>&apos;Chat groups&apos; : Filter item. Selecting it will show all chat groups (with more than one participant).</extracomment>
<translation>Konuşma kümeleri</translation> <translation>Konuşma kümeleri</translation>
</message> </message>
<message>
<source>timelineFilterEphemerals</source>
<extracomment>&apos;Ephemerals&apos; : Filter item. Selecting it will show all chat rooms where the ephemeral mode has been enabled.</extracomment>
<translation>Kısa ömürlüler</translation>
</message>
<message> <message>
<source>timelineSearchPlaceholderText</source> <source>timelineSearchPlaceholderText</source>
<extracomment>&apos;Search in the list&apos; : ths is a placeholder when searching something in the timeline list</extracomment> <extracomment>&apos;Search in the list&apos; : ths is a placeholder when searching something in the timeline list</extracomment>
<translation>Listede ara</translation> <translation>Listede ara</translation>
</message> </message>
<message> <message>
<source>timelineFilterAllSecureLevelRooms</source> <source>chatsTitle</source>
<extracomment>&apos;All security levels&apos; : Filter item. Selecting it will not do any filter on security level.</extracomment> <extracomment>&apos;Messages&apos; : Title for conversations</extracomment>
<translation>Tüm güvenlik düzeyleri</translation> <translation type="unfinished"></translation>
</message>
<message>
<source>timelineFilterStandardRooms</source>
<extracomment>&apos;Standard rooms&apos; : Filter item. Selecting it will show all simple rooms.</extracomment>
<translation>Standart odalar</translation>
</message>
<message>
<source>timelineFilterAnyChatRooms</source>
<extracomment>&apos;Any conversations&apos; : Filter item. Selecting it will not do any filter on the type of conversations.</extracomment>
<translation>Herhangi konuşmalar</translation>
</message>
<message>
<source>timelineFilterAnyEphemerals</source>
<extracomment>&apos;Ephemerals on/off&apos; : Filter item. Selecting it will not do any filter on ephemerals activation.</extracomment>
<translation>Kısa ömürlüler ık/kapalı</translation>
</message>
<message>
<source>timelineFilterNoEphemerals</source>
<extracomment>&apos;No Ephemerals&apos; : Filter item. Selecting it will hide all chat rooms where the ephemeral mode has been enabled.</extracomment>
<translation>Kısa ömürlüler olmadan</translation>
</message>
<message>
<source>timelineFilterConferences</source>
<extracomment>&apos;Conferences&apos; : Filter item. Selecting it will show all conferences.</extracomment>
<translation>Toplantılar</translation>
</message> </message>
</context> </context>
<context> <context>

View file

@ -451,6 +451,34 @@
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
</context> </context>
<context>
<name>CallTimeline</name>
<message>
<source>callListTitle</source>
<extracomment>&apos;Call list&apos; : Call histories title</extracomment>
<translation type="unfinished"></translation>
</message>
<message>
<source>incomingFilter</source>
<extracomment>&apos;Incoming&apos; : Filter label for incoming call</extracomment>
<translation type="unfinished"></translation>
</message>
<message>
<source>outgoingFilter</source>
<extracomment>&apos;Outgoing&apos; : Filter label for outgoing call</extracomment>
<translation type="unfinished"></translation>
</message>
<message>
<source>missedFilter</source>
<extracomment>&apos;Missed&apos; : Filter label for missed call</extracomment>
<translation type="unfinished"></translation>
</message>
<message>
<source>searchListPlaceholderText</source>
<extracomment>&apos;Search in the list&apos; : ths is a placeholder when searching something in a list</extracomment>
<translation type="unfinished"></translation>
</message>
</context>
<context> <context>
<name>CallTransfer</name> <name>CallTransfer</name>
<message> <message>
@ -920,6 +948,11 @@
<extracomment>&apos;The meeting has been deleted&apos; : Message text in a banner to warn the user that the meeting has been deleted.</extracomment> <extracomment>&apos;The meeting has been deleted&apos; : Message text in a banner to warn the user that the meeting has been deleted.</extracomment>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
<message>
<source>createMeeting</source>
<extracomment>&apos;Create Meeting&apos; : Button label to create a meeting</extracomment>
<translation type="unfinished"></translation>
</message>
</context> </context>
<context> <context>
<name>ConfirmDialog</name> <name>ConfirmDialog</name>
@ -1030,12 +1063,9 @@
</message> </message>
<message> <message>
<source>selectAllContacts</source> <source>selectAllContacts</source>
<extracomment>&apos;All&apos; : Filter label to display all items.</extracomment>
<translation>Усі</translation> <translation>Усі</translation>
</message> </message>
<message>
<source>selectConnectedContacts</source>
<translation>Під&apos;єднані</translation>
</message>
<message> <message>
<source>addContact</source> <source>addContact</source>
<translation>ДОДАТИ КОНТАКТ</translation> <translation>ДОДАТИ КОНТАКТ</translation>
@ -1049,21 +1079,24 @@
<extracomment>&apos;You need to set the conference URI in your account settings to create a conference based chat room.&apos; : Tooltip to warn the user that a setting is missing in its configuration.</extracomment> <extracomment>&apos;You need to set the conference URI in your account settings to create a conference based chat room.&apos; : Tooltip to warn the user that a setting is missing in its configuration.</extracomment>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
<message>
<source>localContactsEntry</source>
<extracomment>&apos;Local contacts&apos; : Contacts section label in main window when we have to specify that they are local to the application.</extracomment>
<translation type="unfinished"></translation>
</message>
<message>
<source>contactsEntry</source>
<extracomment>&apos;Contacts&apos; : Contacts section label in main waindow.</extracomment>
<translation type="unfinished">КОНТАКТИ</translation>
</message>
<message>
<source>selectOnlineContacts</source>
<extracomment>&apos;Online&apos; : Filter label to display only online contacts.</extracomment>
<translation type="unfinished"></translation>
</message>
</context> </context>
<context> <context>
<name>Conversation</name> <name>Conversation</name>
<message>
<source>displayCallsAndMessages</source>
<translation>УСІ</translation>
</message>
<message>
<source>displayCalls</source>
<translation>ВИКЛИКИ</translation>
</message>
<message>
<source>displayMessages</source>
<translation>ПОВІДОМЛЕННЯ</translation>
</message>
<message> <message>
<source>removeAllEntriesDescription</source> <source>removeAllEntriesDescription</source>
<translation>Ви впевнені, що волієте вичистити цю історію?</translation> <translation>Ви впевнені, що волієте вичистити цю історію?</translation>
@ -1855,11 +1888,6 @@
<source>mainSearchBarPlaceholder</source> <source>mainSearchBarPlaceholder</source>
<translation>Знайти контакт, почати дзвінок або чат</translation> <translation>Знайти контакт, почати дзвінок або чат</translation>
</message> </message>
<message>
<source>contactsEntry</source>
<extracomment>&apos;Contacts&apos; : Contacts section label in main waindow.</extracomment>
<translation>КОНТАКТИ</translation>
</message>
<message> <message>
<source>autoAnswerStatus</source> <source>autoAnswerStatus</source>
<translation>авто</translation> <translation>авто</translation>
@ -1877,26 +1905,11 @@
<extracomment>&apos;Start a chat room&apos; : Tooltip to illustrate a button</extracomment> <extracomment>&apos;Start a chat room&apos; : Tooltip to illustrate a button</extracomment>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
<message>
<source>hideTimeline</source>
<extracomment>&apos;Hide Timeline&apos; : Tooltip for a button that hide the timeline</extracomment>
<translation type="unfinished"></translation>
</message>
<message>
<source>openTimeline</source>
<extracomment>&apos;Open Timeline&apos; : Tooltip for a button that open the timeline</extracomment>
<translation type="unfinished"></translation>
</message>
<message> <message>
<source>openHome</source> <source>openHome</source>
<extracomment>&apos;Open Home&apos; : Tooltip for a button that open the home view</extracomment> <extracomment>&apos;Open Home&apos; : Tooltip for a button that open the home view</extracomment>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
<message>
<source>mainWindowConferencesTitle</source>
<extracomment>&apos;Meetings&apos; : Meeting title for main window.</extracomment>
<translation type="unfinished"></translation>
</message>
<message> <message>
<source>newChatRoomUriMissing</source> <source>newChatRoomUriMissing</source>
<extracomment>&apos;Conference URI is not set. You have to change it in your account settings in order to create new group chats.&apos; : Tooltip to warn the user to change a setting to activate an action.</extracomment> <extracomment>&apos;Conference URI is not set. You have to change it in your account settings in order to create new group chats.&apos; : Tooltip to warn the user to change a setting to activate an action.</extracomment>
@ -1913,8 +1926,23 @@
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
<message> <message>
<source>localContactsEntry</source> <source>openCalls</source>
<extracomment>&apos;Local contacts&apos; : Contacts section label in main window when we have to specify that they are local to the application.</extracomment> <extracomment>&apos;Open call history&apos; : Tooltip for a button that open the call history view</extracomment>
<translation type="unfinished"></translation>
</message>
<message>
<source>openChats</source>
<extracomment>&apos;Open chats&apos; : Tooltip for a button that open the conversations view</extracomment>
<translation type="unfinished"></translation>
</message>
<message>
<source>openContacts</source>
<extracomment>&apos;Open contacts&apos; : Tooltip for a button that open the contacts view</extracomment>
<translation type="unfinished"></translation>
</message>
<message>
<source>openMeetings</source>
<extracomment>&apos;Open meetings&apos; : Tooltip for a button that open the meetings list</extracomment>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
</context> </context>
@ -3920,26 +3948,6 @@
</context> </context>
<context> <context>
<name>Timeline</name> <name>Timeline</name>
<message>
<source>timelineFilter</source>
<extracomment>A title for filtering mode.</extracomment>
<translation type="unfinished"></translation>
</message>
<message>
<source>timelineFilterAll</source>
<extracomment>&apos;All&apos; The mode for timelines filtering.</extracomment>
<translation type="unfinished"></translation>
</message>
<message>
<source>timelineFilterCustom</source>
<extracomment>&apos;Custom&apos; The mode for timelines filtering.</extracomment>
<translation type="unfinished"></translation>
</message>
<message>
<source>timelineFilterSimpleRooms</source>
<extracomment>&apos;Simple rooms&apos; : Filter item. Selecting it will show all secure chat groups (with more than one participant).</extracomment>
<translation type="unfinished"></translation>
</message>
<message> <message>
<source>timelineFilterSecureRooms</source> <source>timelineFilterSecureRooms</source>
<extracomment>&apos;Secure rooms&apos; : Filter item. Selecting it will show all secure rooms.</extracomment> <extracomment>&apos;Secure rooms&apos; : Filter item. Selecting it will show all secure rooms.</extracomment>
@ -3950,44 +3958,14 @@
<extracomment>&apos;Chat groups&apos; : Filter item. Selecting it will show all chat groups (with more than one participant).</extracomment> <extracomment>&apos;Chat groups&apos; : Filter item. Selecting it will show all chat groups (with more than one participant).</extracomment>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
<message>
<source>timelineFilterEphemerals</source>
<extracomment>&apos;Ephemerals&apos; : Filter item. Selecting it will show all chat rooms where the ephemeral mode has been enabled.</extracomment>
<translation type="unfinished"></translation>
</message>
<message> <message>
<source>timelineSearchPlaceholderText</source> <source>timelineSearchPlaceholderText</source>
<extracomment>&apos;Search in the list&apos; : ths is a placeholder when searching something in the timeline list</extracomment> <extracomment>&apos;Search in the list&apos; : ths is a placeholder when searching something in the timeline list</extracomment>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
<message> <message>
<source>timelineFilterAllSecureLevelRooms</source> <source>chatsTitle</source>
<extracomment>&apos;All security levels&apos; : Filter item. Selecting it will not do any filter on security level.</extracomment> <extracomment>&apos;Messages&apos; : Title for conversations</extracomment>
<translation type="unfinished"></translation>
</message>
<message>
<source>timelineFilterStandardRooms</source>
<extracomment>&apos;Standard rooms&apos; : Filter item. Selecting it will show all simple rooms.</extracomment>
<translation type="unfinished"></translation>
</message>
<message>
<source>timelineFilterAnyChatRooms</source>
<extracomment>&apos;Any conversations&apos; : Filter item. Selecting it will not do any filter on the type of conversations.</extracomment>
<translation type="unfinished"></translation>
</message>
<message>
<source>timelineFilterAnyEphemerals</source>
<extracomment>&apos;Ephemerals on/off&apos; : Filter item. Selecting it will not do any filter on ephemerals activation.</extracomment>
<translation type="unfinished"></translation>
</message>
<message>
<source>timelineFilterNoEphemerals</source>
<extracomment>&apos;No Ephemerals&apos; : Filter item. Selecting it will hide all chat rooms where the ephemeral mode has been enabled.</extracomment>
<translation type="unfinished"></translation>
</message>
<message>
<source>timelineFilterConferences</source>
<extracomment>&apos;Conferences&apos; : Filter item. Selecting it will show all conferences.</extracomment>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
</context> </context>

View file

@ -451,6 +451,34 @@
<translation></translation> <translation></translation>
</message> </message>
</context> </context>
<context>
<name>CallTimeline</name>
<message>
<source>callListTitle</source>
<extracomment>&apos;Call list&apos; : Call histories title</extracomment>
<translation type="unfinished"></translation>
</message>
<message>
<source>incomingFilter</source>
<extracomment>&apos;Incoming&apos; : Filter label for incoming call</extracomment>
<translation type="unfinished"></translation>
</message>
<message>
<source>outgoingFilter</source>
<extracomment>&apos;Outgoing&apos; : Filter label for outgoing call</extracomment>
<translation type="unfinished"></translation>
</message>
<message>
<source>missedFilter</source>
<extracomment>&apos;Missed&apos; : Filter label for missed call</extracomment>
<translation type="unfinished"></translation>
</message>
<message>
<source>searchListPlaceholderText</source>
<extracomment>&apos;Search in the list&apos; : ths is a placeholder when searching something in a list</extracomment>
<translation type="unfinished"></translation>
</message>
</context>
<context> <context>
<name>CallTransfer</name> <name>CallTransfer</name>
<message> <message>
@ -906,6 +934,11 @@
<extracomment>&apos;The meeting has been deleted&apos; : Message text in a banner to warn the user that the meeting has been deleted.</extracomment> <extracomment>&apos;The meeting has been deleted&apos; : Message text in a banner to warn the user that the meeting has been deleted.</extracomment>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
<message>
<source>createMeeting</source>
<extracomment>&apos;Create Meeting&apos; : Button label to create a meeting</extracomment>
<translation type="unfinished"></translation>
</message>
</context> </context>
<context> <context>
<name>ConfirmDialog</name> <name>ConfirmDialog</name>
@ -1016,12 +1049,9 @@
</message> </message>
<message> <message>
<source>selectAllContacts</source> <source>selectAllContacts</source>
<extracomment>&apos;All&apos; : Filter label to display all items.</extracomment>
<translation></translation> <translation></translation>
</message> </message>
<message>
<source>selectConnectedContacts</source>
<translation></translation>
</message>
<message> <message>
<source>addContact</source> <source>addContact</source>
<translation></translation> <translation></translation>
@ -1035,21 +1065,24 @@
<extracomment>&apos;You need to set the conference URI in your account settings to create a conference based chat room.&apos; : Tooltip to warn the user that a setting is missing in its configuration.</extracomment> <extracomment>&apos;You need to set the conference URI in your account settings to create a conference based chat room.&apos; : Tooltip to warn the user that a setting is missing in its configuration.</extracomment>
<translation> URI </translation> <translation> URI </translation>
</message> </message>
<message>
<source>localContactsEntry</source>
<extracomment>&apos;Local contacts&apos; : Contacts section label in main window when we have to specify that they are local to the application.</extracomment>
<translation type="unfinished"></translation>
</message>
<message>
<source>contactsEntry</source>
<extracomment>&apos;Contacts&apos; : Contacts section label in main waindow.</extracomment>
<translation type="unfinished"></translation>
</message>
<message>
<source>selectOnlineContacts</source>
<extracomment>&apos;Online&apos; : Filter label to display only online contacts.</extracomment>
<translation type="unfinished"></translation>
</message>
</context> </context>
<context> <context>
<name>Conversation</name> <name>Conversation</name>
<message>
<source>displayCallsAndMessages</source>
<translation></translation>
</message>
<message>
<source>displayCalls</source>
<translation></translation>
</message>
<message>
<source>displayMessages</source>
<translation></translation>
</message>
<message> <message>
<source>removeAllEntriesDescription</source> <source>removeAllEntriesDescription</source>
<translation></translation> <translation></translation>
@ -1833,11 +1866,6 @@
<source>mainSearchBarPlaceholder</source> <source>mainSearchBarPlaceholder</source>
<translation></translation> <translation></translation>
</message> </message>
<message>
<source>contactsEntry</source>
<extracomment>&apos;Contacts&apos; : Contacts section label in main waindow.</extracomment>
<translation></translation>
</message>
<message> <message>
<source>autoAnswerStatus</source> <source>autoAnswerStatus</source>
<translation></translation> <translation></translation>
@ -1855,26 +1883,11 @@
<extracomment>&apos;Start a chat room&apos; : Tooltip to illustrate a button</extracomment> <extracomment>&apos;Start a chat room&apos; : Tooltip to illustrate a button</extracomment>
<translation></translation> <translation></translation>
</message> </message>
<message>
<source>hideTimeline</source>
<extracomment>&apos;Hide Timeline&apos; : Tooltip for a button that hide the timeline</extracomment>
<translation>线</translation>
</message>
<message>
<source>openTimeline</source>
<extracomment>&apos;Open Timeline&apos; : Tooltip for a button that open the timeline</extracomment>
<translation>线</translation>
</message>
<message> <message>
<source>openHome</source> <source>openHome</source>
<extracomment>&apos;Open Home&apos; : Tooltip for a button that open the home view</extracomment> <extracomment>&apos;Open Home&apos; : Tooltip for a button that open the home view</extracomment>
<translation></translation> <translation></translation>
</message> </message>
<message>
<source>mainWindowConferencesTitle</source>
<extracomment>&apos;Meetings&apos; : Meeting title for main window.</extracomment>
<translation type="unfinished"></translation>
</message>
<message> <message>
<source>newChatRoomUriMissing</source> <source>newChatRoomUriMissing</source>
<extracomment>&apos;Conference URI is not set. You have to change it in your account settings in order to create new group chats.&apos; : Tooltip to warn the user to change a setting to activate an action.</extracomment> <extracomment>&apos;Conference URI is not set. You have to change it in your account settings in order to create new group chats.&apos; : Tooltip to warn the user to change a setting to activate an action.</extracomment>
@ -1891,8 +1904,23 @@
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
<message> <message>
<source>localContactsEntry</source> <source>openCalls</source>
<extracomment>&apos;Local contacts&apos; : Contacts section label in main window when we have to specify that they are local to the application.</extracomment> <extracomment>&apos;Open call history&apos; : Tooltip for a button that open the call history view</extracomment>
<translation type="unfinished"></translation>
</message>
<message>
<source>openChats</source>
<extracomment>&apos;Open chats&apos; : Tooltip for a button that open the conversations view</extracomment>
<translation type="unfinished"></translation>
</message>
<message>
<source>openContacts</source>
<extracomment>&apos;Open contacts&apos; : Tooltip for a button that open the contacts view</extracomment>
<translation type="unfinished"></translation>
</message>
<message>
<source>openMeetings</source>
<extracomment>&apos;Open meetings&apos; : Tooltip for a button that open the meetings list</extracomment>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
</context> </context>
@ -3892,26 +3920,6 @@
</context> </context>
<context> <context>
<name>Timeline</name> <name>Timeline</name>
<message>
<source>timelineFilter</source>
<extracomment>A title for filtering mode.</extracomment>
<translation></translation>
</message>
<message>
<source>timelineFilterAll</source>
<extracomment>&apos;All&apos; The mode for timelines filtering.</extracomment>
<translation></translation>
</message>
<message>
<source>timelineFilterCustom</source>
<extracomment>&apos;Custom&apos; The mode for timelines filtering.</extracomment>
<translation></translation>
</message>
<message>
<source>timelineFilterSimpleRooms</source>
<extracomment>&apos;Simple rooms&apos; : Filter item. Selecting it will show all secure chat groups (with more than one participant).</extracomment>
<translation></translation>
</message>
<message> <message>
<source>timelineFilterSecureRooms</source> <source>timelineFilterSecureRooms</source>
<extracomment>&apos;Secure rooms&apos; : Filter item. Selecting it will show all secure rooms.</extracomment> <extracomment>&apos;Secure rooms&apos; : Filter item. Selecting it will show all secure rooms.</extracomment>
@ -3922,44 +3930,14 @@
<extracomment>&apos;Chat groups&apos; : Filter item. Selecting it will show all chat groups (with more than one participant).</extracomment> <extracomment>&apos;Chat groups&apos; : Filter item. Selecting it will show all chat groups (with more than one participant).</extracomment>
<translation></translation> <translation></translation>
</message> </message>
<message>
<source>timelineFilterEphemerals</source>
<extracomment>&apos;Ephemerals&apos; : Filter item. Selecting it will show all chat rooms where the ephemeral mode has been enabled.</extracomment>
<translation></translation>
</message>
<message> <message>
<source>timelineSearchPlaceholderText</source> <source>timelineSearchPlaceholderText</source>
<extracomment>&apos;Search in the list&apos; : ths is a placeholder when searching something in the timeline list</extracomment> <extracomment>&apos;Search in the list&apos; : ths is a placeholder when searching something in the timeline list</extracomment>
<translation></translation> <translation></translation>
</message> </message>
<message> <message>
<source>timelineFilterAllSecureLevelRooms</source> <source>chatsTitle</source>
<extracomment>&apos;All security levels&apos; : Filter item. Selecting it will not do any filter on security level.</extracomment> <extracomment>&apos;Messages&apos; : Title for conversations</extracomment>
<translation type="unfinished"></translation>
</message>
<message>
<source>timelineFilterStandardRooms</source>
<extracomment>&apos;Standard rooms&apos; : Filter item. Selecting it will show all simple rooms.</extracomment>
<translation type="unfinished"></translation>
</message>
<message>
<source>timelineFilterAnyChatRooms</source>
<extracomment>&apos;Any conversations&apos; : Filter item. Selecting it will not do any filter on the type of conversations.</extracomment>
<translation type="unfinished"></translation>
</message>
<message>
<source>timelineFilterAnyEphemerals</source>
<extracomment>&apos;Ephemerals on/off&apos; : Filter item. Selecting it will not do any filter on ephemerals activation.</extracomment>
<translation type="unfinished"></translation>
</message>
<message>
<source>timelineFilterNoEphemerals</source>
<extracomment>&apos;No Ephemerals&apos; : Filter item. Selecting it will hide all chat rooms where the ephemeral mode has been enabled.</extracomment>
<translation type="unfinished"></translation>
</message>
<message>
<source>timelineFilterConferences</source>
<extracomment>&apos;Conferences&apos; : Filter item. Selecting it will show all conferences.</extracomment>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
</context> </context>

View file

@ -432,6 +432,7 @@
<file>ui/modules/Linphone/Styles/Sticker/DecorationStickerStyle.qml</file> <file>ui/modules/Linphone/Styles/Sticker/DecorationStickerStyle.qml</file>
<file>ui/modules/Linphone/Styles/Sticker/StickerStyle.qml</file> <file>ui/modules/Linphone/Styles/Sticker/StickerStyle.qml</file>
<file>ui/modules/Linphone/Styles/TelKeypad/TelKeypadStyle.qml</file> <file>ui/modules/Linphone/Styles/TelKeypad/TelKeypadStyle.qml</file>
<file>ui/modules/Linphone/Styles/Timeline/CallTimelineStyle.qml</file>
<file>ui/modules/Linphone/Styles/Timeline/TimelineStyle.qml</file> <file>ui/modules/Linphone/Styles/Timeline/TimelineStyle.qml</file>
<file>ui/modules/Linphone/Styles/View/ParticipantsListViewStyle.qml</file> <file>ui/modules/Linphone/Styles/View/ParticipantsListViewStyle.qml</file>
<file>ui/modules/Linphone/Styles/View/ParticipantsViewStyle.qml</file> <file>ui/modules/Linphone/Styles/View/ParticipantsViewStyle.qml</file>
@ -439,6 +440,8 @@
<file>ui/modules/Linphone/TelKeypad/TelKeypadButton.qml</file> <file>ui/modules/Linphone/TelKeypad/TelKeypadButton.qml</file>
<file>ui/modules/Linphone/TelKeypad/TelKeypad.js</file> <file>ui/modules/Linphone/TelKeypad/TelKeypad.js</file>
<file>ui/modules/Linphone/TelKeypad/TelKeypad.qml</file> <file>ui/modules/Linphone/TelKeypad/TelKeypad.qml</file>
<file>ui/modules/Linphone/Timeline/CallTimeline.qml</file>
<file>ui/modules/Linphone/Timeline/CallTimelineItem.qml</file>
<file>ui/modules/Linphone/Timeline/Timeline.js</file> <file>ui/modules/Linphone/Timeline/Timeline.js</file>
<file>ui/modules/Linphone/Timeline/Timeline.qml</file> <file>ui/modules/Linphone/Timeline/Timeline.qml</file>
<file>ui/modules/Linphone/Timeline/TimelineItem.qml</file> <file>ui/modules/Linphone/Timeline/TimelineItem.qml</file>
@ -477,12 +480,14 @@
<file>ui/views/App/Main/Assistant/UseAppSipAccountWithPhoneNumber.qml</file> <file>ui/views/App/Main/Assistant/UseAppSipAccountWithPhoneNumber.qml</file>
<file>ui/views/App/Main/Assistant/UseAppSipAccountWithUsername.qml</file> <file>ui/views/App/Main/Assistant/UseAppSipAccountWithUsername.qml</file>
<file>ui/views/App/Main/Assistant/UseOtherSipAccount.qml</file> <file>ui/views/App/Main/Assistant/UseOtherSipAccount.qml</file>
<file>ui/views/App/Main/Calls.qml</file>
<file>ui/views/App/Main/Conferences.qml</file> <file>ui/views/App/Main/Conferences.qml</file>
<file>ui/views/App/Main/ContactEdit.js</file> <file>ui/views/App/Main/ContactEdit.js</file>
<file>ui/views/App/Main/ContactEdit.qml</file> <file>ui/views/App/Main/ContactEdit.qml</file>
<file>ui/views/App/Main/Contacts.qml</file> <file>ui/views/App/Main/Contacts.qml</file>
<file>ui/views/App/Main/Conversation.js</file> <file>ui/views/App/Main/Conversation.js</file>
<file>ui/views/App/Main/Conversation.qml</file> <file>ui/views/App/Main/Conversation.qml</file>
<file>ui/views/App/Main/Conversations.qml</file>
<file>ui/views/App/Main/Dialogs/About.qml</file> <file>ui/views/App/Main/Dialogs/About.qml</file>
<file>ui/views/App/Main/Dialogs/AuthenticationRequest.js</file> <file>ui/views/App/Main/Dialogs/AuthenticationRequest.js</file>
<file>ui/views/App/Main/Dialogs/AuthenticationRequest.qml</file> <file>ui/views/App/Main/Dialogs/AuthenticationRequest.qml</file>

View file

@ -51,6 +51,8 @@
#include "translator/DefaultTranslator.hpp" #include "translator/DefaultTranslator.hpp"
#include "utils/Utils.hpp" #include "utils/Utils.hpp"
#include "utils/Constants.hpp" #include "utils/Constants.hpp"
#include "components/history/CallHistoryModel.hpp"
#include "components/history/CallHistoryProxyModel.hpp"
#include "components/other/desktop-tools/DesktopTools.hpp" #include "components/other/desktop-tools/DesktopTools.hpp"
#include "components/other/date/DateModel.hpp" #include "components/other/date/DateModel.hpp"
@ -747,6 +749,7 @@ void App::registerTypes () {
registerType<TemporaryFile>("TemporaryFile"); registerType<TemporaryFile>("TemporaryFile");
registerType<TimeZoneProxyModel>("TimeZoneProxyModel"); registerType<TimeZoneProxyModel>("TimeZoneProxyModel");
registerType<CallHistoryProxyModel>("CallHistoryProxyModel");
registerType<ColorProxyModel>("ColorProxyModel"); registerType<ColorProxyModel>("ColorProxyModel");
registerType<ImageColorsProxyModel>("ImageColorsProxyModel"); registerType<ImageColorsProxyModel>("ImageColorsProxyModel");
registerType<ImageProxyModel>("ImageProxyModel"); registerType<ImageProxyModel>("ImageProxyModel");
@ -765,6 +768,7 @@ void App::registerTypes () {
registerUncreatableType<CallModel>("CallModel"); registerUncreatableType<CallModel>("CallModel");
registerUncreatableType<CallHistoryModel>("CallHistoryModel");
registerUncreatableType<ChatCallModel>("ChatCallModel"); registerUncreatableType<ChatCallModel>("ChatCallModel");
registerUncreatableType<ChatMessageModel>("ChatMessageModel"); registerUncreatableType<ChatMessageModel>("ChatMessageModel");
registerUncreatableType<ChatNoticeModel>("ChatNoticeModel"); registerUncreatableType<ChatNoticeModel>("ChatNoticeModel");

View file

@ -61,3 +61,6 @@ void ChatMessageListener::onEphemeralMessageTimerStarted(const std::shared_ptr<l
void ChatMessageListener::onEphemeralMessageDeleted(const std::shared_ptr<linphone::ChatMessage> & message){ void ChatMessageListener::onEphemeralMessageDeleted(const std::shared_ptr<linphone::ChatMessage> & message){
emit ephemeralMessageDeleted(message); emit ephemeralMessageDeleted(message);
} }
void ChatMessageListener::onReactionRemoved(const std::shared_ptr<linphone::ChatMessage> & message, const std::shared_ptr<const linphone::Address> & address) {
emit reactionRemoved(message, address);
}

View file

@ -45,6 +45,7 @@ public:
virtual void onParticipantImdnStateChanged(const std::shared_ptr<linphone::ChatMessage> & message, const std::shared_ptr<const linphone::ParticipantImdnState> & state) override; virtual void onParticipantImdnStateChanged(const std::shared_ptr<linphone::ChatMessage> & message, const std::shared_ptr<const linphone::ParticipantImdnState> & state) override;
virtual void onEphemeralMessageTimerStarted(const std::shared_ptr<linphone::ChatMessage> & message) override; virtual void onEphemeralMessageTimerStarted(const std::shared_ptr<linphone::ChatMessage> & message) override;
virtual void onEphemeralMessageDeleted(const std::shared_ptr<linphone::ChatMessage> & message) override; virtual void onEphemeralMessageDeleted(const std::shared_ptr<linphone::ChatMessage> & message) override;
virtual void onReactionRemoved(const std::shared_ptr<linphone::ChatMessage> & message, const std::shared_ptr<const linphone::Address> & address) override;
signals: signals:
void fileTransferRecv(const std::shared_ptr<linphone::ChatMessage> & message, const std::shared_ptr<linphone::Content> & content, const std::shared_ptr<const linphone::Buffer> & buffer); void fileTransferRecv(const std::shared_ptr<linphone::ChatMessage> & message, const std::shared_ptr<linphone::Content> & content, const std::shared_ptr<const linphone::Buffer> & buffer);
void fileTransferSendChunk(const std::shared_ptr<linphone::ChatMessage> & message, const std::shared_ptr<linphone::Content> & content, size_t offset, size_t size, const std::shared_ptr<linphone::Buffer> & buffer); void fileTransferSendChunk(const std::shared_ptr<linphone::ChatMessage> & message, const std::shared_ptr<linphone::Content> & content, size_t offset, size_t size, const std::shared_ptr<linphone::Buffer> & buffer);
@ -55,6 +56,7 @@ signals:
void participantImdnStateChanged(const std::shared_ptr<linphone::ChatMessage> & message, const std::shared_ptr<const linphone::ParticipantImdnState> & state); void participantImdnStateChanged(const std::shared_ptr<linphone::ChatMessage> & message, const std::shared_ptr<const linphone::ParticipantImdnState> & state);
void ephemeralMessageTimerStarted(const std::shared_ptr<linphone::ChatMessage> & message); void ephemeralMessageTimerStarted(const std::shared_ptr<linphone::ChatMessage> & message);
void ephemeralMessageDeleted(const std::shared_ptr<linphone::ChatMessage> & message); void ephemeralMessageDeleted(const std::shared_ptr<linphone::ChatMessage> & message);
void reactionRemoved(const std::shared_ptr<linphone::ChatMessage> & message, const std::shared_ptr<const linphone::Address> & address);
}; };
Q_DECLARE_METATYPE(ChatMessageListener*) Q_DECLARE_METATYPE(ChatMessageListener*)

View file

@ -68,6 +68,7 @@ void ChatMessageModel::connectTo(ChatMessageListener * listener){
connect(listener, &ChatMessageListener::ephemeralMessageTimerStarted, this, &ChatMessageModel::onEphemeralMessageTimerStarted); connect(listener, &ChatMessageListener::ephemeralMessageTimerStarted, this, &ChatMessageModel::onEphemeralMessageTimerStarted);
connect(listener, &ChatMessageListener::ephemeralMessageDeleted, this, &ChatMessageModel::onEphemeralMessageDeleted); connect(listener, &ChatMessageListener::ephemeralMessageDeleted, this, &ChatMessageModel::onEphemeralMessageDeleted);
connect(listener, &ChatMessageListener::participantImdnStateChanged, this->getParticipantImdnStates().get(), &ParticipantImdnStateListModel::onParticipantImdnStateChanged); connect(listener, &ChatMessageListener::participantImdnStateChanged, this->getParticipantImdnStates().get(), &ParticipantImdnStateListModel::onParticipantImdnStateChanged);
connect(listener, &ChatMessageListener::reactionRemoved, this, &ChatMessageModel::onReactionRemoved);
} }
// ============================================================================= // =============================================================================
@ -153,6 +154,12 @@ QString ChatMessageModel::getToSipAddress() const{
return mChatMessage ? Utils::cleanSipAddress(Utils::coreStringToAppString(mChatMessage->getToAddress()->asStringUriOnly())) : ""; return mChatMessage ? Utils::cleanSipAddress(Utils::coreStringToAppString(mChatMessage->getToAddress()->asStringUriOnly())) : "";
} }
QString ChatMessageModel::getMyReaction() const {
if(!mChatMessage) return "";
auto myReaction = mChatMessage->getOwnReaction();
return myReaction ? Utils::coreStringToAppString(myReaction->getBody()) : "";
}
ContactModel * ChatMessageModel::getContactModel() const{ ContactModel * ChatMessageModel::getContactModel() const{
return mChatMessage ? CoreManager::getInstance()->getContactsListModel()->findContactModelFromSipAddress(Utils::cleanSipAddress(Utils::coreStringToAppString(mChatMessage->getFromAddress()->asStringUriOnly()))).get() : nullptr; return mChatMessage ? CoreManager::getInstance()->getContactsListModel()->findContactModelFromSipAddress(Utils::cleanSipAddress(Utils::coreStringToAppString(mChatMessage->getFromAddress()->asStringUriOnly()))).get() : nullptr;
} }
@ -256,13 +263,16 @@ void ChatMessageModel::resendMessage (){
} }
void ChatMessageModel::sendChatReaction(const QString& reaction){ void ChatMessageModel::sendChatReaction(const QString& reaction){
auto chatReaction = mChatMessage->createReaction(Utils::appStringToCoreString(reaction)); auto myReaction = mChatMessage->getOwnReaction();
if( mChatReactionListModel->exists(chatReaction)) { if( myReaction && Utils::coreStringToAppString(myReaction->getBody()) == reaction) {
chatReaction = mChatMessage->createReaction(""); auto chatReaction = mChatMessage->createReaction("");
return; // TODO : remove return when sending empty emoji will be supported. chatReaction->send();
//emit reactionRemoved(mChatMessage, chatReaction->getFromAddress()); // Do not emit because we want to display what the server got
}else{
auto chatReaction = mChatMessage->createReaction(Utils::appStringToCoreString(reaction));
chatReaction->send();
//emit newMessageReaction(mChatMessage, chatReaction);// Do not emit because we want to display what the server got
} }
chatReaction->send();
emit newMessageReaction(mChatMessage, chatReaction);
} }
void ChatMessageModel::deleteEvent(){ void ChatMessageModel::deleteEvent(){
@ -327,6 +337,8 @@ void ChatMessageModel::onMsgStateChanged (const std::shared_ptr<linphone::ChatMe
} }
void ChatMessageModel::onNewMessageReaction(const std::shared_ptr<linphone::ChatMessage> & message, const std::shared_ptr<const linphone::ChatMessageReaction> & reaction){ void ChatMessageModel::onNewMessageReaction(const std::shared_ptr<linphone::ChatMessage> & message, const std::shared_ptr<const linphone::ChatMessageReaction> & reaction){
if(reaction->getFromAddress()->weakEqual(message->getLocalAddress()))
emit myReactionChanged();
emit newMessageReaction(message, reaction); emit newMessageReaction(message, reaction);
} }
@ -342,6 +354,12 @@ void ChatMessageModel::onEphemeralMessageDeleted(const std::shared_ptr<linphone:
mContentListModel->removeDownloadedFiles(); mContentListModel->removeDownloadedFiles();
emit remove(this); emit remove(this);
} }
void ChatMessageModel::onReactionRemoved(const std::shared_ptr<linphone::ChatMessage> & message, const std::shared_ptr<const linphone::Address> & address) {
if(address->weakEqual(message->getLocalAddress()))
emit myReactionChanged();
emit reactionRemoved(message, address);
}
//------------------------------------------------------------------------------------------------------- //-------------------------------------------------------------------------------------------------------

View file

@ -74,6 +74,7 @@ public:
Q_PROPERTY(bool isForward READ isForward CONSTANT) Q_PROPERTY(bool isForward READ isForward CONSTANT)
Q_PROPERTY(QString getForwardInfo READ getForwardInfo CONSTANT) Q_PROPERTY(QString getForwardInfo READ getForwardInfo CONSTANT)
Q_PROPERTY(QString getForwardInfoDisplayName READ getForwardInfoDisplayName CONSTANT) Q_PROPERTY(QString getForwardInfoDisplayName READ getForwardInfoDisplayName CONSTANT)
Q_PROPERTY(QString myReaction READ getMyReaction NOTIFY myReactionChanged)
std::shared_ptr<linphone::ChatMessage> getChatMessage(); std::shared_ptr<linphone::ChatMessage> getChatMessage();
@ -86,6 +87,7 @@ public:
QString getFromSipAddress() const; QString getFromSipAddress() const;
QString getToDisplayName() const; QString getToDisplayName() const;
QString getToSipAddress() const; QString getToSipAddress() const;
QString getMyReaction() const;
ContactModel * getContactModel() const; ContactModel * getContactModel() const;
bool isEphemeral() const; bool isEphemeral() const;
Q_INVOKABLE qint64 getEphemeralExpireTime() const; Q_INVOKABLE qint64 getEphemeralExpireTime() const;
@ -129,6 +131,7 @@ public:
void onParticipantImdnStateChanged(const std::shared_ptr<linphone::ChatMessage> & message, const std::shared_ptr<const linphone::ParticipantImdnState> & state); void onParticipantImdnStateChanged(const std::shared_ptr<linphone::ChatMessage> & message, const std::shared_ptr<const linphone::ParticipantImdnState> & state);
void onEphemeralMessageTimerStarted(const std::shared_ptr<linphone::ChatMessage> & message); void onEphemeralMessageTimerStarted(const std::shared_ptr<linphone::ChatMessage> & message);
void onEphemeralMessageDeleted(const std::shared_ptr<linphone::ChatMessage> & message); void onEphemeralMessageDeleted(const std::shared_ptr<linphone::ChatMessage> & message);
void onReactionRemoved(const std::shared_ptr<linphone::ChatMessage> & message, const std::shared_ptr<const linphone::Address> & address);
//---------------------------------------------------------------------------- //----------------------------------------------------------------------------
bool mWasDownloaded; bool mWasDownloaded;
@ -145,8 +148,10 @@ signals:
void isOutgoingChanged(); void isOutgoingChanged();
void fileContentChanged(); void fileContentChanged();
void remove(ChatMessageModel* model); void remove(ChatMessageModel* model);
void myReactionChanged();
void newMessageReaction(const std::shared_ptr<linphone::ChatMessage> & message, const std::shared_ptr<const linphone::ChatMessageReaction> & reaction); void newMessageReaction(const std::shared_ptr<linphone::ChatMessage> & message, const std::shared_ptr<const linphone::ChatMessageReaction> & reaction);
void reactionRemoved(const std::shared_ptr<linphone::ChatMessage> & message, const std::shared_ptr<const linphone::Address> & address);
private: private:
void connectTo(ChatMessageListener * listener); void connectTo(ChatMessageListener * listener);

View file

@ -31,11 +31,15 @@ ChatReactionListModel::ChatReactionListModel (ChatMessageModel * message, QObjec
} }
void ChatReactionListModel::setChatMessageModel(ChatMessageModel * message) { void ChatReactionListModel::setChatMessageModel(ChatMessageModel * message) {
if(mParent) if(mParent) {
disconnect(message, &ChatMessageModel::newMessageReaction, this, &ChatReactionListModel::onNewMessageReaction); disconnect(message, &ChatMessageModel::newMessageReaction, this, &ChatReactionListModel::onNewMessageReaction);
disconnect(message, &ChatMessageModel::reactionRemoved, this, &ChatReactionListModel::onReactionRemoved);
}
mParent = message; mParent = message;
if(mParent) if(mParent) {
connect(message, &ChatMessageModel::newMessageReaction, this, &ChatReactionListModel::onNewMessageReaction); connect(message, &ChatMessageModel::newMessageReaction, this, &ChatReactionListModel::onNewMessageReaction);
connect(message, &ChatMessageModel::reactionRemoved, this, &ChatReactionListModel::onReactionRemoved);
}
if(message){ if(message){
auto reactions = message->getChatMessage()->getReactions(); auto reactions = message->getChatMessage()->getReactions();
mReactions.clear(); mReactions.clear();
@ -176,3 +180,12 @@ QStringList ChatReactionListModel::getBodies() const {
void ChatReactionListModel::onNewMessageReaction(const std::shared_ptr<linphone::ChatMessage> & message, const std::shared_ptr<const linphone::ChatMessageReaction> & reaction){ void ChatReactionListModel::onNewMessageReaction(const std::shared_ptr<linphone::ChatMessage> & message, const std::shared_ptr<const linphone::ChatMessageReaction> & reaction){
updateChatReaction(reaction); updateChatReaction(reaction);
} }
void ChatReactionListModel::onReactionRemoved(const std::shared_ptr<linphone::ChatMessage> & message, const std::shared_ptr<const linphone::Address> & address) {
mReactions.remove(Utils::coreStringToAppString(address->asStringUriOnly()));
mBodies.clear();
for(auto it : mReactions)
mBodies[it->getBody()].push_back(it);
updateList();
emit chatReactionCountChanged();
emit bodiesChanged();
}

View file

@ -65,6 +65,7 @@ public:
void updateList(); void updateList();
void onNewMessageReaction(const std::shared_ptr<linphone::ChatMessage> & message, const std::shared_ptr<const linphone::ChatMessageReaction> & reaction); void onNewMessageReaction(const std::shared_ptr<linphone::ChatMessage> & message, const std::shared_ptr<const linphone::ChatMessageReaction> & reaction);
void onReactionRemoved(const std::shared_ptr<linphone::ChatMessage> & message, const std::shared_ptr<const linphone::Address> & address);
signals: signals:
void chatReactionsChanged(); void chatReactionsChanged();
void chatReactionCountChanged(); void chatReactionCountChanged();

View file

@ -23,6 +23,7 @@
#include <algorithm> #include <algorithm>
#include <QDateTime> #include <QDateTime>
#include <QDebug>
#include <QDesktopServices> #include <QDesktopServices>
#include <QElapsedTimer> #include <QElapsedTimer>
#include <QFileInfo> #include <QFileInfo>
@ -126,9 +127,6 @@ ChatRoomModel::ChatRoomModel (const std::shared_ptr<linphone::ChatRoom>& chatRoo
// Get messages. // Get messages.
mList.clear(); mList.clear();
mUnreadMessagesCount = mChatRoom->getUnreadMessagesCount();
mMissedCallsCount = 0;
QElapsedTimer timer; QElapsedTimer timer;
timer.start(); timer.start();
CoreHandlers *coreHandlers = mCoreHandlers.get(); CoreHandlers *coreHandlers = mCoreHandlers.get();
@ -145,7 +143,8 @@ ChatRoomModel::ChatRoomModel (const std::shared_ptr<linphone::ChatRoom>& chatRoo
QObject::connect(coreManager->getContactsListModel(), &ContactsListModel::contactUpdated, this, &ChatRoomModel::avatarChanged); QObject::connect(coreManager->getContactsListModel(), &ContactsListModel::contactUpdated, this, &ChatRoomModel::avatarChanged);
connect(this, &ChatRoomModel::fullPeerAddressChanged, this, &ChatRoomModel::usernameChanged); connect(this, &ChatRoomModel::fullPeerAddressChanged, this, &ChatRoomModel::usernameChanged);
connect(this, &ChatRoomModel::stateChanged, this, &ChatRoomModel::updatingChanged); connect(this, &ChatRoomModel::messageCountReset, this, &ChatRoomModel::unreadMessagesCountChanged);
connect(this, &ChatRoomModel::unreadMessagesCountChanged, coreManager, &CoreManager::eventCountChanged);
if(mChatRoom){ if(mChatRoom){
mParticipantListModel = QSharedPointer<ParticipantListModel>::create(this); mParticipantListModel = QSharedPointer<ParticipantListModel>::create(this);
@ -408,6 +407,10 @@ LinphoneEnums::ChatRoomState ChatRoomModel::getState() const {
return mChatRoom ? LinphoneEnums::fromLinphone(mChatRoom->getState()) : LinphoneEnums::ChatRoomStateNone; return mChatRoom ? LinphoneEnums::fromLinphone(mChatRoom->getState()) : LinphoneEnums::ChatRoomStateNone;
} }
int ChatRoomModel::getUnreadMessagesCount() const{
return mChatRoom ? mChatRoom->getUnreadMessagesCount() : 0;
}
bool ChatRoomModel::isReadOnly() const{ bool ChatRoomModel::isReadOnly() const{
return mChatRoom && mChatRoom->isReadOnly(); return mChatRoom && mChatRoom->isReadOnly();
} }
@ -531,10 +534,6 @@ QString ChatRoomModel::getParticipantAddress() const{
} }
} }
int ChatRoomModel::getAllUnreadCount(){
return mUnreadMessagesCount + mMissedCallsCount;
}
//------------------------------------------------------------------------------------------------ //------------------------------------------------------------------------------------------------
void ChatRoomModel::setSubject(QString& subject){ void ChatRoomModel::setSubject(QString& subject){
@ -564,31 +563,6 @@ void ChatRoomModel::updateLastUpdateTime(){
} }
} }
void ChatRoomModel::setUnreadMessagesCount(const int& count){
updateNewMessageNotice(count);
if(count != mUnreadMessagesCount){
mUnreadMessagesCount = count;
emit unreadMessagesCountChanged();
}
}
void ChatRoomModel::setMissedCallsCount(const int& count){
if(count != mMissedCallsCount){
mMissedCallsCount = count;
emit missedCallsCountChanged();
}
}
void ChatRoomModel::addMissedCallsCount(std::shared_ptr<linphone::Call> call){
insertCall(call->getCallLog());
auto timeline = CoreManager::getInstance()->getTimelineListModel()->getTimeline(mChatRoom, false);
if(!timeline || !timeline->mSelected){
setMissedCallsCount(mMissedCallsCount+1);
if(call->dataExists("call-model"))
CoreManager::getInstance()->getEventCountNotifier()->handleCallMissed(&call->getData<CallModel>("call-model"));
}
}
void ChatRoomModel::setEphemeralEnabled(bool enabled){ void ChatRoomModel::setEphemeralEnabled(bool enabled){
if(isEphemeralEnabled() != enabled){ if(isEphemeralEnabled() != enabled){
mChatRoom->enableEphemeral(enabled); mChatRoom->enableEphemeral(enabled);
@ -658,22 +632,6 @@ void ChatRoomModel::leaveChatRoom (){
void ChatRoomModel::updateParticipants(const QVariantList& participants){ void ChatRoomModel::updateParticipants(const QVariantList& participants){
/*
std::shared_ptr<linphone::ChatRoomParams> params = core->createDefaultChatRoomParams();
std::list <shared_ptr<linphone::Address> > chatRoomParticipants;
std::shared_ptr<const linphone::Address> localAddress;
for(auto p : participants){
ParticipantModel* participant = p.value<ParticipantModel*>();
auto address = Utils::interpretUrl(participant->getSipAddress());
if( address)
chatRoomParticipants.push_back( address );
}
if(mChatRoom->canHandleParticipants()) {
mChatRoom->addParticipants(newParticipants);
mChatRoom->removeParticipants(removeParticipants);
}
linphone::ChatRoom;*/
} }
// ----------------------------------------------------------------------------- // -----------------------------------------------------------------------------
@ -751,12 +709,8 @@ void ChatRoomModel::resetMessageCount () {
if (mChatRoom->getUnreadMessagesCount() > 0){ if (mChatRoom->getUnreadMessagesCount() > 0){
mChatRoom->markAsRead();// Marking as read is only for messages. Not for calls. mChatRoom->markAsRead();// Marking as read is only for messages. Not for calls.
} }
setUnreadMessagesCount(mChatRoom->getUnreadMessagesCount()); }
}else
setUnreadMessagesCount(0);
setMissedCallsCount(0);
emit messageCountReset(); emit messageCountReset();
CoreManager::getInstance()->updateUnreadMessageCount();
} }
} }
//------------------------------------------------- //-------------------------------------------------
@ -976,21 +930,7 @@ void ChatRoomModel::initEntries(){
// Get events // Get events
for(auto &eventLog : mChatRoom->getHistoryEvents(mFirstLastEntriesStep)) for(auto &eventLog : mChatRoom->getHistoryEvents(mFirstLastEntriesStep))
prepareEntries << EntrySorterHelper(eventLog->getCreationTime() , NoticeEntry, eventLog); prepareEntries << EntrySorterHelper(eventLog->getCreationTime() , NoticeEntry, eventLog);
// Get calls.
bool secureChatEnabled = CoreManager::getInstance()->getSettingsModel()->getSecureChatEnabled();
bool standardChatEnabled = CoreManager::getInstance()->getSettingsModel()->getStandardChatEnabled();
bool noChat = !secureChatEnabled && !standardChatEnabled;
if(noChat || (isOneToOne() && (secureChatEnabled && !standardChatEnabled && isSecure()
|| standardChatEnabled && !isSecure())) ) {
auto callHistory = CallsListModel::getCallHistory(getParticipantAddress(), Utils::coreStringToAppString(mChatRoom->getLocalAddress()->asStringUriOnly()));
// callhistory is sorted from newest to oldest
int count = 0;
for (auto callLog = callHistory.begin() ; count < mFirstLastEntriesStep && callLog != callHistory.end() ; ++callLog, ++count ){
if(!(*callLog)->wasConference())
prepareEntries << EntrySorterHelper((*callLog)->getStartDate(), CallEntry, *callLog);
}
}
EntrySorterHelper::getLimitedSelection(&entries, prepareEntries, mFirstLastEntriesStep, this); EntrySorterHelper::getLimitedSelection(&entries, prepareEntries, mFirstLastEntriesStep, this);
qDebug() << "Internal Entries : Built"; qDebug() << "Internal Entries : Built";
if(entries.size() >0){ if(entries.size() >0){
@ -1054,26 +994,6 @@ int ChatRoomModel::loadMoreEntries(){
prepareEntries << EntrySorterHelper(ChatMessageModel::initReceivedTimestamp(message, false).toTime_t() ,MessageEntry, message); prepareEntries << EntrySorterHelper(ChatMessageModel::initReceivedTimestamp(message, false).toTime_t() ,MessageEntry, message);
} }
// Calls
bool secureChatEnabled = CoreManager::getInstance()->getSettingsModel()->getSecureChatEnabled();
bool standardChatEnabled = CoreManager::getInstance()->getSettingsModel()->getStandardChatEnabled();
bool noChat = !secureChatEnabled && !standardChatEnabled;
if( noChat || (isOneToOne() && (secureChatEnabled && !standardChatEnabled && isSecure()
|| standardChatEnabled && !isSecure())) ) {
auto callHistory = CallsListModel::getCallHistory(getParticipantAddress(), Utils::coreStringToAppString(mChatRoom->getLocalAddress()->asStringUriOnly()));
int count = 0;
auto itCallHistory = callHistory.begin();
while(count < entriesCounts[1] && itCallHistory != callHistory.end()){
++itCallHistory;
++count;
}
count = 0;
while( count < mLastEntriesStep && itCallHistory != callHistory.end()){
prepareEntries << EntrySorterHelper((*itCallHistory)->getStartDate(), CallEntry, *itCallHistory);
++itCallHistory;
}
}
// Notices // Notices
for (auto &eventLog : mChatRoom->getHistoryRangeEvents(entriesCounts[2], entriesCounts[2]+mLastEntriesStep)){ for (auto &eventLog : mChatRoom->getHistoryRangeEvents(entriesCounts[2], entriesCounts[2]+mLastEntriesStep)){
auto itEntries = mList.begin(); auto itEntries = mList.begin();
@ -1114,58 +1034,12 @@ int ChatRoomModel::loadMoreEntries(){
//------------------------------------------------- //-------------------------------------------------
void ChatRoomModel::onCallEnded(std::shared_ptr<linphone::Call> call){ void ChatRoomModel::onCallEnded(std::shared_ptr<linphone::Call> call){
if( call->getCallLog()->getStatus() == linphone::Call::Status::Missed)
addMissedCallsCount(call);
else{
insertCall(call->getCallLog());
}
// When a call is end, a new log WILL be written in database. It may have information on display name. // When a call is end, a new log WILL be written in database. It may have information on display name.
QTimer::singleShot(100, this, &ChatRoomModel::fullPeerAddressChanged); QTimer::singleShot(100, this, &ChatRoomModel::fullPeerAddressChanged);
} }
// ----------------------------------------------------------------------------- // -----------------------------------------------------------------------------
void ChatRoomModel::insertCall (const std::shared_ptr<linphone::CallLog> &callLog) {
if(mIsInitialized){
QSharedPointer<ChatCallModel> model = ChatCallModel::create(callLog, true);
if(model){
int row = mList.count();
beginInsertRows(QModelIndex(), row, row);
mList << model;
endInsertRows();
auto lastIndex = index(mList.size()-1,0);
emit dataChanged(lastIndex,lastIndex );
if (callLog->getStatus() == linphone::Call::Status::Success) {
model = ChatCallModel::create(callLog, false);
if(model)
add(model);
}
updateLastUpdateTime();
}
}
}
void ChatRoomModel::insertCalls (const QList<std::shared_ptr<linphone::CallLog> > &calls) {
if(mIsInitialized){
QList<QSharedPointer<QObject> > entries;
for(auto callLog : calls) {
QSharedPointer<ChatCallModel> model = ChatCallModel::create(callLog, true);
if(model){
entries << model;
if (callLog->getStatus() == linphone::Call::Status::Success) {
model = ChatCallModel::create(callLog, false);
if(model){
entries << model;
}
}
}
}
if(entries.size() > 0){
prepend(entries);
}
}
}
QSharedPointer<ChatMessageModel> ChatRoomModel::insertMessageAtEnd (const std::shared_ptr<linphone::ChatMessage> &message) { QSharedPointer<ChatMessageModel> ChatRoomModel::insertMessageAtEnd (const std::shared_ptr<linphone::ChatMessage> &message) {
QSharedPointer<ChatMessageModel> model; QSharedPointer<ChatMessageModel> model;
if(mIsInitialized && !exists(message)){ if(mIsInitialized && !exists(message)){
@ -1173,7 +1047,7 @@ QSharedPointer<ChatMessageModel> ChatRoomModel::insertMessageAtEnd (const std::s
if(model){ if(model){
qDebug() << "Adding at end" << model->getReceivedTimestamp().toString("hh:mm:ss.zzz") << model->getTimestamp().toString("hh:mm:ss.zzz") << QString(message->getUtf8Text().c_str()).left(5); qDebug() << "Adding at end" << model->getReceivedTimestamp().toString("hh:mm:ss.zzz") << model->getTimestamp().toString("hh:mm:ss.zzz") << QString(message->getUtf8Text().c_str()).left(5);
connect(model.get(), &ChatMessageModel::remove, this, &ChatRoomModel::removeEntry); connect(model.get(), &ChatMessageModel::remove, this, &ChatRoomModel::removeEntry);
setUnreadMessagesCount(mChatRoom->getUnreadMessagesCount()); emit unreadMessagesCountChanged();
add(model); add(model);
} }
} }
@ -1192,7 +1066,7 @@ void ChatRoomModel::insertMessages (const QList<std::shared_ptr<linphone::ChatMe
} }
if(entries.size() > 0){ if(entries.size() > 0){
prepend(entries); prepend(entries);
setUnreadMessagesCount(mChatRoom->getUnreadMessagesCount()); emit unreadMessagesCountChanged();
} }
} }
} }
@ -1234,30 +1108,9 @@ QString ChatRoomModel::getChatRoomId(const std::shared_ptr<linphone::ChatRoom>&
return getChatRoomId(Utils::coreStringToAppString(localAddress->asStringUriOnly()), (chatRoom->getPeerAddress() ? Utils::coreStringToAppString(chatRoom->getPeerAddress()->asStringUriOnly()) : "")); return getChatRoomId(Utils::coreStringToAppString(localAddress->asStringUriOnly()), (chatRoom->getPeerAddress() ? Utils::coreStringToAppString(chatRoom->getPeerAddress()->asStringUriOnly()) : ""));
} }
// -----------------------------------------------------------------------------
/*
void ChatRoomModel::removeUnreadMessagesNotice() {
}*/
// ----------------------------------------------------------------------------- // -----------------------------------------------------------------------------
void ChatRoomModel::handleCallStateChanged (const std::shared_ptr<linphone::Call> &call, linphone::Call::State state) { void ChatRoomModel::handleCallStateChanged (const std::shared_ptr<linphone::Call> &call, linphone::Call::State state) {
/*
if (state == linphone::Call::State::End || state == linphone::Call::State::Error){
shared_ptr<linphone::Core> core = CoreManager::getInstance()->getCore();
std::shared_ptr<linphone::ChatRoomParams> params = core->createDefaultChatRoomParams();
std::list<std::shared_ptr<linphone::Address>> participants;
auto chatRoom = core->searchChatRoom(params, mChatRoom->getLocalAddress()
, call->getRemoteAddress()
, participants);
if( mChatRoom == chatRoom){
insertCall(call->getCallLog());
setMissedCallsCount(mMissedCallsCount+1);
}
}
*/
} }
void ChatRoomModel::handleCallCreated(const shared_ptr<linphone::Call> &call){ void ChatRoomModel::handleCallCreated(const shared_ptr<linphone::Call> &call){
@ -1269,8 +1122,6 @@ void ChatRoomModel::handlePresenceStatusReceived(std::shared_ptr<linphone::Frien
bool canUpdatePresence = false; bool canUpdatePresence = false;
auto contactAddresses = contact->getAddresses(); auto contactAddresses = contact->getAddresses();
for( auto itContactAddress = contactAddresses.begin() ; !canUpdatePresence && itContactAddress != contactAddresses.end() ; ++itContactAddress){ for( auto itContactAddress = contactAddresses.begin() ; !canUpdatePresence && itContactAddress != contactAddresses.end() ; ++itContactAddress){
//auto cleanContactAddress = (*itContactAddress)->clone();
//cleanContactAddress->clean();
canUpdatePresence = mChatRoom->getLocalAddress()->weakEqual(*itContactAddress); canUpdatePresence = mChatRoom->getLocalAddress()->weakEqual(*itContactAddress);
if(!canUpdatePresence && !isGroupEnabled() && mChatRoom->getNbParticipants() == 1){ if(!canUpdatePresence && !isGroupEnabled() && mChatRoom->getNbParticipants() == 1){
auto participants = getParticipants(false); auto participants = getParticipants(false);
@ -1285,7 +1136,6 @@ void ChatRoomModel::handlePresenceStatusReceived(std::shared_ptr<linphone::Frien
} }
} }
if(canUpdatePresence) { if(canUpdatePresence) {
//emit presenceStatusChanged((int)contact->getPresenceModel()->getConsolidatedPresence());
emit presenceStatusChanged(); emit presenceStatusChanged();
} }
} }
@ -1308,23 +1158,21 @@ void ChatRoomModel::onIsComposingReceived(const std::shared_ptr<linphone::ChatRo
void ChatRoomModel::onMessageReceived(const std::shared_ptr<linphone::ChatRoom> & chatRoom, const std::shared_ptr<linphone::ChatMessage> & message){ void ChatRoomModel::onMessageReceived(const std::shared_ptr<linphone::ChatRoom> & chatRoom, const std::shared_ptr<linphone::ChatMessage> & message){
if(message) ChatMessageModel::initReceivedTimestamp(message, true); if(message) ChatMessageModel::initReceivedTimestamp(message, true);
setUnreadMessagesCount(chatRoom->getUnreadMessagesCount()); emit unreadMessagesCountChanged();
updateLastUpdateTime(); updateLastUpdateTime();
} }
void ChatRoomModel::onMessagesReceived(const std::shared_ptr<linphone::ChatRoom> & chatRoom, const std::list<std::shared_ptr<linphone::ChatMessage>> & messages){ void ChatRoomModel::onMessagesReceived(const std::shared_ptr<linphone::ChatRoom> & chatRoom, const std::list<std::shared_ptr<linphone::ChatMessage>> & messages){
for(auto message : messages) for(auto message : messages)
if(message) ChatMessageModel::initReceivedTimestamp(message, true); if(message) ChatMessageModel::initReceivedTimestamp(message, true);
setUnreadMessagesCount(chatRoom->getUnreadMessagesCount()); emit unreadMessagesCountChanged();
updateLastUpdateTime(); updateLastUpdateTime();
} }
void ChatRoomModel::onNewEvent(const std::shared_ptr<linphone::ChatRoom> & chatRoom, const std::shared_ptr<const linphone::EventLog> & eventLog){ void ChatRoomModel::onNewEvent(const std::shared_ptr<linphone::ChatRoom> & chatRoom, const std::shared_ptr<const linphone::EventLog> & eventLog){
if(eventLog){ if(eventLog){
if( eventLog->getType() == linphone::EventLog::Type::ConferenceCallEnded ){ if( eventLog->getType() == linphone::EventLog::Type::ConferenceCreated ){
setMissedCallsCount(mMissedCallsCount+1);
}else if( eventLog->getType() == linphone::EventLog::Type::ConferenceCreated ){
emit fullPeerAddressChanged(); emit fullPeerAddressChanged();
} }
updateLastUpdateTime(); updateLastUpdateTime();
@ -1332,17 +1180,12 @@ void ChatRoomModel::onNewEvent(const std::shared_ptr<linphone::ChatRoom> & chatR
} }
void ChatRoomModel::onNewEvents(const std::shared_ptr<linphone::ChatRoom> & chatRoom, const std::list<std::shared_ptr<linphone::EventLog>> & eventLogs){ void ChatRoomModel::onNewEvents(const std::shared_ptr<linphone::ChatRoom> & chatRoom, const std::list<std::shared_ptr<linphone::EventLog>> & eventLogs){
int missCount = 0;
bool updatePeerAddress = false; bool updatePeerAddress = false;
for(auto eventLog : eventLogs) for(auto eventLog : eventLogs)
if(eventLog){ if(eventLog){
if( eventLog->getType() == linphone::EventLog::Type::ConferenceCallEnded )
++missCount;
if( eventLog->getType() == linphone::EventLog::Type::ConferenceCreated ) if( eventLog->getType() == linphone::EventLog::Type::ConferenceCreated )
updatePeerAddress = true; updatePeerAddress = true;
} }
if(missCount > 0)
setMissedCallsCount(mMissedCallsCount+missCount);
if(updatePeerAddress) if(updatePeerAddress)
emit fullPeerAddressChanged(); emit fullPeerAddressChanged();
updateLastUpdateTime(); updateLastUpdateTime();
@ -1470,7 +1313,7 @@ void ChatRoomModel::onConferenceJoined(const std::shared_ptr<linphone::ChatRoom>
if(e != events.end() ) if(e != events.end() )
insertNotice(*e); insertNotice(*e);
} }
setUnreadMessagesCount(mChatRoom->getUnreadMessagesCount()); // Update message count. In the case of joining conference, the conference id was not valid thus, the missing count was not about the chat room but a global one. emit unreadMessagesCountChanged();// Update message count. In the case of joining conference, the conference id was not valid thus, the missing count was not about the chat room but a global one.
updateLastUpdateTime(); updateLastUpdateTime();
emit usernameChanged(); emit usernameChanged();
emit conferenceJoined(eventLog); emit conferenceJoined(eventLog);

View file

@ -61,8 +61,7 @@ public:
Q_PROPERTY(QString subject READ getSubject WRITE setSubject NOTIFY subjectChanged) Q_PROPERTY(QString subject READ getSubject WRITE setSubject NOTIFY subjectChanged)
Q_PROPERTY(QDateTime lastUpdateTime MEMBER mLastUpdateTime WRITE setLastUpdateTime NOTIFY lastUpdateTimeChanged) Q_PROPERTY(QDateTime lastUpdateTime MEMBER mLastUpdateTime WRITE setLastUpdateTime NOTIFY lastUpdateTimeChanged)
Q_PROPERTY(int unreadMessagesCount MEMBER mUnreadMessagesCount WRITE setUnreadMessagesCount NOTIFY unreadMessagesCountChanged) Q_PROPERTY(int unreadMessagesCount READ getUnreadMessagesCount NOTIFY unreadMessagesCountChanged)
Q_PROPERTY(int missedCallsCount MEMBER mMissedCallsCount WRITE setMissedCallsCount NOTIFY missedCallsCountChanged)
Q_PROPERTY(int securityLevel READ getSecurityLevel NOTIFY securityLevelChanged) Q_PROPERTY(int securityLevel READ getSecurityLevel NOTIFY securityLevelChanged)
Q_PROPERTY(bool groupEnabled READ isGroupEnabled NOTIFY groupEnabledChanged) Q_PROPERTY(bool groupEnabled READ isGroupEnabled NOTIFY groupEnabledChanged)
@ -124,6 +123,7 @@ public:
int getPresenceStatus() const; int getPresenceStatus() const;
QDateTime getPresenceTimestamp() const; QDateTime getPresenceTimestamp() const;
LinphoneEnums::ChatRoomState getState() const; LinphoneEnums::ChatRoomState getState() const;
int getUnreadMessagesCount() const;
bool isReadOnly() const; bool isReadOnly() const;
bool isEphemeralEnabled() const; bool isEphemeralEnabled() const;
long getEphemeralLifetime() const; long getEphemeralLifetime() const;
@ -149,7 +149,6 @@ public:
std::list<std::shared_ptr<linphone::Participant>> getParticipants(const bool& withMe = true) const; std::list<std::shared_ptr<linphone::Participant>> getParticipants(const bool& withMe = true) const;
std::shared_ptr<linphone::ChatRoom> getChatRoom(); std::shared_ptr<linphone::ChatRoom> getChatRoom();
QList<QString> getComposers(); QList<QString> getComposers();
int getAllUnreadCount(); // Return unread messages and missed call.
//---- Setters //---- Setters
void setSubject(QString& subject); void setSubject(QString& subject);
@ -157,9 +156,6 @@ public:
void updateLastUpdateTime(); void updateLastUpdateTime();
void setEntriesLoading(const bool& loading); void setEntriesLoading(const bool& loading);
void setUnreadMessagesCount(const int& count);
void setMissedCallsCount(const int& count);
void addMissedCallsCount(std::shared_ptr<linphone::Call> call);
void setEphemeralEnabled(bool enabled); void setEphemeralEnabled(bool enabled);
void setEphemeralLifetime(long lifetime); void setEphemeralLifetime(long lifetime);
void enableMarkAsRead(const bool& enable); void enableMarkAsRead(const bool& enable);
@ -196,8 +192,6 @@ public:
virtual void resetData() override; virtual void resetData() override;
QDateTime mLastUpdateTime; QDateTime mLastUpdateTime;
int mUnreadMessagesCount = 0;
int mMissedCallsCount = 0;
bool mIsInitialized = false; bool mIsInitialized = false;
bool mDeleteChatRoom = false; // Use as workaround because of core->deleteChatRoom() that call destructor without takking account of count ref : call it in ChatRoomModel destructor bool mDeleteChatRoom = false; // Use as workaround because of core->deleteChatRoom() that call destructor without takking account of count ref : call it in ChatRoomModel destructor
@ -206,9 +200,6 @@ public:
bool mMarkAsReadEnabled = true; bool mMarkAsReadEnabled = true;
bool mEntriesLoading = false; bool mEntriesLoading = false;
void insertCall (const std::shared_ptr<linphone::CallLog> &callLog);
void insertCalls (const QList<std::shared_ptr<linphone::CallLog> > &calls);
QSharedPointer<ChatMessageModel> insertMessageAtEnd (const std::shared_ptr<linphone::ChatMessage> &message); QSharedPointer<ChatMessageModel> insertMessageAtEnd (const std::shared_ptr<linphone::ChatMessage> &message);
void insertMessages (const QList<std::shared_ptr<linphone::ChatMessage> > &messages); void insertMessages (const QList<std::shared_ptr<linphone::ChatMessage> > &messages);
void insertNotice (const std::shared_ptr<linphone::EventLog> &enventLog); void insertNotice (const std::shared_ptr<linphone::EventLog> &enventLog);
@ -280,7 +271,6 @@ signals:
void presenceStatusChanged(); void presenceStatusChanged();
void lastUpdateTimeChanged(); void lastUpdateTimeChanged();
void unreadMessagesCountChanged(); void unreadMessagesCountChanged();
void missedCallsCountChanged();
void securityLevelChanged(int securityLevel); void securityLevelChanged(int securityLevel);
void groupEnabledChanged(bool groupEnabled); void groupEnabledChanged(bool groupEnabled);

View file

@ -53,7 +53,10 @@ using namespace std;
// ----------------------------------------------------------------------------- // -----------------------------------------------------------------------------
QSharedPointer<ConferenceInfoModel> ConferenceInfoModel::create(std::shared_ptr<linphone::ConferenceInfo> conferenceInfo){ QSharedPointer<ConferenceInfoModel> ConferenceInfoModel::create(std::shared_ptr<linphone::ConferenceInfo> conferenceInfo){
return QSharedPointer<ConferenceInfoModel>::create(conferenceInfo); if(conferenceInfo)
return QSharedPointer<ConferenceInfoModel>::create(conferenceInfo);
else
return nullptr;
} }
// Callable from QML // Callable from QML

View file

@ -79,10 +79,10 @@ bool ContactsListProxyModel::filterAcceptsRow (
mWeights[contact] = uint(round(computeContactWeight(contact))); mWeights[contact] = uint(round(computeContactWeight(contact)));
return mWeights[contact] > 0 && ( return mWeights[contact] > 0
!mUseConnectedFilter || && (!mUseConnectedFilter || contact->getPresenceLevel() != Presence::PresenceLevel::White)
contact->getPresenceLevel() != Presence::PresenceLevel::White && (!mUseOnlineFilter || contact->getPresenceLevel() == Presence::PresenceLevel::Green)
); ;
} }
bool ContactsListProxyModel::lessThan (const QModelIndex &left, const QModelIndex &right) const { bool ContactsListProxyModel::lessThan (const QModelIndex &left, const QModelIndex &right) const {
@ -150,3 +150,10 @@ void ContactsListProxyModel::setConnectedFilter (bool useConnectedFilter) {
invalidate(); invalidate();
} }
} }
void ContactsListProxyModel::setOnlineFilter (bool useOnlineFilter) {
if (useOnlineFilter != mUseOnlineFilter) {
mUseOnlineFilter = useOnlineFilter;
invalidate();
}
}

View file

@ -31,11 +31,8 @@ class ContactsListModel;
class ContactsListProxyModel : public QSortFilterProxyModel { class ContactsListProxyModel : public QSortFilterProxyModel {
Q_OBJECT; Q_OBJECT;
Q_PROPERTY( Q_PROPERTY(bool useConnectedFilter READ isConnectedFilterUsed WRITE setConnectedFilter);
bool useConnectedFilter Q_PROPERTY(bool useOnlineFilter READ isOnlineFilterUsed WRITE setOnlineFilter);
READ isConnectedFilterUsed
WRITE setConnectedFilter
);
public: public:
ContactsListProxyModel (QObject *parent = Q_NULLPTR); ContactsListProxyModel (QObject *parent = Q_NULLPTR);
@ -53,11 +50,16 @@ private:
bool isConnectedFilterUsed () const { bool isConnectedFilterUsed () const {
return mUseConnectedFilter; return mUseConnectedFilter;
} }
bool isOnlineFilterUsed () const {
return mUseOnlineFilter;
}
void setConnectedFilter (bool useConnectedFilter); void setConnectedFilter (bool useConnectedFilter);
void setOnlineFilter (bool useOnlineFilter);
QString mFilter; QString mFilter;
bool mUseConnectedFilter = false; bool mUseConnectedFilter = false;
bool mUseOnlineFilter = false;
// It's just a cache to save values computed by `filterAcceptsRow` // It's just a cache to save values computed by `filterAcceptsRow`
// and reused by `lessThan`. // and reused by `lessThan`.

View file

@ -142,6 +142,8 @@ void CoreHandlers::onCallStateChanged (
const string & const string &
) { ) {
emit callStateChanged(call, state); emit callStateChanged(call, state);
if (state == linphone::Call::State::End || state == linphone::Call::State::Error)
emit eventCountChanged();
SettingsModel *settingsModel = CoreManager::getInstance()->getSettingsModel(); SettingsModel *settingsModel = CoreManager::getInstance()->getSettingsModel();
if ( if (

View file

@ -62,6 +62,8 @@ signals:
void conferenceInfoReceived(const std::shared_ptr<const linphone::ConferenceInfo> & conferenceInfo); void conferenceInfoReceived(const std::shared_ptr<const linphone::ConferenceInfo> & conferenceInfo);
void foundQRCode(const std::string & result); void foundQRCode(const std::string & result);
void eventCountChanged();
//-------------------- CORE HANDLER //-------------------- CORE HANDLER
public slots: public slots:

View file

@ -93,6 +93,10 @@ void CoreListener::onNotifyPresenceReceived (const std::shared_ptr<linphone::Cor
void CoreListener::onQrcodeFound(const std::shared_ptr<linphone::Core> & core, const std::string & result){ void CoreListener::onQrcodeFound(const std::shared_ptr<linphone::Core> & core, const std::string & result){
emit qrcodeFound(core, result); emit qrcodeFound(core, result);
} }
void CoreListener::onReactionRemoved(const std::shared_ptr<linphone::Core> & core, const std::shared_ptr<linphone::ChatRoom> & chatRoom, const std::shared_ptr<linphone::ChatMessage> & message, const std::shared_ptr<const linphone::Address> & address) {
emit reactionRemoved(core, chatRoom, message, address);
}
void CoreListener::onTransferStateChanged (const std::shared_ptr<linphone::Core> &core,const std::shared_ptr<linphone::Call> &call,linphone::Call::State state){ void CoreListener::onTransferStateChanged (const std::shared_ptr<linphone::Core> &core,const std::shared_ptr<linphone::Call> &call,linphone::Call::State state){
emit transferStateChanged (core,call,state); emit transferStateChanged (core,call,state);
} }

View file

@ -56,6 +56,7 @@ public:
virtual void onNotifyPresenceReceivedForUriOrTel (const std::shared_ptr<linphone::Core> &core,const std::shared_ptr<linphone::Friend> &linphoneFriend,const std::string &uriOrTel,const std::shared_ptr<const linphone::PresenceModel> &presenceModel) override; virtual void onNotifyPresenceReceivedForUriOrTel (const std::shared_ptr<linphone::Core> &core,const std::shared_ptr<linphone::Friend> &linphoneFriend,const std::string &uriOrTel,const std::shared_ptr<const linphone::PresenceModel> &presenceModel) override;
virtual void onNotifyPresenceReceived (const std::shared_ptr<linphone::Core> &core,const std::shared_ptr<linphone::Friend> &linphoneFriend) override; virtual void onNotifyPresenceReceived (const std::shared_ptr<linphone::Core> &core,const std::shared_ptr<linphone::Friend> &linphoneFriend) override;
virtual void onQrcodeFound(const std::shared_ptr<linphone::Core> & core, const std::string & result) override; virtual void onQrcodeFound(const std::shared_ptr<linphone::Core> & core, const std::string & result) override;
virtual void onReactionRemoved(const std::shared_ptr<linphone::Core> & core, const std::shared_ptr<linphone::ChatRoom> & chatRoom, const std::shared_ptr<linphone::ChatMessage> & message, const std::shared_ptr<const linphone::Address> & address) override;
virtual void onTransferStateChanged (const std::shared_ptr<linphone::Core> &core,const std::shared_ptr<linphone::Call> &call,linphone::Call::State state) override; virtual void onTransferStateChanged (const std::shared_ptr<linphone::Core> &core,const std::shared_ptr<linphone::Call> &call,linphone::Call::State state) override;
virtual void onVersionUpdateCheckResultReceived (const std::shared_ptr<linphone::Core> & core,linphone::VersionUpdateCheckResult result,const std::string &version,const std::string &url) override; virtual void onVersionUpdateCheckResultReceived (const std::shared_ptr<linphone::Core> & core,linphone::VersionUpdateCheckResult result,const std::string &version,const std::string &url) override;
virtual void onEcCalibrationResult(const std::shared_ptr<linphone::Core> & core,linphone::EcCalibratorStatus status,int delayMs) override; virtual void onEcCalibrationResult(const std::shared_ptr<linphone::Core> & core,linphone::EcCalibratorStatus status,int delayMs) override;
@ -83,6 +84,7 @@ signals:
void notifyPresenceReceivedForUriOrTel (const std::shared_ptr<linphone::Core> &core,const std::shared_ptr<linphone::Friend> &linphoneFriend,const std::string &uriOrTel,const std::shared_ptr<const linphone::PresenceModel> &presenceModel); void notifyPresenceReceivedForUriOrTel (const std::shared_ptr<linphone::Core> &core,const std::shared_ptr<linphone::Friend> &linphoneFriend,const std::string &uriOrTel,const std::shared_ptr<const linphone::PresenceModel> &presenceModel);
void notifyPresenceReceived (const std::shared_ptr<linphone::Core> &core,const std::shared_ptr<linphone::Friend> &linphoneFriend); void notifyPresenceReceived (const std::shared_ptr<linphone::Core> &core,const std::shared_ptr<linphone::Friend> &linphoneFriend);
void qrcodeFound(const std::shared_ptr<linphone::Core> & core, const std::string & result); void qrcodeFound(const std::shared_ptr<linphone::Core> & core, const std::string & result);
void reactionRemoved(const std::shared_ptr<linphone::Core> & core, const std::shared_ptr<linphone::ChatRoom> & chatRoom, const std::shared_ptr<linphone::ChatMessage> & message, const std::shared_ptr<const linphone::Address> & address);
void transferStateChanged (const std::shared_ptr<linphone::Core> &core,const std::shared_ptr<linphone::Call> &call,linphone::Call::State state); void transferStateChanged (const std::shared_ptr<linphone::Core> &core,const std::shared_ptr<linphone::Call> &call,linphone::Call::State state);
void versionUpdateCheckResultReceived (const std::shared_ptr<linphone::Core> & core,linphone::VersionUpdateCheckResult result,const std::string &version,const std::string &url); void versionUpdateCheckResultReceived (const std::shared_ptr<linphone::Core> & core,linphone::VersionUpdateCheckResult result,const std::string &version,const std::string &url);
void ecCalibrationResult(const std::shared_ptr<linphone::Core> & core,linphone::EcCalibratorStatus status,int delayMs); void ecCalibrationResult(const std::shared_ptr<linphone::Core> & core,linphone::EcCalibratorStatus status,int delayMs);

View file

@ -78,6 +78,7 @@ CoreManager::CoreManager (QObject *parent, const QString &configPath) :
QObject::connect(coreHandlers, &CoreHandlers::coreStopped, this, &CoreManager::stopIterate, Qt::QueuedConnection); QObject::connect(coreHandlers, &CoreHandlers::coreStopped, this, &CoreManager::stopIterate, Qt::QueuedConnection);
QObject::connect(coreHandlers, &CoreHandlers::logsUploadStateChanged, this, &CoreManager::handleLogsUploadStateChanged); QObject::connect(coreHandlers, &CoreHandlers::logsUploadStateChanged, this, &CoreManager::handleLogsUploadStateChanged);
QObject::connect(coreHandlers, &CoreHandlers::callLogUpdated, this, &CoreManager::callLogsCountChanged); QObject::connect(coreHandlers, &CoreHandlers::callLogUpdated, this, &CoreManager::callLogsCountChanged);
QObject::connect(coreHandlers, &CoreHandlers::eventCountChanged, this, &CoreManager::eventCountChanged);
QTimer::singleShot(10, [this, configPath](){// Delay the creation in order to have the CoreManager instance set before QTimer::singleShot(10, [this, configPath](){// Delay the creation in order to have the CoreManager instance set before
createLinphoneCore(configPath); createLinphoneCore(configPath);
@ -97,6 +98,8 @@ void CoreManager::initCoreManager(){
mContactsListModel = new ContactsListModel(this); mContactsListModel = new ContactsListModel(this);
mSipAddressesModel = new SipAddressesModel(this); // at first in order to prioritzed on handler signals. mSipAddressesModel = new SipAddressesModel(this); // at first in order to prioritzed on handler signals.
mAccountSettingsModel = new AccountSettingsModel(this); mAccountSettingsModel = new AccountSettingsModel(this);
connect(this, &CoreManager::eventCountChanged, mAccountSettingsModel, &AccountSettingsModel::missedCallsCountChanged);
connect(this, &CoreManager::eventCountChanged, mAccountSettingsModel, &AccountSettingsModel::unreadMessagesCountChanged);
mSettingsModel = new SettingsModel(this); mSettingsModel = new SettingsModel(this);
mEmojisSettingsModel = new EmojisSettingsModel(this); mEmojisSettingsModel = new EmojisSettingsModel(this);
mCallsListModel = new CallsListModel(this); mCallsListModel = new CallsListModel(this);
@ -106,8 +109,6 @@ void CoreManager::initCoreManager(){
mLdapListModel = new LdapListModel(this); mLdapListModel = new LdapListModel(this);
mEventCountNotifier = new EventCountNotifier(this); mEventCountNotifier = new EventCountNotifier(this);
mTimelineListModel = new TimelineListModel(this); mTimelineListModel = new TimelineListModel(this);
mEventCountNotifier->updateUnreadMessageCount();
QObject::connect(mEventCountNotifier, &EventCountNotifier::eventCountChanged,this, &CoreManager::eventCountChanged);
migrate(); migrate();
mStarted = true; mStarted = true;
@ -179,8 +180,14 @@ void CoreManager::forceRefreshRegisters () {
qInfo() << QStringLiteral("Refresh registers."); qInfo() << QStringLiteral("Refresh registers.");
mCore->refreshRegisters(); mCore->refreshRegisters();
} }
void CoreManager::updateUnreadMessageCount(){
mEventCountNotifier->updateUnreadMessageCount(); void CoreManager::resetMissedCallsCount(){
auto account = CoreManager::getInstance()->getCore()->getDefaultAccount();
if(account)
account->resetMissedCallsCount();
else
CoreManager::getInstance()->getCore()->resetMissedCallsCount();
emit eventCountChanged();
} }
void CoreManager::stateChanged(Qt::ApplicationState pState){ void CoreManager::stateChanged(Qt::ApplicationState pState){
@ -403,12 +410,6 @@ int CoreManager::getEventCount () const {
int CoreManager::getCallLogsCount() const{ int CoreManager::getCallLogsCount() const{
return mCore->getCallLogs().size(); return mCore->getCallLogs().size();
} }
int CoreManager::getMissedCallCount(const QString &peerAddress, const QString &localAddress)const{
return mEventCountNotifier ? mEventCountNotifier->getMissedCallCount(peerAddress, localAddress) : 0;
}
int CoreManager::getMissedCallCountFromLocal( const QString &localAddress)const{
return mEventCountNotifier ? mEventCountNotifier->getMissedCallCountFromLocal(localAddress) : 0;
}
std::list<std::shared_ptr<linphone::Account>> CoreManager::getAccountList()const{ std::list<std::shared_ptr<linphone::Account>> CoreManager::getAccountList()const{
std::list<std::shared_ptr<linphone::Account>> accounts; std::list<std::shared_ptr<linphone::Account>> accounts;

View file

@ -155,15 +155,13 @@ public:
Q_INVOKABLE VcardModel *createDetachedVcardModel () const; Q_INVOKABLE VcardModel *createDetachedVcardModel () const;
Q_INVOKABLE void forceRefreshRegisters (); Q_INVOKABLE void forceRefreshRegisters ();
void updateUnreadMessageCount(); void resetMissedCallsCount();// Reset current default account or core if no default.
void stateChanged(Qt::ApplicationState pState); void stateChanged(Qt::ApplicationState pState);
Q_INVOKABLE void sendLogs () const; Q_INVOKABLE void sendLogs () const;
Q_INVOKABLE void cleanLogs () const; Q_INVOKABLE void cleanLogs () const;
int getCallLogsCount() const; int getCallLogsCount() const;
int getMissedCallCount(const QString &peerAddress, const QString &localAddress) const;// Get missed call count from a chat (useful for showing bubbles on Timelines)
int getMissedCallCountFromLocal(const QString &localAddress) const;// Get missed call count from a chat (useful for showing bubbles on Timelines)
std::list<std::shared_ptr<linphone::Account>> getAccountList()const; std::list<std::shared_ptr<linphone::Account>> getAccountList()const;

View file

@ -21,13 +21,8 @@
#include <QtDebug> #include <QtDebug>
#include "components/call/CallModel.hpp" #include "components/call/CallModel.hpp"
#include "components/calls/CallsListModel.hpp"
#include "components/chat-room/ChatRoomModel.hpp"
#include "components/core/CoreHandlers.hpp"
#include "components/core/CoreManager.hpp" #include "components/core/CoreManager.hpp"
#include "components/history/HistoryModel.hpp"
#include "components/settings/SettingsModel.hpp" #include "components/settings/SettingsModel.hpp"
#include "utils/Utils.hpp"
#include "AbstractEventCountNotifier.hpp" #include "AbstractEventCountNotifier.hpp"
@ -37,116 +32,23 @@ using namespace std;
AbstractEventCountNotifier::AbstractEventCountNotifier (QObject *parent) : QObject(parent) { AbstractEventCountNotifier::AbstractEventCountNotifier (QObject *parent) : QObject(parent) {
CoreManager *coreManager = CoreManager::getInstance(); CoreManager *coreManager = CoreManager::getInstance();
QObject::connect( connect(coreManager, &CoreManager::eventCountChanged, this, &AbstractEventCountNotifier::eventCountChanged);
coreManager, &CoreManager::chatRoomModelCreated, connect(this, &AbstractEventCountNotifier::eventCountChanged, this, &AbstractEventCountNotifier::internalNotifyEventCount);
this, &AbstractEventCountNotifier::handleChatRoomModelCreated
);
QObject::connect(
coreManager, &CoreManager::historyModelCreated,
this, &AbstractEventCountNotifier::handleHistoryModelCreated
);
QObject::connect(
coreManager->getHandlers().get(), &CoreHandlers::messagesReceived,
this, &AbstractEventCountNotifier::updateUnreadMessageCount
);
QObject::connect(
coreManager->getSettingsModel(), &SettingsModel::standardChatEnabledChanged,
this, &AbstractEventCountNotifier::internalnotifyEventCount
);
QObject::connect(
coreManager->getSettingsModel(), &SettingsModel::secureChatEnabledChanged,
this, &AbstractEventCountNotifier::internalnotifyEventCount
);
QObject::connect(coreManager->getSettingsModel(), &SettingsModel::standardChatEnabledChanged, this, &AbstractEventCountNotifier::updateUnreadMessageCount);
QObject::connect(coreManager->getSettingsModel(), &SettingsModel::secureChatEnabledChanged, this, &AbstractEventCountNotifier::updateUnreadMessageCount);
/*
QObject::connect(
coreManager->getCallsListModel(), &CallsListModel::callMissed,
this, &AbstractEventCountNotifier::handleCallMissed
);*/
} }
// ----------------------------------------------------------------------------- // -----------------------------------------------------------------------------
void AbstractEventCountNotifier::updateUnreadMessageCount () { int AbstractEventCountNotifier::getEventCount () const {
auto coreManager = CoreManager::getInstance(); auto coreManager = CoreManager::getInstance();
if(!coreManager->getSettingsModel()->getStandardChatEnabled() && !coreManager->getSettingsModel()->getSecureChatEnabled()) int count = coreManager->getCore()->getMissedCallsCount();
mUnreadMessageCount = 0; if( coreManager->getSettingsModel()->getStandardChatEnabled() || coreManager->getSettingsModel()->getSecureChatEnabled())
else count += coreManager->getCore()->getUnreadChatMessageCount();
mUnreadMessageCount = CoreManager::getInstance()->getCore()->getUnreadChatMessageCountFromActiveLocals();
internalnotifyEventCount();
}
void AbstractEventCountNotifier::internalnotifyEventCount () {
int n = mUnreadMessageCount + getMissedCallCount();
qInfo() << QStringLiteral("Notify event count: %1.").arg(n);
n = n > 99 ? 99 : n;
notifyEventCount(CoreManager::getInstance()->getSettingsModel()->getStandardChatEnabled() || CoreManager::getInstance()->getSettingsModel()->getSecureChatEnabled()? n : 0);
emit eventCountChanged();
}
// Get missed call from a chat (useful for showing bubbles on Timelines)
int AbstractEventCountNotifier::getMissedCallCount(const QString &peerAddress, const QString &localAddress) const{
auto it = mMissedCalls.find({ Utils::cleanSipAddress(peerAddress), Utils::cleanSipAddress(localAddress) });
if (it != mMissedCalls.cend())
return *it;
else
return 0;
}
// Get missed call from a chat (useful for showing bubbles on Timelines)
int AbstractEventCountNotifier::getMissedCallCountFromLocal(const QString &localAddress) const{
QString cleanAddress = Utils::cleanSipAddress(localAddress);
int count = 0;
for(auto it = mMissedCalls.cbegin() ; it != mMissedCalls.cend() ; ++it){
if(it.key().second == cleanAddress)
count += *it;
}
return count; return count;
} }
// -----------------------------------------------------------------------------
void AbstractEventCountNotifier::handleChatRoomModelCreated (const QSharedPointer<ChatRoomModel> &chatRoomModel) { void AbstractEventCountNotifier::internalNotifyEventCount () {
ChatRoomModel *chatRoomModelPtr = chatRoomModel.get(); int n = getEventCount();
QObject::connect( qInfo() << QStringLiteral("Notify event count: %1.").arg(n);
chatRoomModelPtr, &ChatRoomModel::messageCountReset, n = n > 99 ? 99 : n;
this, &AbstractEventCountNotifier::updateUnreadMessageCount notifyEventCount(n);
);
QObject::connect(
chatRoomModelPtr, &ChatRoomModel::focused,
this, [this, chatRoomModelPtr]() { handleResetMissedCalls(chatRoomModelPtr); }
);
QObject::connect(
chatRoomModelPtr, &ChatRoomModel::messageCountReset,
this, [this, chatRoomModelPtr]() { handleResetMissedCalls(chatRoomModelPtr); }
);
}
void AbstractEventCountNotifier::handleHistoryModelCreated (HistoryModel *historyModel) {
QObject::connect(historyModel, &HistoryModel::callCountReset
, this, &AbstractEventCountNotifier::handleResetAllMissedCalls);
}
void AbstractEventCountNotifier::handleResetAllMissedCalls () {
mMissedCalls.clear();
internalnotifyEventCount();
}
void AbstractEventCountNotifier::handleResetMissedCalls (ChatRoomModel *chatRoomModel) {
auto it = mMissedCalls.find({ Utils::cleanSipAddress(chatRoomModel->getPeerAddress()), Utils::cleanSipAddress(chatRoomModel->getLocalAddress()) });
if (it != mMissedCalls.cend()) {
mMissedCalls.erase(it);
internalnotifyEventCount();
}
}
void AbstractEventCountNotifier::handleCallMissed (CallModel *callModel) {
++mMissedCalls[{ Utils::cleanSipAddress(callModel->getPeerAddress()), Utils::cleanSipAddress(callModel->getLocalAddress()) }];
internalnotifyEventCount();
}
void AbstractEventCountNotifier::handleCallMissed (const QString& localAddress, const QString& peerAddress) {
++mMissedCalls[{ peerAddress, localAddress }];
internalnotifyEventCount();
} }

View file

@ -43,41 +43,18 @@ class AbstractEventCountNotifier : public QObject {
public: public:
AbstractEventCountNotifier (QObject *parent = Q_NULLPTR); AbstractEventCountNotifier (QObject *parent = Q_NULLPTR);
void updateUnreadMessageCount (); int getUnreadMessageCount () const;
int getMissedCallCount () const;
int getUnreadMessageCount () const { return mUnreadMessageCount; } int getEventCount () const;
int getMissedCallCount () const {
int t = 0;
for (int n : mMissedCalls) t += n;
return t;
}
int getEventCount () const { return mUnreadMessageCount + getMissedCallCount(); }
int getMissedCallCount(const QString &peerAddress, const QString &localAddress) const;// Get missed call count from a chat (useful for showing bubbles on Timelines)
int getMissedCallCountFromLocal(const QString &localAddress) const;// Get missed call count from a chat (useful for showing bubbles on Timelines)
signals: signals:
void eventCountChanged (); void eventCountChanged ();
public slots:
void handleCallMissed (const QString& localAddress, const QString& peerAddress);
void handleResetAllMissedCalls ();
void handleResetMissedCalls (ChatRoomModel *chatRoomModel);
void handleCallMissed (CallModel *callModel);
protected: protected:
virtual void notifyEventCount (int n) = 0; virtual void notifyEventCount (int n) = 0;
private: private:
using ConferenceId = QPair<QString, QString>;
void internalnotifyEventCount (); void internalNotifyEventCount ();
void handleChatRoomModelCreated (const QSharedPointer<ChatRoomModel> &chatRoomModel);
void handleHistoryModelCreated (HistoryModel *historyModel);
QHash<ConferenceId, int> mMissedCalls;
int mUnreadMessageCount = 0;
}; };
#endif // ABSTRACT_EVENT_COUNT_NOTIFIER_H_ #endif // ABSTRACT_EVENT_COUNT_NOTIFIER_H_

View file

@ -60,11 +60,6 @@ EventCountNotifier::EventCountNotifier (QObject *parent) : AbstractEventCountNot
mBlinkTimer = new QTimer(this); mBlinkTimer = new QTimer(this);
mBlinkTimer->setInterval(IconCounterBlinkInterval); mBlinkTimer->setInterval(IconCounterBlinkInterval);
QObject::connect(mBlinkTimer, &QTimer::timeout, this, &EventCountNotifier::update); QObject::connect(mBlinkTimer, &QTimer::timeout, this, &EventCountNotifier::update);
Utils::connectOnce(
App::getInstance(), &App::focusWindowChanged,
this, &EventCountNotifier::updateUnreadMessageCount
);
} }
EventCountNotifier::~EventCountNotifier () { EventCountNotifier::~EventCountNotifier () {

View file

@ -0,0 +1,123 @@
/*
* Copyright (c) 2010-2020 Belledonne Communications SARL.
*
* This file is part of linphone-desktop
* (see https://www.linphone.org).
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include "CallHistoryListModel.hpp"
#include "CallHistoryModel.hpp"
#include "components/core/CoreManager.hpp"
#include "components/core/CoreHandlers.hpp"
#include "components/settings/AccountSettingsModel.hpp"
#include "utils/Utils.hpp"
// =============================================================================
CallHistoryListModel::CallHistoryListModel (QObject *parent) : ProxyListModel(parent) {
reload();
connect(CoreManager::getInstance()->getHandlers().get(), &CoreHandlers::callLogUpdated, this, &CallHistoryListModel::onCallLogUpdated);
}
QString reorder(const QString& address){
QStringList splitted = address.split(";");
QString newAddress = splitted[0];
splitted.removeFirst();
splitted.sort();
return newAddress + splitted.join(";");
}
void CallHistoryListModel::reload() {
beginResetModel();
mList.clear();
endResetModel();
auto account = CoreManager::getInstance()->getCore()->getDefaultAccount();
auto callLogs = account ? account->getCallLogs() : CoreManager::getInstance()->getCore()->getCallLogs();
add(callLogs);
CoreManager::getInstance()->resetMissedCallsCount();
if(mList.size() > 0)
QTimer::singleShot(1, [&](){
mList.at(0).objectCast<CallHistoryModel>()->selectOnly();
});
}
CallHistoryListModel::~CallHistoryListModel(){
}
void CallHistoryListModel::add(const std::list<std::shared_ptr<linphone::CallLog>>& callLogs){
QList<QSharedPointer<CallHistoryModel>> toAdd;
for(auto callLog : callLogs) {
if(!callLog->getLocalAddress()->weakEqual(CoreManager::getInstance()->getAccountSettingsModel()->getUsedSipAddress()))
continue;
QString confUri;
auto remoteAddress = callLog->getRemoteAddress()->clone();
remoteAddress->clean();
QString address = reorder(Utils::coreStringToAppString(remoteAddress->asStringUriOnly()));
if( callLog->getConferenceInfo()) {
confUri = reorder(Utils::coreStringToAppString(callLog->getConferenceInfo()->getUri()->asStringUriOnly()));
}
QString keyName = address + "/"+confUri;
if(!mCalls.contains(keyName)) {
auto call = QSharedPointer<CallHistoryModel>::create(callLog);
mCalls[keyName] = call;
connect(call.get(), &CallHistoryModel::selectOnlyRequested, this, &CallHistoryListModel::onSelectOnlyRequested);
connect(call.get(), &CallHistoryModel::selectedChanged, this, &CallHistoryListModel::onSelectedChanged);
connect(call.get(), &CallHistoryModel::hasBeenRemoved, this, &CallHistoryListModel::onHasBeenRemoved);
connect(call.get(), &CallHistoryModel::lastCallDateChanged, this, &CallHistoryListModel::lastCallDateChanged);
toAdd << call;
}else{
mCalls[keyName]->update(callLog);
}
}
ProxyListModel::add(toAdd);
}
void CallHistoryListModel::onCallLogUpdated(const std::shared_ptr<linphone::CallLog> &call){
add(std::list<std::shared_ptr<linphone::CallLog>>{call});
}
void CallHistoryListModel::onSelectOnlyRequested() {
for(auto model : mList){
auto callModel = model.objectCast<CallHistoryModel>();
if(callModel != sender())
callModel->setSelected(false);
}
}
void CallHistoryListModel::onSelectedChanged(bool selected, CallHistoryModel * model) {
if(selected) {
emit selectedChanged(model);
CoreManager::getInstance()->resetMissedCallsCount();
}
}
void CallHistoryListModel::onHasBeenRemoved(){
QString confUri;
auto model = qobject_cast<CallHistoryModel*>(sender());
QString address = reorder(model->getRemoteAddress());
if( model->wasConference()) {
confUri = reorder(Utils::coreStringToAppString(model->getConferenceInfoModel()->getConferenceInfo()->getUri()->asStringUriOnly()));
}
remove(sender());
QString keyName = address + "/"+confUri;
mCalls.remove(keyName);
if(model->mSelected) {
if(mList.size() > 0){
mList.at(0).objectCast<CallHistoryModel>()->selectOnly();
}
}
}

View file

@ -0,0 +1,55 @@
/*
* Copyright (c) 2010-2020 Belledonne Communications SARL.
*
* This file is part of linphone-desktop
* (see https://www.linphone.org).
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef CALL_HISTORY_LIST_MODEL_H_
#define CALL_HISTORY_LIST_MODEL_H_
#include <QSharedPointer>
#include <linphone++/linphone.hh>
#include "app/proxyModel/ProxyListModel.hpp"
class CallHistoryModel;
// =============================================================================
class CallHistoryListModel : public ProxyListModel {
Q_OBJECT
public:
Q_PROPERTY(int count READ rowCount NOTIFY countChanged)
CallHistoryListModel (QObject *parent = Q_NULLPTR);
virtual ~CallHistoryListModel();
void reload();
void add(const std::list<std::shared_ptr<linphone::CallLog>>& callLog);
void onCallLogUpdated(const std::shared_ptr<linphone::CallLog> &call);
void onSelectedChanged(bool selected, CallHistoryModel * model);
void onSelectOnlyRequested();
void onHasBeenRemoved();
signals:
void countChanged();
void selectedChanged(CallHistoryModel * model);
void lastCallDateChanged();
private:
QHash<QString, QSharedPointer<CallHistoryModel>> mCalls;
};
#endif

View file

@ -0,0 +1,140 @@
/*
* Copyright (c) 2010-2023 Belledonne Communications SARL.
*
* This file is part of linphone-desktop
* (see https://www.linphone.org).
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include "CallHistoryModel.hpp"
#include "utils/Utils.hpp"
#include <QDebug>
CallHistoryModel::CallHistoryModel(QObject *parent) : QObject(parent){
}
CallHistoryModel::CallHistoryModel(const std::shared_ptr<linphone::CallLog> callLog, QObject *parent) : QObject(parent){
mRemoteAddress = callLog->getRemoteAddress()->clone();
mRemoteAddress->clean();
mLastCallStatus = LinphoneEnums::fromLinphone(callLog->getStatus());
if(mShowEnd && mLastCallStatus == LinphoneEnums::CallStatusSuccess){
mLastCallDate = QDateTime::fromMSecsSinceEpoch((callLog->getStartDate() + callLog->getDuration()) * 1000);
mLastCallIsStart = false;
}else {
mLastCallDate = QDateTime::fromMSecsSinceEpoch(callLog->getStartDate() * 1000);
mLastCallIsStart = true;
}
mLastCallIsOutgoing = callLog->getDir() == linphone::Call::Dir::Outgoing;
mConferenceInfoModel = ConferenceInfoModel::create(callLog->getConferenceInfo());
if(!mConferenceInfoModel && callLog->wasConference())
qWarning() << "Was conf without info : " << Utils::coreStringToAppString(mRemoteAddress->asStringUriOnly());
}
QString CallHistoryModel::getRemoteAddress() const{
return Utils::coreStringToAppString(mRemoteAddress->asStringUriOnly());
}
QString CallHistoryModel::getSipAddress() const{
if( mConferenceInfoModel )
return Utils::coreStringToAppString(mConferenceInfoModel->getConferenceInfo()->getUri()->asStringUriOnly());
else
return Utils::coreStringToAppString(mRemoteAddress->asStringUriOnly());
}
ConferenceInfoModel * CallHistoryModel::getConferenceInfoModel() const {
return mConferenceInfoModel.get();
}
bool CallHistoryModel::wasConference() const {
return mConferenceInfoModel;
}
QString CallHistoryModel::getTitle() const {
if(mConferenceInfoModel)
return mConferenceInfoModel->getSubject();
else
return "";
}
void CallHistoryModel::update(const std::shared_ptr<linphone::CallLog> callLog){
QDateTime callDate;
if(mShowEnd && mLastCallStatus == LinphoneEnums::CallStatusSuccess){
callDate = QDateTime::fromMSecsSinceEpoch((callLog->getStartDate() + callLog->getDuration()) * 1000);
}else {
callDate = QDateTime::fromMSecsSinceEpoch(callLog->getStartDate() * 1000);
}
if(callDate >= mLastCallDate){
setLastCallStatus(LinphoneEnums::fromLinphone(callLog->getStatus()));
if(mShowEnd && mLastCallStatus == LinphoneEnums::CallStatusSuccess){
setLastCallDate(QDateTime::fromMSecsSinceEpoch((callLog->getStartDate() + callLog->getDuration()) * 1000));
setLastCallIsStart(false);
}else {
setLastCallDate(QDateTime::fromMSecsSinceEpoch(callLog->getStartDate() * 1000));
setLastCallIsStart(true);
}
mConferenceInfoModel = ConferenceInfoModel::create(callLog->getConferenceInfo());
emit conferenceInfoModelChanged();
}
}
void CallHistoryModel::setLastCallStatus(LinphoneEnums::CallStatus status) {
if(mLastCallStatus != status){
mLastCallStatus = status;
emit lastCallStatusChanged();
}
}
void CallHistoryModel::setLastCallDate(const QDateTime& date) {
if( mLastCallDate != date) {
mLastCallDate = date;
emit lastCallDateChanged();
}
}
void CallHistoryModel::setLastCallIsStart(const bool& start) {
if( mLastCallIsStart != start) {
mLastCallIsStart = start;
emit lastCallIsStartChanged();
}
}
void CallHistoryModel::setLastCallIsOutgoing(const bool& outgoing){
if( mLastCallIsOutgoing != outgoing) {
mLastCallIsOutgoing = outgoing;
emit lastCallIsOutgoingChanged();
}
}
void CallHistoryModel::setSelected(const bool& selected){
if(selected != mSelected || selected){
mSelected = selected;
if(mSelected){
qInfo() << "Call room selected : Address :" << getRemoteAddress();
}else{
qInfo() << "Unselect call room "<< getRemoteAddress();
}
emit selectedChanged(mSelected, this);
}
}
void CallHistoryModel::selectOnly(){
setSelected(true);
emit selectOnlyRequested();
}

View file

@ -0,0 +1,89 @@
/*
* Copyright (c) 2010-2023 Belledonne Communications SARL.
*
* This file is part of linphone-desktop
* (see https://www.linphone.org).
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef CALL_HISTORY_MODEL_H_
#define CALL_HISTORY_MODEL_H_
#include <QObject>
#include <QDateTime>
#include <linphone++/linphone.hh>
#include "components/conferenceInfo/ConferenceInfoModel.hpp"
#include "utils/LinphoneEnums.hpp"
class CallHistoryModel : public QObject {
Q_OBJECT
public:
Q_PROPERTY(QString remoteAddress READ getRemoteAddress CONSTANT) // strip from gruu/conf-id
Q_PROPERTY(QString sipAddress READ getSipAddress NOTIFY conferenceInfoModelChanged) // Use to call
Q_PROPERTY(bool selected MEMBER mSelected WRITE setSelected NOTIFY selectedChanged)
Q_PROPERTY(LinphoneEnums::CallStatus lastCallStatus MEMBER mLastCallStatus WRITE setLastCallStatus NOTIFY lastCallStatusChanged)
Q_PROPERTY(QDateTime lastCallDate MEMBER mLastCallDate WRITE setLastCallDate NOTIFY lastCallDateChanged)
Q_PROPERTY(bool lastCallIsStart MEMBER mLastCallIsStart WRITE setLastCallIsStart NOTIFY lastCallIsStartChanged)
Q_PROPERTY(bool lastCallIsOutgoing MEMBER mLastCallIsOutgoing WRITE setLastCallIsOutgoing NOTIFY lastCallIsOutgoingChanged)
Q_PROPERTY(ConferenceInfoModel * conferenceInfoModel READ getConferenceInfoModel NOTIFY conferenceInfoModelChanged)
Q_PROPERTY(bool wasConference READ wasConference NOTIFY conferenceInfoModelChanged)
Q_PROPERTY(QString title READ getTitle NOTIFY conferenceInfoModelChanged)
CallHistoryModel(QObject *parent = nullptr);
CallHistoryModel(const std::shared_ptr<linphone::CallLog> callLogs, QObject *parent = nullptr);
QString getRemoteAddress() const;
QString getSipAddress() const;
ConferenceInfoModel * getConferenceInfoModel() const;
bool wasConference() const;
QString getTitle() const;
void update(const std::shared_ptr<linphone::CallLog> callLog);
void setLastCallStatus(LinphoneEnums::CallStatus status);
void setLastCallDate(const QDateTime& date);
void setLastCallIsStart(const bool& start);
void setLastCallIsOutgoing(const bool& outgoing);
void setSelected(const bool& selected);
Q_INVOKABLE void selectOnly(); // Select this item and remove others in parent lists
QDateTime mLastCallDate;
bool mSelected = false;
bool mLastCallIsOutgoing;
LinphoneEnums::CallStatus mLastCallStatus;
signals:
void selectOnlyRequested();
void selectedChanged(bool selected, CallHistoryModel * model);
void lastCallStatusChanged();
void lastCallDateChanged();
void lastCallIsStartChanged();
void lastCallIsOutgoingChanged();
void conferenceInfoModelChanged();
void hasBeenRemoved();
private:
std::shared_ptr<linphone::Address> mRemoteAddress;
bool mLastCallIsStart;
QSharedPointer<ConferenceInfoModel> mConferenceInfoModel;
bool mShowEnd = false; // Display ended call (start + duration)
};
#endif

View file

@ -0,0 +1,118 @@
/*
* Copyright (c) 2010-2020 Belledonne Communications SARL.
*
* This file is part of linphone-desktop
* (see https://www.linphone.org).
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include "CallHistoryProxyModel.hpp"
#include "CallHistoryListModel.hpp"
#include "CallHistoryModel.hpp"
#include "app/App.hpp"
#include "components/core/CoreManager.hpp"
#include "components/settings/AccountSettingsModel.hpp"
#include "utils/Utils.hpp"
#include <QDebug>
#include <QQuickWindow>
// =============================================================================
// -----------------------------------------------------------------------------
CallHistoryProxyModel::CallHistoryProxyModel (QObject *parent) : QSortFilterProxyModel(parent) {
auto model = new CallHistoryListModel();
setSourceModel(model);
sort(0);
connect(CoreManager::getInstance()->getAccountSettingsModel(), &AccountSettingsModel::defaultAccountChanged, model, &CallHistoryListModel::reload);
connect(model, &CallHistoryListModel::lastCallDateChanged, this, &CallHistoryProxyModel::invalidate);
App *app = App::getInstance();
connect(app->getMainWindow(), &QWindow::activeChanged, this, [this]() {
handleIsActiveChanged(App::getInstance()->getMainWindow());
});
}
// -----------------------------------------------------------------------------
void CallHistoryProxyModel::setFilterFlags(int filterFlags){
if( mFilterFlags != filterFlags){
mFilterFlags = filterFlags;
invalidate();
emit filterFlagsChanged();
}
}
void CallHistoryProxyModel::setFilterText(const QString& text){
if( mFilterText != text){
mFilterText = text;
invalidate();
emit filterTextChanged();
}
}
// -----------------------------------------------------------------------------
bool CallHistoryProxyModel::filterAcceptsRow (int sourceRow, const QModelIndex &sourceParent) const {
if(!sourceModel())
return false;
bool show = true;
const QModelIndex index = sourceModel()->index(sourceRow, 0, sourceParent);
auto timeline = sourceModel()->data(index).value<CallHistoryModel*>();
if( mFilterFlags > 0) {
show = ( ((mFilterFlags & CallTimelineFilter::Incoming) == CallTimelineFilter::Incoming) && !timeline->mLastCallIsOutgoing)
|| ( ((mFilterFlags & CallTimelineFilter::Outgoing) == CallTimelineFilter::Outgoing) && timeline->mLastCallIsOutgoing)
|| ( ((mFilterFlags & CallTimelineFilter::Missed) == CallTimelineFilter::Missed) && timeline->mLastCallStatus == LinphoneEnums::CallStatusMissed)
;
}
if(show && mFilterText != ""){
QRegularExpression search(QRegularExpression::escape(mFilterText), QRegularExpression::CaseInsensitiveOption | QRegularExpression::UseUnicodePropertiesOption);
show = ( timeline->getTitle().contains(search)
//|| timeline->getRemoteAddress().contains(search)
|| Utils::getDisplayName(timeline->getRemoteAddress()).contains(search)
);
//|| timeline->getChatRoomModel()->getFullPeerAddress().contains(search); not enough significant?
}
return show;
}
bool CallHistoryProxyModel::lessThan (const QModelIndex &left, const QModelIndex &right) const {
if( !sourceModel())
return false;
const CallHistoryModel* a = sourceModel()->data(left).value<CallHistoryModel*>();
const CallHistoryModel* b = sourceModel()->data(right).value<CallHistoryModel*>();
return a->mLastCallDate > b->mLastCallDate;
}
static inline QWindow *getParentWindow (QObject *object) {
App *app = App::getInstance();
const QWindow *mainWindow = app->getMainWindow();
const QWindow *callsWindow = app->getCallsWindow();
for (QObject *parent = object->parent(); parent; parent = parent->parent())
if (parent == mainWindow || parent == callsWindow)
return static_cast<QWindow *>(parent);
return nullptr;
}
void CallHistoryProxyModel::handleIsActiveChanged (QWindow *window) {
if (window->isActive() && getParentWindow(this) == window) {
CoreManager::getInstance()->resetMissedCallsCount();
}
}

View file

@ -0,0 +1,70 @@
/*
* Copyright (c) 2020-2023 Belledonne Communications SARL.
*
* This file is part of linphone-desktop
* (see https://www.linphone.org).
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef CALL_HISTORY_PROXY_MODEL_H_
#define CALL_HISTORY_PROXY_MODEL_H_
#include <QSortFilterProxyModel>
#include <memory>
class CallHistoryModel;
class QWindow;
// =============================================================================
class CallHistoryProxyModel : public QSortFilterProxyModel {
Q_OBJECT
public:
CallHistoryProxyModel (QObject *parent = Q_NULLPTR);
enum CallTimelineFilter {
Incoming = 1,
Outgoing = 2,
Missed = 4,
All = 0
};
Q_ENUM(CallTimelineFilter)
Q_PROPERTY(int filterFlags MEMBER mFilterFlags WRITE setFilterFlags NOTIFY filterFlagsChanged)
Q_PROPERTY(QString filterText MEMBER mFilterText WRITE setFilterText NOTIFY filterTextChanged)
Q_PROPERTY(int count READ rowCount NOTIFY countChanged)
void setFilterFlags(int flags);
Q_INVOKABLE void setFilterText(const QString& text);
void handleIsActiveChanged (QWindow *window);
signals:
void countChanged();
void filterTextChanged();
void selectedChanged(const QString& remoteAddress);
void filterFlagsChanged();
protected:
bool filterAcceptsRow (int sourceRow, const QModelIndex &sourceParent) const override;
bool lessThan (const QModelIndex &left, const QModelIndex &right) const override;
private:
QString mFilterText;
int mFilterFlags = -1;
};
#endif

View file

@ -31,8 +31,10 @@
#include <QUrlQuery> #include <QUrlQuery>
#include <QImageReader> #include <QImageReader>
#include "CallHistoryModel.hpp"
#include "components/core/CoreHandlers.hpp" #include "components/core/CoreHandlers.hpp"
#include "components/core/CoreManager.hpp" #include "components/core/CoreManager.hpp"
#include "components/settings/AccountSettingsModel.hpp"
#include "utils/Utils.hpp" #include "utils/Utils.hpp"
#include "HistoryModel.hpp" #include "HistoryModel.hpp"
@ -83,10 +85,19 @@ HistoryModel::HistoryModel (QObject *parent) :QAbstractListModel(parent){
setSipAddresses(); setSipAddresses();
CoreHandlers *coreHandlers = mCoreHandlers.get(); CoreHandlers *coreHandlers = mCoreHandlers.get();
QObject::connect(coreHandlers, &CoreHandlers::callStateChanged, this, &HistoryModel::handleCallStateChanged); QObject::connect(coreHandlers, &CoreHandlers::callStateChanged, this, &HistoryModel::handleCallStateChanged);
}
HistoryModel::HistoryModel (CallHistoryModel * callHistoryModel, QObject *parent) :QAbstractListModel(parent){
CoreManager *coreManager = CoreManager::getInstance();
mCoreHandlers = coreManager->getHandlers();
setSipAddresses(callHistoryModel);
CoreHandlers *coreHandlers = mCoreHandlers.get();
QObject::connect(coreHandlers, &CoreHandlers::callStateChanged, this, &HistoryModel::handleCallStateChanged);
} }
HistoryModel::~HistoryModel () { HistoryModel::~HistoryModel () {
qWarning() << "Destroying HistoryModel";
} }
QHash<int, QByteArray> HistoryModel::roleNames () const { QHash<int, QByteArray> HistoryModel::roleNames () const {
@ -148,23 +159,110 @@ bool HistoryModel::removeRows (int row, int count, const QModelIndex &parent) {
return true; return true;
} }
void HistoryModel::setSipAddresses () { static bool hasSameParameters(const QStringList& a, const QStringList& b){
if(a.size() != b.size())
return false;
int i = 0;
while(i < a.size()) {
if(b.contains(a[i]))
++i;
else
break;
}
return i >= a.size();
}
// Why complicated?
// - Address parameters can be stored in different order and getCallHistory() reorder address parameters => need to get on pure address without parameters.
// - A call to/from someone (no gruu and no conf-id) can a conference call => the pair remotre address + URI need to be check (watchout of parameters order)
void HistoryModel::setSipAddresses (CallHistoryModel *callModel) {
shared_ptr<linphone::Core> core = CoreManager::getInstance()->getCore(); shared_ptr<linphone::Core> core = CoreManager::getInstance()->getCore();
beginResetModel();
mEntries.clear(); mEntries.clear();
QElapsedTimer timer; QElapsedTimer timer;
timer.start(); timer.start();
// Get calls. // Get calls.
for (auto &callLog : core->getCallLogs()) if(!callModel)
insertCall(callLog); for (auto &callLog : core->getCallLogs())
insertCall(callLog);
else{
mRemoteAddress = callModel->getRemoteAddress();
auto address = Utils::interpretUrl(mRemoteAddress);// already cleaned
auto conferenceInfoModel = callModel->getConferenceInfoModel();
QStringList conferenceInfoModelParams;
if(conferenceInfoModel) {
mConferenceUri = conferenceInfoModel->getUri();
conferenceInfoModelParams = mConferenceUri.split(";");
}
for (auto &callLog : core->getCallHistory(address, CoreManager::getInstance()->getAccountSettingsModel()->getUsedSipAddress())) {
bool toInsert = false;
auto callLogConferenceInfoModel = callLog->getConferenceInfo();
if(conferenceInfoModel && callLogConferenceInfoModel) {
QStringList logConfUriParams = Utils::coreStringToAppString(callLogConferenceInfoModel->getUri()->asStringUriOnly()).split(";");
if(hasSameParameters(conferenceInfoModelParams, logConfUriParams)) {// Uri addresses are equal
toInsert = true;
}
}else if(!conferenceInfoModel && !callLogConferenceInfoModel)
toInsert = true;
if(toInsert)
insertCall(callLog);
}
/*
QString uriOnly = Utils::coreStringToAppString(address->asStringUriOnly());
QStringList parameters = uriOnly.split(";");
auto conferenceInfoModel = callModel->getConferenceInfoModel();
QStringList conferenceInfoModelParams;
if(conferenceInfoModel) {
conferenceInfoModelParams = conferenceInfoModel->getUri().split(";");
}
for (auto &callLog : core->getCallHistory(Utils::interpretUrl(parameters[0]), CoreManager::getInstance()->getAccountSettingsModel()->getUsedSipAddress())) {
if(parameters.size() > 2) { // We have to check address with mixed parameters order from the result of getCallHistory()
for (auto &callLog : core->getCallHistory(Utils::interpretUrl(parameters[0]), CoreManager::getInstance()->getAccountSettingsModel()->getUsedSipAddress())) {
QStringList logParams = Utils::coreStringToAppString(callLog->getRemoteAddress()->asStringUriOnly()).split(";");
if(hasSameParameters(parameters, logParams)) {// Remote address are equal
bool toInsert = false;
auto callLogConferenceInfoModel = callLog->getConferenceInfo();
if(conferenceInfoModel && callLogConferenceInfoModel) {
QStringList logConfUriParams = Utils::coreStringToAppString(callLogConferenceInfoModel->getUri()->asStringUriOnly()).split(";");
if(hasSameParameters(conferenceInfoModelParams, logConfUriParams)) {// Uri addresses are equal
toInsert = true;
}
}else if(!conferenceInfoModel && !callLogConferenceInfoModel)
toInsert = true;
if(toInsert)
insertCall(callLog);
}
}
}else {
for (auto &callLog : core->getCallHistory(address, CoreManager::getInstance()->getAccountSettingsModel()->getUsedSipAddress())) {
auto callLogConferenceInfoModel = callLog->getConferenceInfo();
bool toInsert = false;
if(conferenceInfoModel && callLogConferenceInfoModel) {
QStringList logConfUriParams = Utils::coreStringToAppString(callLogConferenceInfoModel->getUri()->asStringUriOnly()).split(";");
if(hasSameParameters(conferenceInfoModelParams, logConfUriParams)) {// Uri addresses are equal
toInsert = true;
}
}else if(!conferenceInfoModel && !callLogConferenceInfoModel)
toInsert = true;
if(toInsert)
insertCall(callLog);
}
}*/
}
qInfo() << QStringLiteral("HistoryModel loaded in %3 milliseconds.").arg(timer.elapsed()); qInfo() << QStringLiteral("HistoryModel loaded in %3 milliseconds.").arg(timer.elapsed());
endResetModel();
} }
void HistoryModel::reload(){ void HistoryModel::reload(){
beginResetModel(); beginResetModel();
setSipAddresses(); //setSipAddresses();
endResetModel(); endResetModel();
} }
// ----------------------------------------------------------------------------- // -----------------------------------------------------------------------------
@ -267,7 +365,25 @@ void HistoryModel::resetMessageCount () {
// ----------------------------------------------------------------------------- // -----------------------------------------------------------------------------
void HistoryModel::handleCallStateChanged (const shared_ptr<linphone::Call> &call, linphone::Call::State state) { void HistoryModel::handleCallStateChanged (const shared_ptr<linphone::Call> &call, linphone::Call::State state) {
if (state == linphone::Call::State::End || state == linphone::Call::State::Error) if (state == linphone::Call::State::End || state == linphone::Call::State::Error) {
insertCall(call->getCallLog()); auto address = Utils::interpretUrl(mRemoteAddress);// already cleaned
QStringList conferenceInfoModelParams = mConferenceUri.split(";");
bool toInsert = false;
auto callLog = call->getCallLog();
auto callLogConferenceInfoModel = callLog->getConferenceInfo();
if(mRemoteAddress.isEmpty())
toInsert = true;
else if(address->weakEqual(callLog->getRemoteAddress()) && callLog->getLocalAddress()->weakEqual(CoreManager::getInstance()->getAccountSettingsModel()->getUsedSipAddress())) {
if(!mConferenceUri.isEmpty() && callLogConferenceInfoModel) {
QStringList logConfUriParams = Utils::coreStringToAppString(callLogConferenceInfoModel->getUri()->asStringUriOnly()).split(";");
if(hasSameParameters(conferenceInfoModelParams, logConfUriParams)) {// Uri addresses are equal
toInsert = true;
}
}else if(mConferenceUri.isEmpty() && !callLogConferenceInfoModel)
toInsert = true;
}
if(toInsert)
insertCall(callLog);
}
} }

View file

@ -30,6 +30,7 @@
// ============================================================================= // =============================================================================
class CoreHandlers; class CoreHandlers;
class CallHistoryModel;
class HistoryModel : public QAbstractListModel { class HistoryModel : public QAbstractListModel {
@ -59,6 +60,7 @@ public:
Q_ENUM(CallStatus) Q_ENUM(CallStatus)
HistoryModel (QObject *parent = Q_NULLPTR); HistoryModel (QObject *parent = Q_NULLPTR);
HistoryModel (CallHistoryModel *callHistoryModel, QObject *parent = Q_NULLPTR);
virtual ~HistoryModel (); virtual ~HistoryModel ();
int rowCount (const QModelIndex &index = QModelIndex()) const override; int rowCount (const QModelIndex &index = QModelIndex()) const override;
@ -72,6 +74,8 @@ public:
void removeEntry (int id); void removeEntry (int id);
void removeAllEntries (); void removeAllEntries ();
void setSipAddresses (CallHistoryModel * callModel = nullptr);
void resetMessageCount (); void resetMessageCount ();
Q_INVOKABLE void reload(); Q_INVOKABLE void reload();
@ -86,13 +90,14 @@ signals:
private: private:
typedef QPair<QVariantMap, std::shared_ptr<void>> HistoryEntryData; typedef QPair<QVariantMap, std::shared_ptr<void>> HistoryEntryData;
void setSipAddresses ();
void removeEntry (HistoryEntryData &entry); void removeEntry (HistoryEntryData &entry);
void insertCall (const std::shared_ptr<linphone::CallLog> &callLog); void insertCall (const std::shared_ptr<linphone::CallLog> &callLog);
void handleCallStateChanged (const std::shared_ptr<linphone::Call> &call, linphone::Call::State state); void handleCallStateChanged (const std::shared_ptr<linphone::Call> &call, linphone::Call::State state);
mutable QList<HistoryEntryData> mEntries; mutable QList<HistoryEntryData> mEntries;
QString mRemoteAddress;
QString mConferenceUri;
QSharedPointer<CoreHandlers> mCoreHandlers; QSharedPointer<CoreHandlers> mCoreHandlers;
}; };

View file

@ -24,6 +24,7 @@
#include "components/core/CoreManager.hpp" #include "components/core/CoreManager.hpp"
#include "HistoryProxyModel.hpp" #include "HistoryProxyModel.hpp"
#include "CallHistoryModel.hpp"
#include "components/sip-addresses/SipAddressesModel.hpp" #include "components/sip-addresses/SipAddressesModel.hpp"
// ============================================================================= // =============================================================================
@ -55,6 +56,13 @@ protected:
return data["type"].toInt() == mEntryTypeFilter; return data["type"].toInt() == mEntryTypeFilter;
} }
bool lessThan (const QModelIndex &left, const QModelIndex &right) const override {
if( !sourceModel())
return false;
auto a = sourceModel()->data(left).value<QVariantMap>();
auto b = sourceModel()->data(right).value<QVariantMap>();
return a["receivedTimestamp"] > b["receivedTimestamp"];
}
private: private:
HistoryModel::EntryType mEntryTypeFilter = HistoryModel::EntryType::GenericEntry; HistoryModel::EntryType mEntryTypeFilter = HistoryModel::EntryType::GenericEntry;
}; };
@ -64,8 +72,7 @@ private:
HistoryProxyModel::HistoryProxyModel (QObject *parent) : QSortFilterProxyModel(parent) { HistoryProxyModel::HistoryProxyModel (QObject *parent) : QSortFilterProxyModel(parent) {
setSourceModel(new HistoryModelFilter(this)); setSourceModel(new HistoryModelFilter(this));
reload(); sort(0);
App *app = App::getInstance(); App *app = App::getInstance();
QObject::connect(app->getMainWindow(), &QWindow::activeChanged, this, [this]() { QObject::connect(app->getMainWindow(), &QWindow::activeChanged, this, [this]() {
handleIsActiveChanged(App::getInstance()->getMainWindow()); handleIsActiveChanged(App::getInstance()->getMainWindow());
@ -78,20 +85,22 @@ HistoryProxyModel::HistoryProxyModel (QObject *parent) : QSortFilterProxyModel(p
}); });
} }
void HistoryProxyModel::setCallHistoryModel(CallHistoryModel * model) {
if(mCallHistoryModel != model){
mCallHistoryModel = model;
reload();
emit callHistoryModelChanged();
}
}
// ----------------------------------------------------------------------------- // -----------------------------------------------------------------------------
void HistoryProxyModel::removeAllEntries(){ void HistoryProxyModel::removeAllEntries(){
auto model = CoreManager::getInstance()->getHistoryModel(); static_cast<HistoryModel*>(static_cast<HistoryModelFilter *>(sourceModel())->sourceModel())->removeAllEntries();
if (!model) emit mCallHistoryModel->hasBeenRemoved();
return;
model->removeAllEntries();
} }
void HistoryProxyModel::removeEntry (int id){ void HistoryProxyModel::removeEntry (int id){
auto model = CoreManager::getInstance()->getHistoryModel();
if (!model)
return;
QModelIndex sourceIndex = mapToSource(index(id, 0)); QModelIndex sourceIndex = mapToSource(index(id, 0));
model->removeEntry(static_cast<HistoryModelFilter *>(sourceModel())->mapToSource(sourceIndex).row() ); static_cast<HistoryModel*>(static_cast<HistoryModelFilter *>(sourceModel())->sourceModel())->removeEntry(static_cast<HistoryModelFilter *>(sourceModel())->mapToSource(sourceIndex).row() );
} }
// ----------------------------------------------------------------------------- // -----------------------------------------------------------------------------
@ -128,19 +137,31 @@ bool HistoryProxyModel::filterAcceptsRow (int sourceRow, const QModelIndex &) co
return sourceModel()->rowCount() - sourceRow <= mMaxDisplayedEntries; return sourceModel()->rowCount() - sourceRow <= mMaxDisplayedEntries;
} }
bool HistoryProxyModel::lessThan (const QModelIndex &left, const QModelIndex &right) const{
if( !sourceModel())
return false;
auto a = sourceModel()->data(left).value<QVariantMap>();
auto b = sourceModel()->data(right).value<QVariantMap>();
return a["receivedTimestamp"] > b["receivedTimestamp"];
}
// ----------------------------------------------------------------------------- // -----------------------------------------------------------------------------
void HistoryProxyModel::reload () { void HistoryProxyModel::reload () {
mMaxDisplayedEntries = EntriesChunkSize; mMaxDisplayedEntries = EntriesChunkSize;
auto model = CoreManager::getInstance()->getHistoryModel(); //auto model = CoreManager::getInstance()->getHistoryModel();
//model->reload(); //model->reload();
static_cast<HistoryModelFilter *>(sourceModel())->setSourceModel(model); static_cast<HistoryModelFilter *>(sourceModel())->setSourceModel(new HistoryModel(mCallHistoryModel));
invalidate();
} }
void HistoryProxyModel::resetMessageCount(){ void HistoryProxyModel::resetMessageCount(){
static_cast<HistoryModel*>(static_cast<HistoryModelFilter *>(sourceModel())->sourceModel())->resetMessageCount();
/*
auto model = CoreManager::getInstance()->getHistoryModel(); auto model = CoreManager::getInstance()->getHistoryModel();
if( model){ if( model){
model->resetMessageCount(); model->resetMessageCount();
} }
*/
} }
// ----------------------------------------------------------------------------- // -----------------------------------------------------------------------------

View file

@ -32,11 +32,14 @@ class QWindow;
class HistoryProxyModel : public QSortFilterProxyModel { class HistoryProxyModel : public QSortFilterProxyModel {
class HistoryModelFilter; class HistoryModelFilter;
Q_OBJECT; Q_OBJECT
public: public:
Q_PROPERTY(CallHistoryModel *callHistoryModel MEMBER mCallHistoryModel WRITE setCallHistoryModel NOTIFY callHistoryModelChanged)
HistoryProxyModel (QObject *parent = Q_NULLPTR); HistoryProxyModel (QObject *parent = Q_NULLPTR);
void setCallHistoryModel(CallHistoryModel * model);
Q_INVOKABLE void loadMoreEntries (); Q_INVOKABLE void loadMoreEntries ();
Q_INVOKABLE void setEntryTypeFilter (HistoryModel::EntryType type = HistoryModel::EntryType::CallEntry); Q_INVOKABLE void setEntryTypeFilter (HistoryModel::EntryType type = HistoryModel::EntryType::CallEntry);
Q_INVOKABLE void removeEntry (int id); Q_INVOKABLE void removeEntry (int id);
@ -48,17 +51,18 @@ public:
Q_INVOKABLE void reload(); Q_INVOKABLE void reload();
signals: signals:
void moreEntriesLoaded (int n); void moreEntriesLoaded (int n);
void entryTypeFilterChanged (HistoryModel::EntryType type); void entryTypeFilterChanged (HistoryModel::EntryType type);
void callHistoryModelChanged();
protected: protected:
bool filterAcceptsRow (int sourceRow, const QModelIndex &sourceParent) const override; bool filterAcceptsRow (int sourceRow, const QModelIndex &sourceParent) const override;
bool lessThan (const QModelIndex &left, const QModelIndex &right) const override;
private: private:
void handleIsActiveChanged (QWindow *window); void handleIsActiveChanged (QWindow *window);
CallHistoryModel * mCallHistoryModel = nullptr;
int mMaxDisplayedEntries = EntriesChunkSize; int mMaxDisplayedEntries = EntriesChunkSize;

View file

@ -155,6 +155,8 @@ class ColorListModel : public ProxyListModel {
ADD_COLOR("progress_bg", "black", "Background of round progress bar") ADD_COLOR("progress_bg", "black", "Background of round progress bar")
ADD_COLOR("progress_remaining_fg", "white", "Remaining progression color") ADD_COLOR("progress_remaining_fg", "white", "Remaining progression color")
ADD_COLOR("timeline_header_bg", "#E1E4E7", "Header Timeline background")
ADD_COLOR("timeline_bg_1", "#EFF0F2", "Timeline background color 1") ADD_COLOR("timeline_bg_1", "#EFF0F2", "Timeline background color 1")
ADD_COLOR("timeline_bg_2", "#FFFFFF", "Timeline background color 2") ADD_COLOR("timeline_bg_2", "#FFFFFF", "Timeline background color 2")

View file

@ -23,6 +23,7 @@
#include <QImageReader> #include <QImageReader>
#include <QPainter> #include <QPainter>
#include <QMediaPlayer> #include <QMediaPlayer>
#include <QSvgRenderer>
#include "app/App.hpp" #include "app/App.hpp"
#include "utils/Utils.hpp" #include "utils/Utils.hpp"
@ -88,22 +89,36 @@ QImage ImageModel::createThumbnail(const QString& path, QImage originalImage){
QExifImageHeader exifImageHeader; QExifImageHeader exifImageHeader;
if (exifImageHeader.loadFromJpeg(path)) if (exifImageHeader.loadFromJpeg(path))
rotation = int(exifImageHeader.value(QExifImageHeader::ImageTag::Orientation).toShort()); rotation = int(exifImageHeader.value(QExifImageHeader::ImageTag::Orientation).toShort());
// Fill with color to replace transparency with white color instead of black (default). double factor = originalImage.width() / (double)originalImage.height();
QImage image(originalImage.size(), originalImage.format());
image.fill(QColor(Qt::white).rgb());
QPainter painter(&image);
painter.drawImage(0, 0, originalImage);
//--------------------
double factor = image.width() / (double)image.height();
Qt::AspectRatioMode aspectRatio = Qt::KeepAspectRatio; Qt::AspectRatioMode aspectRatio = Qt::KeepAspectRatio;
if(factor < 0.2 || factor > 5) if(factor < 0.2 || factor > 5)
aspectRatio = Qt::KeepAspectRatioByExpanding; aspectRatio = Qt::KeepAspectRatioByExpanding;
thumbnail = image.scaled( QImageReader reader(path);
Constants::ThumbnailImageFileWidth, Constants::ThumbnailImageFileHeight, if(reader.format() == "svg"){
aspectRatio , Qt::SmoothTransformation QSvgRenderer svgRenderer(path);
); if(svgRenderer.isValid()){
if(aspectRatio == Qt::KeepAspectRatioByExpanding) thumbnail = QImage(Constants::ThumbnailImageFileWidth, Constants::ThumbnailImageFileHeight, originalImage.format());
thumbnail = thumbnail.copy(0,0,Constants::ThumbnailImageFileWidth, Constants::ThumbnailImageFileHeight); thumbnail.fill(QColor(Qt::transparent));
QPainter painter(&thumbnail);
svgRenderer.setAspectRatioMode(aspectRatio);
svgRenderer.render(&painter);
}
}
if(thumbnail.isNull()){
QImage image(originalImage.size(), originalImage.format());
// Fill with color to replace transparency with white color instead of black (default).
image.fill(QColor(Qt::white).rgb());
QPainter painter(&image);
painter.drawImage(0, 0, originalImage);
//--------------------
thumbnail = image.scaled(
Constants::ThumbnailImageFileWidth, Constants::ThumbnailImageFileHeight,
aspectRatio , Qt::SmoothTransformation
);
if(aspectRatio == Qt::KeepAspectRatioByExpanding)// Cut
thumbnail = thumbnail.copy(0,0,Constants::ThumbnailImageFileWidth, Constants::ThumbnailImageFileHeight);
}
if (rotation != 0) { if (rotation != 0) {
QTransform transform; QTransform transform;

View file

@ -58,10 +58,9 @@ static inline AccountSettingsModel::RegistrationState mapLinphoneRegistrationSta
AccountSettingsModel::AccountSettingsModel (QObject *parent) : QObject(parent) { AccountSettingsModel::AccountSettingsModel (QObject *parent) : QObject(parent) {
CoreManager *coreManager = CoreManager::getInstance(); CoreManager *coreManager = CoreManager::getInstance();
QObject::connect( QObject::connect(coreManager->getHandlers().get(), &CoreHandlers::registrationStateChanged, this, &AccountSettingsModel::handleRegistrationStateChanged);
coreManager->getHandlers().get(), &CoreHandlers::registrationStateChanged, QObject::connect(coreManager, &CoreManager::callLogsCountChanged, this, &AccountSettingsModel::missedCallsCountChanged);
this, &AccountSettingsModel::handleRegistrationStateChanged
);
//QObject::connect(coreManager, &CoreManager::eventCountChanged, this, [this]() { emit accountSettingsUpdated(); }); //QObject::connect(coreManager, &CoreManager::eventCountChanged, this, [this]() { emit accountSettingsUpdated(); });
QObject::connect(this, &AccountSettingsModel::accountSettingsUpdated, this, &AccountSettingsModel::usernameChanged); QObject::connect(this, &AccountSettingsModel::accountSettingsUpdated, this, &AccountSettingsModel::usernameChanged);
@ -75,6 +74,8 @@ AccountSettingsModel::AccountSettingsModel (QObject *parent) : QObject(parent) {
QObject::connect(this, &AccountSettingsModel::accountSettingsUpdated, this, &AccountSettingsModel::primaryUsernameChanged); QObject::connect(this, &AccountSettingsModel::accountSettingsUpdated, this, &AccountSettingsModel::primaryUsernameChanged);
QObject::connect(this, &AccountSettingsModel::accountSettingsUpdated, this, &AccountSettingsModel::primarySipAddressChanged); QObject::connect(this, &AccountSettingsModel::accountSettingsUpdated, this, &AccountSettingsModel::primarySipAddressChanged);
QObject::connect(this, &AccountSettingsModel::accountSettingsUpdated, this, &AccountSettingsModel::accountsChanged); QObject::connect(this, &AccountSettingsModel::accountSettingsUpdated, this, &AccountSettingsModel::accountsChanged);
QObject::connect(this, &AccountSettingsModel::accountsChanged, this, &AccountSettingsModel::missedCallsCountChanged);
QObject::connect(this, &AccountSettingsModel::accountsChanged, this, &AccountSettingsModel::unreadMessagesCountChanged);
mSelectedAccount = coreManager->getCore()->getDefaultAccount(); mSelectedAccount = coreManager->getCore()->getDefaultAccount();
} }
@ -251,6 +252,19 @@ bool AccountSettingsModel::getUseInternationalPrefixForCallsAndChats() const{
return false; return false;
} }
int AccountSettingsModel::getMissedCallsCount() const {
shared_ptr<linphone::Core> core = CoreManager::getInstance()->getCore();
shared_ptr<linphone::Account> account = core->getDefaultAccount();
return account ? account->getMissedCallsCount() : core->getMissedCallsCount();
}
int AccountSettingsModel::getUnreadMessagesCount() const {
shared_ptr<linphone::Core> core = CoreManager::getInstance()->getCore();
shared_ptr<linphone::Account> account = core->getDefaultAccount();
return account ? account->getUnreadChatMessageCount() : core->getUnreadChatMessageCount();
}
void AccountSettingsModel::setDefaultAccount (const shared_ptr<linphone::Account> &account) { void AccountSettingsModel::setDefaultAccount (const shared_ptr<linphone::Account> &account) {
shared_ptr<linphone::Core> core = CoreManager::getInstance()->getCore(); shared_ptr<linphone::Core> core = CoreManager::getInstance()->getCore();
if (mSelectedAccount != account) { if (mSelectedAccount != account) {
@ -602,8 +616,8 @@ QVariantList AccountSettingsModel::getAccounts () const {
QVariantMap account; QVariantMap account;
account["sipAddress"] = Utils::coreStringToAppString(core->createPrimaryContactParsed()->asStringUriOnly()); account["sipAddress"] = Utils::coreStringToAppString(core->createPrimaryContactParsed()->asStringUriOnly());
account["fullSipAddress"] = Utils::coreStringToAppString(core->createPrimaryContactParsed()->asString()); account["fullSipAddress"] = Utils::coreStringToAppString(core->createPrimaryContactParsed()->asString());
account["unreadMessageCount"] = settingsModel->getStandardChatEnabled() || settingsModel->getSecureChatEnabled() ? core->getUnreadChatMessageCountFromLocal(core->createPrimaryContactParsed()) : 0; account["unreadMessageCount"] = settingsModel->getStandardChatEnabled() || settingsModel->getSecureChatEnabled() ? core->getUnreadChatMessageCount() : 0;
account["missedCallCount"] = CoreManager::getInstance()->getMissedCallCountFromLocal(account["sipAddress"].toString()); account["missedCallCount"] = core->getMissedCallsCount();
account["account"].setValue(nullptr); account["account"].setValue(nullptr);
accounts << account; accounts << account;
} }
@ -615,7 +629,7 @@ QVariantList AccountSettingsModel::getAccounts () const {
accountMap["fullSipAddress"] = Utils::coreStringToAppString(params->getIdentityAddress()->asString()); accountMap["fullSipAddress"] = Utils::coreStringToAppString(params->getIdentityAddress()->asString());
accountMap["account"].setValue(account); accountMap["account"].setValue(account);
accountMap["unreadMessageCount"] = settingsModel->getStandardChatEnabled() || settingsModel->getSecureChatEnabled() ? account->getUnreadChatMessageCount() : 0; accountMap["unreadMessageCount"] = settingsModel->getStandardChatEnabled() || settingsModel->getSecureChatEnabled() ? account->getUnreadChatMessageCount() : 0;
accountMap["missedCallCount"] = CoreManager::getInstance()->getMissedCallCountFromLocal(accountMap["sipAddress"].toString()); accountMap["missedCallCount"] = account->getMissedCallsCount();
accountMap["registerEnabled"] = params->registerEnabled(); accountMap["registerEnabled"] = params->registerEnabled();
accounts << accountMap; accounts << accountMap;
} }

View file

@ -51,6 +51,9 @@ class AccountSettingsModel : public QObject {
Q_PROPERTY(QString defaultAccountDomain READ getDefaultAccountDomain NOTIFY defaultAccountChanged) Q_PROPERTY(QString defaultAccountDomain READ getDefaultAccountDomain NOTIFY defaultAccountChanged)
Q_PROPERTY(QVariantList accounts READ getAccounts NOTIFY accountsChanged) Q_PROPERTY(QVariantList accounts READ getAccounts NOTIFY accountsChanged)
Q_PROPERTY(int missedCallsCount READ getMissedCallsCount NOTIFY missedCallsCountChanged)
Q_PROPERTY(int unreadMessagesCount READ getUnreadMessagesCount NOTIFY unreadMessagesCountChanged)
public: public:
enum RegistrationState { enum RegistrationState {
@ -80,6 +83,8 @@ public:
QString getVideoConferenceUri() const; QString getVideoConferenceUri() const;
QString getLimeServerUrl() const; QString getLimeServerUrl() const;
bool getUseInternationalPrefixForCallsAndChats() const; bool getUseInternationalPrefixForCallsAndChats() const;
int getMissedCallsCount() const;
int getUnreadMessagesCount() const;
Q_INVOKABLE void setDefaultAccount (const std::shared_ptr<linphone::Account> &account = nullptr); Q_INVOKABLE void setDefaultAccount (const std::shared_ptr<linphone::Account> &account = nullptr);
Q_INVOKABLE void setDefaultAccountFromSipAddress (const QString &sipAddress); Q_INVOKABLE void setDefaultAccountFromSipAddress (const QString &sipAddress);
@ -120,6 +125,8 @@ signals:
void defaultAccountChanged(); void defaultAccountChanged();
void publishPresenceChanged(); void publishPresenceChanged();
void defaultRegistrationChanged(); void defaultRegistrationChanged();
void missedCallsCountChanged();
void unreadMessagesCountChanged();
private: private:
QString getUsername () const; QString getUsername () const;

View file

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2010-2020 Belledonne Communications SARL. * Copyright (c) 2010-2023 Belledonne Communications SARL.
* *
* This file is part of linphone-desktop * This file is part of linphone-desktop
* (see https://www.linphone.org). * (see https://www.linphone.org).
@ -50,11 +50,3 @@ void SipAddressObserver::setPresenceTimestamp(const QDateTime &presenceTimestamp
mPresenceTimestamp = presenceTimestamp; mPresenceTimestamp = presenceTimestamp;
emit presenceTimestampChanged(presenceTimestamp); emit presenceTimestampChanged(presenceTimestamp);
} }
void SipAddressObserver::setUnreadMessageCount (int unreadMessageCount) {
if (unreadMessageCount == mUnreadMessageCount)
return;
mUnreadMessageCount = unreadMessageCount;
emit unreadMessageCountChanged(unreadMessageCount);
}

View file

@ -41,7 +41,6 @@ class SipAddressObserver : public QObject {
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(Presence::PresenceStatus presenceStatus READ getPresenceStatus NOTIFY presenceStatusChanged);
Q_PROPERTY(QDateTime presenceTimestamp READ getPresenceTimestamp NOTIFY presenceTimestampChanged); Q_PROPERTY(QDateTime presenceTimestamp READ getPresenceTimestamp NOTIFY presenceTimestampChanged);
Q_PROPERTY(int unreadMessageCount READ getUnreadMessageCount NOTIFY unreadMessageCountChanged);
Q_PROPERTY(bool isOneToOne MEMBER isOneToOne CONSTANT); Q_PROPERTY(bool isOneToOne MEMBER isOneToOne CONSTANT);
Q_PROPERTY(bool haveEncryption MEMBER haveEncryption CONSTANT); Q_PROPERTY(bool haveEncryption MEMBER haveEncryption CONSTANT);
@ -57,7 +56,6 @@ signals:
void contactChanged (QSharedPointer<ContactModel>); void contactChanged (QSharedPointer<ContactModel>);
void presenceStatusChanged (const Presence::PresenceStatus &presenceStatus); void presenceStatusChanged (const Presence::PresenceStatus &presenceStatus);
void presenceTimestampChanged (const QDateTime &presenceTimestamp); void presenceTimestampChanged (const QDateTime &presenceTimestamp);
void unreadMessageCountChanged (int unreadMessageCount);
private: private:
QString getPeerAddress () const { QString getPeerAddress () const {
@ -89,20 +87,12 @@ private:
void setPresenceTimestamp (const QDateTime &presenceTimestamp); void setPresenceTimestamp (const QDateTime &presenceTimestamp);
// --------------------------------------------------------------------------- // ---------------------------------------------------------------------------
int getUnreadMessageCount () const {
return mUnreadMessageCount;
}
void setUnreadMessageCount (int unreadMessageCount);
QString mPeerAddress; QString mPeerAddress;
QString mLocalAddress; QString mLocalAddress;
QSharedPointer<ContactModel> mContact; QSharedPointer<ContactModel> mContact;
Presence::PresenceStatus mPresenceStatus = Presence::PresenceStatus::Offline; Presence::PresenceStatus mPresenceStatus = Presence::PresenceStatus::Offline;
QDateTime mPresenceTimestamp; QDateTime mPresenceTimestamp;
int mUnreadMessageCount = 0;
}; };
Q_DECLARE_METATYPE(SipAddressObserver *); Q_DECLARE_METATYPE(SipAddressObserver *);

View file

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2010-2020 Belledonne Communications SARL. * Copyright (c) 2010-2023 Belledonne Communications SARL.
* *
* This file is part of linphone-desktop * This file is part of linphone-desktop
* (see https://www.linphone.org). * (see https://www.linphone.org).
@ -177,10 +177,6 @@ SipAddressObserver *SipAddressesModel::getSipAddressObserver (const QString &pee
model->setContact(it->contact); model->setContact(it->contact);
model->setPresenceStatus(it->presenceStatus); model->setPresenceStatus(it->presenceStatus);
model->setPresenceTimestamp(it->presenceTimestamp); model->setPresenceTimestamp(it->presenceTimestamp);
auto it2 = it->localAddressToConferenceEntry.find(cleanedLocalAddress);
if (it2 != it->localAddressToConferenceEntry.end())
model->setUnreadMessageCount(it2->unreadMessageCount+it2->missedCallCount);
} }
mObservers.insert(cleanedPeerAddress, model); mObservers.insert(cleanedPeerAddress, model);
@ -327,17 +323,11 @@ void SipAddressesModel::handleChatRoomModelCreated (const QSharedPointer<ChatRoo
QObject::connect(ptr, &ChatRoomModel::lastEntryRemoved, this, [this, ptr] { QObject::connect(ptr, &ChatRoomModel::lastEntryRemoved, this, [this, ptr] {
handleLastEntryRemoved(ptr); handleLastEntryRemoved(ptr);
}); });
QObject::connect(ptr, &ChatRoomModel::messageCountReset, this, [this, ptr] {
handleMessageCountReset(ptr);
});
QObject::connect(ptr, &ChatRoomModel::messageSent, this, &SipAddressesModel::handleMessageSent); QObject::connect(ptr, &ChatRoomModel::messageSent, this, &SipAddressesModel::handleMessageSent);
} }
void SipAddressesModel::handleHistoryModelCreated (HistoryModel *historyModel) { void SipAddressesModel::handleHistoryModelCreated (HistoryModel *historyModel) {
QObject::connect(historyModel, &HistoryModel::callCountReset, this, [this] {
handleAllCallCountReset();
});
} }
void SipAddressesModel::handleContactAdded (QSharedPointer<ContactModel> contact) { void SipAddressesModel::handleContactAdded (QSharedPointer<ContactModel> contact) {
@ -485,38 +475,6 @@ void SipAddressesModel::handleLastEntryRemoved (ChatRoomModel *chatRoomModel) {
emit dataChanged(index(row, 0), index(row, 0)); emit dataChanged(index(row, 0), index(row, 0));
} }
void SipAddressesModel::handleAllCallCountReset () {
for( auto peer = mPeerAddressToSipAddressEntry.begin() ; peer != mPeerAddressToSipAddressEntry.end() ; ++peer){
for( auto local = peer->localAddressToConferenceEntry.begin() ; local != peer->localAddressToConferenceEntry.end() ; ++local){
local->missedCallCount = 0;
updateObservers(peer.key(), local.key(), local->unreadMessageCount, local->missedCallCount);
}
int row = mRefs.indexOf(&(*peer));
emit dataChanged(index(row, 0), index(row, 0));
}
}
void SipAddressesModel::handleMessageCountReset (ChatRoomModel *chatRoomModel) {
const QString &peerAddress = Utils::cleanSipAddress(chatRoomModel->getPeerAddress());
auto it = mPeerAddressToSipAddressEntry.find(peerAddress);
if (it == mPeerAddressToSipAddressEntry.end())
return;
const QString &localAddress = Utils::cleanSipAddress(chatRoomModel->getLocalAddress());
auto it2 = it->localAddressToConferenceEntry.find(localAddress);
if (it2 == it->localAddressToConferenceEntry.end())
return;
it2->unreadMessageCount = 0;
it2->missedCallCount = 0;
int row = mRefs.indexOf(&(*it));
Q_ASSERT(row != -1);
emit dataChanged(index(row, 0), index(row, 0));
updateObservers(peerAddress, localAddress, 0, 0);
}
void SipAddressesModel::handleMessageSent (const shared_ptr<linphone::ChatMessage> &message) { void SipAddressesModel::handleMessageSent (const shared_ptr<linphone::ChatMessage> &message) {
if(message->getChatRoom() && message->getChatRoom()->getPeerAddress()){ if(message->getChatRoom() && message->getChatRoom()->getPeerAddress()){
auto lPeerAddress = message->getChatRoom()->getPeerAddress(); auto lPeerAddress = message->getChatRoom()->getPeerAddress();
@ -573,12 +531,10 @@ void SipAddressesModel::addOrUpdateSipAddress (SipAddressEntry &sipAddressEntry,
conferenceEntry.timestamp = callLog->getStatus() == linphone::Call::Status::Success conferenceEntry.timestamp = callLog->getStatus() == linphone::Call::Status::Success
? QDateTime::fromMSecsSinceEpoch((callLog->getStartDate() + callLog->getDuration()) * 1000) ? QDateTime::fromMSecsSinceEpoch((callLog->getStartDate() + callLog->getDuration()) * 1000)
: QDateTime::fromMSecsSinceEpoch(callLog->getStartDate() * 1000); : QDateTime::fromMSecsSinceEpoch(callLog->getStartDate() * 1000);
conferenceEntry.missedCallCount = CoreManager::getInstance()->getMissedCallCount(peerAddress, localAddress);
QString oldDisplayName = sipAddressEntry.displayNames.get(); QString oldDisplayName = sipAddressEntry.displayNames.get();
sipAddressEntry.displayNames.updateFromCall(lPeerAddress); sipAddressEntry.displayNames.updateFromCall(lPeerAddress);
if(oldDisplayName != sipAddressEntry.displayNames.get()) if(oldDisplayName != sipAddressEntry.displayNames.get())
emit CoreManager::getInstance()->getContactsListModel()->contactUpdated(nullptr); emit CoreManager::getInstance()->getContactsListModel()->contactUpdated(nullptr);
updateObservers(sipAddressEntry.sipAddress, localAddress, conferenceEntry.unreadMessageCount,conferenceEntry.missedCallCount);
} }
void SipAddressesModel::addOrUpdateSipAddress (SipAddressEntry &sipAddressEntry, const shared_ptr<linphone::ChatMessage> &message) { void SipAddressesModel::addOrUpdateSipAddress (SipAddressEntry &sipAddressEntry, const shared_ptr<linphone::ChatMessage> &message) {
@ -595,10 +551,7 @@ void SipAddressesModel::addOrUpdateSipAddress (SipAddressEntry &sipAddressEntry,
ConferenceEntry &conferenceEntry = sipAddressEntry.localAddressToConferenceEntry[localAddress]; ConferenceEntry &conferenceEntry = sipAddressEntry.localAddressToConferenceEntry[localAddress];
conferenceEntry.timestamp = QDateTime::fromMSecsSinceEpoch(message->getTime() * 1000); conferenceEntry.timestamp = QDateTime::fromMSecsSinceEpoch(message->getTime() * 1000);
conferenceEntry.unreadMessageCount = count ;
conferenceEntry.missedCallCount = CoreManager::getInstance()->getMissedCallCount(peerAddress, localAddress);
sipAddressEntry.displayNames.updateFromChatMessage(lPeerAddress); sipAddressEntry.displayNames.updateFromChatMessage(lPeerAddress);
updateObservers(sipAddressEntry.sipAddress, localAddress, count,conferenceEntry.missedCallCount);
} }
template<typename T> template<typename T>
@ -685,8 +638,6 @@ void SipAddressesModel::initSipAddressesFromChat () {
QString localAddress(Utils::cleanSipAddress(Utils::coreStringToAppString(chatRoom->getLocalAddress()->asStringUriOnly()))); QString localAddress(Utils::cleanSipAddress(Utils::coreStringToAppString(chatRoom->getLocalAddress()->asStringUriOnly())));
getSipAddressEntry(peerAddress, lPeerAddress)->localAddressToConferenceEntry[localAddress] = { getSipAddressEntry(peerAddress, lPeerAddress)->localAddressToConferenceEntry[localAddress] = {
chatRoom->getUnreadMessagesCount(),
CoreManager::getInstance()->getMissedCallCount(peerAddress, localAddress),
false, false,
QDateTime::fromMSecsSinceEpoch(lastMessage->getTime() * 1000) QDateTime::fromMSecsSinceEpoch(lastMessage->getTime() * 1000)
}; };
@ -716,7 +667,7 @@ void SipAddressesModel::initSipAddressesFromCalls () {
auto &localToConferenceEntry = sipAddressEntry->localAddressToConferenceEntry; auto &localToConferenceEntry = sipAddressEntry->localAddressToConferenceEntry;
auto it = localToConferenceEntry.find(localAddress); auto it = localToConferenceEntry.find(localAddress);
if (it == localToConferenceEntry.end()) { if (it == localToConferenceEntry.end()) {
localToConferenceEntry[localAddress] = { 0,0, false, move(timestamp) }; localToConferenceEntry[localAddress] = { false, move(timestamp) };
sipAddressEntry->displayNames.mFromCallLogs = QString::fromStdString(callLog->getRemoteAddress()->getDisplayName()); sipAddressEntry->displayNames.mFromCallLogs = QString::fromStdString(callLog->getRemoteAddress()->getDisplayName());
}else if (it->timestamp.isNull() || timestamp > it->timestamp){ }else if (it->timestamp.isNull() || timestamp > it->timestamp){
it->timestamp = move(timestamp); it->timestamp = move(timestamp);
@ -748,12 +699,3 @@ void SipAddressesModel::updateObservers (const QString &sipAddress, const Presen
observer->setPresenceTimestamp(presenceTimestamp); observer->setPresenceTimestamp(presenceTimestamp);
} }
} }
void SipAddressesModel::updateObservers (const QString &peerAddress, const QString &localAddress, int messageCount, int missedCallCount) {
for (auto &observer : mObservers.values(peerAddress)) {
if (observer->getLocalAddress() == localAddress) {
observer->setUnreadMessageCount(messageCount+missedCallCount);
return;
}
}
}

View file

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2010-2020 Belledonne Communications SARL. * Copyright (c) 2010-2023 Belledonne Communications SARL.
* *
* This file is part of linphone-desktop * This file is part of linphone-desktop
* (see https://www.linphone.org). * (see https://www.linphone.org).
@ -37,12 +37,10 @@ class CoreHandlers;
class HistoryModel; class HistoryModel;
class SipAddressesModel : public QAbstractListModel { class SipAddressesModel : public QAbstractListModel {
Q_OBJECT; Q_OBJECT
public: public:
struct ConferenceEntry { struct ConferenceEntry {
int unreadMessageCount;
int missedCallCount;
bool isComposing; bool isComposing;
QDateTime timestamp; QDateTime timestamp;
}; };
@ -81,8 +79,6 @@ public:
QHash<int, QByteArray> roleNames () const override; QHash<int, QByteArray> roleNames () const override;
QVariant data (const QModelIndex &index, int role = Qt::DisplayRole) const override; QVariant data (const QModelIndex &index, int role = Qt::DisplayRole) const override;
//Q_PROPERTY(QList<QVariant> resultExceptions READ getResultExceptions WRITE setResultExceptions NOTIFY resultExceptionsChanged)
Q_INVOKABLE QVariantMap find (const QString &sipAddress) const; Q_INVOKABLE QVariantMap find (const QString &sipAddress) const;
Q_INVOKABLE ContactModel *mapSipAddressToContact (const QString &sipAddress) const; Q_INVOKABLE ContactModel *mapSipAddressToContact (const QString &sipAddress) const;
Q_INVOKABLE SipAddressObserver *getSipAddressObserver (const QString &peerAddress, const QString &localAddress); Q_INVOKABLE SipAddressObserver *getSipAddressObserver (const QString &peerAddress, const QString &localAddress);
@ -113,9 +109,6 @@ public:
signals: signals:
void sipAddressReset();// The model has been reset void sipAddressReset();// The model has been reset
public slots:
void handleAllCallCountReset ();
private: private:
bool removeRow (int row, const QModelIndex &parent = QModelIndex()); bool removeRow (int row, const QModelIndex &parent = QModelIndex());
bool removeRows (int row, int count, const QModelIndex &parent = QModelIndex()) override; bool removeRows (int row, int count, const QModelIndex &parent = QModelIndex()) override;
@ -140,8 +133,6 @@ private:
void handleAllEntriesRemoved (ChatRoomModel *chatRoomModel); void handleAllEntriesRemoved (ChatRoomModel *chatRoomModel);
void handleLastEntryRemoved (ChatRoomModel *chatRoomModel); void handleLastEntryRemoved (ChatRoomModel *chatRoomModel);
void handleMessageCountReset (ChatRoomModel *chatRoomModel);
void handleMessageSent (const std::shared_ptr<linphone::ChatMessage> &message); void handleMessageSent (const std::shared_ptr<linphone::ChatMessage> &message);
void handleIsComposingChanged (const std::shared_ptr<linphone::ChatRoom> &chatRoom); void handleIsComposingChanged (const std::shared_ptr<linphone::ChatRoom> &chatRoom);
@ -166,7 +157,6 @@ private:
void updateObservers (const QString &sipAddress, QSharedPointer<ContactModel> contact); void updateObservers (const QString &sipAddress, QSharedPointer<ContactModel> contact);
void updateObservers (const QString &sipAddress, const Presence::PresenceStatus &presenceStatus, const QDateTime &presenceTimestamp); void updateObservers (const QString &sipAddress, const Presence::PresenceStatus &presenceStatus, const QDateTime &presenceTimestamp);
void updateObservers (const QString &peerAddress, const QString &localAddress, int messageCount, int missedCallCount);
// --------------------------------------------------------------------------- // ---------------------------------------------------------------------------

View file

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2010-2020 Belledonne Communications SARL. * Copyright (c) 2010-2023 Belledonne Communications SARL.
* *
* This file is part of linphone-desktop * This file is part of linphone-desktop
* (see https://www.linphone.org). * (see https://www.linphone.org).
@ -25,8 +25,6 @@
#include "components/calls/CallsListModel.hpp" #include "components/calls/CallsListModel.hpp"
#include "components/settings/AccountSettingsModel.hpp" #include "components/settings/AccountSettingsModel.hpp"
#include "components/settings/SettingsModel.hpp" #include "components/settings/SettingsModel.hpp"
#include "components/sip-addresses/SipAddressesModel.hpp"
#include "components/contacts/ContactsListModel.hpp"
#include "utils/Utils.hpp" #include "utils/Utils.hpp"
@ -327,7 +325,6 @@ void TimelineListModel::updateTimelines () {
qInfo() << "Timelines adding :" << stepsTimer.restart() << "ms for " << models.size() << " new timelines"; qInfo() << "Timelines adding :" << stepsTimer.restart() << "ms for " << models.size() << " new timelines";
add(models); add(models);
qInfo() << "Timelines adding GUI :" << stepsTimer.restart() << "ms."; qInfo() << "Timelines adding GUI :" << stepsTimer.restart() << "ms.";
CoreManager::getInstance()->updateUnreadMessageCount();
qInfo() << "Timelines initialized in:" << timer.elapsed() << "ms."; qInfo() << "Timelines initialized in:" << timer.elapsed() << "ms.";
} }
@ -460,7 +457,6 @@ void TimelineListModel::onCallCreated(const std::shared_ptr<linphone::Call> &cal
} }
if(!found){// Create a default chat room if(!found){// Create a default chat room
QVariantList participants; QVariantList participants;
//participants << Utils::coreStringToAppString(callLog->getRemoteAddress()->asStringUriOnly()); // This allow chatting to a specific device but the current design is not adapted to show them
auto remoteAddress = callLog->getRemoteAddress()->clone(); auto remoteAddress = callLog->getRemoteAddress()->clone();
remoteAddress->clean(); remoteAddress->clean();
participants << Utils::coreStringToAppString(remoteAddress->asStringUriOnly()); participants << Utils::coreStringToAppString(remoteAddress->asStringUriOnly());

View file

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2010-2020 Belledonne Communications SARL. * Copyright (c) 2010-2023 Belledonne Communications SARL.
* *
* This file is part of linphone-desktop * This file is part of linphone-desktop
* (see https://www.linphone.org). * (see https://www.linphone.org).

View file

@ -62,6 +62,13 @@ void TimelineProxyModel::setFilterText(const QString& text){
} }
} }
void TimelineProxyModel::setMode(const TimelineMode& mode) {
if(mMode != mode) {
mMode = mode;
emit modeChanged();
}
}
TimelineProxyModel::TimelineListSource TimelineProxyModel::getListSource() const{ TimelineProxyModel::TimelineListSource TimelineProxyModel::getListSource() const{
return mListSource; return mListSource;
} }
@ -115,15 +122,12 @@ bool TimelineProxyModel::filterAcceptsRow (int sourceRow, const QModelIndex &sou
return false; return false;
bool show = (mFilterFlags==0);// Show all at 0 (no hide all) bool show = (mFilterFlags==0);// Show all at 0 (no hide all)
bool isGroup = timeline->getChatRoomModel()->isGroupEnabled(); bool isGroup = timeline->getChatRoomModel()->isGroupEnabled();
bool isEphemeral = timeline->getChatRoomModel()->isEphemeralEnabled();
if( mFilterFlags > 0) { if( mFilterFlags > 0) {
show = !(( ( (mFilterFlags & TimelineFilter::SimpleChatRoom) == TimelineFilter::SimpleChatRoom) && isGroup) show = !(
|| ( ( (mFilterFlags & TimelineFilter::SecureChatRoom) == TimelineFilter::SecureChatRoom) && !haveEncryption) ( ((mFilterFlags & TimelineFilter::SecureChatRoom) == TimelineFilter::SecureChatRoom) && !haveEncryption)
|| ( ( (mFilterFlags & TimelineFilter::GroupChatRoom) == TimelineFilter::GroupChatRoom) && !isGroup) || ( ((mFilterFlags & TimelineFilter::GroupChatRoom) == TimelineFilter::GroupChatRoom) && !isGroup)
|| ( ( (mFilterFlags & TimelineFilter::StandardChatRoom) == TimelineFilter::StandardChatRoom) && haveEncryption) );
|| ( ( (mFilterFlags & TimelineFilter::EphemeralChatRoom) == TimelineFilter::EphemeralChatRoom) && !isEphemeral)
|| ( ( (mFilterFlags & TimelineFilter::NoEphemeralChatRoom) == TimelineFilter::NoEphemeralChatRoom) && isEphemeral));
} }
if(show && mFilterText != ""){ if(show && mFilterText != ""){
@ -142,8 +146,8 @@ bool TimelineProxyModel::lessThan (const QModelIndex &left, const QModelIndex &r
return false; return false;
const TimelineModel* a = sourceModel()->data(left).value<TimelineModel*>(); const TimelineModel* a = sourceModel()->data(left).value<TimelineModel*>();
const TimelineModel* b = sourceModel()->data(right).value<TimelineModel*>(); const TimelineModel* b = sourceModel()->data(right).value<TimelineModel*>();
bool aHaveUnread = a->getChatRoomModel()->getAllUnreadCount() > 0; bool aHaveUnread = a->getChatRoomModel()->getUnreadMessagesCount() > 0;
bool bHaveUnread = b->getChatRoomModel()->getAllUnreadCount() > 0; bool bHaveUnread = b->getChatRoomModel()->getUnreadMessagesCount() > 0;
return (aHaveUnread && !bHaveUnread) return (aHaveUnread && !bHaveUnread)
|| (aHaveUnread == bHaveUnread && a->getChatRoomModel()->mLastUpdateTime > b->getChatRoomModel()->mLastUpdateTime); || (aHaveUnread == bHaveUnread && a->getChatRoomModel()->mLastUpdateTime > b->getChatRoomModel()->mLastUpdateTime);
} }

View file

@ -34,18 +34,19 @@ class TimelineProxyModel : public QSortFilterProxyModel {
public: public:
enum TimelineFilter { enum TimelineFilter {
StandardChatRoom=1, SecureChatRoom = 1,
SecureChatRoom=2, GroupChatRoom = 2,
SimpleChatRoom=4,
GroupChatRoom=8,
EphemeralChatRoom=16,
NoEphemeralChatRoom=32,
AllChatRooms = 0 AllChatRooms = 0
}; };
Q_ENUM(TimelineFilter) Q_ENUM(TimelineFilter)
enum TimelineListSource{ enum TimelineMode {
Chats,
Calls
};
Q_ENUM(TimelineMode)
enum TimelineListSource{
Undefined, Undefined,
Main, // Timeline list comes from the singleton stored in CoreManager. Main, // Timeline list comes from the singleton stored in CoreManager.
Copy // Timeline list is created from Main but have no attach to the main list (aside of root items). Copy // Timeline list is created from Main but have no attach to the main list (aside of root items).
@ -59,10 +60,12 @@ public:
Q_PROPERTY(int filterFlags MEMBER mFilterFlags WRITE setFilterFlags NOTIFY filterFlagsChanged) Q_PROPERTY(int filterFlags MEMBER mFilterFlags WRITE setFilterFlags NOTIFY filterFlagsChanged)
Q_PROPERTY(QString filterText MEMBER mFilterText WRITE setFilterText NOTIFY filterTextChanged) Q_PROPERTY(QString filterText MEMBER mFilterText WRITE setFilterText NOTIFY filterTextChanged)
Q_PROPERTY(int count READ rowCount NOTIFY countChanged) Q_PROPERTY(int count READ rowCount NOTIFY countChanged)
Q_PROPERTY(TimelineMode mode MEMBER mMode WRITE setMode NOTIFY modeChanged)
Q_INVOKABLE void unselectAll(); Q_INVOKABLE void unselectAll();
Q_INVOKABLE void setFilterFlags(const int& filterFlags); Q_INVOKABLE void setFilterFlags(const int& filterFlags);
Q_INVOKABLE void setFilterText(const QString& text); Q_INVOKABLE void setFilterText(const QString& text);
Q_INVOKABLE void setMode(const TimelineMode& mode);
TimelineListSource getListSource() const; TimelineListSource getListSource() const;
void setListSource(const TimelineListSource& source); void setListSource(const TimelineListSource& source);
@ -74,6 +77,7 @@ signals:
void filterFlagsChanged(); void filterFlagsChanged();
void filterTextChanged(); void filterTextChanged();
void listSourceChanged(); void listSourceChanged();
void modeChanged();
protected: protected:
@ -87,6 +91,7 @@ protected:
private: private:
int mFilterFlags = 0; int mFilterFlags = 0;
QString mFilterText; QString mFilterText;
TimelineMode mMode = Chats;
TimelineListSource mListSource = Undefined; TimelineListSource mListSource = Undefined;
}; };

View file

@ -119,11 +119,11 @@ QDateTime Utils::getOffsettedUTC(const QDateTime& date){
return utc; return utc;
} }
QString Utils::toDateTimeString(QDateTime date){ QString Utils::toDateTimeString(QDateTime date, const QString& format){
if(date.date() == QDate::currentDate()) if(date.date() == QDate::currentDate())
return toTimeString(date); return toTimeString(date);
else{ else{
return getOffsettedUTC(date).toString("yyyy/MM/dd hh:mm:ss"); return getOffsettedUTC(date).toString(format);
} }
} }
@ -223,7 +223,8 @@ bool Utils::isGreatherThan(const QDate& d1, const QDate& d2) {
//-------------------------------------------------------------------------------------- //--------------------------------------------------------------------------------------
QString Utils::getDisplayName(const QString& address){ QString Utils::getDisplayName(const QString& address){
return getDisplayName(interpretUrl(address)); QString displayName = getDisplayName(interpretUrl(address));
return displayName.isEmpty() ? address : displayName;
} }
QString Utils::getInitials(const QString& username){ QString Utils::getInitials(const QString& username){

View file

@ -68,7 +68,7 @@ public:
//***** DATE TIME //***** DATE TIME
Q_INVOKABLE static QDateTime addMinutes(QDateTime date, const int& min); Q_INVOKABLE static QDateTime addMinutes(QDateTime date, const int& min);
static QDateTime getOffsettedUTC(const QDateTime& date); static QDateTime getOffsettedUTC(const QDateTime& date);
Q_INVOKABLE static QString toDateTimeString(QDateTime date); Q_INVOKABLE static QString toDateTimeString(QDateTime date, const QString& format = "yyyy/MM/dd hh:mm:ss");
Q_INVOKABLE static QString toTimeString(QDateTime date, const QString& format = "hh:mm:ss"); Q_INVOKABLE static QString toTimeString(QDateTime date, const QString& format = "hh:mm:ss");
Q_INVOKABLE static QString toDateString(QDateTime date, const QString& format = ""); Q_INVOKABLE static QString toDateString(QDateTime date, const QString& format = "");
Q_INVOKABLE static QString toDateString(QDate date, const QString& format = ""); Q_INVOKABLE static QString toDateString(QDate date, const QString& format = "");

View file

@ -30,7 +30,7 @@ Item {
image.colorOverwriteEnabled = false image.colorOverwriteEnabled = false
height: iconHeight > 0 ? iconHeight : iconSize height: iconHeight > 0 ? iconHeight : iconSize
width: iconWidth > 0 ? iconWidth : iconSize width: iconWidth > 0 ? iconWidth : iconSize
visible: icon != ''
Image { Image {
id:image id:image
anchors.fill: parent anchors.fill: parent

View file

@ -9,8 +9,10 @@ import Common.Styles 1.0
Controls.Menu { Controls.Menu {
id: menu id: menu
property var menuStyle : MenuStyle.normal property var menuStyle : MenuStyle.normal
property alias radius: brackgroundArea.radius
width: menuStyle.width ? menuStyle.width : parent.width width: menuStyle.width ? menuStyle.width : parent.width
background: Rectangle { background: Rectangle {
id: brackgroundArea
implicitWidth: menu.width implicitWidth: menu.width
color: menuStyle.colorModel.color color: menuStyle.colorModel.color
radius: menuStyle.radius radius: menuStyle.radius

View file

@ -17,18 +17,22 @@ Controls.MenuItem {
property alias iconSizeMenu: iconArea.iconSize property alias iconSizeMenu: iconArea.iconSize
property alias iconOverwriteColorMenu: iconArea.overwriteColor property alias iconOverwriteColorMenu: iconArea.overwriteColor
property alias iconLayoutDirection : rowArea.layoutDirection property alias iconLayoutDirection : rowArea.layoutDirection
property alias radius: backgroundArea.radius
property var menuItemStyle : MenuItemStyle.normal property var menuItemStyle : MenuItemStyle.normal
onMenuItemStyleChanged: if(!menuItemStyle) menuItemStyle = MenuItemStyle.normal onMenuItemStyleChanged: if(!menuItemStyle) menuItemStyle = MenuItemStyle.normal
property alias textWeight : rowText.font.bold property alias textWeight : rowText.font.bold
property int offsetTopMargin : 0 property int offsetTopMargin : 0
property int offsetBottomMargin : 0 property int offsetBottomMargin : 0
property bool displaySelection: true
property bool isTabBar: false
height:visible?undefined:0 height:visible?undefined:0
Component.onCompleted: menu.width = Math.max(menu.width, implicitWidth) Component.onCompleted: if(!isTabBar) menu.width = Math.max(menu.width, implicitWidth)
background: Rectangle { background: Rectangle {
id: backgroundArea
color: button.down color: button.down
? menuItemStyle.background.color.pressed.color ? menuItemStyle.background.color.pressed.color
: ( : (
@ -40,7 +44,7 @@ Controls.MenuItem {
} }
contentItem:RowLayout{ contentItem:RowLayout{
id:rowArea id:rowArea
spacing:10 spacing: iconArea.icon? 10 : 0
Item{ Item{
Layout.fillHeight: true Layout.fillHeight: true
Layout.preferredWidth: iconArea.icon?height/rowText.lineCount:0 Layout.preferredWidth: iconArea.icon?height/rowText.lineCount:0
@ -66,8 +70,8 @@ Controls.MenuItem {
id:rowText id:rowText
Layout.fillWidth: true Layout.fillWidth: true
Layout.fillHeight: true Layout.fillHeight: true
Layout.leftMargin:(iconLayoutDirection == Qt.LeftToRight ? 0 : menuItemStyle.leftMargin) Layout.leftMargin:(isTabBar || iconLayoutDirection == Qt.LeftToRight ? 0 : menuItemStyle.leftMargin) + (button.checkable ? CheckBoxTextStyle.size : 0)
Layout.rightMargin:(iconLayoutDirection == Qt.LeftToRight ? menuItemStyle.rightMargin : 0) Layout.rightMargin:(!isTabBar && iconLayoutDirection == Qt.LeftToRight ? menuItemStyle.rightMargin : 0)
color: button.enabled color: button.enabled
? (button.down ? (button.down
? menuItemStyle.text.color.pressed.color ? menuItemStyle.text.color.pressed.color
@ -90,10 +94,55 @@ Controls.MenuItem {
verticalAlignment: Text.AlignVCenter verticalAlignment: Text.AlignVCenter
} }
} }
indicator: Rectangle {
visible: button.checkable
border.color: button.down
? CheckBoxTextStyle.color.pressed.color
: (
button.hovered
? CheckBoxTextStyle.color.hovered.color
: (
button.checked
? CheckBoxTextStyle.color.selected.color
: CheckBoxTextStyle.color.normal.color
)
)
implicitHeight: CheckBoxTextStyle.size
implicitWidth: CheckBoxTextStyle.size
radius: CheckBoxTextStyle.radius
x: button.leftPadding
y: parent.height / 2 - height / 2
Rectangle {
color: button.down
? CheckBoxTextStyle.color.pressed.color
: (button.hovered
? CheckBoxTextStyle.color.hovered.color
: (
button.checked
? CheckBoxTextStyle.color.selected.color
: CheckBoxTextStyle.color.normal.color
)
)
height: parent.height - y * 2
width: parent.width - x * 2
radius: CheckBoxTextStyle.radius
visible: button.checked
x: 4 // Fixed, no needed to use style file.
y: 4 // Same thing.
}
}
hoverEnabled: true hoverEnabled: true
MouseArea{ MouseArea{
anchors.fill:parent anchors.fill:parent
visible: button.displaySelection
propagateComposedEvents:true propagateComposedEvents:true
acceptedButtons: Qt.NoButton acceptedButtons: Qt.NoButton
cursorShape: parent.hovered cursorShape: parent.hovered

View file

@ -8,8 +8,8 @@ import ColorsList 1.0
QtObject { QtObject {
property string sectionName: 'SmallButton' property string sectionName: 'SmallButton'
property int leftPadding: 5 property int leftPadding: 10
property int rightPadding: 5 property int rightPadding: 10
property QtObject background: QtObject { property QtObject background: QtObject {
property int height: 22 property int height: 22

View file

@ -30,37 +30,44 @@ Item {
ColumnLayout { ColumnLayout {
anchors.fill:parent anchors.fill:parent
spacing: AccountStatusStyle.verticalSpacing spacing: 0
Item{
Layout.fillHeight: true
Layout.fillWidth: true
}
RowLayout { RowLayout {
Layout.preferredHeight: parent.height / 2 Layout.fillHeight: false
Layout.maximumHeight: parent.height / 2
Layout.maximumWidth: parent.width Layout.maximumWidth: parent.width
Layout.alignment: Qt.AlignBottom | Qt.AlignLeft Layout.alignment: Qt.AlignLeft
spacing: AccountStatusStyle.horizontalSpacing spacing: AccountStatusStyle.horizontalSpacing
Item { Item {
Layout.alignment: !subtitle.visible ? Qt.AlignVCenter | Qt.AlignLeft: Qt.AlignBottom | Qt.AlignLeft Layout.preferredHeight: visible ? AccountStatusStyle.presenceLevel.size : 0
Layout.bottomMargin: AccountStatusStyle.presenceLevel.bottomMargin Layout.preferredWidth: visible ? AccountStatusStyle.presenceLevel.size : 0
Layout.preferredHeight: AccountStatusStyle.presenceLevel.size visible: !accountStatus.noAccountConfigured && (isRegistrated || isProgressing || haveErrors)
Layout.preferredWidth: AccountStatusStyle.presenceLevel.size property bool isRegistrated: AccountSettingsModel.registrationState === AccountSettingsModel.RegistrationStateRegistered
visible: !accountStatus.noAccountConfigured property bool isProgressing: AccountSettingsModel.registrationState === AccountSettingsModel.RegistrationStateInProgress
property bool haveErrors: AccountSettingsModel.registrationState === AccountSettingsModel.RegistrationStateNotRegistered || AccountSettingsModel.registrationState === AccountSettingsModel.RegistrationStateNoProxy
PresenceLevel { PresenceLevel {
id:presenceLevel id:presenceLevel
anchors.fill:parent anchors.fill:parent
level: OwnPresenceModel.presenceStatus===Presence.Offline?Presence.White:( SettingsModel.rlsUriEnabled ? OwnPresenceModel.presenceLevel : Presence.Green) level: OwnPresenceModel.presenceStatus===Presence.Offline?Presence.White:( SettingsModel.rlsUriEnabled ? OwnPresenceModel.presenceLevel : Presence.Green)
visible: AccountSettingsModel.registrationState === AccountSettingsModel.RegistrationStateRegistered visible: parent.isRegistrated
} }
BusyIndicator { BusyIndicator {
id: registrationProcessing
anchors.fill:parent anchors.fill:parent
running: AccountSettingsModel.registrationState === AccountSettingsModel.RegistrationStateInProgress running: parent.isProgressing
color: AccountStatusStyle.busyColor.color color: AccountStatusStyle.busyColor.color
} }
Icon { Icon {
id: registrationError
iconSize: parent.width iconSize: parent.width
icon: 'generic_error' icon: 'generic_error'
visible: AccountSettingsModel.registrationState === AccountSettingsModel.RegistrationStateNotRegistered || AccountSettingsModel.registrationState === AccountSettingsModel.RegistrationStateNoProxy visible: parent.haveErrors
TooltipArea{ TooltipArea{
text : 'Not Registered' text : 'Not Registered'
} }
@ -70,50 +77,47 @@ Item {
Text { Text {
id:username id:username
Layout.fillWidth: true Layout.fillWidth: true
Layout.preferredHeight: accountStatus.noAccountConfigured ? -1 : parent.height / 2
Layout.alignment: !subtitle.visible ? Qt.AlignVCenter | Qt.AlignLeft : Qt.AlignBottom | Qt.AlignLeft
color: AccountStatusStyle.username.colorModel.color color: AccountStatusStyle.username.colorModel.color
elide: Text.ElideRight elide: Text.ElideRight
font.bold: true font.bold: true
font.pointSize: AccountStatusStyle.username.pointSize font.pointSize: AccountStatusStyle.username.pointSize
//: 'No account configured' : Status text when there is no configured account. //: 'No account configured' : Status text when there is no configured account.
text: accountStatus.noAccountConfigured ? qsTr('noAccount'): AccountSettingsModel.username text: accountStatus.noAccountConfigured ? qsTr('noAccount'): AccountSettingsModel.username
verticalAlignment: Text.AlignBottom
wrapMode: Text.WordWrap wrapMode: Text.WordWrap
maximumLineCount: 3 maximumLineCount: 3
} }
Item { Item {
Layout.alignment: !subtitle.visible ? Qt.AlignVCenter | Qt.AlignLeft: Qt.AlignBottom | Qt.AlignLeft Layout.preferredHeight: username.height
Layout.bottomMargin: 5 Layout.preferredWidth: messageCounter.width
Layout.preferredHeight: AccountStatusStyle.presenceLevel.size
Layout.preferredWidth: AccountStatusStyle.presenceLevel.size
visible: !accountStatus.noAccountConfigured visible: !accountStatus.noAccountConfigured
MessageCounter { MessageCounter {
id: messageCounter id: messageCounter
anchors.fill: parent anchors.centerIn: parent
count: CoreManager.eventCount count: CoreManager.eventCount
iconSize: AccountStatusStyle.messageCounter.iconSize
pointSize: AccountStatusStyle.messageCounter.pointSize
MouseArea{ MouseArea{
anchors.fill: parent anchors.fill: parent
onClicked: window.setView('HistoryView') onClicked: window.setView('HistoryView')
} }
} }
} }
Item{//Spacer
Layout.fillHeight: true
Layout.fillWidth: true
}
}//RowLayout }//RowLayout
Text { Text {
id: subtitle id: subtitle
Layout.preferredHeight:parent.height / 2 Layout.fillHeight: true
Layout.maximumHeight:parent.height / 2
Layout.preferredWidth:parent.width Layout.preferredWidth:parent.width
visible: !accountStatus.noAccountConfigured && text != username.text visible: !accountStatus.noAccountConfigured && text != username.text
color: AccountStatusStyle.sipAddress.colorModel.color color: AccountStatusStyle.sipAddress.colorModel.color
elide: Text.ElideRight elide: Text.ElideRight
font.pointSize: AccountStatusStyle.sipAddress.pointSize font.pointSize: AccountStatusStyle.sipAddress.pointSize
text: UtilsCpp.toDisplayString(AccountSettingsModel.sipAddress, SettingsModel.sipDisplayMode) text: UtilsCpp.toDisplayString(AccountSettingsModel.sipAddress, SettingsModel.sipDisplayMode)
verticalAlignment: Text.AlignTop }
Item{
Layout.fillHeight: true
Layout.fillWidth: true
} }
}//ColumnLayout }//ColumnLayout

View file

@ -80,24 +80,22 @@ function sendMessage (text) {
} }
function forwardMessage(chatRoomModel, chatEntry, chatRoomConfig){ function forwardMessage(chatRoomModel, chatEntry, chatRoomConfig){
Qt.callLater(function (){// This avoid to detach virtual window while selecting chatroom/user. This can be the case when we got an address from the smartsearch bar that need to close itself before doing this stuff. window.attachVirtualWindow(Utils.buildCommonDialogUri('ConfirmDialog'), {
window.detachVirtualWindow() flat: true,
window.attachVirtualWindow(Utils.buildCommonDialogUri('ConfirmDialog'), { //: 'Do you want to forward this message?' : text to confirm to forward a message
flat: true, descriptionText: '<b>'+qsTr('confirmForward'),
//: 'Do you want to forward this message?' : text to confirm to forward a message }, function (status) {
descriptionText: '<b>'+qsTr('confirmForward'), if (status) {
}, function (status) { if(!chatRoomModel) {
if (status) { var chat = Linphone.CallsListModel.createChatRoom( chatRoomConfig.subject, chatRoomConfig.haveEncryption, chatRoomConfig.participants, chatRoomConfig.toSelect)
if(!chatRoomModel) { if(chat)
var chat = CallsListModel.createChatRoom( chatRoomConfig.subject, chatRoomConfig.haveEncryption, chatRoomConfig.participants, chatRoomConfig.toSelect) chatRoomModel = chat.chatRoomModel
if(chat)
chatRoomModel = chat.chatRoomModel
}
if(chatRoomModel){
chatRoomModel.forwardMessage(chatEntry)
Linphone.TimelineListModel.select(chatRoomModel)
}
} }
}) if(chatRoomModel){
}) chatRoomModel.forwardMessage(chatEntry)
Linphone.TimelineListModel.select(chatRoomModel)
}
window.detachVirtualWindow()
}
})
} }

View file

@ -46,33 +46,45 @@ Item {
Menu { Menu {
id: messageMenu id: messageMenu
menuStyle : MenuStyle.aux menuStyle : MenuStyle.aux
MenuItem { RowLayout{
id: reactionBar id: reactionBar
property font customFont : SettingsModel.emojiFont property font customFont : SettingsModel.emojiFont
menuItemStyle : MenuItemStyle.aux width: parent.width
contentItem: RowLayout{ height: 50
Layout.fillWidth: true anchors.margins: 10 // Let parent border displayed
spacing:0 spacing: 0
Repeater{
Repeater{
model: ConstantsCpp.reactionsList model: ConstantsCpp.reactionsList
delegate: Text{ delegate: MenuItem{
isTabBar: true
Layout.fillWidth: true Layout.fillWidth: true
horizontalAlignment: Text.AlignHCenter Layout.fillHeight: true
verticalAlignment: Text.AlignVCenter Layout.topMargin: 5
text: modelData Layout.bottomMargin: 5
font.family: reactionBar.customFont.family Layout.leftMargin: 2
font.pointSize: Units.dp * reactionBar.customFont.pointSize * 2 Layout.rightMargin: 2
MouseArea{
radius: messageMenu.radius
down: chatMessageModel && modelData && modelData == chatMessageModel.myReaction
onTriggered: {
chatMessageModel.sendChatReaction(modelData)
messageMenu.close()
}
Text{
id: bodyItem
anchors.fill: parent anchors.fill: parent
onClicked: { horizontalAlignment: Text.AlignHCenter
chatMessageModel.sendChatReaction(modelData) verticalAlignment: Text.AlignVCenter
messageMenu.close() text: modelData
} font.family: reactionBar.customFont.family
font.pointSize: Units.dp * reactionBar.customFont.pointSize * 2
} }
} }
} }
}
} }
MenuItem { MenuItem {
//: 'Copy all' : Text menu to copy all message text into clipboard //: 'Copy all' : Text menu to copy all message text into clipboard
text: (container.lastTextSelected == '' ? qsTr('menuCopyAll') text: (container.lastTextSelected == '' ? qsTr('menuCopyAll')

View file

@ -4,6 +4,7 @@ import QtQml.Models 2.15
import Common 1.0 import Common 1.0
import Linphone 1.0 import Linphone 1.0
import Linphone.Styles 1.0
import Units 1.0 import Units 1.0
@ -23,6 +24,8 @@ Rectangle{
visible: reactionList.count > 0 visible: reactionList.count > 0
property font customFont : SettingsModel.textMessageFont property font customFont : SettingsModel.textMessageFont
property font customEmojiFont : SettingsModel.emojiFont property font customEmojiFont : SettingsModel.emojiFont
border.width: 1
border.color: ChatStyle.colorModel.color
RowLayout{ RowLayout{
id: reactionLayout id: reactionLayout

View file

@ -19,6 +19,8 @@ Rectangle {
// entry should have these functions : presenceStatus, sipAddress, username, avatar (image) // entry should have these functions : presenceStatus, sipAddress, username, avatar (image)
property alias subtitleColor: description.subtitleColor property alias subtitleColor: description.subtitleColor
property alias subtitleIconData: description.subtitleIconData
property alias subtitleText: description.subtitleText
property alias titleColor: description.titleColor property alias titleColor: description.titleColor
property alias statusText : description.statusText property alias statusText : description.statusText
property alias isDarkMode: avatar.isDarkMode property alias isDarkMode: avatar.isDarkMode
@ -76,7 +78,8 @@ Rectangle {
? '' ? ''
: item.username : item.username
: item.username : item.username
isOneToOne: entry==undefined || entry.isOneToOne==undefined || entry.isOneToOne isOneToOne: entry==undefined || (entry.isOneToOne==undefined || entry.isOneToOne) && !entry.conferenceInfoModel || false
//Component.onCompleted: console.log(username + " / " +entry + " / " +entry.conferenceInfoModel)
Icon{ Icon{
anchors.top:parent.top anchors.top:parent.top

View file

@ -12,6 +12,7 @@ Column {
id:mainItem id:mainItem
property alias titleText: title.fullText property alias titleText: title.fullText
property alias subtitleText: subtitle.fullText property alias subtitleText: subtitle.fullText
property QtObject subtitleIconData
property string sipAddress property string sipAddress
property alias statusText : status.text property alias statusText : status.text
@ -96,38 +97,51 @@ Column {
anchors.right: parent.right anchors.right: parent.right
height: (parent.height-parent.topPadding-parent.bottomPadding)/parent.visibleChildren.length height: (parent.height-parent.topPadding-parent.bottomPadding)/parent.visibleChildren.length
visible: subtitle.fullText != '' && subtitle.fullText != title.fullText visible: subtitle.fullText != '' && subtitle.fullText != title.fullText
TextEdit { RowLayout{
id:subtitle
property string fullText
anchors.fill: parent anchors.fill: parent
color: subtitleColor spacing: 0
font.family: SettingsModel.textMessageFont.family Icon {
font.weight: contactDescriptionStyle.subtitle.weight Layout.preferredHeight: subtitleMetrics.height
font.pointSize: contactDescriptionStyle.subtitle.pointSize Layout.preferredWidth: visible ? subtitleMetrics.height : 0
textFormat: Text.RichText Layout.alignment: (title.visible? Qt.AlignTop : Qt.AlignVCenter)
horizontalAlignment: horizontalTextAlignment icon: mainItem.subtitleIconData ? mainItem.subtitleIconData.icon : null
verticalAlignment: (title.visible?Text.AlignTop:Text.AlignVCenter) overwriteColor: mainItem.subtitleIconData ? mainItem.subtitleIconData.colorModel.color: ''
iconSize: visible ? HistoryStyle.entry.event.iconSize : 0
text: UtilsCpp.encodeTextToQmlRichFormat(subtitleMetrics.elidedText, {noLink:true})
onActiveFocusChanged: deselect();
readOnly: true
selectByMouse: true
Text{// Workaround to get implicitWidth from text without eliding
id: subtitleImplicitWidthWorkaround
text: subtitle.fullText
font.weight: subtitle.font.weight
font.pointSize: subtitle.font.pointSize
visible: false
textFormat: Text.RichText
} }
TextEdit {
id:subtitle
property string fullText
Layout.fillWidth: true
Layout.fillHeight: true
color: subtitleColor
font.family: SettingsModel.textMessageFont.family
font.weight: contactDescriptionStyle.subtitle.weight
font.pointSize: contactDescriptionStyle.subtitle.pointSize
textFormat: Text.RichText
horizontalAlignment: horizontalTextAlignment
verticalAlignment: (title.visible?Text.AlignTop:Text.AlignVCenter)
TextMetrics { text: UtilsCpp.encodeTextToQmlRichFormat(subtitleMetrics.elidedText, {noLink:true})
id: subtitleMetrics
font: subtitle.font onActiveFocusChanged: deselect();
text: subtitle.fullText readOnly: true
elideWidth: subtitle.width selectByMouse: true
elide: Qt.ElideRight Text{// Workaround to get implicitWidth from text without eliding
id: subtitleImplicitWidthWorkaround
text: subtitle.fullText
font.weight: subtitle.font.weight
font.pointSize: subtitle.font.pointSize
visible: false
textFormat: Text.RichText
}
TextMetrics {
id: subtitleMetrics
font: subtitle.font
text: subtitle.fullText
elideWidth: subtitle.width
elide: Qt.ElideRight
}
} }
} }
} }

View file

@ -5,6 +5,7 @@ import Common 1.0
import Linphone 1.0 import Linphone 1.0
import Linphone.Styles 1.0 import Linphone.Styles 1.0
import 'qrc:/ui/scripts/Utils/utils.js' as Utils
// ============================================================================= // =============================================================================
Item { Item {
@ -17,7 +18,7 @@ Item {
implicitHeight: counterIcon.height + ContactMessageCounterStyle.verticalMargins * 2 implicitHeight: counterIcon.height + ContactMessageCounterStyle.verticalMargins * 2
implicitWidth: counterIcon.width + ContactMessageCounterStyle.horizontalMargins * 2 implicitWidth: counterIcon.width + ContactMessageCounterStyle.horizontalMargins * 2
visible: count > 0 ?(entry.unreadMessagesCount !== null || entry.missedCallsCount !== null) && displayCounter:false visible: count > 0 ?(entry.unreadMessagesCount !== null) && displayCounter:false
MessageCounter { MessageCounter {
id: counterIcon id: counterIcon
@ -28,10 +29,10 @@ Item {
icon: messageCounter.isComposing icon: messageCounter.isComposing
? ('chat_is_composing_' + counterIcon.composingIndex) ? ('chat_is_composing_' + counterIcon.composingIndex)
: 'chat_count' : ''
visible: messageCounter.count > 0 || messageCounter.isComposing visible: messageCounter.count > 0 || messageCounter.isComposing
count: messageCounter.entry?Number(messageCounter.entry.unreadMessagesCount) + Number(messageCounter.entry.missedCallsCount):0 count: messageCounter.entry?Number(messageCounter.entry.unreadMessagesCount):0
Timer { Timer {
interval: 500 interval: 500

View file

@ -58,15 +58,15 @@ DialogPlus {
return UtilsCpp.hasCapability(entry.sipAddress, LinphoneEnums.FriendCapabilityLimeX3Dh, true) return UtilsCpp.hasCapability(entry.sipAddress, LinphoneEnums.FriendCapabilityLimeX3Dh, true)
}, },
handler: function (entry) { handler: function (entry) {
console.debug("Call selected: " +entry + "/"+entry.sipAddress) console.debug("Entry selected: " +entry + "/"+entry.sipAddress)
smartSearchBar.entryClicked(entry) smartSearchBar.entryClicked(entry)
smartSearchBar.closeMenu()
}, },
}] }]
onEntryClicked: { onEntryClicked: {
console.debug("Call selected from button: " +entry + "/"+entry.sipAddress) console.debug("Entry selected from button: " +entry + "/"+entry.sipAddress)
mainItem.addressSelectedCallback(entry.sipAddress) mainItem.addressSelectedCallback(entry.sipAddress)
mainItem.exit(1)
} }
} }
Text { Text {
@ -108,7 +108,6 @@ DialogPlus {
onEntrySelected:{ onEntrySelected:{
if( entry) { if( entry) {
mainItem.chatRoomSelectedCallback(entry.chatRoomModel) mainItem.chatRoomSelectedCallback(entry.chatRoomModel)
exit(1)
} }
} }
} }

View file

@ -7,16 +7,19 @@ import Linphone.Styles 1.0
import Utils 1.0 import Utils 1.0
import UtilsCpp 1.0 import UtilsCpp 1.0
import 'qrc:/ui/scripts/Utils/utils.js' as Utils
// ============================================================================= // =============================================================================
Row { Row {
id: mainItem id: mainItem
signal entryClicked(var entry) signal entryClicked(var entry)
property var _sipAddressObserver: $historyEntry.sipAddress ? SipAddressesModel.getSipAddressObserver($historyEntry.sipAddress, '') : $historyEntry.title property var sipAddressObserver: $historyEntry.sipAddress ? SipAddressesModel.getSipAddressObserver($historyEntry.sipAddress, '') : $historyEntry.title
property QtObject iconData property QtObject iconData
property string translation property string translation
Component.onDestruction: _sipAddressObserver=null// Need to set it to null because of not calling destructor if not. Component.onDestruction: sipAddressObserver=null// Need to set it to null because of not calling destructor if not.
Component.onCompleted: { Component.onCompleted: {
if ($historyEntry.status == LinphoneEnums.CallStatusSuccess) { if ($historyEntry.status == LinphoneEnums.CallStatusSuccess) {
if(!$historyEntry.isStart){ if(!$historyEntry.isStart){
@ -141,8 +144,8 @@ Row {
height: parent.height height: parent.height
text: $historyEntry && $historyEntry.title text: $historyEntry && $historyEntry.title
? $historyEntry.title ? $historyEntry.title
: _sipAddressObserver : sipAddressObserver
? ( UtilsCpp.getDisplayName(_sipAddressObserver.peerAddress || $historyEntry.sipAddress) || _sipAddressObserver) ? UtilsCpp.getDisplayName(sipAddressObserver.peerAddress || $historyEntry.sipAddress) || sipAddressObserver
: '' : ''
verticalAlignment: Text.AlignVCenter verticalAlignment: Text.AlignVCenter
MouseArea{ MouseArea{

View file

@ -29,13 +29,13 @@
function initView () { function initView () {
history.tryToLoadMoreEntries = false history.tryToLoadMoreEntries = false
history.bindToEnd = true history.bindToStart = true
} }
function loadMoreEntries () { function loadMoreEntries () {
if (history.atYBeginning && !history.tryToLoadMoreEntries) { if (history.atYEnd && !history.tryToLoadMoreEntries) {
history.tryToLoadMoreEntries = true history.tryToLoadMoreEntries = true
history.positionViewAtBeginning() history.positionViewAtEnd()
container.proxyModel.loadMoreEntries() container.proxyModel.loadMoreEntries()
} }
} }
@ -55,11 +55,11 @@ function handleMoreEntriesLoaded (n) {
} }
function handleMovementEnded () { function handleMovementEnded () {
if (history.atYEnd) { if (history.atYBeginning) {
history.bindToEnd = true history.bindToStart = true
} }
} }
function handleMovementStarted () { function handleMovementStarted () {
history.bindToEnd = false history.bindToStart = false
} }

View file

@ -31,7 +31,7 @@ Rectangle {
// ----------------------------------------------------------------------- // -----------------------------------------------------------------------
property bool bindToEnd: false property bool bindToStart: false
property bool tryToLoadMoreEntries: true property bool tryToLoadMoreEntries: true
// ----------------------------------------------------------------------- // -----------------------------------------------------------------------
@ -196,6 +196,6 @@ Rectangle {
repeat: true repeat: true
running: true running: true
onTriggered: history.bindToEnd && history.positionViewAtEnd() onTriggered: history.bindToStart && history.positionViewAtBeginning()
} }
} }

View file

@ -7,7 +7,7 @@ import Linphone.Styles 1.0
Item{ Item{
id: messageCounter id: messageCounter
property bool showOnlyNumber: false property bool showOnlyNumber: backgroundIcon.icon == ''
property int count: 0 property int count: 0
property alias icon: backgroundIcon.icon property alias icon: backgroundIcon.icon
property alias iconSize: amountIcon.iconSize property alias iconSize: amountIcon.iconSize
@ -20,15 +20,15 @@ Item{
Icon { Icon {
id: backgroundIcon id: backgroundIcon
icon: 'chat_count' icon: ''
iconSize: MessageCounterStyle.iconSize.message iconSize: visible ? MessageCounterStyle.iconSize.message : 0
visible: !messageCounter.showOnlyNumber visible: !messageCounter.showOnlyNumber
} }
Icon { Icon {
id: amountIcon id: amountIcon
anchors { anchors {
horizontalCenter: parent.right horizontalCenter: messageCounter.showOnlyNumber ? parent.horizontalCenter : parent.right
verticalCenter: parent.bottom verticalCenter: messageCounter.showOnlyNumber ? parent.verticalCenter : parent.bottom
} }
icon: 'chat_amount' icon: 'chat_amount'
@ -39,6 +39,7 @@ Item{
anchors.centerIn: parent anchors.centerIn: parent
color: MessageCounterStyle.text.colorModel.color color: MessageCounterStyle.text.colorModel.color
font.pointSize: messageCounter.pointSize font.pointSize: messageCounter.pointSize
font.weight: Font.Bold
text: (messageCounter.count>99 ? '+' : messageCounter.count) text: (messageCounter.count>99 ? '+' : messageCounter.count)
} }
} }

View file

@ -84,8 +84,7 @@ SearchBox {
searchBox.launchChat(entry.sipAddress) searchBox.launchChat(entry.sipAddress)
searchBox.closeMenu() searchBox.closeMenu()
}, },
visible: SettingsModel.standardChatEnabled, visible: SettingsModel.standardChatEnabled
zz: 'toto'
}, { }, {
colorSet: SettingsModel.getShowStartChatButton() ? SipAddressesViewStyle.chat : SipAddressesViewStyle.history, colorSet: SettingsModel.getShowStartChatButton() ? SipAddressesViewStyle.chat : SipAddressesViewStyle.history,
secure: 1, secure: 1,

View file

@ -27,7 +27,7 @@ QtObject {
property int pointSize: Units.dp * 11 property int pointSize: Units.dp * 11
} }
property QtObject messageCounter: QtObject { property QtObject messageCounter: QtObject {
property int bottomMargin: 4 property int iconSize: 15
property int size: 16 property int pointSize: Units.dp * 9
} }
} }

View file

@ -0,0 +1,34 @@
pragma Singleton
import QtQml 2.2
import Units 1.0
import ColorsList 1.0
// =============================================================================
QtObject {
property string sectionName: 'CallTimeline'
property var colorModel: ColorsList.add(sectionName+'_bg', 'd')
property QtObject backgroundColor: QtObject {
property var normal: ColorsList.add(sectionName+'_legend_bg_n', 'timeline_header_bg')
}
property int pointSize: Units.dp * 11
property QtObject searchField: QtObject {
property var colorModel: ColorsList.add(sectionName+'_searchField', 'c')
property int pointSize: Units.dp * 9
}
property QtObject filterAction: QtObject {
property int iconSize: 30
property string name : 'filter'
property string icon : 'filter_params_custom'
property var backgroundNormalColor : ColorsList.addImageColor(sectionName+'_'+name+'_bg_n', icon, 'me_n_b_bg')
property var backgroundHoveredColor : ColorsList.addImageColor(sectionName+'_'+name+'_bg_h', icon, 'me_h_b_bg')
property var backgroundPressedColor : ColorsList.addImageColor(sectionName+'_'+name+'_bg_p', icon, 'me_p_b_bg')
property var backgroundUpdatingColor : ColorsList.addImageColor(sectionName+'_'+name+'_bg_u', icon, 'me_p_b_bg')
property var foregroundNormalColor : ColorsList.addImageColor(sectionName+'_'+name+'_fg_n', icon, 'me_n_b_fg')
property var foregroundHoveredColor : ColorsList.addImageColor(sectionName+'_'+name+'_fg_h', icon, 'me_h_b_fg')
property var foregroundPressedColor : ColorsList.addImageColor(sectionName+'_'+name+'_fg_p', icon, 'me_p_b_fg')
property var foregroundUpdatingColor : ColorsList.addImageColor(sectionName+'_'+name+'_fg_u', icon, 'me_p_b_fg')
}
}

View file

@ -52,11 +52,10 @@ QtObject {
property QtObject legend: QtObject { property QtObject legend: QtObject {
property QtObject backgroundColor: QtObject { property QtObject backgroundColor: QtObject {
property var normal: ColorsList.add(sectionName+'_legend_bg_n', 'f') property var normal: ColorsList.add(sectionName+'_legend_bg_n', 'timeline_header_bg')
property var hovered: ColorsList.add(sectionName+'_legend_bg_h', 'c')
} }
property var colorModel: ColorsList.add(sectionName+'_legend', 'd') property var colorModel: ColorsList.add(sectionName+'_legend', 'd')
property int pointSize: Units.dp * 10 property int pointSize: Units.dp * 11
property int height: 30 property int height: 30
property int iconSize: 28 property int iconSize: 28
property int leftMargin: 17 property int leftMargin: 17
@ -97,4 +96,17 @@ QtObject {
property var foregroundHoveredColor : ColorsList.addImageColor(sectionName+'_'+name+'_fg_h', icon, 'me_n_b_fg') property var foregroundHoveredColor : ColorsList.addImageColor(sectionName+'_'+name+'_fg_h', icon, 'me_n_b_fg')
property var foregroundPressedColor : ColorsList.addImageColor(sectionName+'_'+name+'_fg_p', icon, 'me_p_b_fg') property var foregroundPressedColor : ColorsList.addImageColor(sectionName+'_'+name+'_fg_p', icon, 'me_p_b_fg')
} }
property QtObject filterAction: QtObject {
property int iconSize: 30
property string name : 'filter'
property string icon : 'filter_params_custom'
property var backgroundNormalColor : ColorsList.addImageColor(sectionName+'_'+name+'_bg_n', icon, 'me_n_b_bg')
property var backgroundHoveredColor : ColorsList.addImageColor(sectionName+'_'+name+'_bg_h', icon, 'me_h_b_bg')
property var backgroundPressedColor : ColorsList.addImageColor(sectionName+'_'+name+'_bg_p', icon, 'me_p_b_bg')
property var backgroundUpdatingColor : ColorsList.addImageColor(sectionName+'_'+name+'_bg_u', icon, 'me_p_b_bg')
property var foregroundNormalColor : ColorsList.addImageColor(sectionName+'_'+name+'_fg_n', icon, 'me_n_b_fg')
property var foregroundHoveredColor : ColorsList.addImageColor(sectionName+'_'+name+'_fg_h', icon, 'me_h_b_fg')
property var foregroundPressedColor : ColorsList.addImageColor(sectionName+'_'+name+'_fg_p', icon, 'me_p_b_fg')
property var foregroundUpdatingColor : ColorsList.addImageColor(sectionName+'_'+name+'_fg_u', icon, 'me_p_b_fg')
}
} }

View file

@ -60,6 +60,7 @@ singleton StickerStyle 1.0 Sticker/StickerStyle.qml
singleton TelKeypadStyle 1.0 TelKeypad/TelKeypadStyle.qml singleton TelKeypadStyle 1.0 TelKeypad/TelKeypadStyle.qml
singleton CallTimelineStyle 1.0 Timeline/CallTimelineStyle.qml
singleton TimelineStyle 1.0 Timeline/TimelineStyle.qml singleton TimelineStyle 1.0 Timeline/TimelineStyle.qml
singleton ParticipantsListViewStyle 1.0 View/ParticipantsListViewStyle.qml singleton ParticipantsListViewStyle 1.0 View/ParticipantsListViewStyle.qml

View file

@ -0,0 +1,139 @@
import QtQuick 2.7
import QtQuick.Layouts 1.3
import QtQuick.Controls 2.5
import QtQuick.Shapes 1.10
import Common 1.0
import Common.Styles 1.0
import Linphone 1.0
import Linphone.Styles 1.0
import ColorsList 1.0
import UtilsCpp 1.0
import 'Timeline.js' as Logic
import 'qrc:/ui/scripts/Utils/utils.js' as Utils
// =============================================================================
ColumnLayout{
id: mainItem
signal entrySelected(var model)
Layout.fillHeight: true
spacing: 0
// HEADER
Rectangle {
id: legendArea
Layout.preferredWidth: mainItem.width
Layout.preferredHeight: 50
Layout.alignment: Qt.AlignTop
color: CallTimelineStyle.backgroundColor.normal.color
RowLayout{
anchors.fill: parent
spacing: 2
Text {
Layout.preferredHeight: parent.height
Layout.fillWidth: true
Layout.leftMargin: 10
color: CallTimelineStyle.colorModel.color
font.pointSize: CallTimelineStyle.pointSize
font.weight: Font.Bold
//: 'Call list' : Call histories title
text: qsTr('callListTitle')
verticalAlignment: Text.AlignVCenter
}
ActionButton {
id:filterButton
Layout.alignment: Qt.AlignRight
isCustom: true
colorSet: CallTimelineStyle.filterAction
toggled: view.model.filterFlags != 0 && view.model.filterFlags != CallHistoryProxyModel.All
onClicked: filterMenu.open()
Menu{
id: filterMenu
MenuItem{
id: incomingFilter
//: 'Incoming' : Filter label for incoming call
text: qsTr('incomingFilter')
checkable: true
}
MenuItem{
id: outgoingFilter
//: 'Outgoing' : Filter label for outgoing call
text: qsTr('outgoingFilter')
checkable: true
}
MenuItem{
id: missedFilter
//: 'Missed' : Filter label for missed call
text: qsTr('missedFilter')
checkable: true
}
}
}
}
}
// -------------------------------------------------------------------------
// Search.
// -------------------------------------------------------------------------
Rectangle{
id:searchView
Layout.preferredWidth: mainItem.width
Layout.preferredHeight: 50
Layout.alignment: Qt.AlignCenter
color: legendArea.color
TextField {
id:searchBar
anchors.fill: parent
anchors.rightMargin: 10
anchors.leftMargin: 10
anchors.topMargin: 5
anchors.bottomMargin: 10
width: parent.width - 14
icon: text == '' ? 'search_custom' : 'close_custom'
iconSize: 30
overwriteColor: CallTimelineStyle.searchField.colorModel.color
//: 'Search in the list' : ths is a placeholder when searching something in a list
placeholderText: qsTr('searchListPlaceholderText')
onTextChanged: searchDelay.restart()
font.pointSize: CallTimelineStyle.searchField.pointSize
Timer{
id: searchDelay
interval: 600
repeat: false
onTriggered: view.model.filterText = searchBar.text
}
}
}
ScrollableListView {
id: view
Layout.fillHeight: true
Layout.preferredWidth: mainItem.width
currentIndex: -1
model: CallHistoryProxyModel{
filterFlags: (incomingFilter.checked ? CallHistoryProxyModel.Incoming : 0)
| (outgoingFilter.checked ? CallHistoryProxyModel.Outgoing : 0)
| (missedFilter.checked ? CallHistoryProxyModel.Missed : 0)
}
delegate: CallTimelineItem{
callHistoryModel: $modelData
modelIndex: index
Connections{
target: $modelData
onSelectedChanged:{
if(selected) {
view.currentIndex = index;
mainItem.entrySelected(model)
}
}
}
}
}
}

View file

@ -0,0 +1,277 @@
import QtQuick 2.7
import QtQuick.Layouts 1.3
import QtQuick.Controls 2.5
import Common 1.0
import Common.Styles 1.0
import Linphone 1.0
import LinphoneEnums 1.0
import Linphone.Styles 1.0
import ColorsList 1.0
import UtilsCpp 1.0
import 'Timeline.js' as Logic
import 'qrc:/ui/scripts/Utils/utils.js' as Utils
// =============================================================================
Rectangle {
id: mainItem
property CallHistoryModel callHistoryModel
property bool optionsTogglable: true // Right click => display/hide options
property bool optionsToggled: false
property int modelIndex: 0
property var actions: []
height: TimelineStyle.contact.height
width: parent ? parent.width : 0
state: optionsToggled ? 'options' : 'normal'
states: [State {
name: "normal"
}, State {
name: "options"
}
]
transitions: [Transition {
from: 'normal'
to: 'options'
//NumberAnimation { target: contactView; property: 'x'; to:-contactView.width; duration: 200;}
NumberAnimation { target: optionsView; property: 'x'; to:0; duration: 200;}
},
Transition {
from: 'options'
to: 'normal'
//NumberAnimation { target: contactView; property: 'x'; to:0; duration: 200;}
NumberAnimation { target: optionsView; property: 'x'; to:optionsView.width; duration: 200;}
}
]
enabled: !contactView.showBusyIndicator
color: contactView.isSelected
? TimelineStyle.contact.backgroundColor.selected.color
: (
mainItem.modelIndex % 2 == 0
? TimelineStyle.contact.backgroundColor.a.color
: TimelineStyle.contact.backgroundColor.b.color
)
RowLayout{
anchors.fill: parent
anchors.rightMargin: 5
spacing: 0
Contact {
id: contactView
property bool isSelected: mainItem.callHistoryModel != undefined && mainItem.callHistoryModel.selected
Layout.fillHeight: true
Layout.fillWidth: true
color: isSelected
? TimelineStyle.contact.backgroundColor.selected.color
: (
mainItem.modelIndex % 2 == 0
? TimelineStyle.contact.backgroundColor.a.color
: TimelineStyle.contact.backgroundColor.b.color
)
displayUnreadMessageCount: false
entry: mainItem.callHistoryModel && (mainItem.callHistoryModel.conferenceInfoModel && mainItem.callHistoryModel
|| SipAddressesModel.getSipAddressObserver(mainItem.callHistoryModel.remoteAddress, ''))
property var subtitleSelectedColors: TimelineStyle.contact.subtitle.color.selected
property var subtitleNormalColors: TimelineStyle.contact.subtitle.color.normal
property var titleSelectedColors: TimelineStyle.contact.title.color.selected
property var titleNormalColors: TimelineStyle.contact.title.color.normal
function getIconData(){
var iconData
if(!mainItem.callHistoryModel)
return HistoryStyle.entry.event.unknownCallEvent
if (mainItem.callHistoryModel.lastCallStatus == LinphoneEnums.CallStatusSuccess) {
if(!mainItem.callHistoryModel.lastCallIsStart){
iconData = HistoryStyle.entry.event.endedCall
}else if(mainItem.callHistoryModel.lastCallIsOutgoing ){
iconData = HistoryStyle.entry.event.outgoingCall
}else{
iconData = HistoryStyle.entry.event.incomingCall
}
}else if(mainItem.callHistoryModel.lastCallStatus == LinphoneEnums.CallStatusDeclined) {
if(mainItem.callHistoryModel.lastCallIsOutgoing ){
iconData = HistoryStyle.entry.event.declinedOutgoingCall
}else{
iconData = HistoryStyle.entry.event.declinedIncomingCall
}
}else if(mainItem.callHistoryModel.lastCallStatus == LinphoneEnums.CallStatusMissed) {
if(mainItem.callHistoryModel.lastCallIsOutgoing ){
iconData = HistoryStyle.entry.event.missedOutgoingCall
}else{
iconData = HistoryStyle.entry.event.missedIncomingCall
}
}else if(mainItem.callHistoryModel.lastCallStatus == LinphoneEnums.CallStatusAborted) {
if(mainItem.callHistoryModel.lastCallIsOutgoing ){
iconData = HistoryStyle.entry.event.outgoingCall
}else{
iconData = HistoryStyle.entry.event.incomingCall
}
}else if(mainItem.callHistoryModel.lastCallStatus == LinphoneEnums.CallStatusDeclined) {
if(mainItem.callHistoryModel.lastCallIsOutgoing ){
iconData = HistoryStyle.entry.event.declinedOutgoingCall
}else{
iconData = HistoryStyle.entry.event.declinedIncomingCall
}
}else if(mainItem.callHistoryModel.lastCallStatus == LinphoneEnums.CallStatusEarlyAborted) {
if(mainItem.callHistoryModel.lastCallIsOutgoing ){
iconData = HistoryStyle.entry.event.missedOutgoingCall
}else{
iconData = HistoryStyle.entry.event.missedIncomingCall
}
}else if(mainItem.callHistoryModel.lastCallStatus == LinphoneEnums.CallStatusAcceptedElsewhere) {
if(mainItem.callHistoryModel.lastCallIsOutgoing ){
iconData = HistoryStyle.entry.event.outgoingCall
}else{
iconData = HistoryStyle.entry.event.incomingCall
}
}else if(mainItem.callHistoryModel.lastCallStatus == LinphoneEnums.CallStatusDeclinedElsewhere) {
if(mainItem.callHistoryModel.lastCallIsOutgoing ){
iconData = HistoryStyle.entry.event.declinedOutgoingCall
}else{
iconData = HistoryStyle.entry.event.declinedIncomingCall
}
}else {
iconData = HistoryStyle.entry.event.unknownCallEvent
}
return iconData
}
subtitleColor: isSelected
? subtitleSelectedColors.color
: subtitleNormalColors.color
titleColor: isSelected
? titleSelectedColors.color
: titleNormalColors.color
subtitleIconData: getIconData()
subtitleText: mainItem.callHistoryModel && UtilsCpp.toDateTimeString(mainItem.callHistoryModel.lastCallDate, 'yyyy/MM/dd - hh:mm') || ''
MouseArea {
anchors.fill: parent
acceptedButtons: Qt.LeftButton | Qt.RightButton
propagateComposedEvents: true
preventStealing: false
onClicked: {
if(mouse.button == Qt.LeftButton){
if(mainItem.callHistoryModel)
mainItem.callHistoryModel.selectOnly()
}else if(mainItem.optionsTogglable){
mainItem.optionsToggled = !mainItem.optionsToggled
}
}
}
}
ColumnLayout{
spacing: 0
Layout.maximumWidth: statusLayout.count > 0 || unreadMessageCounter.visible ? -1 : 0
Layout.fillHeight: true
RowLayout{
Layout.alignment: Qt.AlignTop | Qt.AlignRight
Layout.fillHeight: true
spacing: 0
ContactMessageCounter {
id: unreadMessageCounter
Layout.alignment: Qt.AlignTop
Layout.preferredWidth: implicitWidth
Layout.preferredHeight: implicitHeight
Layout.rightMargin: 9
displayCounter: SettingsModel.standardChatEnabled || SettingsModel.secureChatEnabled
entry: contactView.entry
}
}
RowLayout{
id: statusLayout
property int count : (ephemeralIcon.visible ? 1 : 0) + (notificationsIcon.visible ? 1 : 0)
spacing: 0
Layout.alignment: Qt.AlignBottom | Qt.AlignRight
Layout.preferredHeight: TimelineStyle.status.iconSize
visible: false //SettingsModel.standardChatEnabled || SettingsModel.secureChatEnabled
Icon{
id: notificationsIcon
Layout.preferredHeight: TimelineStyle.status.iconSize
Layout.preferredWidth: TimelineStyle.status.iconSize
icon: TimelineStyle.disabledNotifications.icon
iconSize: TimelineStyle.status.iconSize
//overwriteColor: mainItem.timelineModel && mainItem.timelineModel.selected ? TimelineStyle.disabledNotifications.selectedColorModel.color : TimelineStyle.disabledNotifications.colorModel.color
//visible: mainItem.timelineModel && !mainItem.timelineModel.chatRoomModel.notificationsEnabled
}
Icon{
id: ephemeralIcon
Layout.preferredHeight: TimelineStyle.status.iconSize
Layout.preferredWidth: TimelineStyle.status.iconSize
icon: TimelineStyle.ephemeralTimer.icon
iconSize: TimelineStyle.status.iconSize
//overwriteColor: mainItem.timelineModel && mainItem.timelineModel.selected ? TimelineStyle.ephemeralTimer.selectedTimerColor.color : TimelineStyle.ephemeralTimer.timerColor.color
//visible: mainItem.timelineModel && mainItem.timelineModel.chatRoomModel.ephemeralEnabled
}
}
}
}
RowLayout{
anchors.fill: parent
anchors.rightMargin: 5
visible: mainItem.actions.length > 0
Item{// Spacer
Layout.fillHeight: true
Layout.fillWidth: true
}
Repeater {
model: mainItem.actions
ActionButton {
isCustom: true
backgroundRadius: 90
colorSet: modelData.colorSet
visible: modelData.visible
onClicked: {
if( mainItem.callHistoryModel)
mainItem.actions[index].handler( // Do not use modelData on functions
mainItem.callHistoryModel
)
}
}
}
}
Item{
id: optionsView
height: mainItem.height
width: mainItem.width
x:width
visible: x!=width
RowLayout{
anchors.fill: parent
MouseArea {
Layout.fillHeight: true
Layout.fillWidth: true
onClicked: {
if(mainItem.optionsTogglable)
mainItem.optionsToggled = !mainItem.optionsToggled
}
}
Rectangle{
Layout.fillHeight: true
Layout.preferredWidth: optionsLayout.width
color: contactView.color
MouseArea {// Grabber
anchors.fill: parent
cursorShape: Qt.ArrowCursor
}
RowLayout{
id: optionsLayout
anchors.centerIn: parent
}
}
}
}
}

View file

@ -29,7 +29,7 @@ Rectangle {
property var actions: [] property var actions: []
// --------------------------------------------------------------------------- // ---------------------------------------------------------------------------
signal entrySelected (TimelineModel entry) signal entrySelected (var entry)
signal showHistoryRequest() signal showHistoryRequest()
// --------------------------------------------------------------------------- // ---------------------------------------------------------------------------
@ -40,7 +40,6 @@ Rectangle {
anchors.fill: parent anchors.fill: parent
spacing: 0 spacing: 0
// ------------------------------------------------------------------------- // -------------------------------------------------------------------------
Connections { Connections {
@ -56,254 +55,47 @@ Rectangle {
// ------------------------------------------------------------------------- // -------------------------------------------------------------------------
// Legend. // Legend.
// ------------------------------------------------------------------------- // -------------------------------------------------------------------------
Rectangle { Rectangle {
id: legendArea id: legendArea
Layout.fillWidth: true Layout.preferredWidth: timeline.width
Layout.preferredHeight: TimelineStyle.legend.height Layout.preferredHeight: 50
Layout.alignment: Qt.AlignTop Layout.alignment: Qt.AlignTop
color: showHistory.containsMouse?TimelineStyle.legend.backgroundColor.hovered.color:TimelineStyle.legend.backgroundColor.normal.color color: TimelineStyle.legend.backgroundColor.normal.color
visible: showHistoryButton || showFiltersButtons
MouseArea{// no more showing history
id:showHistory
anchors.fill:parent
visible: showFiltersButtons
onClicked: {
timeline.showFilterView = !timeline.showFilterView
}
}
RowLayout{ RowLayout{
anchors.fill:parent anchors.fill: parent
spacing:TimelineStyle.legend.spacing
Text { Text {
Layout.preferredHeight: parent.height Layout.preferredHeight: parent.height
Layout.fillWidth: true Layout.fillWidth: true
Layout.leftMargin: TimelineStyle.legend.leftMargin Layout.leftMargin: 10
visible: showFiltersButtons
color: TimelineStyle.legend.colorModel.color color: TimelineStyle.legend.colorModel.color
font.pointSize: TimelineStyle.legend.pointSize font.pointSize: TimelineStyle.legend.pointSize
//: A title for filtering mode. font.weight: Font.Bold
text: qsTr('timelineFilter')+' : ' //: 'Messages' : Title for conversations
+(timeline.model.filterFlags == 0 || timeline.model.filterFlags == TimelineProxyModel.AllChatRooms text: qsTr('chatsTitle')
//: 'All' The mode for timelines filtering.
? qsTr('timelineFilterAll')
//: 'Custom' The mode for timelines filtering.
: qsTr('timelineFilterCustom'))
verticalAlignment: Text.AlignVCenter verticalAlignment: Text.AlignVCenter
} }
Icon { ActionButton {
id:filterButton id:filterButton
Layout.alignment: Qt.AlignRight Layout.alignment: Qt.AlignRight
icon: 'filter_params_custom' isCustom: true
iconSize: TimelineStyle.legend.iconSize colorSet: TimelineStyle.filterAction
overwriteColor: TimelineStyle.legend.colorModel.color toggled: view.model.filterFlags != 0 && view.model.filterFlags != TimelineProxyModel.AllChatRooms
visible: showFiltersButtons onClicked: filterMenu.open()
MouseArea{ Menu{
anchors.fill:parent id: filterMenu
onClicked:{ MenuItem{
timeline.showFilterView = !timeline.showFilterView id: secureFilter
//: 'Secure rooms' : Filter item. Selecting it will show all secure rooms.
text: qsTr('timelineFilterSecureRooms')
checkable: true
}
MenuItem{
id: chatGroupFilter
//: 'Chat groups' : Filter item. Selecting it will show all chat groups (with more than one participant).
text: qsTr('timelineFilterChatGroups')
checkable: true
} }
}
}
MouseArea{
Layout.alignment: Qt.AlignRight
Layout.fillHeight: true
Layout.preferredWidth: TimelineStyle.legend.iconSize
visible: showFiltersButtons
onClicked:{
searchView.visible = !searchView.visible
}
Icon {
id:searchButton
anchors.verticalCenter: parent.verticalCenter
anchors.horizontalCenter: parent.horizontalCenter
property bool searching: searchView.visible
icon: (searchView.visible? 'close_custom': 'search_custom')
iconSize: TimelineStyle.legend.iconSize
overwriteColor: TimelineStyle.legend.colorModel.color
}
}
MouseArea{
Layout.alignment: Qt.AlignRight
Layout.rightMargin: TimelineStyle.legend.lastRightMargin
Layout.fillHeight: true
Layout.preferredWidth: TimelineStyle.legend.iconSize
visible: timeline.showHistoryButton
onClicked:{
showHistoryRequest()
}
Icon {
id:callHistoryButton
anchors.verticalCenter: parent.verticalCenter
anchors.horizontalCenter: parent.horizontalCenter
property bool searching: searchView.visible
icon: 'call_history_custom'
iconSize: TimelineStyle.legend.iconSize
overwriteColor: TimelineStyle.legend.colorModel.color
}
}
}
}
// -------------------------------------------------------------------------
// Filter.
// -------------------------------------------------------------------------
Rectangle{
id:exhaustiveFilterView
Layout.fillWidth: true
Layout.preferredHeight: filterChoices.height
Layout.alignment: Qt.AlignCenter
border.color: TimelineStyle.filterField.borderColor.color
border.width: 2
visible: timeline.showFilterView && !SettingsModel.useMinimalTimelineFilter
ColumnLayout{
id:filterChoices
anchors.leftMargin: 20
anchors.left:parent.left
anchors.right:parent.right
spacing:-4
function getFilterFlags(){
return secureFilter.model.get(secureFilter.currentIndex).value | groupFilter.model.get(groupFilter.currentIndex).value | ephemeralsFilter.model.get(ephemeralsFilter.currentIndex).value;
}
ComboBox {
Layout.fillWidth: true
id:secureFilter
currentIndex: 0
onCurrentIndexChanged: timeline.model.filterFlags = filterChoices.getFilterFlags()
textRole: "key"
model: ListModel {
ListElement {
//: 'All security levels' : Filter item. Selecting it will not do any filter on security level.
key: qsTr('timelineFilterAllSecureLevelRooms'); value: 0}
ListElement {
//: 'Standard rooms' : Filter item. Selecting it will show all simple rooms.
key: qsTr('timelineFilterStandardRooms'); value: TimelineProxyModel.StandardChatRoom}
ListElement {
//: 'Secure rooms' : Filter item. Selecting it will show all secure rooms.
key: qsTr('timelineFilterSecureRooms'); value: TimelineProxyModel.SecureChatRoom}
}
haveBorder: false
haveMargin: false
backgroundColor: 'transparent'
visible: SettingsModel.secureChatEnabled && SettingsModel.standardChatEnabled
}
ComboBox {
Layout.fillWidth: true
id:groupFilter
currentIndex: 0
onCurrentIndexChanged: timeline.model.filterFlags = filterChoices.getFilterFlags()
textRole: "key"
model: ListModel {
ListElement {
//: 'Any conversations' : Filter item. Selecting it will not do any filter on the type of conversations.
key: qsTr('timelineFilterAnyChatRooms'); value: 0}
ListElement {
//: 'Simple rooms' : Filter item. Selecting it will show all secure chat groups (with more than one participant).
key: qsTr('timelineFilterSimpleRooms'); value: TimelineProxyModel.SimpleChatRoom}
ListElement {
//: 'Chat groups' : Filter item. Selecting it will show all chat groups (with more than one participant).
key: qsTr('timelineFilterChatGroups'); value: TimelineProxyModel.GroupChatRoom}
}
haveBorder: false
haveMargin: false
backgroundColor: 'transparent'
visible: SettingsModel.secureChatEnabled || SettingsModel.standardChatEnabled
}
ComboBox {
Layout.fillWidth: true
id:ephemeralsFilter
currentIndex: 0
onCurrentIndexChanged: timeline.model.filterFlags = filterChoices.getFilterFlags()
textRole: "key"
model: ListModel {
ListElement {
//: 'Ephemerals on/off' : Filter item. Selecting it will not do any filter on ephemerals activation.
key: qsTr('timelineFilterAnyEphemerals'); value: 0}
ListElement {
//: 'No Ephemerals' : Filter item. Selecting it will hide all chat rooms where the ephemeral mode has been enabled.
key: qsTr('timelineFilterNoEphemerals'); value: TimelineProxyModel.NoEphemeralChatRoom}
ListElement {
//: 'Ephemerals' : Filter item. Selecting it will show all chat rooms where the ephemeral mode has been enabled.
key: qsTr('timelineFilterEphemerals'); value: TimelineProxyModel.EphemeralChatRoom}
}
haveBorder: false
haveMargin: false
backgroundColor: 'transparent'
visible: SettingsModel.secureChatEnabled || SettingsModel.standardChatEnabled
}
}
}
Rectangle{
id:minimalFilterView
Layout.fillWidth: true
Layout.preferredHeight: minimalFilterChoices.height
Layout.alignment: Qt.AlignCenter
border.color: TimelineStyle.filterField.borderColor.color
border.width: 2
visible: timeline.showFilterView && SettingsModel.useMinimalTimelineFilter
ColumnLayout{
id:minimalFilterChoices
anchors.leftMargin: 20
anchors.left:parent.left
anchors.right:parent.right
spacing:-4
function getFilterFlags(){
return securedCheckBox.getValue() | groupCheckBox.getValue() | conferenceCheckBox.getValue();
}
CheckBoxText {
id: securedCheckBox
Layout.fillWidth: true
visible: SettingsModel.secureChatEnabled && SettingsModel.standardChatEnabled
//: 'Secure rooms' : Filter item. Selecting it will show all secure rooms.
text: qsTr('timelineFilterSecureRooms')
onClicked: {
timeline.model.filterFlags = minimalFilterChoices.getFilterFlags()
}
function getValue(){
if( checked)
return TimelineProxyModel.SecureChatRoom
else
return 0
}
}
CheckBoxText {
id: groupCheckBox
Layout.fillWidth: true
visible: SettingsModel.secureChatEnabled || SettingsModel.standardChatEnabled
//: 'Chat groups' : Filter item. Selecting it will show all chat groups (with more than one participant).
text: qsTr('timelineFilterChatGroups')
onClicked: {
timeline.model.filterFlags = minimalFilterChoices.getFilterFlags()
}
function getValue(){
if( checked)
return TimelineProxyModel.GroupChatRoom
else
return 0
}
}
CheckBoxText {
id: conferenceCheckBox
Layout.fillWidth: true
visible: false
//: 'Conferences' : Filter item. Selecting it will show all conferences.
text: qsTr('timelineFilterConferences')
onClicked: {
timeline.model.filterFlags = minimalFilterChoices.getFilterFlags()
}
function getValue(){
return 0
} }
} }
} }
@ -314,25 +106,16 @@ Rectangle {
Rectangle{ Rectangle{
id:searchView id:searchView
Layout.fillWidth: true Layout.fillWidth: true
Layout.preferredHeight: 40 Layout.preferredHeight: 50
Layout.alignment: Qt.AlignCenter Layout.alignment: Qt.AlignCenter
border.color: TimelineStyle.searchField.borderColor.color color: legendArea.color
border.width: 2
visible:false
onVisibleChanged: if(visible){
timeline.model.filterText = searchBar.text
searchBar.forceActiveFocus()
}else{
timeline.model.filterText = ''
}
TextField { TextField {
id:searchBar id:searchBar
anchors.fill: parent anchors.fill: parent
anchors.rightMargin: 7 anchors.rightMargin: 10
anchors.leftMargin: 7 anchors.leftMargin: 10
anchors.topMargin: 5 anchors.topMargin: 5
anchors.bottomMargin: 5 anchors.bottomMargin: 10
width: parent.width - 14 width: parent.width - 14
icon: text == '' ? 'search_custom' : 'close_custom' icon: text == '' ? 'search_custom' : 'close_custom'
iconSize: 30 iconSize: 30
@ -360,12 +143,18 @@ Rectangle {
Layout.fillHeight: true Layout.fillHeight: true
Layout.fillWidth: true Layout.fillWidth: true
currentIndex: -1 currentIndex: -1
model: TimelineProxyModel{
listSource: TimelineProxyModel.Main
filterFlags: (secureFilter.checked ? TimelineProxyModel.SecureChatRoom : 0)
| (chatGroupFilter.checked ? TimelineProxyModel.GroupChatRoom : 0)
}
delegate: TimelineItem{ delegate: TimelineItem{
timelineModel: $modelData timelineModel: $modelData
modelIndex: index modelIndex: index
optionsTogglable: timeline.optionsTogglable optionsTogglable: timeline.optionsTogglable
actions: timeline.actions actions: timeline.actions
Connections{ Connections{
target: $modelData target: $modelData
onSelectedChanged:{ onSelectedChanged:{

View file

@ -100,7 +100,8 @@ Rectangle {
preventStealing: false preventStealing: false
onClicked: { onClicked: {
if(mouse.button == Qt.LeftButton){ if(mouse.button == Qt.LeftButton){
mainItem.timelineModel.selected = true if(mainItem.timelineModel)
mainItem.timelineModel.selected = true
}else if(mainItem.optionsTogglable){ }else if(mainItem.optionsTogglable){
mainItem.optionsToggled = !mainItem.optionsToggled mainItem.optionsToggled = !mainItem.optionsToggled
} }
@ -172,9 +173,10 @@ Rectangle {
visible: modelData.visible visible: modelData.visible
onClicked: { onClicked: {
mainItem.actions[index].handler( // Do not use modelData on functions if( mainItem.timelineModel)
mainItem.timelineModel mainItem.actions[index].handler( // Do not use modelData on functions
) mainItem.timelineModel
)
} }
} }
@ -225,7 +227,7 @@ Rectangle {
id: deleteButton id: deleteButton
Layout.alignment: Qt.AlignCenter Layout.alignment: Qt.AlignCenter
Layout.rightMargin: 6 Layout.rightMargin: 6
visible: mainItem.timelineModel
isCustom: true isCustom: true
colorSet: contactView.isSelected ? TimelineStyle.selectedDeleteAction : TimelineStyle.deleteAction colorSet: contactView.isSelected ? TimelineStyle.selectedDeleteAction : TimelineStyle.deleteAction
onClicked: window.attachVirtualWindow(Utils.buildCommonDialogUri('ConfirmDialog'), { onClicked: window.attachVirtualWindow(Utils.buildCommonDialogUri('ConfirmDialog'), {
@ -233,7 +235,8 @@ Rectangle {
descriptionText: qsTr('deleteTimeline'), descriptionText: qsTr('deleteTimeline'),
}, function (status) { }, function (status) {
if (status) { if (status) {
mainItem.timelineModel.chatRoomModel.deleteChatRoom() if( mainItem.timelineModel)
mainItem.timelineModel.chatRoomModel.deleteChatRoom()
} }
}) })
TooltipArea { TooltipArea {

View file

@ -65,6 +65,8 @@ Sticker 1.0 Sticker/Sticker.qml
TelKeypad 1.0 TelKeypad/TelKeypad.qml TelKeypad 1.0 TelKeypad/TelKeypad.qml
CallTimeline 1.0 Timeline/CallTimeline.qml
CallTimelineItem 1.0 Timeline/CallTimelineItem.qml
Timeline 1.0 Timeline/Timeline.qml Timeline 1.0 Timeline/Timeline.qml
TimelineItem 1.0 Timeline/TimelineItem.qml TimelineItem 1.0 Timeline/TimelineItem.qml

View file

@ -522,6 +522,12 @@ function genRandomNumber (min, max) {
return Math.random() * (max - min) + min return Math.random() * (max - min) + min
} }
function genRandomColor(){
return '#'+ Math.floor(Math.random()*255).toString(16)
+Math.floor(Math.random()*255).toString(16)
+Math.floor(Math.random()*255).toString(16)
}
// ----------------------------------------------------------------------------- // -----------------------------------------------------------------------------
// Generate a random number between a set of intervals. // Generate a random number between a set of intervals.

View file

@ -0,0 +1,43 @@
import QtQuick 2.7
import QtQuick.Layouts 1.3
import Clipboard 1.0
import Common 1.0
import Linphone 1.0
import Utils 1.0
import UtilsCpp 1.0
import LinphoneEnums 1.0
import App.Styles 1.0
import Common.Styles 1.0
import Linphone.Styles 1.0
import Units 1.0
import ColorsList 1.0
import 'Conversation.js' as Logic
// =============================================================================
RowLayout{
spacing: 0
CallTimeline{
Layout.fillHeight: true
Layout.preferredWidth: MainWindowStyle.menu.width
onEntrySelected:{
content.setSource('HistoryView.qml', {
callHistoryModel: model
})
}
}
Loader{
id: content
Layout.fillHeight: true
Layout.fillWidth: true
}
}

View file

@ -34,7 +34,7 @@ Item{
anchors.fill: parent anchors.fill: parent
verticalAlignment: Qt.AlignVCenter verticalAlignment: Qt.AlignVCenter
anchors.leftMargin: 40 anchors.leftMargin: 28
color: ConferencesStyle.bar.text.colorModel.color color: ConferencesStyle.bar.text.colorModel.color
font { font {
@ -44,6 +44,25 @@ Item{
//: 'Meetings' : Conference list title. //: 'Meetings' : Conference list title.
text: qsTr('conferencesTitle') text: qsTr('conferencesTitle')
} }
TextButtonB {
anchors.verticalCenter: parent.verticalCenter
anchors.right: parent.right
anchors.rightMargin: 10
addHeight: 10
addWidth: 80
//: 'Create Meeting' : Button label to create a meeting
text: qsTr('createMeeting')
capitalization: Font.Capitalize
onClicked: {
window.detachVirtualWindow()
window.attachVirtualWindow(Utils.buildAppDialogUri('NewConference')
,{}, function (status) {
if( status){
setView('Conferences')
}
})
}
}
} }
Rectangle { Rectangle {
Layout.fillWidth: true Layout.fillWidth: true

View file

@ -9,6 +9,7 @@ import LinphoneEnums 1.0
import App.Styles 1.0 import App.Styles 1.0
import 'qrc:/ui/scripts/Utils/utils.js' as Utils
// ============================================================================= // =============================================================================
ColumnLayout { ColumnLayout {
@ -41,10 +42,26 @@ ColumnLayout {
rightMargin: ContactsStyle.bar.rightMargin rightMargin: ContactsStyle.bar.rightMargin
} }
spacing: ContactsStyle.spacing spacing: ContactsStyle.spacing
Text {
Layout.preferredHeight: parent.height
Layout.preferredWidth: contentWidth
Layout.leftMargin: 10
color: ContactsStyle.bar.foregroundColor.color
font.pointSize: ContactsStyle.bar.pointSize
font.weight: Font.Bold
font.capitalization: Font.Capitalize
text: LdapListModel.count > 0
//: 'Local contacts' : Contacts section label in main window when we have to specify that they are local to the application.
? qsTr('localContactsEntry')
//: 'Contacts' : Contacts section label in main waindow.
: qsTr('contactsEntry')
verticalAlignment: Text.AlignVCenter
}
TextField { TextField {
Layout.fillWidth: true Layout.fillWidth: true
icon: ContactsStyle.filter.icon icon: ContactsStyle.filter.icon
iconSize: 35
overwriteColor: ContactsStyle.filter.colorModel.color overwriteColor: ContactsStyle.filter.colorModel.color
placeholderText: qsTr('searchContactPlaceholder') placeholderText: qsTr('searchContactPlaceholder')
@ -53,16 +70,24 @@ ColumnLayout {
ExclusiveButtons { ExclusiveButtons {
texts: [ texts: [
//: 'All' : Filter label to display all items.
qsTr('selectAllContacts'), qsTr('selectAllContacts'),
qsTr('selectConnectedContacts') //: 'Online' : Filter label to display only online contacts.
qsTr('selectOnlineContacts')
] ]
capitalization: Font.AllUppercase
onClicked: contacts.useConnectedFilter = !!button onClicked: contacts.useOnlineFilter = !!button
}
Item{
Layout.fillHeight: true
Layout.fillWidth: true
} }
TextButtonB { TextButtonB {
addHeight: 15 Layout.leftMargin: 20
text: qsTr('addContact') addHeight: 10
addWidth: 80
text: qsTr('addContact').toLowerCase()
capitalization: Font.Capitalize
onClicked: window.setView('ContactEdit') onClicked: window.setView('ContactEdit')
} }
} }
@ -209,17 +234,26 @@ ColumnLayout {
target: lastChatRoom target: lastChatRoom
onStateChanged: if(state === 1) { onStateChanged: if(state === 1) {
console.debug("Load conversation from contacts") console.debug("Load conversation from contacts")
window.setView('Conversation', { window.setView('Conversation')
chatRoomModel: lastChatRoom
})
} }
} }
readonly property var handlers: [ readonly property var handlers: [
CallsListModel.launchVideoCall, CallsListModel.launchVideoCall,
CallsListModel.launchAudioCall, CallsListModel.launchAudioCall,
function (sipAddress) {CallsListModel.launchChat( sipAddress,0 )}, function (sipAddress) {
function (sipAddress) {CallsListModel.launchChat( sipAddress,1 )} var model = CallsListModel.launchChat( sipAddress,0 )
if(model && model.chatRoomModel) {
lastChatRoom = model.chatRoomModel
window.setView('Conversations')
}
},
function (sipAddress) {
var model = CallsListModel.launchChat( sipAddress,1 )
if(model && model.chatRoomModel) {
lastChatRoom = model.chatRoomModel
window.setView('Conversations')
}}
] ]
model: handlers model: handlers

View file

@ -582,28 +582,13 @@ ColumnLayout {
topWidth: ConversationStyle.filters.border.topWidth topWidth: ConversationStyle.filters.border.topWidth
visible: chatRoomModel && (!chatRoomModel.haveEncryption && SettingsModel.standardChatEnabled || chatRoomModel.haveEncryption && SettingsModel.secureChatEnabled) visible: chatRoomModel && (!chatRoomModel.haveEncryption && SettingsModel.standardChatEnabled || chatRoomModel.haveEncryption && SettingsModel.secureChatEnabled)
ExclusiveButtons {
id: filterButtons
anchors {
left: parent.left
leftMargin: ConversationStyle.filters.leftMargin
verticalCenter: parent.verticalCenter
}
texts: [
qsTr('displayCallsAndMessages'),
qsTr('displayCalls'),
qsTr('displayMessages')
]
onClicked: Logic.updateChatFilter(button)
}
BusyIndicator{ BusyIndicator{
id: chatLoading id: chatLoading
width: 20 width: 20
height: 20 height: 20
anchors.left: filterButtons.right anchors.left: parent.left
anchors.leftMargin: 50 anchors.leftMargin: parent.width/3
anchors.verticalCenter: parent.verticalCenter anchors.verticalCenter: parent.verticalCenter
color: BusyIndicatorStyle.alternateColor.color color: BusyIndicatorStyle.alternateColor.color
running: chatArea.tryingToLoadMoreEntries running: chatArea.tryingToLoadMoreEntries
@ -654,6 +639,7 @@ ColumnLayout {
} }
width: parent.width-14 width: parent.width-14
icon: text != '' ? 'close_custom' : 'search_custom' icon: text != '' ? 'close_custom' : 'search_custom'
iconSize: 30
overwriteColor: ConversationStyle.filters.iconColor.color overwriteColor: ConversationStyle.filters.iconColor.color
//: 'Search in messages' : this is a placeholder when searching something in the timeline list //: 'Search in messages' : this is a placeholder when searching something in the timeline list
placeholderText: qsTr('searchMessagesPlaceholder') placeholderText: qsTr('searchMessagesPlaceholder')

Some files were not shown because too many files have changed in this diff Show more