diff --git a/linphone-app/CMakeLists.txt b/linphone-app/CMakeLists.txt
index 709cd1ead..3bc9420ae 100644
--- a/linphone-app/CMakeLists.txt
+++ b/linphone-app/CMakeLists.txt
@@ -138,6 +138,8 @@ set(SOURCES
src/components/core/event-count-notifier/AbstractEventCountNotifier.cpp
src/components/file/FileDownloader.cpp
src/components/file/FileExtractor.cpp
+ src/components/history/HistoryModel.cpp
+ src/components/history/HistoryProxyModel.cpp
src/components/notifier/Notifier.cpp
src/components/other/clipboard/Clipboard.cpp
src/components/other/colors/Colors.cpp
@@ -198,6 +200,8 @@ set(HEADERS
src/components/core/event-count-notifier/AbstractEventCountNotifier.hpp
src/components/file/FileDownloader.hpp
src/components/file/FileExtractor.hpp
+ src/components/history/HistoryModel.hpp
+ src/components/history/HistoryProxyModel.hpp
src/components/notifier/Notifier.hpp
src/components/other/clipboard/Clipboard.hpp
src/components/other/colors/Colors.hpp
diff --git a/linphone-app/assets/languages/da.ts b/linphone-app/assets/languages/da.ts
index 589bf7cb0..8309e0067 100644
--- a/linphone-app/assets/languages/da.ts
+++ b/linphone-app/assets/languages/da.ts
@@ -830,6 +830,25 @@ Server url ikke konfigureret.
Det er nødvendigt at genstarte applikationen. Vil du gøre det nu?
+
+ HistoryView
+
+ removeAllEntriesDescription
+ Er du sikker på at du vil rydde op historikken?
+
+
+ tooltipContactEdit
+ Rediger kontakt
+
+
+ tooltipContactAdd
+ Tilføj kontakt
+
+
+ cleanHistory
+ Slet historik
+
+
Home
diff --git a/linphone-app/assets/languages/de.ts b/linphone-app/assets/languages/de.ts
index 8bd3dcf5c..a616dde32 100644
--- a/linphone-app/assets/languages/de.ts
+++ b/linphone-app/assets/languages/de.ts
@@ -830,6 +830,25 @@ Server URL ist nicht konfiguriert.
Ein Neustart der Anwendung ist notwendig. Möchten Sie die Anwendung jetzt neu starten?
+
+ HistoryView
+
+ removeAllEntriesDescription
+ Möchten Sie diese Historie wirklich löschen?
+
+
+ tooltipContactEdit
+ Kontakt bearbeiten
+
+
+ tooltipContactAdd
+ Kontakt hinzufügen
+
+
+ cleanHistory
+ Verlauf löschen
+
+
Home
diff --git a/linphone-app/assets/languages/en.ts b/linphone-app/assets/languages/en.ts
index 393afd92d..1dcd7d652 100644
--- a/linphone-app/assets/languages/en.ts
+++ b/linphone-app/assets/languages/en.ts
@@ -832,6 +832,25 @@ Server URL not configured.
It is necessary to restart the application. Do you want to restart now?
+
+ HistoryView
+
+ removeAllEntriesDescription
+ Are you sure you want to clear this history?
+
+
+ tooltipContactEdit
+ Edit contact
+
+
+ tooltipContactAdd
+ Add contact
+
+
+ cleanHistory
+ Delete history
+
+
Home
diff --git a/linphone-app/assets/languages/es.ts b/linphone-app/assets/languages/es.ts
index e40aa9bbf..4b035a9f5 100644
--- a/linphone-app/assets/languages/es.ts
+++ b/linphone-app/assets/languages/es.ts
@@ -830,6 +830,25 @@ URL del servidor no configurada.
Es necesario reiniciar la aplicación. ¿Desea reiniciarla ahora?
+
+ HistoryView
+
+ removeAllEntriesDescription
+ ¿Estás seguro de que quieres limpiar este historial?
+
+
+ tooltipContactEdit
+ Editar contacto
+
+
+ tooltipContactAdd
+ Añadir contacto
+
+
+ cleanHistory
+ Eliminar historial
+
+
Home
diff --git a/linphone-app/assets/languages/fr_FR.ts b/linphone-app/assets/languages/fr_FR.ts
index 4fca75aed..7d9db2d5b 100644
--- a/linphone-app/assets/languages/fr_FR.ts
+++ b/linphone-app/assets/languages/fr_FR.ts
@@ -830,6 +830,25 @@ Url du serveur non configurée.
Voulez-vous redémarrer maintenant pour prendre en compte ces modifications ?
+
+ HistoryView
+
+ removeAllEntriesDescription
+ Êtes-vous sûr de vouloir supprimer cet historique ?
+
+
+ tooltipContactEdit
+ Editer le contact
+
+
+ tooltipContactAdd
+ Ajouter le contact
+
+
+ cleanHistory
+ Supprimer l'historique
+
+
Home
diff --git a/linphone-app/assets/languages/hu.ts b/linphone-app/assets/languages/hu.ts
index 27c3c8924..7f2596d6e 100644
--- a/linphone-app/assets/languages/hu.ts
+++ b/linphone-app/assets/languages/hu.ts
@@ -830,6 +830,25 @@ A kiszolgáló URL-je nincs konfigurálva.
Az alkalmazás újraindítása szükséges. Szeretné most újraindítani?
+
+ HistoryView
+
+ removeAllEntriesDescription
+ Biztosan törölni kívánja ezt az előzményt?
+
+
+ tooltipContactEdit
+ Kapcsolat szerkesztése
+
+
+ tooltipContactAdd
+ Kapcsolat hozzáadása
+
+
+ cleanHistory
+ Előzmények törlése
+
+
Home
diff --git a/linphone-app/assets/languages/it.ts b/linphone-app/assets/languages/it.ts
index b03a0227d..929c7e0ce 100644
--- a/linphone-app/assets/languages/it.ts
+++ b/linphone-app/assets/languages/it.ts
@@ -830,6 +830,25 @@ URL del server non configurato.
È necessario riavviare l'applicazione. Vuoi riavviare ora?
+
+ HistoryView
+
+ removeAllEntriesDescription
+ Sei sicuro di voler cancellare questa cronologia?
+
+
+ tooltipContactEdit
+ Modifica contatto
+
+
+ tooltipContactAdd
+ Aggiungi contatto
+
+
+ cleanHistory
+ Cancella cronologia
+
+
Home
diff --git a/linphone-app/assets/languages/ja.ts b/linphone-app/assets/languages/ja.ts
index 42d6584a1..a51c1dfa5 100644
--- a/linphone-app/assets/languages/ja.ts
+++ b/linphone-app/assets/languages/ja.ts
@@ -830,6 +830,25 @@
アプリケーションを再起動する必要があります。今すぐ再起動しますか?
+
+ HistoryView
+
+ removeAllEntriesDescription
+ 履歴をクリアしてよろしいですか?
+
+
+ tooltipContactEdit
+ 連絡先の編集
+
+
+ tooltipContactAdd
+ 連絡先の追加
+
+
+ cleanHistory
+ 履歴の削除
+
+
Home
diff --git a/linphone-app/assets/languages/lt.ts b/linphone-app/assets/languages/lt.ts
index db71da49b..95f54834f 100644
--- a/linphone-app/assets/languages/lt.ts
+++ b/linphone-app/assets/languages/lt.ts
@@ -830,6 +830,25 @@ Nesukonfigūruotas serverio url.
Yra būtina paleisti programą iš naujo. Ar norite tai atlikti dabar?
+
+ HistoryView
+
+ removeAllEntriesDescription
+ Ar tikrai norite išvalyti šią istoriją?
+
+
+ tooltipContactEdit
+ Redaguoti kontaktą
+
+
+ tooltipContactAdd
+ Pridėti kontaktą
+
+
+ cleanHistory
+ Ištrinti istoriją
+
+
Home
diff --git a/linphone-app/assets/languages/pt_BR.ts b/linphone-app/assets/languages/pt_BR.ts
index 5ca09d079..08c92897e 100644
--- a/linphone-app/assets/languages/pt_BR.ts
+++ b/linphone-app/assets/languages/pt_BR.ts
@@ -830,6 +830,25 @@ URL do servidor não configurado.
É necessário reiniciar o aplicativo. Deseja reiniciar agora?
+
+ HistoryView
+
+ removeAllEntriesDescription
+ Tem certeza de que deseja limpar esse histórico?
+
+
+ tooltipContactEdit
+ Editar contato
+
+
+ tooltipContactAdd
+ Adicionar contato
+
+
+ cleanHistory
+ Excluir histórico
+
+
Home
diff --git a/linphone-app/assets/languages/ru.ts b/linphone-app/assets/languages/ru.ts
index 28edf5c36..790b08f30 100644
--- a/linphone-app/assets/languages/ru.ts
+++ b/linphone-app/assets/languages/ru.ts
@@ -830,6 +830,25 @@
Требуется перезапустить приложение. Хотите перезапустить сейчас?
+
+ HistoryView
+
+ removeAllEntriesDescription
+ Вы уверены, что хотите очистить эту историю?
+
+
+ tooltipContactEdit
+ Изменить контакт
+
+
+ tooltipContactAdd
+ Добавить контакт
+
+
+ cleanHistory
+ Удалить историю
+
+
Home
diff --git a/linphone-app/assets/languages/sv.ts b/linphone-app/assets/languages/sv.ts
index 1f5581297..464896f62 100644
--- a/linphone-app/assets/languages/sv.ts
+++ b/linphone-app/assets/languages/sv.ts
@@ -830,6 +830,25 @@ Serverwebbadressen är inte konfigurerad.
Det är nödvändigt att starta om programmet. Vill du starta om nu?
+
+ HistoryView
+
+ removeAllEntriesDescription
+ Är du säker på att du vill rensa den här historiken?
+
+
+ tooltipContactEdit
+ Redigera kontakt
+
+
+ tooltipContactAdd
+ Lägg till kontakt
+
+
+ cleanHistory
+ Radera historik
+
+
Home
diff --git a/linphone-app/assets/languages/tr.ts b/linphone-app/assets/languages/tr.ts
index f102f97ac..671688298 100644
--- a/linphone-app/assets/languages/tr.ts
+++ b/linphone-app/assets/languages/tr.ts
@@ -830,6 +830,25 @@ Sunucu url'si yapılandırılmadı.
Uygulamanın yeniden başlaması gerekiyor. Şimdi yeniden başlatmak ister misiniz?
+
+ HistoryView
+
+ removeAllEntriesDescription
+ Bu geçmişi temizlemek istediğinize emin misiniz?
+
+
+ tooltipContactEdit
+ Kişi düzenle
+
+
+ tooltipContactAdd
+ Kişi ekle
+
+
+ cleanHistory
+ Geçmişi sil
+
+
Home
diff --git a/linphone-app/assets/languages/uk.ts b/linphone-app/assets/languages/uk.ts
index 89a6f781e..1281eb03b 100644
--- a/linphone-app/assets/languages/uk.ts
+++ b/linphone-app/assets/languages/uk.ts
@@ -830,6 +830,25 @@
Потрібно перезапустити застосунок. Бажаєте перезапустити зараз?
+
+ HistoryView
+
+ removeAllEntriesDescription
+ Ви впевнені, що волієте вичистити цю історію?
+
+
+ tooltipContactEdit
+ Редагувати контакт
+
+
+ tooltipContactAdd
+ Додати контакт
+
+
+ cleanHistory
+ Вилучити історію
+
+
Home
diff --git a/linphone-app/assets/languages/zh_CN.ts b/linphone-app/assets/languages/zh_CN.ts
index 0b7459d5f..52327110f 100644
--- a/linphone-app/assets/languages/zh_CN.ts
+++ b/linphone-app/assets/languages/zh_CN.ts
@@ -830,6 +830,25 @@
需要重启应用程序。您想要立刻重启吗?
+
+ HistoryView
+
+ removeAllEntriesDescription
+ 你确定要清除该历史吗?
+
+
+ tooltipContactEdit
+ 编辑联系人
+
+
+ tooltipContactAdd
+ 添加联系人
+
+
+ cleanHistory
+ 删除历史记录
+
+
Home
diff --git a/linphone-app/resources.qrc b/linphone-app/resources.qrc
index aac0c7fd2..1948cf996 100644
--- a/linphone-app/resources.qrc
+++ b/linphone-app/resources.qrc
@@ -229,6 +229,7 @@
ui/modules/Common/Form/ListForm.qml
ui/modules/Common/Form/ListItemSelector.js
ui/modules/Common/Form/ListItemSelector.qml
+ ui/modules/Common/Form/MouseArea.qml
ui/modules/Common/Form/Placements/FormEmptyLine.qml
ui/modules/Common/Form/Placements/FormGroup.qml
ui/modules/Common/Form/Placements/FormHGroup.qml
@@ -338,6 +339,9 @@
ui/modules/Linphone/Contact/ContactMessageCounter.qml
ui/modules/Linphone/Contact/Contact.qml
ui/modules/Linphone/Dialog/OnlineInstallerDialog.qml
+ ui/modules/Linphone/History/History.qml
+ ui/modules/Linphone/History/History.js
+ ui/modules/Linphone/History/Event.qml
ui/modules/Linphone/Menus/SipAddressesMenu.qml
ui/modules/Linphone/Misc/MessageCounter.qml
ui/modules/Linphone/Notifications/NotificationBasic.qml
@@ -365,6 +369,7 @@
ui/modules/Linphone/Styles/Contact/ContactMessageCounterStyle.qml
ui/modules/Linphone/Styles/Contact/ContactStyle.qml
ui/modules/Linphone/Styles/Dialog/OnlineInstallerDialogStyle.qml
+ ui/modules/Linphone/Styles/History/HistoryStyle.qml
ui/modules/Linphone/Styles/Menus/SipAddressesMenuStyle.qml
ui/modules/Linphone/Styles/Misc/MessageCounterStyle.qml
ui/modules/Linphone/Styles/Notifications/NotificationBasicStyle.qml
@@ -428,10 +433,13 @@
ui/views/App/Main/Dialogs/ManageAccount.js
ui/views/App/Main/Dialogs/ManageAccounts.qml
ui/views/App/Main/Home.qml
+ ui/views/App/Main/HistoryView.qml
+ ui/views/App/Main/HistoryView.js
ui/views/App/Main/InviteFriends.qml
ui/views/App/Main/MainWindow.js
ui/views/App/Main/MainWindowMenuBar.qml
ui/views/App/Main/MainWindow.qml
+ ui/views/App/Main/MainWindowTopMenuBar.qml
ui/views/App/Settings/Dialogs/SettingsSipAccountsEdit.js
ui/views/App/Settings/Dialogs/SettingsSipAccountsEdit.qml
ui/views/App/Settings/Dialogs/SettingsVideoPreview.qml
@@ -469,6 +477,7 @@
ui/views/App/Styles/Main/Dialogs/ManageAccountsStyle.qml
ui/views/App/Styles/Main/HomeStyle.qml
ui/views/App/Styles/Main/InviteFriendsStyle.qml
+ ui/views/App/Styles/Main/HistoryViewStyle.qml
ui/views/App/Styles/Main/MainWindowStyle.qml
ui/views/App/Styles/qmldir
ui/views/App/Styles/Settings/Dialogs/SettingsSipAccountsEditStyle.qml
@@ -477,7 +486,6 @@
ui/views/App/Styles/Settings/SettingsAudioStyle.qml
ui/views/App/Styles/Settings/SettingsWindowStyle.qml
assets/images/linphone_logo.svg
- ui/views/App/Main/MainWindowTopMenuBar.qml
ui/dev-modules/Colors/Colors.qml
ui/dev-modules/Units/Units.qml
assets/icon.ico
diff --git a/linphone-app/src/app/App.cpp b/linphone-app/src/app/App.cpp
index 7342eab24..353fe126f 100644
--- a/linphone-app/src/app/App.cpp
+++ b/linphone-app/src/app/App.cpp
@@ -520,6 +520,7 @@ void App::registerTypes () {
registerType("ContactsListProxyModel");
registerType("FileDownloader");
registerType("FileExtractor");
+ registerType("HistoryProxyModel");
registerType("SipAddressesProxyModel");
registerType("SoundPlayer");
registerType("TelephoneNumbersModel");
@@ -535,6 +536,7 @@ void App::registerTypes () {
registerUncreatableType("ChatModel");
registerUncreatableType("ConferenceAddModel");
registerUncreatableType("ContactModel");
+ registerUncreatableType("HistoryModel");
registerUncreatableType("SipAddressObserver");
registerUncreatableType("VcardModel");
}
diff --git a/linphone-app/src/components/Components.hpp b/linphone-app/src/components/Components.hpp
index 8147d8432..05feab2c9 100644
--- a/linphone-app/src/components/Components.hpp
+++ b/linphone-app/src/components/Components.hpp
@@ -41,6 +41,7 @@
#include "core/CoreManager.hpp"
#include "file/FileDownloader.hpp"
#include "file/FileExtractor.hpp"
+#include "history/HistoryProxyModel.hpp"
#include "notifier/Notifier.hpp"
#include "presence/OwnPresenceModel.hpp"
#include "settings/AccountSettingsModel.hpp"
diff --git a/linphone-app/src/components/calls/CallsListModel.cpp b/linphone-app/src/components/calls/CallsListModel.cpp
index d50ae296a..d4f9e2bdc 100644
--- a/linphone-app/src/components/calls/CallsListModel.cpp
+++ b/linphone-app/src/components/calls/CallsListModel.cpp
@@ -111,7 +111,7 @@ void CallsListModel::launchAudioCall (const QString &sipAddress, const QHashaddCustomHeader(Utils::appStringToCoreString(iterator.key()), Utils::appStringToCoreString(iterator.value()));
}
-
+ params->setProxyConfig(core->getDefaultProxyConfig());
CallModel::setRecordFile(params, Utils::coreStringToAppString(address->getUsername()));
core->inviteAddressWithParams(address, params);
}
@@ -130,7 +130,7 @@ void CallsListModel::launchVideoCall (const QString &sipAddress) const {
shared_ptr params = core->createCallParams(nullptr);
params->enableVideo(true);
-
+ params->setProxyConfig(core->getDefaultProxyConfig());
CallModel::setRecordFile(params, Utils::coreStringToAppString(address->getUsername()));
core->inviteAddressWithParams(address, params);
}
diff --git a/linphone-app/src/components/core/CoreManager.cpp b/linphone-app/src/components/core/CoreManager.cpp
index fa2a35c42..bcd1d0df0 100644
--- a/linphone-app/src/components/core/CoreManager.cpp
+++ b/linphone-app/src/components/core/CoreManager.cpp
@@ -32,6 +32,7 @@
#include "components/chat/ChatModel.hpp"
#include "components/contact/VcardModel.hpp"
#include "components/contacts/ContactsListModel.hpp"
+#include "components/history/HistoryModel.hpp"
#include "components/settings/AccountSettingsModel.hpp"
#include "components/settings/SettingsModel.hpp"
#include "components/sip-addresses/SipAddressesModel.hpp"
@@ -145,6 +146,13 @@ bool CoreManager::chatModelExists (const QString &peerAddress, const QString &lo
return mChatModels.contains({ peerAddress, localAddress });
}
+HistoryModel* CoreManager::getHistoryModel(){
+ if(!mHistoryModel){
+ mHistoryModel = new HistoryModel(this);
+ emit historyModelCreated(mHistoryModel);
+ }
+ return mHistoryModel;
+}
// -----------------------------------------------------------------------------
void CoreManager::init (QObject *parent, const QString &configPath) {
diff --git a/linphone-app/src/components/core/CoreManager.hpp b/linphone-app/src/components/core/CoreManager.hpp
index 27fb88997..0f5544a43 100644
--- a/linphone-app/src/components/core/CoreManager.hpp
+++ b/linphone-app/src/components/core/CoreManager.hpp
@@ -37,6 +37,7 @@ class ChatModel;
class ContactsListModel;
class CoreHandlers;
class EventCountNotifier;
+class HistoryModel;
class SettingsModel;
class SipAddressesModel;
class VcardModel;
@@ -44,9 +45,9 @@ class VcardModel;
class CoreManager : public QObject {
Q_OBJECT;
- Q_PROPERTY(QString version READ getVersion CONSTANT);
- Q_PROPERTY(QString downloadUrl READ getDownloadUrl CONSTANT);
- Q_PROPERTY(int eventCount READ getEventCount NOTIFY eventCountChanged);
+ Q_PROPERTY(QString version READ getVersion CONSTANT)
+ Q_PROPERTY(QString downloadUrl READ getDownloadUrl CONSTANT)
+ Q_PROPERTY(int eventCount READ getEventCount NOTIFY eventCountChanged)
public:
bool started () const {
@@ -65,6 +66,8 @@ public:
std::shared_ptr getChatModel (const QString &peerAddress, const QString &localAddress);
bool chatModelExists (const QString &sipAddress, const QString &localAddress);
+
+ HistoryModel* getHistoryModel();
// ---------------------------------------------------------------------------
// Video render lock.
@@ -138,6 +141,7 @@ signals:
void coreStarted ();
void chatModelCreated (const std::shared_ptr &chatModel);
+ void historyModelCreated (HistoryModel *historyModel);
void logsUploaded (const QString &url);
@@ -177,6 +181,7 @@ private:
EventCountNotifier *mEventCountNotifier = nullptr;
QHash, std::weak_ptr> mChatModels;
+ HistoryModel * mHistoryModel = nullptr;
QTimer *mCbsTimer = nullptr;
diff --git a/linphone-app/src/components/core/event-count-notifier/AbstractEventCountNotifier.cpp b/linphone-app/src/components/core/event-count-notifier/AbstractEventCountNotifier.cpp
index 575ddb05d..81469bb68 100644
--- a/linphone-app/src/components/core/event-count-notifier/AbstractEventCountNotifier.cpp
+++ b/linphone-app/src/components/core/event-count-notifier/AbstractEventCountNotifier.cpp
@@ -25,6 +25,7 @@
#include "components/chat/ChatModel.hpp"
#include "components/core/CoreHandlers.hpp"
#include "components/core/CoreManager.hpp"
+#include "components/history/HistoryModel.hpp"
#include "components/settings/SettingsModel.hpp"
#include "utils/Utils.hpp"
@@ -40,6 +41,10 @@ AbstractEventCountNotifier::AbstractEventCountNotifier (QObject *parent) : QObje
coreManager, &CoreManager::chatModelCreated,
this, &AbstractEventCountNotifier::handleChatModelCreated
);
+ QObject::connect(
+ coreManager, &CoreManager::historyModelCreated,
+ this, &AbstractEventCountNotifier::handleHistoryModelCreated
+ );
QObject::connect(
coreManager->getHandlers().get(), &CoreHandlers::messageReceived,
this, &AbstractEventCountNotifier::updateUnreadMessageCount
@@ -98,11 +103,26 @@ void AbstractEventCountNotifier::handleChatModelCreated (const shared_ptrgetPeerAddress()), Utils::cleanSipAddress(chatModel->getLocalAddress()) });
if (it != mMissedCalls.cend()) {
mMissedCalls.erase(it);
diff --git a/linphone-app/src/components/core/event-count-notifier/AbstractEventCountNotifier.hpp b/linphone-app/src/components/core/event-count-notifier/AbstractEventCountNotifier.hpp
index 923640323..4af9bb61d 100644
--- a/linphone-app/src/components/core/event-count-notifier/AbstractEventCountNotifier.hpp
+++ b/linphone-app/src/components/core/event-count-notifier/AbstractEventCountNotifier.hpp
@@ -35,6 +35,7 @@ namespace linphone {
class CallModel;
class ChatModel;
+class HistoryModel;
class AbstractEventCountNotifier : public QObject {
Q_OBJECT;
@@ -68,7 +69,11 @@ private:
void handleChatModelCreated (const std::shared_ptr &chatModel);
- void handleChatModelFocused (ChatModel *chatModel);
+ void handleHistoryModelCreated (HistoryModel *historyModel);
+
+
+ void handleResetAllMissedCalls ();
+ void handleResetMissedCalls (ChatModel *chatModel);
void handleCallMissed (CallModel *callModel);
QHash mMissedCalls;
diff --git a/linphone-app/src/components/history/HistoryModel.cpp b/linphone-app/src/components/history/HistoryModel.cpp
new file mode 100644
index 000000000..6c341f7cb
--- /dev/null
+++ b/linphone-app/src/components/history/HistoryModel.cpp
@@ -0,0 +1,256 @@
+/*
+ * 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 .
+ */
+
+#include
+
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+
+#include "app/App.hpp"
+#include "app/paths/Paths.hpp"
+#include "app/providers/ThumbnailProvider.hpp"
+#include "components/core/CoreHandlers.hpp"
+#include "components/core/CoreManager.hpp"
+#include "components/notifier/Notifier.hpp"
+#include "components/settings/SettingsModel.hpp"
+#include "utils/QExifImageHeader.hpp"
+#include "utils/Utils.hpp"
+
+#include "HistoryModel.hpp"
+
+// =============================================================================
+
+using namespace std;
+
+static inline void fillCallStartEntry (QVariantMap &dest, const shared_ptr &callLog) {
+ dest["type"] = HistoryModel::CallEntry;
+ dest["timestamp"] = QDateTime::fromMSecsSinceEpoch(callLog->getStartDate() * 1000);
+ dest["isOutgoing"] = callLog->getDir() == linphone::Call::Dir::Outgoing;
+ dest["status"] = static_cast(callLog->getStatus());
+ dest["isStart"] = true;
+ dest["sipAddress"] = Utils::coreStringToAppString(callLog->getRemoteAddress()->asString());
+}
+
+static inline void fillCallEndEntry (QVariantMap &dest, const shared_ptr &callLog) {
+ dest["type"] = HistoryModel::CallEntry;
+ dest["timestamp"] = QDateTime::fromMSecsSinceEpoch((callLog->getStartDate() + callLog->getDuration()) * 1000);
+ dest["isOutgoing"] = callLog->getDir() == linphone::Call::Dir::Outgoing;
+ dest["status"] = static_cast(callLog->getStatus());
+ dest["isStart"] = false;
+ dest["sipAddress"] = Utils::coreStringToAppString(callLog->getRemoteAddress()->asString());
+}
+
+// -----------------------------------------------------------------------------
+
+HistoryModel::HistoryModel (QObject *parent) :QAbstractListModel(parent){
+ CoreManager *coreManager = CoreManager::getInstance();
+
+ mCoreHandlers = coreManager->getHandlers();
+
+ setSipAddresses();
+ CoreHandlers *coreHandlers = mCoreHandlers.get();
+ QObject::connect(coreHandlers, &CoreHandlers::callStateChanged, this, &HistoryModel::handleCallStateChanged);
+
+}
+
+HistoryModel::~HistoryModel () {
+}
+
+QHash HistoryModel::roleNames () const {
+ QHash roles;
+ roles[Roles::HistoryEntry] = "$historyEntry";
+ roles[Roles::SectionDate] = "$sectionDate";
+ return roles;
+}
+
+int HistoryModel::rowCount (const QModelIndex &) const {
+ return mEntries.count();
+}
+
+QVariant HistoryModel::data (const QModelIndex &index, int role) const {
+ int row = index.row();
+
+ if (!index.isValid() || row < 0 || row >= mEntries.count())
+ return QVariant();
+
+ switch (role) {
+ case Roles::HistoryEntry: {
+ auto &data = mEntries[row].first;
+ return QVariant::fromValue(data);
+ }
+ case Roles::SectionDate:
+ return QVariant::fromValue(mEntries[row].first["timestamp"].toDate());
+ }
+
+ return QVariant();
+}
+
+bool HistoryModel::removeRow (int row, const QModelIndex &) {
+ return removeRows(row, 1);
+}
+
+bool HistoryModel::removeRows (int row, int count, const QModelIndex &parent) {
+ int limit = row + count - 1;
+
+ if (row < 0 || count < 0 || limit >= mEntries.count())
+ return false;
+
+ beginRemoveRows(parent, row, limit);
+
+ for (int i = 0; i < count; ++i) {
+ removeEntry(mEntries[row]);
+ mEntries.removeAt(row);
+ }
+
+ endRemoveRows();
+
+ if (mEntries.count() == 0)
+ emit allEntriesRemoved();
+ else if (limit == mEntries.count())
+ emit lastEntryRemoved();
+ emit focused();// Removing rows is like having focus. Don't wait asynchronous events.
+ return true;
+}
+
+void HistoryModel::setSipAddresses () {
+ shared_ptr core = CoreManager::getInstance()->getCore();
+ mEntries.clear();
+
+ QElapsedTimer timer;
+ timer.start();
+
+ // Get calls.
+ for (auto &callLog : core->getCallLogs())
+ insertCall(callLog);
+
+ qInfo() << QStringLiteral("HistoryModel loaded in %3 milliseconds.").arg(timer.elapsed());
+
+}
+
+// -----------------------------------------------------------------------------
+
+void HistoryModel::removeEntry (int id) {
+ qInfo() << QStringLiteral("Removing call entry: %1.").arg(id);
+
+ if (!removeRow(id))
+ qWarning() << QStringLiteral("Unable to remove call entry: %1").arg(id);
+}
+
+void HistoryModel::removeAllEntries () {
+ qInfo() << QStringLiteral("Removing all call entries.");
+
+ beginResetModel();
+
+ for (auto &entry : mEntries)
+ removeEntry(entry);
+
+ mEntries.clear();
+
+ endResetModel();
+
+ emit allEntriesRemoved();
+ emit focused();// Removing all entries is like having focus. Don't wait asynchronous events.
+}
+
+// -----------------------------------------------------------------------------
+
+void HistoryModel::removeEntry (HistoryEntryData &entry) {
+ int type = entry.first["type"].toInt();
+
+ switch (type) {
+
+ case HistoryModel::CallEntry: {
+ if (entry.first["status"].toInt() == CallStatusSuccess) {
+ // WARNING: Unable to remove symmetric call here. (start/end)
+ // We are between `beginRemoveRows` and `endRemoveRows`.
+ // A solution is to schedule a `removeEntry` call in the Qt main loop.
+ shared_ptr linphonePtr = entry.second;
+ QTimer::singleShot(0, this, [this, linphonePtr]() {
+ auto it = find_if(mEntries.begin(), mEntries.end(), [linphonePtr](const HistoryEntryData &entry) {
+ return entry.second == linphonePtr;
+ });
+
+ if (it != mEntries.end())
+ removeEntry(int(distance(mEntries.begin(), it)));
+ });
+ }
+
+ CoreManager::getInstance()->getCore()->removeCallLog(static_pointer_cast(entry.second));
+ break;
+ }
+
+ default:
+ qWarning() << QStringLiteral("Unknown history entry type: %1.").arg(type);
+ }
+}
+
+void HistoryModel::insertCall (const shared_ptr &callLog) {
+ linphone::Call::Status status = callLog->getStatus();
+
+ auto insertEntry = [this](
+ const HistoryEntryData &entry,
+ const QList::iterator *start = nullptr
+ ) {
+ auto it = lower_bound(start ? *start : mEntries.begin(), mEntries.end(), entry, [](const HistoryEntryData &a, const HistoryEntryData &b) {
+ return a.first["timestamp"] < b.first["timestamp"];
+ });
+
+ int row = int(distance(mEntries.begin(), it));
+
+ beginInsertRows(QModelIndex(), row, row);
+ it = mEntries.insert(it, entry);
+ endInsertRows();
+
+ return it;
+ };
+
+ // Add start call.
+ QVariantMap start;
+ fillCallStartEntry(start, callLog);
+ auto it = insertEntry(qMakePair(start, static_pointer_cast(callLog)));
+
+ if (status == linphone::Call::Status::Success) {
+ QVariantMap end;
+ fillCallEndEntry(end, callLog);
+ insertEntry(qMakePair(end, static_pointer_cast(callLog)), &it);
+ }
+}
+
+// -----------------------------------------------------------------------------
+
+void HistoryModel::resetMessageCount () {
+ emit callCountReset();
+}
+
+// -----------------------------------------------------------------------------
+
+void HistoryModel::handleCallStateChanged (const shared_ptr &call, linphone::Call::State state) {
+ if (state == linphone::Call::State::End || state == linphone::Call::State::Error)
+ insertCall(call->getCallLog());
+}
+
diff --git a/linphone-app/src/components/history/HistoryModel.hpp b/linphone-app/src/components/history/HistoryModel.hpp
new file mode 100644
index 000000000..67652d204
--- /dev/null
+++ b/linphone-app/src/components/history/HistoryModel.hpp
@@ -0,0 +1,96 @@
+/*
+ * 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 .
+ */
+
+#ifndef HISTORY_MODEL_H_
+#define HISTORY_MODEL_H_
+
+#include
+#include
+
+// =============================================================================
+// Fetch all N messages of the History.
+// =============================================================================
+
+class CoreHandlers;
+
+class HistoryModel : public QAbstractListModel {
+
+ Q_OBJECT
+
+public:
+ enum Roles {
+ HistoryEntry = Qt::DisplayRole,
+ SectionDate
+ };
+
+ enum EntryType {
+ GenericEntry,
+ CallEntry
+ };
+ Q_ENUM(EntryType)
+
+ enum CallStatus {
+ CallStatusDeclined = int(linphone::Call::Status::Declined),
+ CallStatusMissed = int(linphone::Call::Status::Missed),
+ CallStatusSuccess = int(linphone::Call::Status::Success),
+ CallStatusAborted = int(linphone::Call::Status::Aborted),
+ CallStatusEarlyAborted = int(linphone::Call::Status::EarlyAborted),
+ CallStatusAcceptedElsewhere = int(linphone::Call::Status::AcceptedElsewhere),
+ CallStatusDeclinedElsewhere = int(linphone::Call::Status::DeclinedElsewhere)
+ };
+ Q_ENUM(CallStatus)
+
+ HistoryModel (QObject *parent = Q_NULLPTR);
+ virtual ~HistoryModel ();
+
+ int rowCount (const QModelIndex &index = QModelIndex()) const override;
+
+ QHash roleNames () const override;
+ QVariant data (const QModelIndex &index, int role) const override;
+
+ bool removeRow (int row, const QModelIndex &parent = QModelIndex());
+ bool removeRows (int row, int count, const QModelIndex &parent = QModelIndex()) override;
+
+ void removeEntry (int id);
+ void removeAllEntries ();
+
+ void resetMessageCount ();
+
+signals:
+ void allEntriesRemoved ();
+ void lastEntryRemoved ();
+
+ void focused ();
+ void callCountReset();
+
+private:
+ typedef QPair> HistoryEntryData;
+
+ void setSipAddresses ();
+ void removeEntry (HistoryEntryData &entry);
+ void insertCall (const std::shared_ptr &callLog);
+ void handleCallStateChanged (const std::shared_ptr &call, linphone::Call::State state);
+
+ mutable QList mEntries;
+
+ std::shared_ptr mCoreHandlers;
+};
+
+#endif // HISTORY_MODEL_H_
diff --git a/linphone-app/src/components/history/HistoryProxyModel.cpp b/linphone-app/src/components/history/HistoryProxyModel.cpp
new file mode 100644
index 000000000..e7f490b58
--- /dev/null
+++ b/linphone-app/src/components/history/HistoryProxyModel.cpp
@@ -0,0 +1,161 @@
+/*
+ * 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 .
+ */
+
+#include
+
+#include "app/App.hpp"
+#include "components/core/CoreManager.hpp"
+
+#include "HistoryProxyModel.hpp"
+#include "components/sip-addresses/SipAddressesModel.hpp"
+
+// =============================================================================
+
+using namespace std;
+
+// Fetch the L last filtered history entries.
+class HistoryProxyModel::HistoryModelFilter : public QSortFilterProxyModel {
+public:
+ HistoryModelFilter (QObject *parent) : QSortFilterProxyModel(parent) { }
+
+ HistoryModel::EntryType getEntryTypeFilter () {
+ return mEntryTypeFilter;
+ }
+
+ void setEntryTypeFilter (HistoryModel::EntryType type) {
+ mEntryTypeFilter = type;
+ invalidate();
+ }
+
+protected:
+ bool filterAcceptsRow (int sourceRow, const QModelIndex &) const override {
+ if (mEntryTypeFilter == HistoryModel::EntryType::GenericEntry)
+ return true;
+
+ QModelIndex index = sourceModel()->index(sourceRow, 0, QModelIndex());
+ const QVariantMap data = index.data().toMap();
+
+ return data["type"].toInt() == mEntryTypeFilter;
+ }
+
+private:
+ HistoryModel::EntryType mEntryTypeFilter = HistoryModel::EntryType::GenericEntry;
+};
+
+// =============================================================================
+
+HistoryProxyModel::HistoryProxyModel (QObject *parent) : QSortFilterProxyModel(parent) {
+
+ setSourceModel(new HistoryModelFilter(this));
+ reload();
+
+ App *app = App::getInstance();
+ QObject::connect(app->getMainWindow(), &QWindow::activeChanged, this, [this]() {
+ handleIsActiveChanged(App::getInstance()->getMainWindow());
+ });
+
+ QQuickWindow *callsWindow = app->getCallsWindow();
+ if (callsWindow)
+ QObject::connect(callsWindow, &QWindow::activeChanged, this, [this, callsWindow]() {
+ handleIsActiveChanged(callsWindow);
+ });
+}
+
+// -----------------------------------------------------------------------------
+
+void HistoryProxyModel::removeAllEntries(){
+ auto model = CoreManager::getInstance()->getHistoryModel();
+ if (!model)
+ return;
+ model->removeAllEntries();
+}
+void HistoryProxyModel::removeEntry (int id){
+ auto model = CoreManager::getInstance()->getHistoryModel();
+ if (!model)
+ return;
+ QModelIndex sourceIndex = mapToSource(index(id, 0));
+ model->removeEntry(static_cast(sourceModel())->mapToSource(sourceIndex).row() );
+}
+// -----------------------------------------------------------------------------
+
+void HistoryProxyModel::loadMoreEntries () {
+ int count = rowCount();
+ int parentCount = sourceModel()->rowCount();
+
+ if (count < parentCount) {
+ // Do not increase `mMaxDisplayedEntries` if it's not necessary...
+ // Limit qml calls.
+ if (count == mMaxDisplayedEntries)
+ mMaxDisplayedEntries += EntriesChunkSize;
+
+ invalidateFilter();
+
+ count = rowCount() - count;
+ if (count > 0)
+ emit moreEntriesLoaded(count);
+ }
+}
+
+void HistoryProxyModel::setEntryTypeFilter (HistoryModel::EntryType type) {
+ HistoryModelFilter *HistoryModelFilter = static_cast(sourceModel());
+
+ if (HistoryModelFilter->getEntryTypeFilter() != type) {
+ HistoryModelFilter->setEntryTypeFilter(type);
+ emit entryTypeFilterChanged(type);
+ }
+}
+
+// -----------------------------------------------------------------------------
+
+bool HistoryProxyModel::filterAcceptsRow (int sourceRow, const QModelIndex &) const {
+ return sourceModel()->rowCount() - sourceRow <= mMaxDisplayedEntries;
+}
+
+// -----------------------------------------------------------------------------
+
+void HistoryProxyModel::reload () {
+ mMaxDisplayedEntries = EntriesChunkSize;
+ static_cast(sourceModel())->setSourceModel(CoreManager::getInstance()->getHistoryModel());
+}
+void HistoryProxyModel::resetMessageCount(){
+ auto model = CoreManager::getInstance()->getHistoryModel();
+ if( model){
+ model->resetMessageCount();
+ }
+}
+// -----------------------------------------------------------------------------
+
+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(parent);
+ return nullptr;
+}
+
+void HistoryProxyModel::handleIsActiveChanged (QWindow *window) {
+ auto model = CoreManager::getInstance()->getHistoryModel();
+ if (model && window->isActive() && getParentWindow(this) == window) {
+ model->focused();
+ model->resetMessageCount();
+ }
+}
diff --git a/linphone-app/src/components/history/HistoryProxyModel.hpp b/linphone-app/src/components/history/HistoryProxyModel.hpp
new file mode 100644
index 000000000..ddd6fa5a1
--- /dev/null
+++ b/linphone-app/src/components/history/HistoryProxyModel.hpp
@@ -0,0 +1,68 @@
+/*
+ * 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 .
+ */
+
+#ifndef HISTORY_PROXY_MODEL_H_
+#define HISTORY_PROXY_MODEL_H_
+
+#include
+
+#include "HistoryModel.hpp"
+
+// =============================================================================
+
+class QWindow;
+
+class HistoryProxyModel : public QSortFilterProxyModel {
+ class HistoryModelFilter;
+
+ Q_OBJECT;
+
+public:
+ HistoryProxyModel (QObject *parent = Q_NULLPTR);
+
+ Q_INVOKABLE void loadMoreEntries ();
+ Q_INVOKABLE void setEntryTypeFilter (HistoryModel::EntryType type = HistoryModel::EntryType::CallEntry);
+ Q_INVOKABLE void removeEntry (int id);
+
+ Q_INVOKABLE void removeAllEntries ();
+
+ Q_INVOKABLE void resetMessageCount();
+
+signals:
+
+ void moreEntriesLoaded (int n);
+
+ void entryTypeFilterChanged (HistoryModel::EntryType type);
+
+protected:
+ bool filterAcceptsRow (int sourceRow, const QModelIndex &sourceParent) const override;
+
+private:
+
+ void reload ();
+
+ void handleIsActiveChanged (QWindow *window);
+
+ int mMaxDisplayedEntries = EntriesChunkSize;
+
+ static constexpr int EntriesChunkSize = 50;
+};
+
+#endif // HISTORY_PROXY_MODEL_H_
diff --git a/linphone-app/src/components/sip-addresses/SipAddressesModel.cpp b/linphone-app/src/components/sip-addresses/SipAddressesModel.cpp
index 847e20eb2..4de3697ac 100644
--- a/linphone-app/src/components/sip-addresses/SipAddressesModel.cpp
+++ b/linphone-app/src/components/sip-addresses/SipAddressesModel.cpp
@@ -30,6 +30,7 @@
#include "components/contacts/ContactsListModel.hpp"
#include "components/core/CoreHandlers.hpp"
#include "components/core/CoreManager.hpp"
+#include "components/history/HistoryModel.hpp"
#include "components/settings/AccountSettingsModel.hpp"
#include "utils/LinphoneUtils.hpp"
#include "utils/Utils.hpp"
@@ -59,6 +60,7 @@ SipAddressesModel::SipAddressesModel (QObject *parent) : QAbstractListModel(pare
mCoreHandlers = coreManager->getHandlers();
QObject::connect(coreManager, &CoreManager::chatModelCreated, this, &SipAddressesModel::handleChatModelCreated);
+ QObject::connect(coreManager, &CoreManager::historyModelCreated, this, &SipAddressesModel::handleHistoryModelCreated);
ContactsListModel *contacts = CoreManager::getInstance()->getContactsListModel();
QObject::connect(contacts, &ContactsListModel::contactAdded, this, &SipAddressesModel::handleContactAdded);
@@ -261,6 +263,11 @@ void SipAddressesModel::handleChatModelCreated (const shared_ptr &cha
QObject::connect(ptr, &ChatModel::messageSent, this, &SipAddressesModel::handleMessageSent);
}
+void SipAddressesModel::handleHistoryModelCreated (HistoryModel *historyModel) {
+ QObject::connect(historyModel, &HistoryModel::callCountReset, this, [this] {
+ handleAllCallCountReset();
+ });
+}
void SipAddressesModel::handleContactAdded (ContactModel *contact) {
for (const auto &sipAddress : contact->getVcardModel()->getSipAddresses())
addOrUpdateSipAddress(sipAddress.toString(), contact);
@@ -385,7 +392,16 @@ void SipAddressesModel::handleLastEntryRemoved (ChatModel *chatModel) {
it2->timestamp = map["timestamp"].toDateTime();
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 (ChatModel *chatModel) {
const QString &peerAddress = Utils::cleanSipAddress(chatModel->getPeerAddress());
auto it = mPeerAddressToSipAddressEntry.find(peerAddress);
diff --git a/linphone-app/src/components/sip-addresses/SipAddressesModel.hpp b/linphone-app/src/components/sip-addresses/SipAddressesModel.hpp
index 2c0200dfa..841b7c43e 100644
--- a/linphone-app/src/components/sip-addresses/SipAddressesModel.hpp
+++ b/linphone-app/src/components/sip-addresses/SipAddressesModel.hpp
@@ -32,6 +32,7 @@ class QUrl;
class ChatModel;
class CoreHandlers;
+class HistoryModel;
class SipAddressesModel : public QAbstractListModel {
Q_OBJECT;
@@ -82,6 +83,9 @@ public:
// ---------------------------------------------------------------------------
signals:
void sipAddressReset();// The model has been reset
+
+public slots:
+ void handleAllCallCountReset ();
private:
bool removeRow (int row, const QModelIndex &parent = QModelIndex());
@@ -90,6 +94,7 @@ private:
// ---------------------------------------------------------------------------
void handleChatModelCreated (const std::shared_ptr &chatModel);
+ void handleHistoryModelCreated (HistoryModel *historyModel) ;
void handleContactAdded (ContactModel *contact);
void handleContactRemoved (const ContactModel *contact);
@@ -103,6 +108,7 @@ private:
void handleAllEntriesRemoved (ChatModel *chatModel);
void handleLastEntryRemoved (ChatModel *chatModel);
+
void handleMessageCountReset (ChatModel *chatModel);
void handleMessageSent (const std::shared_ptr &message);
diff --git a/linphone-app/src/components/timeline/TimelineModel.cpp b/linphone-app/src/components/timeline/TimelineModel.cpp
index fc22fc447..839ff6ba2 100644
--- a/linphone-app/src/components/timeline/TimelineModel.cpp
+++ b/linphone-app/src/components/timeline/TimelineModel.cpp
@@ -25,6 +25,8 @@
#include "TimelineModel.hpp"
+#include
+
// =============================================================================
@@ -72,8 +74,8 @@ QVariant TimelineModel::data (const QModelIndex &index, int role) const {
}
bool TimelineModel::filterAcceptsRow (int sourceRow, const QModelIndex &sourceParent) const {
- const QModelIndex index = sourceModel()->index(sourceRow, 0, sourceParent);
- return getLocalToConferenceEntry(index.data().toMap())->contains(getCleanedLocalAddress());
+ const QModelIndex index = sourceModel()->index(sourceRow, 0, sourceParent);
+ return getLocalToConferenceEntry(index.data().toMap())->contains(getCleanedLocalAddress());
}
bool TimelineModel::lessThan (const QModelIndex &left, const QModelIndex &right) const {
diff --git a/linphone-app/ui/modules/Common/Form/Buttons/AbstractTextButton.qml b/linphone-app/ui/modules/Common/Form/Buttons/AbstractTextButton.qml
index 196c86fff..2500b2d3f 100644
--- a/linphone-app/ui/modules/Common/Form/Buttons/AbstractTextButton.qml
+++ b/linphone-app/ui/modules/Common/Form/Buttons/AbstractTextButton.qml
@@ -1,6 +1,7 @@
import QtQuick 2.7
import QtQuick.Controls 2.2
+import Common 1.0
import Common.Styles 1.0
// =============================================================================
@@ -76,15 +77,10 @@ Item {
hoverEnabled: true
- MouseArea
- {
+ MouseArea {
id: mouseArea
anchors.fill: parent
onPressed: mouse.accepted = false
- hoverEnabled: true
- cursorShape: containsMouse
- ? Qt.PointingHandCursor
- : Qt.ArrowCursor
}
height: parent.height
diff --git a/linphone-app/ui/modules/Common/Form/Buttons/FileChooserButton.qml b/linphone-app/ui/modules/Common/Form/Buttons/FileChooserButton.qml
index f5b8b1e70..e04524890 100644
--- a/linphone-app/ui/modules/Common/Form/Buttons/FileChooserButton.qml
+++ b/linphone-app/ui/modules/Common/Form/Buttons/FileChooserButton.qml
@@ -101,7 +101,6 @@ TextField {
anchors.fill: parent
enabled: !textField.readOnly
- hoverEnabled: true
onClicked: fileDialog.open()
}
diff --git a/linphone-app/ui/modules/Common/Form/Buttons/SmallButton.qml b/linphone-app/ui/modules/Common/Form/Buttons/SmallButton.qml
index 96a01d758..0c310de93 100644
--- a/linphone-app/ui/modules/Common/Form/Buttons/SmallButton.qml
+++ b/linphone-app/ui/modules/Common/Form/Buttons/SmallButton.qml
@@ -1,6 +1,7 @@
import QtQuick 2.7
import QtQuick.Controls 2.2
+import Common 1.0
import Common.Styles 1.0
// =============================================================================
@@ -32,14 +33,9 @@ Button {
rightPadding: SmallButtonStyle.rightPadding
}
hoverEnabled: true
- MouseArea
- {
+ MouseArea {
id: mouseArea
anchors.fill: parent
onPressed: mouse.accepted = false
- hoverEnabled: true
- cursorShape: containsMouse
- ? Qt.PointingHandCursor
- : Qt.ArrowCursor
}
}
diff --git a/linphone-app/ui/modules/Common/Form/Fields/ScrollableListViewField.qml b/linphone-app/ui/modules/Common/Form/Fields/ScrollableListViewField.qml
index ebd3b6c82..180f1b1da 100644
--- a/linphone-app/ui/modules/Common/Form/Fields/ScrollableListViewField.qml
+++ b/linphone-app/ui/modules/Common/Form/Fields/ScrollableListViewField.qml
@@ -42,7 +42,7 @@ Rectangle {
MouseArea {
anchors.fill: parent
- hoverEnabled: true
+ cursorShape: Qt.ArrowCursor
visible: field.readOnly
onWheel: wheel.accepted = true
diff --git a/linphone-app/ui/modules/Common/Form/Fields/TextField.qml b/linphone-app/ui/modules/Common/Form/Fields/TextField.qml
index b13d0455d..0ecc35df6 100644
--- a/linphone-app/ui/modules/Common/Form/Fields/TextField.qml
+++ b/linphone-app/ui/modules/Common/Form/Fields/TextField.qml
@@ -43,7 +43,7 @@ Controls.TextField {
MouseArea {
anchors.right: parent.right
height: parent.height
- hoverEnabled: true
+ cursorShape: Qt.ArrowCursor
implicitWidth: tools ? tools.width : 0
Rectangle {
diff --git a/linphone-app/ui/modules/Common/Form/MouseArea.qml b/linphone-app/ui/modules/Common/Form/MouseArea.qml
new file mode 100644
index 000000000..17433106c
--- /dev/null
+++ b/linphone-app/ui/modules/Common/Form/MouseArea.qml
@@ -0,0 +1,11 @@
+import QtQuick 2.7 as Quick
+
+import Common 1.0
+import Common.Styles 1.0
+
+Quick.MouseArea {
+ cursorShape: containsMouse
+ ? Qt.PointingHandCursor
+ : Qt.ArrowCursor
+ hoverEnabled: true
+}
diff --git a/linphone-app/ui/modules/Common/Form/Switch.qml b/linphone-app/ui/modules/Common/Form/Switch.qml
index ec897e620..0e174b6e4 100644
--- a/linphone-app/ui/modules/Common/Form/Switch.qml
+++ b/linphone-app/ui/modules/Common/Form/Switch.qml
@@ -1,6 +1,7 @@
import QtQuick 2.7
import QtQuick.Controls 2.2
+import Common 1.0
import Common.Styles 1.0
// =============================================================================
@@ -97,7 +98,7 @@ Switch {
MouseArea {
anchors.fill: parent
-
+
onClicked: control.enabled && control.clicked()
}
}
diff --git a/linphone-app/ui/modules/Common/Helpers/DragBox.qml b/linphone-app/ui/modules/Common/Helpers/DragBox.qml
index 0b3ade33a..b330c889b 100644
--- a/linphone-app/ui/modules/Common/Helpers/DragBox.qml
+++ b/linphone-app/ui/modules/Common/Helpers/DragBox.qml
@@ -1,5 +1,6 @@
import QtQuick 2.7
+import Common 1.0
// =============================================================================
Item {
diff --git a/linphone-app/ui/modules/Common/Helpers/InvertedMouseArea.qml b/linphone-app/ui/modules/Common/Helpers/InvertedMouseArea.qml
index 9b9a17e17..33d9c0fca 100644
--- a/linphone-app/ui/modules/Common/Helpers/InvertedMouseArea.qml
+++ b/linphone-app/ui/modules/Common/Helpers/InvertedMouseArea.qml
@@ -68,6 +68,7 @@ Item {
id: builder
MouseArea {
+ cursorShape: Qt.ArrowCursor
property var _timeout
function _checkPosition (positionEvent) {
diff --git a/linphone-app/ui/modules/Common/Helpers/InvertedMouseArea.spec.qml b/linphone-app/ui/modules/Common/Helpers/InvertedMouseArea.spec.qml
index 5749234e9..6fb0a809e 100644
--- a/linphone-app/ui/modules/Common/Helpers/InvertedMouseArea.spec.qml
+++ b/linphone-app/ui/modules/Common/Helpers/InvertedMouseArea.spec.qml
@@ -2,7 +2,7 @@ import QtQuick 2.7
import QtTest 1.1
import Utils 1.0
-
+import Common 1.0
// =============================================================================
Rectangle {
diff --git a/linphone-app/ui/modules/Common/Menus/ApplicationMenuEntry.qml b/linphone-app/ui/modules/Common/Menus/ApplicationMenuEntry.qml
index e3c3fab7a..ebdee78a7 100644
--- a/linphone-app/ui/modules/Common/Menus/ApplicationMenuEntry.qml
+++ b/linphone-app/ui/modules/Common/Menus/ApplicationMenuEntry.qml
@@ -94,7 +94,6 @@ Rectangle {
id: mouseArea
anchors.fill: parent
- hoverEnabled: true
onClicked: entry.select()
}
diff --git a/linphone-app/ui/modules/Common/Menus/DropDownStaticMenuEntry.qml b/linphone-app/ui/modules/Common/Menus/DropDownStaticMenuEntry.qml
index 18e5a4f77..8023cadc4 100644
--- a/linphone-app/ui/modules/Common/Menus/DropDownStaticMenuEntry.qml
+++ b/linphone-app/ui/modules/Common/Menus/DropDownStaticMenuEntry.qml
@@ -1,5 +1,6 @@
import QtQuick 2.7
+import Common 1.0
import Common.Styles 1.0
// =============================================================================
@@ -42,7 +43,6 @@ Rectangle {
id: mouseArea
anchors.fill: parent
- hoverEnabled: true
onClicked: entry.clicked()
}
diff --git a/linphone-app/ui/modules/Common/Misc/Paned.qml b/linphone-app/ui/modules/Common/Misc/Paned.qml
index 0b3c1beb4..37f8c6995 100644
--- a/linphone-app/ui/modules/Common/Misc/Paned.qml
+++ b/linphone-app/ui/modules/Common/Misc/Paned.qml
@@ -1,5 +1,6 @@
import QtQuick 2.7
+import Common 1.0
import Common.Styles 1.0
import Utils 1.0
diff --git a/linphone-app/ui/modules/Common/Window/VirtualWindow.qml b/linphone-app/ui/modules/Common/Window/VirtualWindow.qml
index feb031029..b9f08ddf8 100644
--- a/linphone-app/ui/modules/Common/Window/VirtualWindow.qml
+++ b/linphone-app/ui/modules/Common/Window/VirtualWindow.qml
@@ -1,6 +1,7 @@
import QtQuick 2.7
import QtQuick.Controls 2.5
+import Common 1.0
import Common.Styles 1.0
import 'Window.js' as Logic
@@ -57,6 +58,7 @@ StackView{
anchors.fill: parent
hoverEnabled: true
onWheel: wheel.accepted = true
+ cursorShape: Qt.ArrowCursor
}
Rectangle {
id: content
diff --git a/linphone-app/ui/modules/Common/qmldir b/linphone-app/ui/modules/Common/qmldir
index 5f8e5a071..fc8cc3d76 100644
--- a/linphone-app/ui/modules/Common/qmldir
+++ b/linphone-app/ui/modules/Common/qmldir
@@ -24,6 +24,7 @@ CommonItemDelegate 1.0 Form/CommonItemDelegate.qml
DroppableTextArea 1.0 Form/DroppableTextArea.qml
ListForm 1.0 Form/ListForm.qml
ListItemSelector 1.0 Form/ListItemSelector.qml
+MouseArea 1.0 Form/MouseArea.qml
SearchBox 1.0 Form/SearchBox.qml
Slider 1.0 Form/Slider.qml
StaticListForm 1.0 Form/StaticListForm.qml
diff --git a/linphone-app/ui/modules/Linphone/Account/AccountStatus.qml b/linphone-app/ui/modules/Linphone/Account/AccountStatus.qml
index 450bbc2b9..06dd3acb1 100644
--- a/linphone-app/ui/modules/Linphone/Account/AccountStatus.qml
+++ b/linphone-app/ui/modules/Linphone/Account/AccountStatus.qml
@@ -14,6 +14,7 @@ Item {
// ---------------------------------------------------------------------------
signal clicked
+ property alias cursorShape:mouseArea.cursorShape
// ---------------------------------------------------------------------------
@@ -94,11 +95,8 @@ Item {
}
MouseArea {
+ id:mouseArea
anchors.fill: parent
- cursorShape: containsMouse
- ? Qt.PointingHandCursor
- : Qt.ArrowCursor
- hoverEnabled: true
onClicked: accountStatus.clicked()
}
diff --git a/linphone-app/ui/modules/Linphone/Chat/Chat.qml b/linphone-app/ui/modules/Linphone/Chat/Chat.qml
index e36f33005..0d72d1761 100644
--- a/linphone-app/ui/modules/Linphone/Chat/Chat.qml
+++ b/linphone-app/ui/modules/Linphone/Chat/Chat.qml
@@ -148,6 +148,7 @@ Rectangle {
MouseArea {
id: mouseArea
+ cursorShape: Qt.ArrowCursor
hoverEnabled: true
implicitHeight: layout.height
width: parent.width + parent.anchors.rightMargin
diff --git a/linphone-app/ui/modules/Linphone/Chat/FileMessage.qml b/linphone-app/ui/modules/Linphone/Chat/FileMessage.qml
index 4a544e612..158d5a4d1 100644
--- a/linphone-app/ui/modules/Linphone/Chat/FileMessage.qml
+++ b/linphone-app/ui/modules/Linphone/Chat/FileMessage.qml
@@ -253,10 +253,6 @@ Row {
}
anchors.fill: parent
- cursorShape: containsMouse
- ? Qt.PointingHandCursor
- : Qt.ArrowCursor
- hoverEnabled: true
visible: (rectangle.isUploaded || rectangle.isRead) && !$chatEntry.isOutgoing
onClicked: {
@@ -296,10 +292,6 @@ Row {
MouseArea {
anchors.fill: parent
- cursorShape: containsMouse
- ? Qt.PointingHandCursor
- : Qt.ArrowCursor
- hoverEnabled: true
visible: (rectangle.isError || $chatEntry.status === ChatModel.MessageStatusIdle) && $chatEntry.isOutgoing
onClicked: proxyModel.resendMessage(index)
}
diff --git a/linphone-app/ui/modules/Linphone/Codecs/CodecsViewer.qml b/linphone-app/ui/modules/Linphone/Codecs/CodecsViewer.qml
index f61304eaa..ef3234919 100644
--- a/linphone-app/ui/modules/Linphone/Codecs/CodecsViewer.qml
+++ b/linphone-app/ui/modules/Linphone/Codecs/CodecsViewer.qml
@@ -89,6 +89,7 @@ Column {
delegate: MouseArea {
id: dragArea
+ cursorShape: Qt.ArrowCursor
property bool held: false
@@ -189,7 +190,7 @@ Column {
id: mouseArea
anchors.fill: parent
- hoverEnabled: true
+ cursorShape: Qt.ArrowCursor
onPressed: mouse.accepted = false
}
diff --git a/linphone-app/ui/modules/Linphone/History/Event.qml b/linphone-app/ui/modules/Linphone/History/Event.qml
new file mode 100644
index 000000000..aec5f7e44
--- /dev/null
+++ b/linphone-app/ui/modules/Linphone/History/Event.qml
@@ -0,0 +1,105 @@
+import QtQuick 2.7
+
+import Common 1.0
+import Linphone 1.0
+import LinphoneUtils 1.0
+import Linphone.Styles 1.0
+import Utils 1.0
+
+// =============================================================================
+
+Row {
+ signal entryClicked(string sipAddress)
+
+ readonly property var _sipAddressObserver: SipAddressesModel.getSipAddressObserver($historyEntry.sipAddress, '')
+
+ property string _type: {
+ var status = $historyEntry.status
+
+ if (status === HistoryModel.CallStatusSuccess) {
+ if (!$historyEntry.isStart) {
+ return 'ended_call'
+ }
+ return $historyEntry.isOutgoing ? 'outgoing_call' : 'incoming_call'
+ }
+ if (status === HistoryModel.CallStatusDeclined) {
+ return $historyEntry.isOutgoing ? 'declined_outgoing_call' : 'declined_incoming_call'
+ }
+ if (status === HistoryModel.CallStatusMissed) {
+ return $historyEntry.isOutgoing ? 'missed_outgoing_call' : 'missed_incoming_call'
+ }
+ if (status === HistoryModel.CallStatusAborted) {
+ return $historyEntry.isOutgoing ? 'outgoing_call' : 'incoming_call'
+ }
+ if (status === HistoryModel.CallStatusEarlyAborted) {
+ return $historyEntry.isOutgoing ? 'missed_outgoing_call' : 'missed_incoming_call'
+ }
+ if (status === HistoryModel.CallStatusAcceptedElsewhere) {
+ return $historyEntry.isOutgoing ? 'outgoing_call' : 'incoming_call'
+ }
+ if (status === HistoryModel.CallStatusDeclinedElsewhere) {
+ return $historyEntry.isOutgoing ? 'declined_outgoing_call' : 'declined_incoming_call'
+ }
+
+ return 'unknown_call_event'
+ }
+
+ height: HistoryStyle.entry.lineHeight
+ spacing: HistoryStyle.entry.message.extraContent.spacing
+
+ Icon {
+ height: parent.height
+ icon: _type
+ iconSize: HistoryStyle.entry.event.iconSize
+ width: HistoryStyle.entry.metaWidth
+ }
+
+ Text {
+ Component {
+ // Never created.
+ // Private data for `lupdate`.
+ Item {
+ property var i18n: [
+ QT_TR_NOOP('declinedIncomingCall'),
+ QT_TR_NOOP('declinedOutgoingCall'),
+ QT_TR_NOOP('endedCall'),
+ QT_TR_NOOP('incomingCall'),
+ QT_TR_NOOP('missedIncomingCall'),
+ QT_TR_NOOP('missedOutgoingCall'),
+ QT_TR_NOOP('outgoingCall')
+ ]
+ }
+ }
+
+ color: HistoryStyle.entry.event.text.color
+ font {
+ bold: true
+ pointSize: HistoryStyle.entry.event.text.pointSize
+ }
+ height: parent.height
+ text: qsTr(Utils.snakeToCamel(_type)) +' - '
+ verticalAlignment: Text.AlignVCenter
+ }
+ Text {
+ color: HistoryStyle.entry.event.text.color
+ font {
+ bold: true
+ pointSize: HistoryStyle.entry.event.text.pointSize
+ }
+ height: parent.height
+ text: LinphoneUtils.getContactUsername(_sipAddressObserver)
+ verticalAlignment: Text.AlignVCenter
+ MouseArea{
+ anchors.fill:parent
+ onClicked:entryClicked($historyEntry.sipAddress)
+ }
+ }
+ ActionButton {
+ height: HistoryStyle.entry.lineHeight
+ icon: 'delete'
+ iconSize: HistoryStyle.entry.deleteIconSize
+ visible: isHoverEntry()
+
+ onClicked: removeEntry()
+ }
+}
diff --git a/linphone-app/ui/modules/Linphone/History/History.js b/linphone-app/ui/modules/Linphone/History/History.js
new file mode 100644
index 000000000..6cef48676
--- /dev/null
+++ b/linphone-app/ui/modules/Linphone/History/History.js
@@ -0,0 +1,67 @@
+/*
+ * 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 .
+ */
+// =============================================================================
+// `Chat.qml` Logic.
+// =============================================================================
+
+.import QtQuick 2.7 as QtQuick
+
+.import Linphone 1.0 as Linphone
+
+.import 'qrc:/ui/scripts/LinphoneUtils/linphone-utils.js' as LinphoneUtils
+
+// =============================================================================
+
+function initView () {
+ history.tryToLoadMoreEntries = false
+ history.bindToEnd = true
+}
+
+function loadMoreEntries () {
+ if (history.atYBeginning && !history.tryToLoadMoreEntries) {
+ history.tryToLoadMoreEntries = true
+ history.positionViewAtBeginning()
+ container.proxyModel.loadMoreEntries()
+ }
+}
+
+function getComponentFromEntry (historyEntry) {
+
+ if (historyEntry.type === Linphone.HistoryModel.CallEntry) {
+ return 'Event.qml'
+ }
+
+ return ''
+}
+
+function handleMoreEntriesLoaded (n) {
+ history.positionViewAtIndex(n - 1, QtQuick.ListView.Beginning)
+ history.tryToLoadMoreEntries = false
+}
+
+function handleMovementEnded () {
+ if (history.atYEnd) {
+ history.bindToEnd = true
+ }
+}
+
+function handleMovementStarted () {
+ history.bindToEnd = false
+}
diff --git a/linphone-app/ui/modules/Linphone/History/History.qml b/linphone-app/ui/modules/Linphone/History/History.qml
new file mode 100644
index 000000000..d6b8a76f1
--- /dev/null
+++ b/linphone-app/ui/modules/Linphone/History/History.qml
@@ -0,0 +1,205 @@
+import QtQuick 2.7
+import QtQuick.Controls 2.2
+import QtQuick.Layouts 1.3
+
+import Common 1.0
+import Linphone 1.0
+import Linphone.Styles 1.0
+
+import 'History.js' as Logic
+
+// =============================================================================
+
+Rectangle {
+ id: container
+
+ property alias proxyModel: history.model
+ signal entryClicked(string sipAddress)
+
+ // ---------------------------------------------------------------------------
+
+ color: HistoryStyle.color
+
+ ColumnLayout {
+ anchors.fill: parent
+ spacing: 0
+
+ ScrollableListView {
+ id: history
+
+ // -----------------------------------------------------------------------
+
+ property bool bindToEnd: false
+ property bool tryToLoadMoreEntries: true
+
+ // -----------------------------------------------------------------------
+
+ Layout.fillHeight: true
+ Layout.fillWidth: true
+
+ highlightFollowsCurrentItem: false
+
+ section {
+ criteria: ViewSection.FullString
+ delegate: sectionHeading
+ property: '$sectionDate'
+ }
+
+ // -----------------------------------------------------------------------
+
+ Component.onCompleted: Logic.initView()
+
+ onContentYChanged: Logic.loadMoreEntries()
+ onMovementEnded: Logic.handleMovementEnded()
+ onMovementStarted: Logic.handleMovementStarted()
+
+ // -----------------------------------------------------------------------
+
+ Connections {
+ target: proxyModel
+
+ // When the view is changed (for example `Calls` -> `Messages`),
+ // the position is set at end and it can be possible to load
+ // more entries.
+ onEntryTypeFilterChanged: Logic.initView()
+ onMoreEntriesLoaded: Logic.handleMoreEntriesLoaded(n)
+ }
+
+ // -----------------------------------------------------------------------
+ // Heading.
+ // -----------------------------------------------------------------------
+
+ Component {
+ id: sectionHeading
+
+ Item {
+ implicitHeight: container.height + HistoryStyle.sectionHeading.bottomMargin
+ width: parent.width
+
+ Borders {
+ id: container
+
+ borderColor: HistoryStyle.sectionHeading.border.color
+ bottomWidth: HistoryStyle.sectionHeading.border.width
+ implicitHeight: text.contentHeight +
+ HistoryStyle.sectionHeading.padding * 2 +
+ HistoryStyle.sectionHeading.border.width * 2
+ topWidth: HistoryStyle.sectionHeading.border.width
+ width: parent.width
+
+ Text {
+ id: text
+
+ anchors.fill: parent
+ color: HistoryStyle.sectionHeading.text.color
+ font {
+ bold: true
+ pointSize: HistoryStyle.sectionHeading.text.pointSize
+ }
+ horizontalAlignment: Text.AlignHCenter
+ verticalAlignment: Text.AlignVCenter
+
+ // Cast section to integer because Qt converts the
+ // sectionDate in string!!!
+ text: new Date(section).toLocaleDateString(
+ Qt.locale(App.locale)
+ )
+ }
+ }
+ }
+ }
+
+ // -----------------------------------------------------------------------
+ // Message/Event renderer.
+ // -----------------------------------------------------------------------
+
+ delegate: Rectangle {
+ id: entry
+
+ function isHoverEntry () {
+ return mouseArea.containsMouse
+ }
+
+ function removeEntry () {
+ proxyModel.removeEntry(index)
+ }
+
+ anchors {
+ left: parent ? parent.left : undefined
+ leftMargin: HistoryStyle.entry.leftMargin
+ right: parent ? parent.right : undefined
+
+ rightMargin: HistoryStyle.entry.deleteIconSize +
+ HistoryStyle.entry.message.extraContent.spacing +
+ HistoryStyle.entry.message.extraContent.rightMargin +
+ HistoryStyle.entry.message.extraContent.leftMargin
+ }
+
+ color: HistoryStyle.color
+ implicitHeight: layout.height + HistoryStyle.entry.bottomMargin
+
+ // ---------------------------------------------------------------------
+
+ MouseArea {
+ id: mouseArea
+
+ cursorShape: Qt.ArrowCursor
+ hoverEnabled: true
+ implicitHeight: layout.height
+ width: parent.width + parent.anchors.rightMargin
+
+ RowLayout {
+ id: layout
+
+ spacing: 0
+ width: entry.width
+
+ // Display time.
+ Text {
+ Layout.alignment: Qt.AlignTop
+ Layout.preferredHeight: HistoryStyle.entry.lineHeight
+ Layout.preferredWidth: HistoryStyle.entry.time.width
+
+ color: HistoryStyle.entry.time.color
+ font.pointSize: HistoryStyle.entry.time.pointSize
+
+ text: $historyEntry.timestamp.toLocaleString(
+ Qt.locale(App.locale),
+ 'hh:mm'
+ )
+
+ verticalAlignment: Text.AlignVCenter
+
+ TooltipArea {
+ text: $historyEntry.timestamp.toLocaleString(Qt.locale(App.locale))
+ }
+ }
+
+ // Display content.
+ Loader {
+ id:entryLoader
+ Layout.fillWidth: true
+ source: Logic.getComponentFromEntry($historyEntry)
+ }
+ Connections{
+ target:entryLoader.item
+ onEntryClicked:{entryClicked(sipAddress)}
+ }
+ }
+ }
+ }
+ }
+ }
+
+ // ---------------------------------------------------------------------------
+ // Scroll at end if necessary.
+ // ---------------------------------------------------------------------------
+
+ Timer {
+ interval: 100
+ repeat: true
+ running: true
+
+ onTriggered: history.bindToEnd && history.positionViewAtEnd()
+ }
+}
diff --git a/linphone-app/ui/modules/Linphone/Menus/SipAddressesMenu.qml b/linphone-app/ui/modules/Linphone/Menus/SipAddressesMenu.qml
index 448716d09..f194974e3 100644
--- a/linphone-app/ui/modules/Linphone/Menus/SipAddressesMenu.qml
+++ b/linphone-app/ui/modules/Linphone/Menus/SipAddressesMenu.qml
@@ -101,7 +101,6 @@ Item {
id: mouseArea
anchors.fill: parent
- hoverEnabled: true
onClicked: {
menu.close()
diff --git a/linphone-app/ui/modules/Linphone/Notifications/NotificationBasic.qml b/linphone-app/ui/modules/Linphone/Notifications/NotificationBasic.qml
index c2ec8cd5f..369b4cea0 100644
--- a/linphone-app/ui/modules/Linphone/Notifications/NotificationBasic.qml
+++ b/linphone-app/ui/modules/Linphone/Notifications/NotificationBasic.qml
@@ -35,8 +35,6 @@ Notification {
MouseArea {
anchors.fill: parent
- cursorShape: containsMouse ? Qt.PointingHandCursor : Qt.ArrowCursor
- hoverEnabled: true
onClicked: notification._close(notification.handler)
}
diff --git a/linphone-app/ui/modules/Linphone/Notifications/NotificationReceivedFileMessage.qml b/linphone-app/ui/modules/Linphone/Notifications/NotificationReceivedFileMessage.qml
index d1a381218..28a89c92c 100644
--- a/linphone-app/ui/modules/Linphone/Notifications/NotificationReceivedFileMessage.qml
+++ b/linphone-app/ui/modules/Linphone/Notifications/NotificationReceivedFileMessage.qml
@@ -65,8 +65,6 @@ Notification {
MouseArea {
anchors.fill: parent
- cursorShape: containsMouse ? Qt.PointingHandCursor : Qt.ArrowCursor
- hoverEnabled: true
onClicked: notification._close(function () {
var uri = Utils.getUriFromSystemPath(notification.fileUri)
diff --git a/linphone-app/ui/modules/Linphone/Notifications/NotificationReceivedMessage.qml b/linphone-app/ui/modules/Linphone/Notifications/NotificationReceivedMessage.qml
index b15b03588..553c56dff 100644
--- a/linphone-app/ui/modules/Linphone/Notifications/NotificationReceivedMessage.qml
+++ b/linphone-app/ui/modules/Linphone/Notifications/NotificationReceivedMessage.qml
@@ -71,8 +71,6 @@ Notification {
MouseArea {
anchors.fill: parent
- cursorShape: containsMouse ? Qt.PointingHandCursor : Qt.ArrowCursor
- hoverEnabled: true
onClicked: notification._close(function () {
AccountSettingsModel.setDefaultProxyConfigFromSipAddress(notification.localAddress)
diff --git a/linphone-app/ui/modules/Linphone/Styles/History/HistoryStyle.qml b/linphone-app/ui/modules/Linphone/Styles/History/HistoryStyle.qml
new file mode 100644
index 000000000..e459a0ef3
--- /dev/null
+++ b/linphone-app/ui/modules/Linphone/Styles/History/HistoryStyle.qml
@@ -0,0 +1,61 @@
+pragma Singleton
+import QtQml 2.2
+
+import Colors 1.0
+import Units 1.0
+
+// =============================================================================
+
+QtObject {
+ property color color: Colors.q
+
+ property QtObject sectionHeading: QtObject {
+ property int padding: 5
+ property int bottomMargin: 20
+
+ property QtObject border: QtObject {
+ property color color: Colors.g10
+ property int width: 1
+ }
+
+ property QtObject text: QtObject {
+ property int pointSize: Units.dp * 10
+ property color color: Colors.g
+ }
+ }
+
+
+ property QtObject entry: QtObject {
+ property int bottomMargin: 10
+ property int deleteIconSize: 22
+ property int leftMargin: 18
+ property int lineHeight: 30
+ property int metaWidth: 40
+
+ property QtObject event: QtObject {
+ property int iconSize: 18
+
+ property QtObject text: QtObject {
+ property color color: Colors.d
+ property int pointSize: Units.dp * 10
+ }
+ }
+
+ property QtObject message: QtObject {
+ property int padding: 8
+ property int radius: 4
+
+ property QtObject extraContent: QtObject {
+ property int leftMargin: 10
+ property int spacing: 5
+ property int rightMargin: 5
+ }
+ }
+
+ property QtObject time: QtObject {
+ property color color: Colors.d
+ property int pointSize: Units.dp * 10
+ property int width: 44
+ }
+ }
+}
diff --git a/linphone-app/ui/modules/Linphone/Styles/Timeline/TimelineStyle.qml b/linphone-app/ui/modules/Linphone/Styles/Timeline/TimelineStyle.qml
index 78f033b97..a70b59ad0 100644
--- a/linphone-app/ui/modules/Linphone/Styles/Timeline/TimelineStyle.qml
+++ b/linphone-app/ui/modules/Linphone/Styles/Timeline/TimelineStyle.qml
@@ -34,7 +34,10 @@ QtObject {
}
property QtObject legend: QtObject {
- property color backgroundColor: Colors.f
+ property QtObject backgroundColor: QtObject {
+ property color normal: Colors.f
+ property color hovered: Colors.c
+ }
property color color: Colors.d
property int pointSize: Units.dp * 11
property int height: 30
diff --git a/linphone-app/ui/modules/Linphone/Styles/qmldir b/linphone-app/ui/modules/Linphone/Styles/qmldir
index 416f69706..e6ee7fb0c 100644
--- a/linphone-app/ui/modules/Linphone/Styles/qmldir
+++ b/linphone-app/ui/modules/Linphone/Styles/qmldir
@@ -25,6 +25,8 @@ singleton ContactStyle 1.0 Contact/ContactStyle.qml
singleton OnlineInstallerDialogStyle 1.0 Dialog/OnlineInstallerDialogStyle.qml
+singleton HistoryStyle 1.0 History/HistoryStyle.qml
+
singleton SipAddressesMenuStyle 1.0 Menus/SipAddressesMenuStyle.qml
singleton MessageCounterStyle 1.0 Misc/MessageCounterStyle.qml
diff --git a/linphone-app/ui/modules/Linphone/Timeline/Timeline.qml b/linphone-app/ui/modules/Linphone/Timeline/Timeline.qml
index b618dc899..fe90a60f0 100644
--- a/linphone-app/ui/modules/Linphone/Timeline/Timeline.qml
+++ b/linphone-app/ui/modules/Linphone/Timeline/Timeline.qml
@@ -55,7 +55,16 @@ Rectangle {
Rectangle {
Layout.fillWidth: true
Layout.preferredHeight: TimelineStyle.legend.height
- color: TimelineStyle.legend.backgroundColor
+ color: showHistory.containsMouse?TimelineStyle.legend.backgroundColor.hovered:TimelineStyle.legend.backgroundColor.normal
+
+ MouseArea{
+ id:showHistory
+ anchors.fill:parent
+ onClicked: {
+ view.currentIndex = -1
+ timeline.entrySelected('')
+ }
+ }
Row {
anchors {
diff --git a/linphone-app/ui/modules/Linphone/View/SipAddressesView.qml b/linphone-app/ui/modules/Linphone/View/SipAddressesView.qml
index 4bf1dc6ea..4cac04ac0 100644
--- a/linphone-app/ui/modules/Linphone/View/SipAddressesView.qml
+++ b/linphone-app/ui/modules/Linphone/View/SipAddressesView.qml
@@ -50,6 +50,7 @@ ScrollableListView {
// Workaround to handle mouse.
// Without it, the mouse can be given to items list when mouse is hover header.
hoverEnabled: true
+ cursorShape: Qt.ArrowCursor
Column {
anchors.fill: parent
@@ -194,7 +195,7 @@ ScrollableListView {
id: mouseArea
anchors.fill: parent
- hoverEnabled: true
+ cursorShape: Qt.ArrowCursor
RowLayout {
anchors {
@@ -215,12 +216,6 @@ ScrollableListView {
MouseArea {
anchors.fill: parent
-
- cursorShape: containsMouse
- ? Qt.PointingHandCursor
- : Qt.ArrowCursor
- hoverEnabled: true
-
onClicked: sipAddressesView.entryClicked($sipAddress)
}
}
diff --git a/linphone-app/ui/modules/Linphone/qmldir b/linphone-app/ui/modules/Linphone/qmldir
index 57f05a355..8f41a1d39 100644
--- a/linphone-app/ui/modules/Linphone/qmldir
+++ b/linphone-app/ui/modules/Linphone/qmldir
@@ -16,6 +16,8 @@ CallStatistics 1.0 Calls/CallStatistics.qml
Chat 1.0 Chat/Chat.qml
+History 1.0 History/History.qml
+
CodecsViewer 1.0 Codecs/CodecsViewer.qml
Avatar 1.0 Contact/Avatar.qml
diff --git a/linphone-app/ui/scripts/LinphoneUtils/linphone-utils.js b/linphone-app/ui/scripts/LinphoneUtils/linphone-utils.js
index 93b49afae..3c16a6ac3 100644
--- a/linphone-app/ui/scripts/LinphoneUtils/linphone-utils.js
+++ b/linphone-app/ui/scripts/LinphoneUtils/linphone-utils.js
@@ -84,28 +84,31 @@ function _getUsername (str) {
// Returns the username of a contact/sipAddressObserver object or URI string.
function getContactUsername (contact) {
- var object = contact.contact || // Contact object from `SipAddressObserver`.
- (contact.vcard && contact) // Contact object.
-
- // 1. `object` is a contact.
- if (object) {
- return object.vcard.username
- }
-
- // 2. `object` is just a string.
- object = Utils.isString(contact.peerAddress)
- ? contact.peerAddress // String from `SipAddressObserver`.
- : contact // Just a String.
-
- // Use display name.
- var name = _getDisplayName(object)
- if (name != null) {
- return name
- }
-
- // Use username.
- name = _getUsername(object)
- return name == null ? 'Bad EGG' : name
+ if(contact){
+ var object = contact.contact || // Contact object from `SipAddressObserver`.
+ (contact.vcard && contact) // Contact object.
+
+ // 1. `object` is a contact.
+ if (object) {
+ return object.vcard.username
+ }
+
+ // 2. `object` is just a string.
+ object = Utils.isString(contact.peerAddress)
+ ? contact.peerAddress // String from `SipAddressObserver`.
+ : contact // Just a String.
+
+ // Use display name.
+ var name = _getDisplayName(object)
+ if (name != null) {
+ return name
+ }
+
+ // Use username.
+ name = _getUsername(object)
+ return name == null ? 'Bad EGG' : name
+ }else
+ return '';
}
// =============================================================================
diff --git a/linphone-app/ui/views/App/Calls/IncallFullscreenWindow.qml b/linphone-app/ui/views/App/Calls/IncallFullscreenWindow.qml
index bbd2df5f3..98e6e34e3 100644
--- a/linphone-app/ui/views/App/Calls/IncallFullscreenWindow.qml
+++ b/linphone-app/ui/views/App/Calls/IncallFullscreenWindow.qml
@@ -101,8 +101,8 @@ Window {
anchors.fill: parent
acceptedButtons: Qt.NoButton
- hoverEnabled: true
propagateComposedEvents: true
+ cursorShape: Qt.ArrowCursor
onEntered: hideButtonsTimer.start()
onExited: hideButtonsTimer.stop()
diff --git a/linphone-app/ui/views/App/Main/Contacts.qml b/linphone-app/ui/views/App/Main/Contacts.qml
index ce4c70c39..378c5a776 100644
--- a/linphone-app/ui/views/App/Main/Contacts.qml
+++ b/linphone-app/ui/views/App/Main/Contacts.qml
@@ -208,14 +208,10 @@ ColumnLayout {
id: mouseArea
anchors.fill: parent
- hoverEnabled: true
+ cursorShape: Qt.ArrowCursor
MouseArea {
anchors.fill: parent
- cursorShape: containsMouse
- ? Qt.PointingHandCursor
- : Qt.ArrowCursor
- hoverEnabled: true
onClicked: window.setView('ContactEdit', {
sipAddress: $contact.vcard.sipAddresses[0]
diff --git a/linphone-app/ui/views/App/Main/Conversation.qml b/linphone-app/ui/views/App/Main/Conversation.qml
index 26320e079..937890419 100644
--- a/linphone-app/ui/views/App/Main/Conversation.qml
+++ b/linphone-app/ui/views/App/Main/Conversation.qml
@@ -102,9 +102,9 @@ ColumnLayout {
onClicked: window.setView('ContactEdit', {
sipAddress: conversation.peerAddress
})
- TooltipArea {
- text: Logic.getEditTooltipText()
- }
+ TooltipArea {
+ text: Logic.getEditTooltipText()
+ }
}
ActionButton {
diff --git a/linphone-app/ui/views/App/Main/HistoryView.js b/linphone-app/ui/views/App/Main/HistoryView.js
new file mode 100644
index 000000000..bc657b104
--- /dev/null
+++ b/linphone-app/ui/views/App/Main/HistoryView.js
@@ -0,0 +1,65 @@
+/*
+ * 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 .
+ */
+// =============================================================================
+// `Conversation.qml` Logic.
+// =============================================================================
+
+.import Linphone 1.0 as Linphone
+
+.import 'qrc:/ui/scripts/LinphoneUtils/linphone-utils.js' as LinphoneUtils
+.import 'qrc:/ui/scripts/Utils/utils.js' as Utils
+
+// =============================================================================
+
+function removeAllEntries () {
+ window.attachVirtualWindow(Utils.buildDialogUri('ConfirmDialog'), {
+ descriptionText: qsTr('removeAllEntriesDescription'),
+ }, function (status) {
+ if (status) {
+ historyProxyModel.removeAllEntries()
+ }
+ })
+}
+
+function getAvatar () {
+ var contact = historyView._sipAddressObserver.contact
+ return contact ? contact.vcard.avatar : ''
+}
+
+function getEditIcon () {
+ return historyView._sipAddressObserver && historyView._sipAddressObserver.contact ? 'contact_edit' : 'contact_add'
+}
+
+function getEditTooltipText() {
+ return historyView._sipAddressObserver && historyView._sipAddressObserver.contact ? qsTr('tooltipContactEdit') : qsTr('tooltipContactAdd')
+}
+
+function getUsername () {
+ return LinphoneUtils.getContactUsername(historyView._sipAddressObserver)
+}
+
+function updateHistoryFilter (button) {
+ var HistoryModel = Linphone.HistoryModel
+ if (button === 0) {
+ historyProxyModel.setEntryTypeFilter(HistoryModel.GenericEntry)
+ } else if (button === 1) {
+ historyProxyModel.setEntryTypeFilter(HistoryModel.CallEntry)
+ }
+}
diff --git a/linphone-app/ui/views/App/Main/HistoryView.qml b/linphone-app/ui/views/App/Main/HistoryView.qml
new file mode 100644
index 000000000..837bfc5ba
--- /dev/null
+++ b/linphone-app/ui/views/App/Main/HistoryView.qml
@@ -0,0 +1,150 @@
+import QtQuick 2.7
+import QtQuick.Layouts 1.3
+
+import Common 1.0
+import Linphone 1.0
+
+import App.Styles 1.0
+
+import 'HistoryView.js' as Logic
+
+// =============================================================================
+
+ColumnLayout {
+ id: historyView
+
+ property string peerAddress
+ property string fullPeerAddress
+
+ readonly property var _sipAddressObserver: peerAddress?SipAddressesModel.getSipAddressObserver((fullPeerAddress?fullPeerAddress:peerAddress), ''):null
+
+
+ // ---------------------------------------------------------------------------
+
+ spacing: 0
+
+ // ---------------------------------------------------------------------------
+ // Contact bar.
+ // ---------------------------------------------------------------------------
+
+ Rectangle {
+ Layout.fillWidth: true
+ Layout.preferredHeight: peerAddress?HistoryViewStyle.bar.height:HistoryViewStyle.bar.height/2
+
+ color: HistoryViewStyle.bar.backgroundColor
+
+ RowLayout {
+ anchors {
+ fill: parent
+ leftMargin: HistoryViewStyle.bar.leftMargin
+ rightMargin: HistoryViewStyle.bar.rightMargin
+ }
+ spacing: HistoryViewStyle.bar.spacing
+
+ layoutDirection: peerAddress?Qt.LeftToRight :Qt.RightToLeft
+
+ Avatar {
+ id: avatar
+
+ Layout.preferredHeight: HistoryViewStyle.bar.avatarSize
+ Layout.preferredWidth: HistoryViewStyle.bar.avatarSize
+
+ image: peerAddress?Logic.getAvatar():null
+
+ presenceLevel: historyView._sipAddressObserver?Presence.getPresenceLevel(
+ historyView._sipAddressObserver.presenceStatus
+ ):null
+
+ username: peerAddress?Logic.getUsername():null
+ visible:peerAddress
+ }
+
+ ContactDescription {
+ Layout.fillHeight: true
+ Layout.fillWidth: true
+
+ sipAddress: historyView.peerAddress
+ sipAddressColor: HistoryViewStyle.bar.description.sipAddressColor
+ username: avatar.username
+ usernameColor: HistoryViewStyle.bar.description.usernameColor
+ visible:peerAddress
+ }
+
+ Row {
+ Layout.fillHeight: true
+
+ spacing: HistoryViewStyle.bar.actions.spacing
+
+ ActionBar {
+ anchors.verticalCenter: parent.verticalCenter
+ iconSize: HistoryViewStyle.bar.actions.call.iconSize
+
+ ActionButton {
+ icon: 'video_call'
+ visible: peerAddress && SettingsModel.videoSupported && SettingsModel.outgoingCallsEnabled
+
+ onClicked: CallsListModel.launchVideoCall(historyView.peerAddress)
+ }
+
+ ActionButton {
+ icon: 'call'
+ visible: peerAddress && SettingsModel.outgoingCallsEnabled
+
+ onClicked: CallsListModel.launchAudioCall(historyView.peerAddress)
+ }
+ }
+
+ ActionBar {
+ anchors.verticalCenter: parent.verticalCenter
+
+ ActionButton {
+ icon: Logic.getEditIcon()
+ iconSize: HistoryViewStyle.bar.actions.edit.iconSize
+ visible: peerAddress && SettingsModel.contactsEnabled
+
+ onClicked: window.setView('ContactEdit', { sipAddress: historyView.peerAddress })
+ TooltipArea {
+ text: peerAddress?Logic.getEditTooltipText():''
+ }
+ }
+
+ ActionButton {
+ icon: 'delete'
+ iconSize: HistoryViewStyle.bar.actions.edit.iconSize
+
+ onClicked: Logic.removeAllEntries()
+
+ TooltipArea {
+ text: qsTr('cleanHistory')
+ }
+ }
+ }
+ }
+ }
+ }
+
+ // ---------------------------------------------------------------------------
+ // History.
+ // ---------------------------------------------------------------------------
+
+ History {
+ Layout.fillHeight: true
+ Layout.fillWidth: true
+
+ onEntryClicked:{
+ historyView.fullPeerAddress=sipAddress
+ historyView.peerAddress=sipAddress
+ historyProxyModel.resetMessageCount()
+ }
+
+ proxyModel: HistoryProxyModel {
+ id: historyProxyModel
+
+ Component.onCompleted: {
+ setEntryTypeFilter()
+ resetMessageCount()
+ }
+ }
+ }
+
+}
diff --git a/linphone-app/ui/views/App/Main/MainWindow.qml b/linphone-app/ui/views/App/Main/MainWindow.qml
index e69f6b8d6..cba397da8 100644
--- a/linphone-app/ui/views/App/Main/MainWindow.qml
+++ b/linphone-app/ui/views/App/Main/MainWindow.qml
@@ -110,6 +110,7 @@ ApplicationWindow {
TooltipArea {
text: AccountSettingsModel.sipAddress
+ hoveringCursor: Qt.PointingHandCursor
}
onClicked: {
@@ -260,12 +261,14 @@ ApplicationWindow {
Layout.fillWidth: true
model: TimelineModel
- onEntrySelected: setView('Conversation', {
- peerAddress: entry,
- localAddress: AccountSettingsModel.sipAddress,
- fullPeerAddress: entry,
- fullLocalAddress: AccountSettingsModel.fullSipAddress
- })
+ onEntrySelected: (entry?setView('Conversation', {
+ peerAddress: entry,
+ localAddress: AccountSettingsModel.sipAddress,
+ fullPeerAddress: entry,
+ fullLocalAddress: AccountSettingsModel.fullSipAddress
+ }):
+ setView('HistoryView', {})
+ )
}
}
@@ -279,7 +282,7 @@ ApplicationWindow {
Layout.fillWidth: true
source: 'Home.qml'
- }
+ }
}
}
}
@@ -287,7 +290,7 @@ ApplicationWindow {
// ---------------------------------------------------------------------------
// Url handlers.
// ---------------------------------------------------------------------------
-
+
Connections {
target: UrlHandlers
diff --git a/linphone-app/ui/views/App/Settings/SettingsWindow.qml b/linphone-app/ui/views/App/Settings/SettingsWindow.qml
index 374f3a81a..0227c4e33 100644
--- a/linphone-app/ui/views/App/Settings/SettingsWindow.qml
+++ b/linphone-app/ui/views/App/Settings/SettingsWindow.qml
@@ -116,6 +116,7 @@ ApplicationWindow {
anchors.fill: parent
onClicked: konami.forceActiveFocus()
+ cursorShape: Qt.ArrowCursor
Konami {
id: konami
diff --git a/linphone-app/ui/views/App/Styles/Main/HistoryViewStyle.qml b/linphone-app/ui/views/App/Styles/Main/HistoryViewStyle.qml
new file mode 100644
index 000000000..0cbc42ecc
--- /dev/null
+++ b/linphone-app/ui/views/App/Styles/Main/HistoryViewStyle.qml
@@ -0,0 +1,50 @@
+pragma Singleton
+import QtQml 2.2
+
+import Colors 1.0
+
+// =============================================================================
+
+QtObject {
+ property QtObject bar: QtObject {
+ property color backgroundColor: Colors.e
+ property int avatarSize: 60
+ property int height: 80
+ property int leftMargin: 40
+ property int rightMargin: 30
+ property int spacing: 20
+
+ property QtObject actions: QtObject {
+ property int spacing: 40
+
+ property QtObject call: QtObject {
+ property int iconSize: 40
+ }
+
+ property QtObject del: QtObject {
+ property int iconSize: 22
+ }
+
+ property QtObject edit: QtObject {
+ property int iconSize: 22
+ }
+ }
+
+ property QtObject description: QtObject {
+ property color sipAddressColor: Colors.g
+ property color usernameColor: Colors.j
+ }
+ }
+
+ property QtObject filters: QtObject {
+ property color backgroundColor: Colors.q
+ property int height: 51
+ property int leftMargin: 40
+
+ property QtObject border: QtObject {
+ property color color: Colors.g10
+ property int bottomWidth: 1
+ property int topWidth: 0
+ }
+ }
+}
diff --git a/linphone-app/ui/views/App/Styles/qmldir b/linphone-app/ui/views/App/Styles/qmldir
index b750e834b..6eafce9e8 100644
--- a/linphone-app/ui/views/App/Styles/qmldir
+++ b/linphone-app/ui/views/App/Styles/qmldir
@@ -29,6 +29,7 @@ singleton ContactEditStyle 1.0 Main/ContactEditSty
singleton ContactsStyle 1.0 Main/ContactsStyle.qml
singleton ConversationStyle 1.0 Main/ConversationStyle.qml
singleton HomeStyle 1.0 Main/HomeStyle.qml
+singleton HistoryViewStyle 1.0 Main/HistoryViewStyle.qml
singleton InviteFriendsStyle 1.0 Main/InviteFriendsStyle.qml
singleton MainWindowStyle 1.0 Main/MainWindowStyle.qml