mirror of
https://gitlab.linphone.org/BC/public/linphone-desktop.git
synced 2026-05-07 14:44:01 +00:00
Rework Data models to fit SDK : eg. ChatModel into ChatRoomModel
Use models as it is from QML and avoid to use data translations (using address to get chat room replaced by using directly the chat room) Use SDK chat room handlers on ChatRooms instead of general Core Handlers Use a timeline as a proxy of chat rooms Move events managments like unread messages or missed call to chat rooms Add Chat rooms list and proxy, Participants Add prototype for managing secure chat room Add secure group chats feature Convert some deprecated functions Fix contacts display name and allow to show a subject instead of an address Qt bug workaround : remove annoying warnings on Qt 5.15.1 and later Fix secure group chat creation by adding the conference factory address to linphonerc and to the settings panel
This commit is contained in:
parent
0850c59395
commit
8cb6261cb3
54 changed files with 1840 additions and 589 deletions
|
|
@ -122,8 +122,9 @@ set(SOURCES
|
|||
src/components/calls/CallsListProxyModel.cpp
|
||||
src/components/camera/Camera.cpp
|
||||
src/components/camera/CameraPreview.cpp
|
||||
src/components/chat/ChatModel.cpp
|
||||
src/components/chat/ChatProxyModel.cpp
|
||||
src/components/chat-room/ChatRoomModel.cpp
|
||||
src/components/chat-room/ChatRoomListModel.cpp
|
||||
src/components/chat-room/ChatRoomProxyModel.cpp
|
||||
src/components/codecs/AbstractCodecsModel.cpp
|
||||
src/components/codecs/AudioCodecsModel.cpp
|
||||
src/components/codecs/VideoCodecsModel.cpp
|
||||
|
|
@ -153,6 +154,7 @@ set(SOURCES
|
|||
src/components/other/colors/Colors.cpp
|
||||
src/components/other/text-to-speech/TextToSpeech.cpp
|
||||
src/components/other/units/Units.cpp
|
||||
src/components/participant/ParticipantModel.cpp
|
||||
src/components/presence/OwnPresenceModel.cpp
|
||||
src/components/presence/Presence.cpp
|
||||
src/components/search/SearchHandler.cpp
|
||||
|
|
@ -198,8 +200,9 @@ set(HEADERS
|
|||
src/components/calls/CallsListProxyModel.hpp
|
||||
src/components/camera/Camera.hpp
|
||||
src/components/camera/CameraPreview.hpp
|
||||
src/components/chat/ChatModel.hpp
|
||||
src/components/chat/ChatProxyModel.hpp
|
||||
src/components/chat-room/ChatRoomModel.hpp
|
||||
src/components/chat-room/ChatRoomListModel.hpp
|
||||
src/components/chat-room/ChatRoomProxyModel.hpp
|
||||
src/components/codecs/AbstractCodecsModel.hpp
|
||||
src/components/codecs/AudioCodecsModel.hpp
|
||||
src/components/codecs/VideoCodecsModel.hpp
|
||||
|
|
@ -231,6 +234,7 @@ set(HEADERS
|
|||
src/components/other/desktop-tools/DesktopTools.hpp
|
||||
src/components/other/text-to-speech/TextToSpeech.hpp
|
||||
src/components/other/units/Units.hpp
|
||||
src/components/participant/ParticipantModel.hpp
|
||||
src/components/presence/OwnPresenceModel.hpp
|
||||
src/components/presence/Presence.hpp
|
||||
src/components/search/SearchHandler.hpp
|
||||
|
|
|
|||
|
|
@ -432,6 +432,7 @@
|
|||
<file>ui/views/App/Main/Dialogs/AuthenticationRequest.qml</file>
|
||||
<file>ui/views/App/Main/Dialogs/ManageAccount.js</file>
|
||||
<file>ui/views/App/Main/Dialogs/ManageAccounts.qml</file>
|
||||
<file>ui/views/App/Main/Dialogs/ManageChatRoom.qml</file>
|
||||
<file>ui/views/App/Main/Home.qml</file>
|
||||
<file>ui/views/App/Main/HistoryView.qml</file>
|
||||
<file>ui/views/App/Main/HistoryView.js</file>
|
||||
|
|
|
|||
|
|
@ -582,17 +582,17 @@ void App::registerTypes () {
|
|||
qInfo() << QStringLiteral("Registering types...");
|
||||
|
||||
qRegisterMetaType<shared_ptr<linphone::ProxyConfig>>();
|
||||
qRegisterMetaType<ChatModel::EntryType>();
|
||||
qRegisterMetaType<ChatRoomModel::EntryType>();
|
||||
qRegisterMetaType<shared_ptr<linphone::SearchResult>>();
|
||||
qRegisterMetaType<std::list<std::shared_ptr<linphone::SearchResult> > >();
|
||||
qRegisterMetaType<std::shared_ptr<ChatModel>>();
|
||||
qRegisterMetaType<std::shared_ptr<ChatRoomModel>>();
|
||||
|
||||
registerType<AssistantModel>("AssistantModel");
|
||||
registerType<AuthenticationNotifier>("AuthenticationNotifier");
|
||||
registerType<CallsListProxyModel>("CallsListProxyModel");
|
||||
registerType<Camera>("Camera");
|
||||
registerType<CameraPreview>("CameraPreview");
|
||||
registerType<ChatProxyModel>("ChatProxyModel");
|
||||
registerType<ChatRoomProxyModel>("ChatRoomProxyModel");
|
||||
registerType<ConferenceHelperModel>("ConferenceHelperModel");
|
||||
registerType<ConferenceModel>("ConferenceModel");
|
||||
registerType<ContactsListProxyModel>("ContactsListProxyModel");
|
||||
|
|
@ -616,7 +616,7 @@ void App::registerTypes () {
|
|||
registerSingletonType<VideoCodecsModel>("VideoCodecsModel");
|
||||
|
||||
registerUncreatableType<CallModel>("CallModel");
|
||||
registerUncreatableType<ChatModel>("ChatModel");
|
||||
registerUncreatableType<ChatRoomModel>("ChatRoomModel");
|
||||
registerUncreatableType<ConferenceHelperModel::ConferenceAddModel>("ConferenceAddModel");
|
||||
registerUncreatableType<ContactModel>("ContactModel");
|
||||
registerUncreatableType<ContactsImporterModel>("ContactsImporterModel");
|
||||
|
|
|
|||
|
|
@ -23,6 +23,7 @@
|
|||
#include <QDateTime>
|
||||
#include <QThread>
|
||||
#include <QMessageBox>
|
||||
#include <QLoggingCategory>
|
||||
|
||||
#include "config.h"
|
||||
|
||||
|
|
@ -192,7 +193,7 @@ void Logger::enable (bool status) {
|
|||
void Logger::init (const shared_ptr<linphone::Config> &config) {
|
||||
if (mInstance)
|
||||
return;
|
||||
|
||||
QLoggingCategory::setFilterRules("qt.qml.connections.warning=false");
|
||||
const QString folder = SettingsModel::getLogsFolder(config);
|
||||
Q_ASSERT(!folder.isEmpty());
|
||||
|
||||
|
|
|
|||
|
|
@ -28,7 +28,7 @@
|
|||
#include "calls/CallsListProxyModel.hpp"
|
||||
#include "camera/Camera.hpp"
|
||||
#include "camera/CameraPreview.hpp"
|
||||
#include "chat/ChatProxyModel.hpp"
|
||||
#include "chat-room/ChatRoomProxyModel.hpp"
|
||||
#include "codecs/AudioCodecsModel.hpp"
|
||||
#include "codecs/VideoCodecsModel.hpp"
|
||||
#include "conference/ConferenceAddModel.hpp"
|
||||
|
|
|
|||
|
|
@ -26,6 +26,8 @@
|
|||
|
||||
#include "app/App.hpp"
|
||||
#include "components/calls/CallsListModel.hpp"
|
||||
#include "components/contact/ContactModel.hpp"
|
||||
#include "components/contacts/ContactsListModel.hpp"
|
||||
#include "components/core/CoreHandlers.hpp"
|
||||
#include "components/core/CoreManager.hpp"
|
||||
#include "components/notifier/Notifier.hpp"
|
||||
|
|
@ -112,6 +114,13 @@ QString CallModel::getFullLocalAddress () const {
|
|||
}
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
ContactModel *CallModel::getContactModel() const{
|
||||
auto contact = CoreManager::getInstance()->getContactsListModel()->findContactModelFromSipAddress(QString::fromStdString(mCall->getRemoteAddress()->asString()));
|
||||
return contact;
|
||||
}
|
||||
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
void CallModel::setRecordFile (const shared_ptr<linphone::CallParams> &callParams) {
|
||||
callParams->setRecordFile(Utils::appStringToCoreString(
|
||||
CoreManager::getInstance()->getSettingsModel()->getSavedCallsFolder()
|
||||
|
|
|
|||
|
|
@ -26,6 +26,7 @@
|
|||
#include "../search/SearchHandler.hpp"
|
||||
|
||||
// =============================================================================
|
||||
class ContactModel;
|
||||
|
||||
class CallModel : public QObject {
|
||||
Q_OBJECT;
|
||||
|
|
@ -34,6 +35,12 @@ class CallModel : public QObject {
|
|||
Q_PROPERTY(QString localAddress READ getLocalAddress CONSTANT);
|
||||
Q_PROPERTY(QString fullPeerAddress READ getFullPeerAddress NOTIFY fullPeerAddressChanged);
|
||||
Q_PROPERTY(QString fullLocalAddress READ getFullLocalAddress CONSTANT);
|
||||
|
||||
Q_PROPERTY(ContactModel *contact READ getContactModel CONSTANT )/*
|
||||
Q_PROPERTY(QString sipAddress READ getFullPeerAddress NOTIFY fullPeerAddressChanged)
|
||||
Q_PROPERTY(QString username READ getUsername NOTIFY usernameChanged)
|
||||
Q_PROPERTY(QString avatar READ getAvatar NOTIFY avatarChanged)
|
||||
Q_PROPERTY(int presenceStatus READ getPresenceStatus NOTIFY presenceStatusChanged)*/
|
||||
|
||||
Q_PROPERTY(CallStatus status READ getStatus NOTIFY statusChanged);
|
||||
Q_PROPERTY(QString callError READ getCallError NOTIFY callErrorChanged);
|
||||
|
|
@ -98,6 +105,8 @@ public:
|
|||
QString getLocalAddress () const;
|
||||
QString getFullPeerAddress () const;
|
||||
QString getFullLocalAddress () const;
|
||||
|
||||
ContactModel *getContactModel() const;
|
||||
|
||||
bool isInConference () const {
|
||||
return mIsInConference;
|
||||
|
|
|
|||
|
|
@ -183,6 +183,29 @@ bool CallsListModel::launchSecureChat (const QString &sipAddress) const {
|
|||
*/
|
||||
return false;
|
||||
}
|
||||
|
||||
bool CallsListModel::createSecureChat (const QString& subject, const QString &participantAddress) const{
|
||||
shared_ptr<linphone::Core> core = CoreManager::getInstance()->getCore();
|
||||
shared_ptr<linphone::Address> address = core->interpretUrl(Utils::appStringToCoreString(participantAddress));
|
||||
if (!address)
|
||||
return false;
|
||||
|
||||
std::shared_ptr<linphone::ChatRoomParams> params = core->createDefaultChatRoomParams();
|
||||
std::list <shared_ptr<linphone::Address> > participants;
|
||||
std::shared_ptr<const linphone::Address> localAddress;
|
||||
participants.push_back(address);
|
||||
auto proxy = core->getDefaultProxyConfig();
|
||||
params->enableEncryption(true);
|
||||
|
||||
params->setSubject(subject.toStdString());
|
||||
params->setBackend(linphone::ChatRoomBackend::FlexisipChat);
|
||||
params->setEncryptionBackend(linphone::ChatRoomEncryptionBackend::Lime);
|
||||
params->enableGroup(true);
|
||||
|
||||
std::shared_ptr<linphone::ChatRoom> chatRoom = core->createChatRoom(params, localAddress, participants);
|
||||
return chatRoom != nullptr;
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
int CallsListModel::getRunningCallsNumber () const {
|
||||
|
|
|
|||
|
|
@ -45,6 +45,7 @@ public:
|
|||
Q_INVOKABLE void launchAudioCall (const QString &sipAddress, const QHash<QString, QString> &headers = {}) const;
|
||||
Q_INVOKABLE void launchVideoCall (const QString &sipAddress) const;
|
||||
Q_INVOKABLE bool launchSecureChat (const QString &sipAddress) const;
|
||||
Q_INVOKABLE bool createSecureChat (const QString& subject, const QString &participantAddress) const;
|
||||
|
||||
Q_INVOKABLE int getRunningCallsNumber () const;
|
||||
|
||||
|
|
|
|||
96
linphone-app/src/components/chat-room/ChatRoomListModel.cpp
Normal file
96
linphone-app/src/components/chat-room/ChatRoomListModel.cpp
Normal file
|
|
@ -0,0 +1,96 @@
|
|||
/*
|
||||
* Copyright (c) 2021 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 <QQmlApplicationEngine>
|
||||
#include <QQuickWindow>
|
||||
#include <QTimer>
|
||||
|
||||
#include "app/App.hpp"
|
||||
#include "components/conference/ConferenceAddModel.hpp"
|
||||
#include "components/conference/ConferenceHelperModel.hpp"
|
||||
#include "components/core/CoreHandlers.hpp"
|
||||
#include "components/core/CoreManager.hpp"
|
||||
#include "components/settings/SettingsModel.hpp"
|
||||
#include "utils/Utils.hpp"
|
||||
|
||||
#include "ChatRoomListModel.hpp"
|
||||
#include "ChatRoomModel.hpp"
|
||||
|
||||
// =============================================================================
|
||||
|
||||
using namespace std;
|
||||
|
||||
namespace {
|
||||
// Delay before removing call in ms.
|
||||
constexpr int DelayBeforeRemoveCall = 3000;
|
||||
}
|
||||
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
ChatRoomListModel::ChatRoomListModel (QObject *parent) : QAbstractListModel(parent) {
|
||||
}
|
||||
|
||||
int ChatRoomListModel::rowCount (const QModelIndex &) const {
|
||||
return mList.count();
|
||||
}
|
||||
|
||||
QHash<int, QByteArray> ChatRoomListModel::roleNames () const {
|
||||
QHash<int, QByteArray> roles;
|
||||
roles[Qt::DisplayRole] = "$chatRoom";
|
||||
return roles;
|
||||
}
|
||||
|
||||
QVariant ChatRoomListModel::data (const QModelIndex &index, int role) const {
|
||||
int row = index.row();
|
||||
|
||||
if (!index.isValid() || row < 0 || row >= mList.count())
|
||||
return QVariant();
|
||||
|
||||
if (role == Qt::DisplayRole)
|
||||
return QVariant::fromValue(mList[row]);
|
||||
|
||||
return QVariant();
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
|
||||
bool ChatRoomListModel::removeRow (int row, const QModelIndex &parent) {
|
||||
return removeRows(row, 1, parent);
|
||||
}
|
||||
|
||||
bool ChatRoomListModel::removeRows (int row, int count, const QModelIndex &parent) {
|
||||
int limit = row + count - 1;
|
||||
|
||||
if (row < 0 || count < 0 || limit >= mList.count())
|
||||
return false;
|
||||
|
||||
beginRemoveRows(parent, row, limit);
|
||||
|
||||
for (int i = 0; i < count; ++i)
|
||||
mList.takeAt(row)->deleteLater();
|
||||
|
||||
endRemoveRows();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
51
linphone-app/src/components/chat-room/ChatRoomListModel.hpp
Normal file
51
linphone-app/src/components/chat-room/ChatRoomListModel.hpp
Normal file
|
|
@ -0,0 +1,51 @@
|
|||
/*
|
||||
* Copyright (c) 2021 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 _CHAT_ROOM_LIST_MODEL_H_
|
||||
#define _CHAT_ROOM_LIST_MODEL_H_
|
||||
|
||||
#include <linphone++/linphone.hh>
|
||||
#include <QAbstractListModel>
|
||||
|
||||
// =============================================================================
|
||||
|
||||
class ChatRoomModel;
|
||||
|
||||
class ChatRoomListModel : public QAbstractListModel {
|
||||
Q_OBJECT;
|
||||
|
||||
public:
|
||||
ChatRoomListModel (QObject *parent = Q_NULLPTR);
|
||||
|
||||
int rowCount (const QModelIndex &index = QModelIndex()) const override;
|
||||
|
||||
QHash<int, QByteArray> roleNames () const override;
|
||||
QVariant data (const QModelIndex &index, int role = Qt::DisplayRole) const override;
|
||||
|
||||
|
||||
private:
|
||||
bool removeRow (int row, const QModelIndex &parent = QModelIndex());
|
||||
bool removeRows (int row, int count, const QModelIndex &parent = QModelIndex()) override;
|
||||
|
||||
QList<ChatRoomModel *> mList;
|
||||
|
||||
};
|
||||
|
||||
#endif // _CHAT_ROOM_LIST_MODEL_H_
|
||||
|
|
@ -34,14 +34,19 @@
|
|||
#include "app/App.hpp"
|
||||
#include "app/paths/Paths.hpp"
|
||||
#include "app/providers/ThumbnailProvider.hpp"
|
||||
#include "components/contact/ContactModel.hpp"
|
||||
#include "components/contact/VcardModel.hpp"
|
||||
#include "components/contacts/ContactsListModel.hpp"
|
||||
#include "components/core/CoreHandlers.hpp"
|
||||
#include "components/core/CoreManager.hpp"
|
||||
#include "components/notifier/Notifier.hpp"
|
||||
#include "components/settings/SettingsModel.hpp"
|
||||
#include "components/participant/ParticipantModel.hpp"
|
||||
#include "components/presence/Presence.hpp"
|
||||
#include "utils/QExifImageHeader.hpp"
|
||||
#include "utils/Utils.hpp"
|
||||
|
||||
#include "ChatModel.hpp"
|
||||
#include "ChatRoomModel.hpp"
|
||||
|
||||
// =============================================================================
|
||||
|
||||
|
|
@ -204,9 +209,9 @@ static inline void fillMessageEntry (QVariantMap &dest, const shared_ptr<linphon
|
|||
// It can exist messages with a not delivered status. It's a linphone core bug.
|
||||
linphone::ChatMessage::State state = message->getState();
|
||||
if (state == linphone::ChatMessage::State::InProgress)
|
||||
dest["status"] = ChatModel::MessageStatusNotDelivered;
|
||||
dest["status"] = ChatRoomModel::MessageStatusNotDelivered;
|
||||
else
|
||||
dest["status"] = static_cast<ChatModel::MessageStatus>(message->getState());
|
||||
dest["status"] = static_cast<ChatRoomModel::MessageStatus>(message->getState());
|
||||
|
||||
shared_ptr<const linphone::Content> content = message->getFileTransferInformation();
|
||||
if (content) {
|
||||
|
|
@ -220,39 +225,39 @@ static inline void fillMessageEntry (QVariantMap &dest, const shared_ptr<linphon
|
|||
}
|
||||
|
||||
static inline void fillCallStartEntry (QVariantMap &dest, const shared_ptr<linphone::CallLog> &callLog) {
|
||||
dest["type"] = ChatModel::CallEntry;
|
||||
dest["type"] = ChatRoomModel::CallEntry;
|
||||
dest["timestamp"] = QDateTime::fromMSecsSinceEpoch(callLog->getStartDate() * 1000);
|
||||
dest["isOutgoing"] = callLog->getDir() == linphone::Call::Dir::Outgoing;
|
||||
dest["status"] = static_cast<ChatModel::CallStatus>(callLog->getStatus());
|
||||
dest["status"] = static_cast<ChatRoomModel::CallStatus>(callLog->getStatus());
|
||||
dest["isStart"] = true;
|
||||
}
|
||||
|
||||
static inline void fillCallEndEntry (QVariantMap &dest, const shared_ptr<linphone::CallLog> &callLog) {
|
||||
dest["type"] = ChatModel::CallEntry;
|
||||
dest["type"] = ChatRoomModel::CallEntry;
|
||||
dest["timestamp"] = QDateTime::fromMSecsSinceEpoch((callLog->getStartDate() + callLog->getDuration()) * 1000);
|
||||
dest["isOutgoing"] = callLog->getDir() == linphone::Call::Dir::Outgoing;
|
||||
dest["status"] = static_cast<ChatModel::CallStatus>(callLog->getStatus());
|
||||
dest["status"] = static_cast<ChatRoomModel::CallStatus>(callLog->getStatus());
|
||||
dest["isStart"] = false;
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
class ChatModel::MessageHandlers : public linphone::ChatMessageListener {
|
||||
friend class ChatModel;
|
||||
class ChatRoomModel::MessageHandlers : public linphone::ChatMessageListener {
|
||||
friend class ChatRoomModel;
|
||||
|
||||
public:
|
||||
MessageHandlers (ChatModel *chatModel) : mChatModel(chatModel) {}
|
||||
MessageHandlers (ChatRoomModel *ChatRoomModel) : mChatRoomModel(ChatRoomModel) {}
|
||||
|
||||
private:
|
||||
QList<ChatEntryData>::iterator findMessageEntry (const shared_ptr<linphone::ChatMessage> &message) {
|
||||
return find_if(mChatModel->mEntries.begin(), mChatModel->mEntries.end(), [&message](const ChatEntryData &entry) {
|
||||
return find_if(mChatRoomModel->mEntries.begin(), mChatRoomModel->mEntries.end(), [&message](const ChatEntryData &entry) {
|
||||
return entry.second == message;
|
||||
});
|
||||
}
|
||||
|
||||
void signalDataChanged (const QList<ChatEntryData>::iterator &it) {
|
||||
int row = int(distance(mChatModel->mEntries.begin(), it));
|
||||
emit mChatModel->dataChanged(mChatModel->index(row, 0), mChatModel->index(row, 0));
|
||||
int row = int(distance(mChatRoomModel->mEntries.begin(), it));
|
||||
emit mChatRoomModel->dataChanged(mChatRoomModel->index(row, 0), mChatRoomModel->index(row, 0));
|
||||
}
|
||||
|
||||
shared_ptr<linphone::Buffer> onFileTransferSend (
|
||||
|
|
@ -271,11 +276,11 @@ private:
|
|||
size_t offset,
|
||||
size_t
|
||||
) override {
|
||||
if (!mChatModel)
|
||||
if (!mChatRoomModel)
|
||||
return;
|
||||
|
||||
auto it = findMessageEntry(message);
|
||||
if (it == mChatModel->mEntries.end())
|
||||
if (it == mChatRoomModel->mEntries.end())
|
||||
return;
|
||||
|
||||
(*it).first["fileOffset"] = quint64(offset);
|
||||
|
|
@ -284,11 +289,11 @@ private:
|
|||
}
|
||||
|
||||
void onMsgStateChanged (const shared_ptr<linphone::ChatMessage> &message, linphone::ChatMessage::State state) override {
|
||||
if (!mChatModel)
|
||||
if (!mChatRoomModel)
|
||||
return;
|
||||
|
||||
auto it = findMessageEntry(message);
|
||||
if (it == mChatModel->mEntries.end())
|
||||
if (it == mChatRoomModel->mEntries.end())
|
||||
return;
|
||||
|
||||
// File message downloaded.
|
||||
|
|
@ -304,12 +309,12 @@ private:
|
|||
signalDataChanged(it);
|
||||
}
|
||||
|
||||
ChatModel *mChatModel;
|
||||
ChatRoomModel *mChatRoomModel;
|
||||
};
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
ChatModel::ChatModel (const QString &peerAddress, const QString &localAddress, const bool& isSecure) {
|
||||
/*
|
||||
ChatRoomModel::ChatRoomModel (const QString &peerAddress, const QString &localAddress, const bool& isSecure) {
|
||||
CoreManager *coreManager = CoreManager::getInstance();
|
||||
|
||||
mCoreHandlers = coreManager->getHandlers();
|
||||
|
|
@ -319,21 +324,10 @@ ChatModel::ChatModel (const QString &peerAddress, const QString &localAddress, c
|
|||
shared_ptr<linphone::Factory> factory(linphone::Factory::get());
|
||||
std::shared_ptr<linphone::ChatRoomParams> params = core->createDefaultChatRoomParams();
|
||||
std::list<std::shared_ptr<linphone::Address>> participants;
|
||||
|
||||
//params->enableEncryption(isSecure);
|
||||
//if(isSecure){
|
||||
// params->setBackend(linphone::ChatRoomBackend::FlexisipChat);
|
||||
// params->setEncryptionBackend(linphone::ChatRoomEncryptionBackend::Lime);
|
||||
// }
|
||||
|
||||
|
||||
mChatRoom = core->searchChatRoom(params, factory->createAddress(localAddress.toStdString())
|
||||
, factory->createAddress(peerAddress.toStdString())
|
||||
, participants);
|
||||
/*
|
||||
mChatRoom = core->getChatRoom(
|
||||
factory->createAddress(peerAddress.toStdString()),
|
||||
factory->createAddress(localAddress.toStdString())
|
||||
);*/
|
||||
Q_ASSERT(mChatRoom);
|
||||
|
||||
handleIsComposingChanged(mChatRoom);
|
||||
|
|
@ -358,7 +352,7 @@ ChatModel::ChatModel (const QString &peerAddress, const QString &localAddress, c
|
|||
for (auto &callLog : core->getCallHistory(mChatRoom->getPeerAddress(), mChatRoom->getLocalAddress()))
|
||||
insertCall(callLog);
|
||||
|
||||
qInfo() << QStringLiteral("ChatModel (%1, %2) loaded in %3 milliseconds.")
|
||||
qInfo() << QStringLiteral("ChatRoomModel (%1, %2) loaded in %3 milliseconds.")
|
||||
.arg(peerAddress).arg(localAddress).arg(timer.elapsed());
|
||||
|
||||
// Rebind lost handlers
|
||||
|
|
@ -371,15 +365,16 @@ ChatModel::ChatModel (const QString &peerAddress, const QString &localAddress, c
|
|||
}
|
||||
{
|
||||
CoreHandlers *coreHandlers = mCoreHandlers.get();
|
||||
QObject::connect(coreHandlers, &CoreHandlers::messageReceived, this, &ChatModel::handleMessageReceived);
|
||||
QObject::connect(coreHandlers, &CoreHandlers::callStateChanged, this, &ChatModel::handleCallStateChanged);
|
||||
QObject::connect(coreHandlers, &CoreHandlers::isComposingChanged, this, &ChatModel::handleIsComposingChanged);
|
||||
QObject::connect(coreHandlers, &CoreHandlers::messageReceived, this, &ChatRoomModel::handleMessageReceived);
|
||||
QObject::connect(coreHandlers, &CoreHandlers::callStateChanged, this, &ChatRoomModel::handleCallStateChanged);
|
||||
QObject::connect(coreHandlers, &CoreHandlers::isComposingChanged, this, &ChatRoomModel::handleIsComposingChanged);
|
||||
}
|
||||
if(!mChatRoom)
|
||||
qWarning("TOTO A");
|
||||
}
|
||||
*/
|
||||
|
||||
ChatModel::ChatModel (std::shared_ptr<linphone::ChatRoom> chatRoom){
|
||||
ChatRoomModel::ChatRoomModel (std::shared_ptr<linphone::ChatRoom> chatRoom){
|
||||
CoreManager *coreManager = CoreManager::getInstance();
|
||||
|
||||
mCoreHandlers = coreManager->getHandlers();
|
||||
|
|
@ -394,8 +389,12 @@ ChatModel::ChatModel (std::shared_ptr<linphone::ChatRoom> chatRoom){
|
|||
mChatRoom = chatRoom;
|
||||
|
||||
Q_ASSERT(mChatRoom);
|
||||
|
||||
setLastUpdateTime(QDateTime::fromMSecsSinceEpoch(chatRoom->getLastUpdateTime()));
|
||||
setUnreadMessagesCount(chatRoom->getUnreadMessagesCount());
|
||||
mMissedCallsCount = 0;
|
||||
|
||||
handleIsComposingChanged(mChatRoom);
|
||||
//handleIsComposingChanged(mChatRoom);
|
||||
|
||||
// Get messages.
|
||||
mEntries.clear();
|
||||
|
|
@ -430,30 +429,35 @@ ChatModel::ChatModel (std::shared_ptr<linphone::ChatRoom> chatRoom){
|
|||
}
|
||||
{
|
||||
CoreHandlers *coreHandlers = mCoreHandlers.get();
|
||||
QObject::connect(coreHandlers, &CoreHandlers::messageReceived, this, &ChatModel::handleMessageReceived);
|
||||
QObject::connect(coreHandlers, &CoreHandlers::callStateChanged, this, &ChatModel::handleCallStateChanged);
|
||||
QObject::connect(coreHandlers, &CoreHandlers::isComposingChanged, this, &ChatModel::handleIsComposingChanged);
|
||||
//QObject::connect(coreHandlers, &CoreHandlers::messageReceived, this, &ChatRoomModel::handleMessageReceived);
|
||||
QObject::connect(coreHandlers, &CoreHandlers::callCreated, this, &ChatRoomModel::handleCallCreated);
|
||||
QObject::connect(coreHandlers, &CoreHandlers::callStateChanged, this, &ChatRoomModel::handleCallStateChanged);
|
||||
//QObject::connect(coreHandlers, &CoreHandlers::isComposingChanged, this, &ChatRoomModel::handleIsComposingChanged);
|
||||
}
|
||||
if(mChatRoom){
|
||||
std::list<std::shared_ptr<linphone::Participant>> participants = mChatRoom->getParticipants();
|
||||
for(auto it = participants.begin() ; it != participants.end() ; ++it){
|
||||
mParticipants << new ParticipantModel(*it, this);
|
||||
}
|
||||
}
|
||||
if(!mChatRoom)
|
||||
qWarning("TOTO B");
|
||||
}
|
||||
|
||||
ChatModel::~ChatModel () {
|
||||
mMessageHandlers->mChatModel = nullptr;
|
||||
ChatRoomModel::~ChatRoomModel () {
|
||||
mMessageHandlers->mChatRoomModel = nullptr;
|
||||
}
|
||||
|
||||
QHash<int, QByteArray> ChatModel::roleNames () const {
|
||||
QHash<int, QByteArray> ChatRoomModel::roleNames () const {
|
||||
QHash<int, QByteArray> roles;
|
||||
roles[Roles::ChatEntry] = "$chatEntry";
|
||||
roles[Roles::SectionDate] = "$sectionDate";
|
||||
return roles;
|
||||
}
|
||||
|
||||
int ChatModel::rowCount (const QModelIndex &) const {
|
||||
int ChatRoomModel::rowCount (const QModelIndex &) const {
|
||||
return mEntries.count();
|
||||
}
|
||||
|
||||
QVariant ChatModel::data (const QModelIndex &index, int role) const {
|
||||
QVariant ChatRoomModel::data (const QModelIndex &index, int role) const {
|
||||
int row = index.row();
|
||||
|
||||
if (!index.isValid() || row < 0 || row >= mEntries.count())
|
||||
|
|
@ -473,11 +477,11 @@ QVariant ChatModel::data (const QModelIndex &index, int role) const {
|
|||
return QVariant();
|
||||
}
|
||||
|
||||
bool ChatModel::removeRow (int row, const QModelIndex &) {
|
||||
bool ChatRoomModel::removeRow (int row, const QModelIndex &) {
|
||||
return removeRows(row, 1);
|
||||
}
|
||||
|
||||
bool ChatModel::removeRows (int row, int count, const QModelIndex &parent) {
|
||||
bool ChatRoomModel::removeRows (int row, int count, const QModelIndex &parent) {
|
||||
int limit = row + count - 1;
|
||||
|
||||
if (row < 0 || count < 0 || limit >= mEntries.count())
|
||||
|
|
@ -500,46 +504,111 @@ bool ChatModel::removeRows (int row, int count, const QModelIndex &parent) {
|
|||
return true;
|
||||
}
|
||||
|
||||
QString ChatModel::getPeerAddress () const {
|
||||
QString ChatRoomModel::getPeerAddress () const {
|
||||
return Utils::coreStringToAppString(
|
||||
mChatRoom->getPeerAddress()->asStringUriOnly()
|
||||
);
|
||||
}
|
||||
|
||||
QString ChatModel::getLocalAddress () const {
|
||||
QString ChatRoomModel::getLocalAddress () const {
|
||||
return Utils::coreStringToAppString(
|
||||
mChatRoom->getLocalAddress()->asStringUriOnly()
|
||||
);
|
||||
}
|
||||
QString ChatModel::getFullPeerAddress () const {
|
||||
QString ChatRoomModel::getFullPeerAddress () const {
|
||||
if(!mChatRoom)
|
||||
qWarning("TOTO Z");
|
||||
return QString::fromStdString(mChatRoom->getPeerAddress()->asString());
|
||||
}
|
||||
|
||||
QString ChatModel::getFullLocalAddress () const {
|
||||
QString ChatRoomModel::getFullLocalAddress () const {
|
||||
return QString::fromStdString(mChatRoom->getLocalAddress()->asString());
|
||||
}
|
||||
void ChatModel::setSipAddresses (const QString &peerAddress, const QString &localAddress, const bool& isSecure) {
|
||||
|
||||
QString ChatRoomModel::getSubject () const {
|
||||
return QString::fromStdString(mChatRoom->getSubject());
|
||||
}
|
||||
|
||||
QString ChatRoomModel::getUsername () const {
|
||||
std::string username = mChatRoom->getSubject();
|
||||
if(username != ""){
|
||||
return QString::fromStdString(username);
|
||||
}
|
||||
if( mChatRoom->getNbParticipants() == 1){
|
||||
auto participants = mChatRoom->getParticipants();
|
||||
auto contact = CoreManager::getInstance()->getContactsListModel()->findContactModelFromSipAddress(QString::fromStdString((*participants.begin())->getAddress()->asString()));
|
||||
if(contact)
|
||||
return contact->getVcardModel()->getUsername();
|
||||
}
|
||||
username = mChatRoom->getPeerAddress()->getDisplayName();
|
||||
if(username != "")
|
||||
return QString::fromStdString(username);
|
||||
username = mChatRoom->getPeerAddress()->getUsername();
|
||||
if(username != "")
|
||||
return QString::fromStdString(username);
|
||||
return QString::fromStdString(mChatRoom->getPeerAddress()->asStringUriOnly());
|
||||
}
|
||||
|
||||
QString ChatRoomModel::getAvatar () const {
|
||||
if( mChatRoom->getNbParticipants() == 1){
|
||||
auto participants = mChatRoom->getParticipants();
|
||||
auto contact = CoreManager::getInstance()->getContactsListModel()->findContactModelFromSipAddress(QString::fromStdString((*participants.begin())->getAddress()->asString()));
|
||||
if(contact)
|
||||
return contact->getVcardModel()->getAvatar();
|
||||
}
|
||||
return "";
|
||||
}
|
||||
|
||||
int ChatRoomModel::getPresenceStatus() const {
|
||||
if( mChatRoom->getNbParticipants() == 1){
|
||||
auto participants = mChatRoom->getParticipants();
|
||||
auto contact = CoreManager::getInstance()->getContactsListModel()->findContactModelFromSipAddress(QString::fromStdString((*participants.begin())->getAddress()->asString()));
|
||||
if(contact)
|
||||
return contact->getPresenceLevel();
|
||||
else
|
||||
return 0;
|
||||
}else
|
||||
return 0;
|
||||
//return Presence::getPresenceLevel(1);
|
||||
//return mChatRoom->getConsolidatedPresence();
|
||||
}
|
||||
|
||||
void ChatRoomModel::setLastUpdateTime(const QDateTime& lastUpdateDate) {
|
||||
if(mLastUpdateTime != lastUpdateDate ) {
|
||||
mLastUpdateTime = lastUpdateDate;
|
||||
emit lastUpdateTimeChanged();
|
||||
}
|
||||
}
|
||||
|
||||
void ChatRoomModel::setUnreadMessagesCount(const int& count){
|
||||
if(count != mUnreadMessagesCount){
|
||||
mUnreadMessagesCount = count;
|
||||
emit unreadMessagesCountChanged();
|
||||
}
|
||||
}
|
||||
|
||||
void ChatRoomModel::setMissedCallsCount(const int& count){
|
||||
if(count != mMissedCallsCount){
|
||||
mMissedCallsCount = count;
|
||||
emit missedCallsCountChanged();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void ChatRoomModel::leaveChatRoom (){
|
||||
mChatRoom->leave();
|
||||
mChatRoom->getCore()->deleteChatRoom(mChatRoom);
|
||||
}
|
||||
/*
|
||||
void ChatRoomModel::setSipAddresses (const QString &peerAddress, const QString &localAddress, const bool& isSecure) {
|
||||
shared_ptr<linphone::Core> core = CoreManager::getInstance()->getCore();
|
||||
shared_ptr<linphone::Factory> factory(linphone::Factory::get());
|
||||
std::shared_ptr<linphone::ChatRoomParams> params = core->createDefaultChatRoomParams();
|
||||
std::list<std::shared_ptr<linphone::Address>> participants;
|
||||
|
||||
//params->enableEncryption(isSecure);
|
||||
//if(isSecure){
|
||||
// params->setBackend(linphone::ChatRoomBackend::FlexisipChat);
|
||||
// params->setEncryptionBackend(linphone::ChatRoomEncryptionBackend::Lime);
|
||||
// }
|
||||
|
||||
|
||||
mChatRoom = core->searchChatRoom(params, factory->createAddress(localAddress.toStdString())
|
||||
, factory->createAddress(peerAddress.toStdString())
|
||||
, participants);
|
||||
/*
|
||||
mChatRoom = core->getChatRoom(
|
||||
factory->createAddress(peerAddress.toStdString()),
|
||||
factory->createAddress(localAddress.toStdString())
|
||||
);*/
|
||||
Q_ASSERT(mChatRoom);
|
||||
|
||||
handleIsComposingChanged(mChatRoom);
|
||||
|
|
@ -564,26 +633,36 @@ void ChatModel::setSipAddresses (const QString &peerAddress, const QString &loca
|
|||
for (auto &callLog : core->getCallHistory(mChatRoom->getPeerAddress(), mChatRoom->getLocalAddress()))
|
||||
insertCall(callLog);
|
||||
|
||||
qInfo() << QStringLiteral("ChatModel (%1, %2) loaded in %3 milliseconds.")
|
||||
qInfo() << QStringLiteral("ChatRoomModel (%1, %2) loaded in %3 milliseconds.")
|
||||
.arg(peerAddress).arg(localAddress).arg(timer.elapsed());
|
||||
|
||||
if(!mChatRoom)
|
||||
qWarning("TOTO C");
|
||||
|
||||
}
|
||||
*/
|
||||
|
||||
bool ChatModel::getIsSecure() const{
|
||||
bool ChatRoomModel::getIsSecure() const{
|
||||
return mChatRoom->getSecurityLevel() == linphone::ChatRoomSecurityLevel::Encrypted
|
||||
|| mChatRoom->getSecurityLevel() == linphone::ChatRoomSecurityLevel::Safe;
|
||||
}
|
||||
|
||||
bool ChatModel::getIsRemoteComposing () const {
|
||||
bool ChatRoomModel::getIsRemoteComposing () const {
|
||||
return mIsRemoteComposing;
|
||||
}
|
||||
|
||||
//QList<ParticipantModel *> ChatRoomModel::getParticipants() const{
|
||||
QString ChatRoomModel::getParticipants() const{
|
||||
QStringList participants;
|
||||
for(auto it = mParticipants.begin() ; it != mParticipants.end() ; ++it)
|
||||
participants << (*it)->getAddress();
|
||||
|
||||
return participants.join(",");
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
void ChatModel::removeEntry (int id) {
|
||||
void ChatRoomModel::removeEntry (int id) {
|
||||
qInfo() << QStringLiteral("Removing chat entry: %1 of (%2, %3).")
|
||||
.arg(id).arg(getPeerAddress()).arg(getLocalAddress());
|
||||
|
||||
|
|
@ -591,7 +670,7 @@ void ChatModel::removeEntry (int id) {
|
|||
qWarning() << QStringLiteral("Unable to remove chat entry: %1").arg(id);
|
||||
}
|
||||
|
||||
void ChatModel::removeAllEntries () {
|
||||
void ChatRoomModel::removeAllEntries () {
|
||||
qInfo() << QStringLiteral("Removing all chat entries of: (%1, %2).")
|
||||
.arg(getPeerAddress()).arg(getLocalAddress());
|
||||
|
||||
|
|
@ -610,19 +689,18 @@ void ChatModel::removeAllEntries () {
|
|||
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
void ChatModel::sendMessage (const QString &message) {
|
||||
shared_ptr<linphone::ChatMessage> _message = mChatRoom->createMessage("");
|
||||
_message->getContents().begin()->get()->setStringBuffer(message.toUtf8().toStdString());
|
||||
void ChatRoomModel::sendMessage (const QString &message) {
|
||||
shared_ptr<linphone::ChatMessage> _message = mChatRoom->createMessageFromUtf8("");
|
||||
_message->getContents().begin()->get()->setUtf8Text(message.toUtf8().toStdString());
|
||||
_message->removeListener(mMessageHandlers);// Remove old listener if already exists
|
||||
_message->addListener(mMessageHandlers);
|
||||
|
||||
insertMessageAtEnd(_message);
|
||||
_message->send();
|
||||
|
||||
emit messageSent(_message);
|
||||
}
|
||||
|
||||
void ChatModel::resendMessage (int id) {
|
||||
void ChatRoomModel::resendMessage (int id) {
|
||||
if (id < 0 || id > mEntries.count()) {
|
||||
qWarning() << QStringLiteral("Entry %1 not exists.").arg(id);
|
||||
return;
|
||||
|
|
@ -652,7 +730,7 @@ void ChatModel::resendMessage (int id) {
|
|||
}
|
||||
}
|
||||
|
||||
void ChatModel::sendFileMessage (const QString &path) {
|
||||
void ChatRoomModel::sendFileMessage (const QString &path) {
|
||||
QFile file(path);
|
||||
if (!file.exists())
|
||||
return;
|
||||
|
|
@ -682,7 +760,6 @@ void ChatModel::sendFileMessage (const QString &path) {
|
|||
|
||||
createThumbnail(message);
|
||||
|
||||
insertMessageAtEnd(message);
|
||||
message->send();
|
||||
|
||||
emit messageSent(message);
|
||||
|
|
@ -690,7 +767,7 @@ void ChatModel::sendFileMessage (const QString &path) {
|
|||
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
void ChatModel::downloadFile (int id) {
|
||||
void ChatRoomModel::downloadFile (int id) {
|
||||
const ChatEntryData entry = getFileMessageEntry(id);
|
||||
if (!entry.second)
|
||||
return;
|
||||
|
|
@ -734,7 +811,7 @@ void ChatModel::downloadFile (int id) {
|
|||
}
|
||||
}
|
||||
|
||||
void ChatModel::openFile (int id, bool showDirectory) {
|
||||
void ChatRoomModel::openFile (int id, bool showDirectory) {
|
||||
const ChatEntryData entry = getFileMessageEntry(id);
|
||||
if (!entry.second)
|
||||
return;
|
||||
|
|
@ -750,27 +827,29 @@ void ChatModel::openFile (int id, bool showDirectory) {
|
|||
}
|
||||
}
|
||||
|
||||
bool ChatModel::fileWasDownloaded (int id) {
|
||||
bool ChatRoomModel::fileWasDownloaded (int id) {
|
||||
const ChatEntryData entry = getFileMessageEntry(id);
|
||||
return entry.second && ::fileWasDownloaded(static_pointer_cast<linphone::ChatMessage>(entry.second));
|
||||
}
|
||||
|
||||
void ChatModel::compose () {
|
||||
void ChatRoomModel::compose () {
|
||||
mChatRoom->compose();
|
||||
}
|
||||
|
||||
void ChatModel::resetMessageCount () {
|
||||
void ChatRoomModel::resetMessageCount () {
|
||||
if (mChatRoom->getUnreadMessagesCount() > 0){
|
||||
mChatRoom->markAsRead();// Marking as read is only for messages. Not for calls.
|
||||
setUnreadMessagesCount(mChatRoom->getUnreadMessagesCount());
|
||||
}
|
||||
mMissedCallsCount = 0;
|
||||
emit messageCountReset();
|
||||
}
|
||||
std::shared_ptr<linphone::ChatRoom> ChatModel::getChatRoom(){
|
||||
std::shared_ptr<linphone::ChatRoom> ChatRoomModel::getChatRoom(){
|
||||
return mChatRoom;
|
||||
}
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
const ChatModel::ChatEntryData ChatModel::getFileMessageEntry (int id) {
|
||||
const ChatRoomModel::ChatEntryData ChatRoomModel::getFileMessageEntry (int id) {
|
||||
if (id < 0 || id > mEntries.count()) {
|
||||
qWarning() << QStringLiteral("Entry %1 not exists.").arg(id);
|
||||
return ChatEntryData();
|
||||
|
|
@ -793,18 +872,18 @@ const ChatModel::ChatEntryData ChatModel::getFileMessageEntry (int id) {
|
|||
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
void ChatModel::removeEntry (ChatEntryData &entry) {
|
||||
void ChatRoomModel::removeEntry (ChatEntryData &entry) {
|
||||
int type = entry.first["type"].toInt();
|
||||
|
||||
switch (type) {
|
||||
case ChatModel::MessageEntry: {
|
||||
case ChatRoomModel::MessageEntry: {
|
||||
shared_ptr<linphone::ChatMessage> message = static_pointer_cast<linphone::ChatMessage>(entry.second);
|
||||
removeFileMessageThumbnail(message);
|
||||
mChatRoom->deleteMessage(message);
|
||||
break;
|
||||
}
|
||||
|
||||
case ChatModel::CallEntry: {
|
||||
case ChatRoomModel::CallEntry: {
|
||||
if (entry.first["status"].toInt() == CallStatusSuccess) {
|
||||
// WARNING: Unable to remove symmetric call here. (start/end)
|
||||
// We are between `beginRemoveRows` and `endRemoveRows`.
|
||||
|
|
@ -829,7 +908,7 @@ void ChatModel::removeEntry (ChatEntryData &entry) {
|
|||
}
|
||||
}
|
||||
|
||||
void ChatModel::insertCall (const shared_ptr<linphone::CallLog> &callLog) {
|
||||
void ChatRoomModel::insertCall (const shared_ptr<linphone::CallLog> &callLog) {
|
||||
linphone::Call::Status status = callLog->getStatus();
|
||||
|
||||
auto insertEntry = [this](
|
||||
|
|
@ -862,7 +941,7 @@ void ChatModel::insertCall (const shared_ptr<linphone::CallLog> &callLog) {
|
|||
}
|
||||
}
|
||||
|
||||
void ChatModel::insertMessageAtEnd (const shared_ptr<linphone::ChatMessage> &message) {
|
||||
void ChatRoomModel::insertMessageAtEnd (const shared_ptr<linphone::ChatMessage> &message) {
|
||||
int row = mEntries.count();
|
||||
|
||||
beginInsertRows(QModelIndex(), row, row);
|
||||
|
|
@ -879,27 +958,95 @@ void ChatModel::insertMessageAtEnd (const shared_ptr<linphone::ChatMessage> &mes
|
|||
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
void ChatModel::handleCallStateChanged (const shared_ptr<linphone::Call> &call, linphone::Call::State state) {
|
||||
if (
|
||||
(state == linphone::Call::State::End || state == linphone::Call::State::Error) &&
|
||||
mChatRoom == CoreManager::getInstance()->getCore()->findChatRoom(call->getRemoteAddress(), mChatRoom->getLocalAddress())
|
||||
)
|
||||
insertCall(call->getCallLog());
|
||||
void ChatRoomModel::handleCallStateChanged (const 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);
|
||||
}
|
||||
//mChatRoom == CoreManager::getInstance()->getCore()->findChatRoom(call->getRemoteAddress(), mChatRoom->getLocalAddress())
|
||||
}
|
||||
}
|
||||
|
||||
void ChatModel::handleIsComposingChanged (const shared_ptr<linphone::ChatRoom> &chatRoom) {
|
||||
if (mChatRoom == chatRoom) {
|
||||
bool isRemoteComposing = mChatRoom->isRemoteComposing();
|
||||
if (isRemoteComposing != mIsRemoteComposing) {
|
||||
mIsRemoteComposing = isRemoteComposing;
|
||||
void ChatRoomModel::handleCallCreated(const shared_ptr<linphone::Call> &call){
|
||||
}
|
||||
//----------------------------------------------------------
|
||||
//------ CHAT ROOM HANDLERS
|
||||
//----------------------------------------------------------
|
||||
|
||||
void ChatRoomModel::onIsComposingReceived(const std::shared_ptr<linphone::ChatRoom> & chatRoom, const std::shared_ptr<const linphone::Address> & remoteAddress, bool isComposing){
|
||||
if (isComposing != mIsRemoteComposing) {
|
||||
mIsRemoteComposing = isComposing;
|
||||
emit isRemoteComposingChanged(mIsRemoteComposing);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void ChatModel::handleMessageReceived (const shared_ptr<linphone::ChatMessage> &message) {
|
||||
if (mChatRoom == message->getChatRoom()) {
|
||||
insertMessageAtEnd(message);
|
||||
emit messageReceived(message);
|
||||
}
|
||||
void ChatRoomModel::onMessageReceived(const std::shared_ptr<linphone::ChatRoom> & chatRoom, const std::shared_ptr<linphone::ChatMessage> & message){
|
||||
setUnreadMessagesCount(chatRoom->getUnreadMessagesCount());
|
||||
/*
|
||||
insertMessageAtEnd(message);
|
||||
emit messageReceived(message);*/
|
||||
}
|
||||
void ChatRoomModel::onNewEvent(const std::shared_ptr<linphone::ChatRoom> & chatRoom, const std::shared_ptr<const linphone::EventLog> & eventLog){
|
||||
qWarning() << "New Event" <<(int) eventLog->getType();
|
||||
if( eventLog->getType() == linphone::EventLog::Type::ConferenceCallEnd ){
|
||||
setMissedCallsCount(mMissedCallsCount+1);
|
||||
}
|
||||
/*auto message = eventLog->getChatMessage();
|
||||
if(message){
|
||||
insertMessageAtEnd(message);
|
||||
emit messageReceived(message);
|
||||
}*/
|
||||
}
|
||||
void ChatRoomModel::onChatMessageReceived(const std::shared_ptr<linphone::ChatRoom> & chatRoom, const std::shared_ptr<const linphone::EventLog> & eventLog) {
|
||||
|
||||
auto message = eventLog->getChatMessage();
|
||||
if(message){
|
||||
insertMessageAtEnd(message);
|
||||
emit messageReceived(message);
|
||||
setLastUpdateTime(QDateTime::fromMSecsSinceEpoch(chatRoom->getLastUpdateTime()));
|
||||
}
|
||||
}
|
||||
void ChatRoomModel::onChatMessageSending(const std::shared_ptr<linphone::ChatRoom> & chatRoom, const std::shared_ptr<const linphone::EventLog> & eventLog){
|
||||
auto message = eventLog->getChatMessage();
|
||||
if(message){
|
||||
insertMessageAtEnd(message);
|
||||
emit messageReceived(message);
|
||||
setLastUpdateTime(QDateTime::fromMSecsSinceEpoch(chatRoom->getLastUpdateTime()));
|
||||
}
|
||||
}
|
||||
void ChatRoomModel::onChatMessageSent(const std::shared_ptr<linphone::ChatRoom> & chatRoom, const std::shared_ptr<const linphone::EventLog> & eventLog){
|
||||
/*auto message = eventLog->getChatMessage();
|
||||
if(message){
|
||||
insertMessageAtEnd(message);
|
||||
emit messageReceived(message);
|
||||
}*/
|
||||
}
|
||||
void ChatRoomModel::onParticipantAdded(const std::shared_ptr<linphone::ChatRoom> & chatRoom, const std::shared_ptr<const linphone::EventLog> & eventLog){}
|
||||
void ChatRoomModel::onParticipantRemoved(const std::shared_ptr<linphone::ChatRoom> & chatRoom, const std::shared_ptr<const linphone::EventLog> & eventLog){}
|
||||
void ChatRoomModel::onParticipantAdminStatusChanged(const std::shared_ptr<linphone::ChatRoom> & chatRoom, const std::shared_ptr<const linphone::EventLog> & eventLog){}
|
||||
void ChatRoomModel::onStateChanged(const std::shared_ptr<linphone::ChatRoom> & chatRoom, linphone::ChatRoom::State newState){}
|
||||
void ChatRoomModel::onSecurityEvent(const std::shared_ptr<linphone::ChatRoom> & chatRoom, const std::shared_ptr<const linphone::EventLog> & eventLog){}
|
||||
void ChatRoomModel::onSubjectChanged(const std::shared_ptr<linphone::ChatRoom> & chatRoom, const std::shared_ptr<const linphone::EventLog> & eventLog) {
|
||||
emit subjectChanged(getSubject());
|
||||
emit usernameChanged(getUsername());
|
||||
}
|
||||
void ChatRoomModel::onUndecryptableMessageReceived(const std::shared_ptr<linphone::ChatRoom> & chatRoom, const std::shared_ptr<linphone::ChatMessage> & message){}
|
||||
void ChatRoomModel::onParticipantDeviceAdded(const std::shared_ptr<linphone::ChatRoom> & chatRoom, const std::shared_ptr<const linphone::EventLog> & eventLog){}
|
||||
void ChatRoomModel::onParticipantDeviceRemoved(const std::shared_ptr<linphone::ChatRoom> & chatRoom, const std::shared_ptr<const linphone::EventLog> & eventLog){}
|
||||
void ChatRoomModel::onConferenceJoined(const std::shared_ptr<linphone::ChatRoom> & chatRoom, const std::shared_ptr<const linphone::EventLog> & eventLog){}
|
||||
void ChatRoomModel::onConferenceLeft(const std::shared_ptr<linphone::ChatRoom> & chatRoom, const std::shared_ptr<const linphone::EventLog> & eventLog){}
|
||||
void ChatRoomModel::onEphemeralEvent(const std::shared_ptr<linphone::ChatRoom> & chatRoom, const std::shared_ptr<const linphone::EventLog> & eventLog){}
|
||||
void ChatRoomModel::onEphemeralMessageTimerStarted(const std::shared_ptr<linphone::ChatRoom> & chatRoom, const std::shared_ptr<const linphone::EventLog> & eventLog){}
|
||||
void ChatRoomModel::onEphemeralMessageDeleted(const std::shared_ptr<linphone::ChatRoom> & chatRoom, const std::shared_ptr<const linphone::EventLog> & eventLog){}
|
||||
void ChatRoomModel::onConferenceAddressGeneration(const std::shared_ptr<linphone::ChatRoom> & chatRoom){}
|
||||
void ChatRoomModel::onParticipantRegistrationSubscriptionRequested(const std::shared_ptr<linphone::ChatRoom> & chatRoom, const std::shared_ptr<const linphone::Address> & participantAddress){}
|
||||
void ChatRoomModel::onParticipantRegistrationUnsubscriptionRequested(const std::shared_ptr<linphone::ChatRoom> & chatRoom, const std::shared_ptr<const linphone::Address> & participantAddress){}
|
||||
void ChatRoomModel::onChatMessageShouldBeStored(const std::shared_ptr<linphone::ChatRoom> & chatRoom, const std::shared_ptr<linphone::ChatMessage> & message){}
|
||||
void ChatRoomModel::onChatMessageParticipantImdnStateChanged(const std::shared_ptr<linphone::ChatRoom> & chatRoom, const std::shared_ptr<linphone::ChatMessage> & message, const std::shared_ptr<const linphone::ParticipantImdnState> & state){}
|
||||
242
linphone-app/src/components/chat-room/ChatRoomModel.hpp
Normal file
242
linphone-app/src/components/chat-room/ChatRoomModel.hpp
Normal file
|
|
@ -0,0 +1,242 @@
|
|||
/*
|
||||
* 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 CHAT_ROOM_MODEL_H_
|
||||
#define CHAT_ROOM_MODEL_H_
|
||||
|
||||
#include <linphone++/linphone.hh>
|
||||
#include <QAbstractListModel>
|
||||
#include <QDateTime>
|
||||
|
||||
// =============================================================================
|
||||
// Fetch all N messages of a ChatRoom.
|
||||
// =============================================================================
|
||||
|
||||
class CoreHandlers;
|
||||
class ParticipantModel;
|
||||
|
||||
class ChatRoomModel : public QAbstractListModel, public linphone::ChatRoomListener {
|
||||
class MessageHandlers;
|
||||
|
||||
Q_OBJECT;
|
||||
|
||||
public:
|
||||
enum Roles {
|
||||
ChatEntry = Qt::DisplayRole,
|
||||
SectionDate
|
||||
};
|
||||
|
||||
enum EntryType {
|
||||
GenericEntry,
|
||||
MessageEntry,
|
||||
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);
|
||||
|
||||
enum MessageStatus {
|
||||
MessageStatusDelivered = int(linphone::ChatMessage::State::Delivered),
|
||||
MessageStatusDeliveredToUser = int(linphone::ChatMessage::State::DeliveredToUser),
|
||||
MessageStatusDisplayed = int(linphone::ChatMessage::State::Displayed),
|
||||
MessageStatusFileTransferDone = int(linphone::ChatMessage::State::FileTransferDone),
|
||||
MessageStatusFileTransferError = int(linphone::ChatMessage::State::FileTransferError),
|
||||
MessageStatusFileTransferInProgress = int(linphone::ChatMessage::State::FileTransferInProgress),
|
||||
MessageStatusIdle = int(linphone::ChatMessage::State::Idle),
|
||||
MessageStatusInProgress = int(linphone::ChatMessage::State::InProgress),
|
||||
MessageStatusNotDelivered = int(linphone::ChatMessage::State::NotDelivered)
|
||||
|
||||
};
|
||||
Q_ENUM(MessageStatus);
|
||||
|
||||
Q_PROPERTY(QString participants READ getParticipants NOTIFY participantsChanged);
|
||||
Q_PROPERTY(QString subject READ getSubject NOTIFY subjectChanged)
|
||||
Q_PROPERTY(QDateTime lastUpdateTime MEMBER mLastUpdateTime WRITE setLastUpdateTime NOTIFY lastUpdateTimeChanged)
|
||||
Q_PROPERTY(int unreadMessagesCount MEMBER mUnreadMessagesCount WRITE setUnreadMessagesCount NOTIFY unreadMessagesCountChanged)
|
||||
Q_PROPERTY(int missedCallsCount MEMBER mMissedCallsCount WRITE setMissedCallsCount NOTIFY missedCallsCountChanged)
|
||||
|
||||
Q_PROPERTY(bool isComposing MEMBER mIsRemoteComposing NOTIFY isRemoteComposingChanged)
|
||||
|
||||
|
||||
|
||||
Q_PROPERTY(QString sipAddress READ getFullPeerAddress NOTIFY fullPeerAddressChanged)
|
||||
Q_PROPERTY(QString username READ getUsername NOTIFY usernameChanged)
|
||||
Q_PROPERTY(QString avatar READ getAvatar NOTIFY avatarChanged)
|
||||
Q_PROPERTY(int presenceStatus READ getPresenceStatus NOTIFY presenceStatusChanged)
|
||||
|
||||
|
||||
|
||||
//ChatRoomModel (const QString &peerAddress, const QString &localAddress, const bool& isSecure);
|
||||
ChatRoomModel (std::shared_ptr<linphone::ChatRoom> chatRoom);
|
||||
~ChatRoomModel ();
|
||||
|
||||
int rowCount (const QModelIndex &index = QModelIndex()) const override;
|
||||
|
||||
QHash<int, QByteArray> 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;
|
||||
|
||||
Q_INVOKABLE QString getPeerAddress () const;
|
||||
Q_INVOKABLE QString getLocalAddress () const;
|
||||
Q_INVOKABLE QString getFullPeerAddress () const;
|
||||
Q_INVOKABLE QString getFullLocalAddress () const;
|
||||
|
||||
QString getSubject () const;
|
||||
QString getUsername () const;
|
||||
QString getAvatar () const;
|
||||
int getPresenceStatus() const;
|
||||
void setLastUpdateTime(const QDateTime& lastUpdateDate);
|
||||
|
||||
void setUnreadMessagesCount(const int& count);
|
||||
void setMissedCallsCount(const int& count);
|
||||
|
||||
Q_INVOKABLE void leaveChatRoom ();
|
||||
|
||||
bool getIsSecure() const;
|
||||
|
||||
bool getIsRemoteComposing () const;
|
||||
|
||||
|
||||
//Q_INVOKABLE QList<ParticipantModel*> getParticipants()const
|
||||
Q_INVOKABLE QString getParticipants()const;
|
||||
|
||||
|
||||
void removeEntry (int id);
|
||||
void removeAllEntries ();
|
||||
|
||||
void sendMessage (const QString &message);
|
||||
|
||||
void resendMessage (int id);
|
||||
|
||||
void sendFileMessage (const QString &path);
|
||||
|
||||
void downloadFile (int id);
|
||||
void openFile (int id, bool showDirectory = false);
|
||||
void openFileDirectory (int id) {
|
||||
openFile(id, true);
|
||||
}
|
||||
|
||||
bool fileWasDownloaded (int id);
|
||||
|
||||
void compose ();
|
||||
|
||||
void resetMessageCount ();
|
||||
|
||||
std::shared_ptr<linphone::ChatRoom> getChatRoom();
|
||||
QDateTime mLastUpdateTime;
|
||||
int mUnreadMessagesCount;
|
||||
int mMissedCallsCount;
|
||||
|
||||
|
||||
//-------------------- CHAT ROOM HANDLER
|
||||
|
||||
|
||||
virtual void onIsComposingReceived(const std::shared_ptr<linphone::ChatRoom> & chatRoom, const std::shared_ptr<const linphone::Address> & remoteAddress, bool isComposing) override;
|
||||
virtual void onMessageReceived(const std::shared_ptr<linphone::ChatRoom> & chatRoom, const std::shared_ptr<linphone::ChatMessage> & message) override;
|
||||
virtual void onNewEvent(const std::shared_ptr<linphone::ChatRoom> & chatRoom, const std::shared_ptr<const linphone::EventLog> & eventLog) override;
|
||||
virtual void onChatMessageReceived(const std::shared_ptr<linphone::ChatRoom> & chatRoom, const std::shared_ptr<const linphone::EventLog> & eventLog) override;
|
||||
virtual void onChatMessageSending(const std::shared_ptr<linphone::ChatRoom> & chatRoom, const std::shared_ptr<const linphone::EventLog> & eventLog) override;
|
||||
virtual void onChatMessageSent(const std::shared_ptr<linphone::ChatRoom> & chatRoom, const std::shared_ptr<const linphone::EventLog> & eventLog) override;
|
||||
virtual void onParticipantAdded(const std::shared_ptr<linphone::ChatRoom> & chatRoom, const std::shared_ptr<const linphone::EventLog> & eventLog) override;
|
||||
virtual void onParticipantRemoved(const std::shared_ptr<linphone::ChatRoom> & chatRoom, const std::shared_ptr<const linphone::EventLog> & eventLog) override;
|
||||
virtual void onParticipantAdminStatusChanged(const std::shared_ptr<linphone::ChatRoom> & chatRoom, const std::shared_ptr<const linphone::EventLog> & eventLog) override;
|
||||
virtual void onStateChanged(const std::shared_ptr<linphone::ChatRoom> & chatRoom, linphone::ChatRoom::State newState) override;
|
||||
virtual void onSecurityEvent(const std::shared_ptr<linphone::ChatRoom> & chatRoom, const std::shared_ptr<const linphone::EventLog> & eventLog) override;
|
||||
virtual void onSubjectChanged(const std::shared_ptr<linphone::ChatRoom> & chatRoom, const std::shared_ptr<const linphone::EventLog> & eventLog) override;
|
||||
virtual void onUndecryptableMessageReceived(const std::shared_ptr<linphone::ChatRoom> & chatRoom, const std::shared_ptr<linphone::ChatMessage> & message) override;
|
||||
virtual void onParticipantDeviceAdded(const std::shared_ptr<linphone::ChatRoom> & chatRoom, const std::shared_ptr<const linphone::EventLog> & eventLog) override;
|
||||
virtual void onParticipantDeviceRemoved(const std::shared_ptr<linphone::ChatRoom> & chatRoom, const std::shared_ptr<const linphone::EventLog> & eventLog) override;
|
||||
virtual void onConferenceJoined(const std::shared_ptr<linphone::ChatRoom> & chatRoom, const std::shared_ptr<const linphone::EventLog> & eventLog) override;
|
||||
virtual void onConferenceLeft(const std::shared_ptr<linphone::ChatRoom> & chatRoom, const std::shared_ptr<const linphone::EventLog> & eventLog) override;
|
||||
virtual void onEphemeralEvent(const std::shared_ptr<linphone::ChatRoom> & chatRoom, const std::shared_ptr<const linphone::EventLog> & eventLog) override;
|
||||
virtual void onEphemeralMessageTimerStarted(const std::shared_ptr<linphone::ChatRoom> & chatRoom, const std::shared_ptr<const linphone::EventLog> & eventLog) override;
|
||||
virtual void onEphemeralMessageDeleted(const std::shared_ptr<linphone::ChatRoom> & chatRoom, const std::shared_ptr<const linphone::EventLog> & eventLog) override;
|
||||
virtual void onConferenceAddressGeneration(const std::shared_ptr<linphone::ChatRoom> & chatRoom) override;
|
||||
virtual void onParticipantRegistrationSubscriptionRequested(const std::shared_ptr<linphone::ChatRoom> & chatRoom, const std::shared_ptr<const linphone::Address> & participantAddress) override;
|
||||
virtual void onParticipantRegistrationUnsubscriptionRequested(const std::shared_ptr<linphone::ChatRoom> & chatRoom, const std::shared_ptr<const linphone::Address> & participantAddress) override;
|
||||
virtual void onChatMessageShouldBeStored(const std::shared_ptr<linphone::ChatRoom> & chatRoom, const std::shared_ptr<linphone::ChatMessage> & message) override;
|
||||
virtual void onChatMessageParticipantImdnStateChanged(const std::shared_ptr<linphone::ChatRoom> & chatRoom, const std::shared_ptr<linphone::ChatMessage> & message, const std::shared_ptr<const linphone::ParticipantImdnState> & state) override;
|
||||
|
||||
|
||||
signals:
|
||||
bool isRemoteComposingChanged (bool status);
|
||||
|
||||
void allEntriesRemoved ();
|
||||
void lastEntryRemoved ();
|
||||
|
||||
void messageSent (const std::shared_ptr<linphone::ChatMessage> &message);
|
||||
void messageReceived (const std::shared_ptr<linphone::ChatMessage> &message);
|
||||
|
||||
void messageCountReset ();
|
||||
|
||||
void focused ();
|
||||
|
||||
void fullPeerAddressChanged();
|
||||
void participantsChanged();
|
||||
void subjectChanged(QString subject);
|
||||
void usernameChanged(QString username);
|
||||
void avatarChanged(QString avatar);
|
||||
void presenceStatusChanged(int presenceStatus);
|
||||
void lastUpdateTimeChanged();
|
||||
void unreadMessagesCountChanged();
|
||||
void missedCallsCountChanged();
|
||||
|
||||
private:
|
||||
typedef QPair<QVariantMap, std::shared_ptr<void>> ChatEntryData;
|
||||
|
||||
//void setSipAddresses (const QString &peerAddress, const QString &localAddress, const bool& isSecure);
|
||||
|
||||
const ChatEntryData getFileMessageEntry (int id);
|
||||
|
||||
void removeEntry (ChatEntryData &entry);
|
||||
|
||||
void insertCall (const std::shared_ptr<linphone::CallLog> &callLog);
|
||||
void insertMessageAtEnd (const std::shared_ptr<linphone::ChatMessage> &message);
|
||||
|
||||
void handleCallStateChanged (const std::shared_ptr<linphone::Call> &call, linphone::Call::State state);
|
||||
void handleCallCreated(const std::shared_ptr<linphone::Call> &call);// Count an event call
|
||||
//void handleIsComposingChanged (const std::shared_ptr<linphone::ChatRoom> &chatRoom);
|
||||
//void handleMessageReceived (const std::shared_ptr<linphone::ChatMessage> &message);
|
||||
|
||||
bool mIsRemoteComposing = false;
|
||||
|
||||
mutable QList<ChatEntryData> mEntries;
|
||||
QList<ParticipantModel*> mParticipants;
|
||||
|
||||
std::shared_ptr<CoreHandlers> mCoreHandlers;
|
||||
std::shared_ptr<MessageHandlers> mMessageHandlers;
|
||||
|
||||
std::shared_ptr<linphone::ChatRoom> mChatRoom;
|
||||
};
|
||||
|
||||
Q_DECLARE_METATYPE(std::shared_ptr<ChatRoomModel>);
|
||||
|
||||
#endif // CHAT_ROOM_MODEL_H_
|
||||
|
|
@ -23,31 +23,31 @@
|
|||
#include "app/App.hpp"
|
||||
#include "components/core/CoreManager.hpp"
|
||||
|
||||
#include "ChatProxyModel.hpp"
|
||||
#include "ChatRoomProxyModel.hpp"
|
||||
|
||||
// =============================================================================
|
||||
|
||||
using namespace std;
|
||||
|
||||
QString ChatProxyModel::gCachedText;
|
||||
QString ChatRoomProxyModel::gCachedText;
|
||||
|
||||
// Fetch the L last filtered chat entries.
|
||||
class ChatProxyModel::ChatModelFilter : public QSortFilterProxyModel {
|
||||
class ChatRoomProxyModel::ChatRoomModelFilter : public QSortFilterProxyModel {
|
||||
public:
|
||||
ChatModelFilter (QObject *parent) : QSortFilterProxyModel(parent) {}
|
||||
ChatRoomModelFilter (QObject *parent) : QSortFilterProxyModel(parent) {}
|
||||
|
||||
ChatModel::EntryType getEntryTypeFilter () {
|
||||
ChatRoomModel::EntryType getEntryTypeFilter () {
|
||||
return mEntryTypeFilter;
|
||||
}
|
||||
|
||||
void setEntryTypeFilter (ChatModel::EntryType type) {
|
||||
void setEntryTypeFilter (ChatRoomModel::EntryType type) {
|
||||
mEntryTypeFilter = type;
|
||||
invalidate();
|
||||
}
|
||||
|
||||
protected:
|
||||
bool filterAcceptsRow (int sourceRow, const QModelIndex &) const override {
|
||||
if (mEntryTypeFilter == ChatModel::EntryType::GenericEntry)
|
||||
if (mEntryTypeFilter == ChatRoomModel::EntryType::GenericEntry)
|
||||
return true;
|
||||
|
||||
QModelIndex index = sourceModel()->index(sourceRow, 0, QModelIndex());
|
||||
|
|
@ -57,13 +57,13 @@ protected:
|
|||
}
|
||||
|
||||
private:
|
||||
ChatModel::EntryType mEntryTypeFilter = ChatModel::EntryType::GenericEntry;
|
||||
ChatRoomModel::EntryType mEntryTypeFilter = ChatRoomModel::EntryType::GenericEntry;
|
||||
};
|
||||
|
||||
// =============================================================================
|
||||
|
||||
ChatProxyModel::ChatProxyModel (QObject *parent) : QSortFilterProxyModel(parent) {
|
||||
setSourceModel(new ChatModelFilter(this));
|
||||
ChatRoomProxyModel::ChatRoomProxyModel (QObject *parent) : QSortFilterProxyModel(parent) {
|
||||
setSourceModel(new ChatRoomModelFilter(this));
|
||||
mIsSecure = false;
|
||||
|
||||
App *app = App::getInstance();
|
||||
|
|
@ -81,25 +81,25 @@ ChatProxyModel::ChatProxyModel (QObject *parent) : QSortFilterProxyModel(parent)
|
|||
// -----------------------------------------------------------------------------
|
||||
|
||||
#define GET_CHAT_MODEL() \
|
||||
if (!mChatModel) \
|
||||
if (!mChatRoomModel) \
|
||||
return; \
|
||||
mChatModel
|
||||
mChatRoomModel
|
||||
|
||||
#define CREATE_PARENT_MODEL_FUNCTION(METHOD) \
|
||||
void ChatProxyModel::METHOD () { \
|
||||
void ChatRoomProxyModel::METHOD () { \
|
||||
GET_CHAT_MODEL()->METHOD(); \
|
||||
}
|
||||
|
||||
#define CREATE_PARENT_MODEL_FUNCTION_WITH_PARAM(METHOD, ARG_TYPE) \
|
||||
void ChatProxyModel::METHOD (ARG_TYPE value) { \
|
||||
void ChatRoomProxyModel::METHOD (ARG_TYPE value) { \
|
||||
GET_CHAT_MODEL()->METHOD(value); \
|
||||
}
|
||||
|
||||
#define CREATE_PARENT_MODEL_FUNCTION_WITH_ID(METHOD) \
|
||||
void ChatProxyModel::METHOD (int id) { \
|
||||
void ChatRoomProxyModel::METHOD (int id) { \
|
||||
QModelIndex sourceIndex = mapToSource(index(id, 0)); \
|
||||
GET_CHAT_MODEL()->METHOD( \
|
||||
static_cast<ChatModelFilter *>(sourceModel())->mapToSource(sourceIndex).row() \
|
||||
static_cast<ChatRoomModelFilter *>(sourceModel())->mapToSource(sourceIndex).row() \
|
||||
); \
|
||||
}
|
||||
|
||||
|
|
@ -120,15 +120,15 @@ CREATE_PARENT_MODEL_FUNCTION_WITH_ID(resendMessage);
|
|||
#undef CREATE_PARENT_MODEL_FUNCTION_WITH_ID
|
||||
|
||||
|
||||
void ChatProxyModel::compose (const QString& text) {
|
||||
if (mChatModel)
|
||||
mChatModel->compose();
|
||||
void ChatRoomProxyModel::compose (const QString& text) {
|
||||
if (mChatRoomModel)
|
||||
mChatRoomModel->compose();
|
||||
gCachedText = text;
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
void ChatProxyModel::loadMoreEntries () {
|
||||
void ChatRoomProxyModel::loadMoreEntries () {
|
||||
int count = rowCount();
|
||||
int parentCount = sourceModel()->rowCount();
|
||||
|
||||
|
|
@ -146,116 +146,116 @@ void ChatProxyModel::loadMoreEntries () {
|
|||
}
|
||||
}
|
||||
|
||||
void ChatProxyModel::setEntryTypeFilter (ChatModel::EntryType type) {
|
||||
ChatModelFilter *chatModelFilter = static_cast<ChatModelFilter *>(sourceModel());
|
||||
void ChatRoomProxyModel::setEntryTypeFilter (ChatRoomModel::EntryType type) {
|
||||
ChatRoomModelFilter *ChatRoomModelFilter = static_cast<ChatRoomProxyModel::ChatRoomModelFilter *>(sourceModel());
|
||||
|
||||
if (chatModelFilter->getEntryTypeFilter() != type) {
|
||||
chatModelFilter->setEntryTypeFilter(type);
|
||||
if (ChatRoomModelFilter->getEntryTypeFilter() != type) {
|
||||
ChatRoomModelFilter->setEntryTypeFilter(type);
|
||||
emit entryTypeFilterChanged(type);
|
||||
}
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
bool ChatProxyModel::filterAcceptsRow (int sourceRow, const QModelIndex &) const {
|
||||
bool ChatRoomProxyModel::filterAcceptsRow (int sourceRow, const QModelIndex &) const {
|
||||
return sourceModel()->rowCount() - sourceRow <= mMaxDisplayedEntries;
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
QString ChatProxyModel::getPeerAddress () const {
|
||||
return mChatModel ? mChatModel->getPeerAddress() : QString("");
|
||||
QString ChatRoomProxyModel::getPeerAddress () const {
|
||||
return mChatRoomModel ? mChatRoomModel->getPeerAddress() : QString("");
|
||||
}
|
||||
|
||||
void ChatProxyModel::setPeerAddress (const QString &peerAddress) {
|
||||
void ChatRoomProxyModel::setPeerAddress (const QString &peerAddress) {
|
||||
mPeerAddress = peerAddress;
|
||||
//reload();
|
||||
}
|
||||
|
||||
QString ChatProxyModel::getLocalAddress () const {
|
||||
return mChatModel ? mChatModel->getLocalAddress() : QString("");
|
||||
QString ChatRoomProxyModel::getLocalAddress () const {
|
||||
return mChatRoomModel ? mChatRoomModel->getLocalAddress() : QString("");
|
||||
}
|
||||
|
||||
void ChatProxyModel::setLocalAddress (const QString &localAddress) {
|
||||
void ChatRoomProxyModel::setLocalAddress (const QString &localAddress) {
|
||||
mLocalAddress = localAddress;
|
||||
//reload();
|
||||
}
|
||||
|
||||
QString ChatProxyModel::getFullPeerAddress () const {
|
||||
return mChatModel ? mChatModel->getFullPeerAddress() : QString("");
|
||||
QString ChatRoomProxyModel::getFullPeerAddress () const {
|
||||
return mChatRoomModel ? mChatRoomModel->getFullPeerAddress() : QString("");
|
||||
}
|
||||
|
||||
void ChatProxyModel::setFullPeerAddress (const QString &peerAddress) {
|
||||
void ChatRoomProxyModel::setFullPeerAddress (const QString &peerAddress) {
|
||||
mFullPeerAddress = peerAddress;
|
||||
//reload();
|
||||
}
|
||||
|
||||
QString ChatProxyModel::getFullLocalAddress () const {
|
||||
return mChatModel ? mChatModel->getFullLocalAddress() : QString("");
|
||||
QString ChatRoomProxyModel::getFullLocalAddress () const {
|
||||
return mChatRoomModel ? mChatRoomModel->getFullLocalAddress() : QString("");
|
||||
}
|
||||
|
||||
void ChatProxyModel::setFullLocalAddress (const QString &localAddress) {
|
||||
void ChatRoomProxyModel::setFullLocalAddress (const QString &localAddress) {
|
||||
mFullLocalAddress = localAddress;
|
||||
//reload();
|
||||
}
|
||||
|
||||
int ChatProxyModel::getIsSecure () const {
|
||||
return mChatModel ? mChatModel->getIsSecure() : -1;
|
||||
int ChatRoomProxyModel::getIsSecure () const {
|
||||
return mChatRoomModel ? mChatRoomModel->getIsSecure() : -1;
|
||||
}
|
||||
|
||||
void ChatProxyModel::setIsSecure (const int &secure) {
|
||||
void ChatRoomProxyModel::setIsSecure (const int &secure) {
|
||||
mIsSecure = secure;
|
||||
}
|
||||
|
||||
bool ChatProxyModel::getIsRemoteComposing () const {
|
||||
return mChatModel ? mChatModel->getIsRemoteComposing() : false;
|
||||
bool ChatRoomProxyModel::getIsRemoteComposing () const {
|
||||
return mChatRoomModel ? mChatRoomModel->getIsRemoteComposing() : false;
|
||||
}
|
||||
|
||||
QString ChatProxyModel::getCachedText() const{
|
||||
QString ChatRoomProxyModel::getCachedText() const{
|
||||
return gCachedText;
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
void ChatProxyModel::reload () {
|
||||
void ChatRoomProxyModel::reload () {
|
||||
mMaxDisplayedEntries = EntriesChunkSize;
|
||||
|
||||
if (mChatModel) {
|
||||
ChatModel *chatModel = mChatModel.get();
|
||||
QObject::disconnect(chatModel, &ChatModel::isRemoteComposingChanged, this, &ChatProxyModel::handleIsRemoteComposingChanged);
|
||||
QObject::disconnect(chatModel, &ChatModel::messageReceived, this, &ChatProxyModel::handleMessageReceived);
|
||||
QObject::disconnect(chatModel, &ChatModel::messageSent, this, &ChatProxyModel::handleMessageSent);
|
||||
if (mChatRoomModel) {
|
||||
ChatRoomModel *ChatRoomModel = mChatRoomModel.get();
|
||||
QObject::disconnect(ChatRoomModel, &ChatRoomModel::isRemoteComposingChanged, this, &ChatRoomProxyModel::handleIsRemoteComposingChanged);
|
||||
QObject::disconnect(ChatRoomModel, &ChatRoomModel::messageReceived, this, &ChatRoomProxyModel::handleMessageReceived);
|
||||
QObject::disconnect(ChatRoomModel, &ChatRoomModel::messageSent, this, &ChatRoomProxyModel::handleMessageSent);
|
||||
}
|
||||
|
||||
//mChatModel = CoreManager::getInstance()->getChatModel(mPeerAddress, mLocalAddress, mIsSecure);
|
||||
//mChatRoomModel = CoreManager::getInstance()->getChatRoomModel(mPeerAddress, mLocalAddress, mIsSecure);
|
||||
//if(mChatRoom)
|
||||
mChatModel = CoreManager::getInstance()->getChatModel(mChatRoom);
|
||||
mChatRoomModel = CoreManager::getInstance()->getChatRoomModel(mChatRoom);
|
||||
|
||||
|
||||
if (mChatModel) {
|
||||
if (mChatRoomModel) {
|
||||
|
||||
ChatModel *chatModel = mChatModel.get();
|
||||
QObject::connect(chatModel, &ChatModel::isRemoteComposingChanged, this, &ChatProxyModel::handleIsRemoteComposingChanged);
|
||||
QObject::connect(chatModel, &ChatModel::messageReceived, this, &ChatProxyModel::handleMessageReceived);
|
||||
QObject::connect(chatModel, &ChatModel::messageSent, this, &ChatProxyModel::handleMessageSent);
|
||||
ChatRoomModel *ChatRoomModel = mChatRoomModel.get();
|
||||
QObject::connect(ChatRoomModel, &ChatRoomModel::isRemoteComposingChanged, this, &ChatRoomProxyModel::handleIsRemoteComposingChanged);
|
||||
QObject::connect(ChatRoomModel, &ChatRoomModel::messageReceived, this, &ChatRoomProxyModel::handleMessageReceived);
|
||||
QObject::connect(ChatRoomModel, &ChatRoomModel::messageSent, this, &ChatRoomProxyModel::handleMessageSent);
|
||||
}
|
||||
|
||||
static_cast<ChatModelFilter *>(sourceModel())->setSourceModel(mChatModel.get());
|
||||
static_cast<ChatRoomModelFilter *>(sourceModel())->setSourceModel(mChatRoomModel.get());
|
||||
}
|
||||
void ChatProxyModel::resetMessageCount(){
|
||||
if( mChatModel){
|
||||
mChatModel->resetMessageCount();
|
||||
void ChatRoomProxyModel::resetMessageCount(){
|
||||
if( mChatRoomModel){
|
||||
mChatRoomModel->resetMessageCount();
|
||||
}
|
||||
}
|
||||
|
||||
std::shared_ptr<ChatModel> ChatProxyModel::getChatModel () const{
|
||||
return mChatModel;
|
||||
ChatRoomModel *ChatRoomProxyModel::getChatRoomModel () const{
|
||||
return mChatRoomModel.get();
|
||||
|
||||
}
|
||||
void ChatProxyModel::setChatModel (std::shared_ptr<ChatModel> chatModel){
|
||||
mChatRoom = chatModel->getChatRoom();
|
||||
void ChatRoomProxyModel::setChatRoomModel (ChatRoomModel *ChatRoomModel){
|
||||
mChatRoom = ChatRoomModel->getChatRoom();
|
||||
reload();
|
||||
emit chatModelChanged();
|
||||
emit chatRoomModelChanged();
|
||||
}
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
|
|
@ -269,25 +269,25 @@ static inline QWindow *getParentWindow (QObject *object) {
|
|||
return nullptr;
|
||||
}
|
||||
|
||||
void ChatProxyModel::handleIsActiveChanged (QWindow *window) {
|
||||
if (mChatModel && window->isActive() && getParentWindow(this) == window) {
|
||||
mChatModel->resetMessageCount();
|
||||
mChatModel->focused();
|
||||
void ChatRoomProxyModel::handleIsActiveChanged (QWindow *window) {
|
||||
if (mChatRoomModel && window->isActive() && getParentWindow(this) == window) {
|
||||
mChatRoomModel->resetMessageCount();
|
||||
mChatRoomModel->focused();
|
||||
}
|
||||
}
|
||||
|
||||
void ChatProxyModel::handleIsRemoteComposingChanged (bool status) {
|
||||
void ChatRoomProxyModel::handleIsRemoteComposingChanged (bool status) {
|
||||
emit isRemoteComposingChanged(status);
|
||||
}
|
||||
|
||||
void ChatProxyModel::handleMessageReceived (const shared_ptr<linphone::ChatMessage> &) {
|
||||
void ChatRoomProxyModel::handleMessageReceived (const shared_ptr<linphone::ChatMessage> &) {
|
||||
mMaxDisplayedEntries++;
|
||||
|
||||
QWindow *window = getParentWindow(this);
|
||||
if (window && window->isActive())
|
||||
mChatModel->resetMessageCount();
|
||||
mChatRoomModel->resetMessageCount();
|
||||
}
|
||||
|
||||
void ChatProxyModel::handleMessageSent (const shared_ptr<linphone::ChatMessage> &) {
|
||||
void ChatRoomProxyModel::handleMessageSent (const shared_ptr<linphone::ChatMessage> &) {
|
||||
mMaxDisplayedEntries++;
|
||||
}
|
||||
|
|
@ -18,19 +18,19 @@
|
|||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef CHAT_PROXY_MODEL_H_
|
||||
#define CHAT_PROXY_MODEL_H_
|
||||
#ifndef CHAT_ROOM_PROXY_MODEL_H_
|
||||
#define CHAT_ROOM_PROXY_MODEL_H_
|
||||
|
||||
#include <QSortFilterProxyModel>
|
||||
|
||||
#include "ChatModel.hpp"
|
||||
#include "ChatRoomModel.hpp"
|
||||
|
||||
// =============================================================================
|
||||
|
||||
class QWindow;
|
||||
|
||||
class ChatProxyModel : public QSortFilterProxyModel {
|
||||
class ChatModelFilter;
|
||||
class ChatRoomProxyModel : public QSortFilterProxyModel {
|
||||
class ChatRoomModelFilter;
|
||||
|
||||
Q_OBJECT;
|
||||
|
||||
|
|
@ -39,17 +39,17 @@ class ChatProxyModel : public QSortFilterProxyModel {
|
|||
Q_PROPERTY(QString fullPeerAddress READ getFullPeerAddress WRITE setFullPeerAddress NOTIFY fullPeerAddressChanged);
|
||||
Q_PROPERTY(QString fullLocalAddress READ getFullLocalAddress WRITE setFullLocalAddress NOTIFY fullLocalAddressChanged);
|
||||
Q_PROPERTY(int isSecure READ getIsSecure WRITE setIsSecure NOTIFY isSecureChanged);
|
||||
Q_PROPERTY(std::shared_ptr<ChatModel> chatModel READ getChatModel WRITE setChatModel NOTIFY chatModelChanged);
|
||||
Q_PROPERTY(ChatRoomModel *chatRoomModel READ getChatRoomModel WRITE setChatRoomModel NOTIFY chatRoomModelChanged);
|
||||
//Q_PROPERTY(bool isSecure MEMBER mIsSecure NOTIFY isSecureChanged);
|
||||
Q_PROPERTY(bool isRemoteComposing READ getIsRemoteComposing NOTIFY isRemoteComposingChanged);
|
||||
//Q_PROPERTY(bool isSecure READ getIsSecure NOTIFY isSecureChanged);
|
||||
Q_PROPERTY(QString cachedText READ getCachedText);
|
||||
|
||||
public:
|
||||
ChatProxyModel (QObject *parent = Q_NULLPTR);
|
||||
ChatRoomProxyModel (QObject *parent = Q_NULLPTR);
|
||||
|
||||
Q_INVOKABLE void loadMoreEntries ();
|
||||
Q_INVOKABLE void setEntryTypeFilter (ChatModel::EntryType type);
|
||||
Q_INVOKABLE void setEntryTypeFilter (ChatRoomModel::EntryType type);
|
||||
Q_INVOKABLE void removeEntry (int id);
|
||||
|
||||
Q_INVOKABLE void removeAllEntries ();
|
||||
|
|
@ -75,11 +75,11 @@ signals:
|
|||
bool isRemoteComposingChanged (bool status);
|
||||
bool isSecureChanged(bool secure);
|
||||
|
||||
void chatModelChanged();
|
||||
void chatRoomModelChanged();
|
||||
|
||||
void moreEntriesLoaded (int n);
|
||||
|
||||
void entryTypeFilterChanged (ChatModel::EntryType type);
|
||||
void entryTypeFilterChanged (ChatRoomModel::EntryType type);
|
||||
|
||||
protected:
|
||||
bool filterAcceptsRow (int sourceRow, const QModelIndex &sourceParent) const override;
|
||||
|
|
@ -100,8 +100,8 @@ private:
|
|||
int getIsSecure () const;
|
||||
void setIsSecure (const int &secure);
|
||||
|
||||
std::shared_ptr<ChatModel> getChatModel() const;
|
||||
void setChatModel (std::shared_ptr<ChatModel> chatModel);
|
||||
ChatRoomModel *getChatRoomModel() const;
|
||||
void setChatRoomModel (ChatRoomModel *chatRoomModel);
|
||||
|
||||
bool getIsRemoteComposing () const;
|
||||
|
||||
|
|
@ -126,9 +126,9 @@ private:
|
|||
std::shared_ptr<linphone::ChatRoom> mChatRoom;
|
||||
|
||||
|
||||
std::shared_ptr<ChatModel> mChatModel;
|
||||
std::shared_ptr<ChatRoomModel> mChatRoomModel;
|
||||
|
||||
static constexpr int EntriesChunkSize = 50;
|
||||
};
|
||||
|
||||
#endif // CHAT_PROXY_MODEL_H_
|
||||
#endif // CHAT_ROOM_PROXY_MODEL_H_
|
||||
|
|
@ -1,161 +0,0 @@
|
|||
/*
|
||||
* 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 CHAT_MODEL_H_
|
||||
#define CHAT_MODEL_H_
|
||||
|
||||
#include <linphone++/linphone.hh>
|
||||
#include <QAbstractListModel>
|
||||
|
||||
// =============================================================================
|
||||
// Fetch all N messages of a ChatRoom.
|
||||
// =============================================================================
|
||||
|
||||
class CoreHandlers;
|
||||
|
||||
class ChatModel : public QAbstractListModel {
|
||||
class MessageHandlers;
|
||||
|
||||
Q_OBJECT;
|
||||
|
||||
public:
|
||||
enum Roles {
|
||||
ChatEntry = Qt::DisplayRole,
|
||||
SectionDate
|
||||
};
|
||||
|
||||
enum EntryType {
|
||||
GenericEntry,
|
||||
MessageEntry,
|
||||
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);
|
||||
|
||||
enum MessageStatus {
|
||||
MessageStatusDelivered = int(linphone::ChatMessage::State::Delivered),
|
||||
MessageStatusDeliveredToUser = int(linphone::ChatMessage::State::DeliveredToUser),
|
||||
MessageStatusDisplayed = int(linphone::ChatMessage::State::Displayed),
|
||||
MessageStatusFileTransferDone = int(linphone::ChatMessage::State::FileTransferDone),
|
||||
MessageStatusFileTransferError = int(linphone::ChatMessage::State::FileTransferError),
|
||||
MessageStatusFileTransferInProgress = int(linphone::ChatMessage::State::FileTransferInProgress),
|
||||
MessageStatusIdle = int(linphone::ChatMessage::State::Idle),
|
||||
MessageStatusInProgress = int(linphone::ChatMessage::State::InProgress),
|
||||
MessageStatusNotDelivered = int(linphone::ChatMessage::State::NotDelivered)
|
||||
|
||||
};
|
||||
Q_ENUM(MessageStatus);
|
||||
|
||||
ChatModel (const QString &peerAddress, const QString &localAddress, const bool& isSecure);
|
||||
ChatModel (std::shared_ptr<linphone::ChatRoom> chatRoom);
|
||||
~ChatModel ();
|
||||
|
||||
int rowCount (const QModelIndex &index = QModelIndex()) const override;
|
||||
|
||||
QHash<int, QByteArray> 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;
|
||||
|
||||
QString getPeerAddress () const;
|
||||
QString getLocalAddress () const;
|
||||
QString getFullPeerAddress () const;
|
||||
QString getFullLocalAddress () const;
|
||||
|
||||
bool getIsSecure() const;
|
||||
|
||||
bool getIsRemoteComposing () const;
|
||||
|
||||
void removeEntry (int id);
|
||||
void removeAllEntries ();
|
||||
|
||||
void sendMessage (const QString &message);
|
||||
|
||||
void resendMessage (int id);
|
||||
|
||||
void sendFileMessage (const QString &path);
|
||||
|
||||
void downloadFile (int id);
|
||||
void openFile (int id, bool showDirectory = false);
|
||||
void openFileDirectory (int id) {
|
||||
openFile(id, true);
|
||||
}
|
||||
|
||||
bool fileWasDownloaded (int id);
|
||||
|
||||
void compose ();
|
||||
|
||||
void resetMessageCount ();
|
||||
|
||||
std::shared_ptr<linphone::ChatRoom> getChatRoom();
|
||||
|
||||
signals:
|
||||
bool isRemoteComposingChanged (bool status);
|
||||
|
||||
void allEntriesRemoved ();
|
||||
void lastEntryRemoved ();
|
||||
|
||||
void messageSent (const std::shared_ptr<linphone::ChatMessage> &message);
|
||||
void messageReceived (const std::shared_ptr<linphone::ChatMessage> &message);
|
||||
|
||||
void messageCountReset ();
|
||||
|
||||
void focused ();
|
||||
|
||||
private:
|
||||
typedef QPair<QVariantMap, std::shared_ptr<void>> ChatEntryData;
|
||||
|
||||
void setSipAddresses (const QString &peerAddress, const QString &localAddress, const bool& isSecure);
|
||||
|
||||
const ChatEntryData getFileMessageEntry (int id);
|
||||
|
||||
void removeEntry (ChatEntryData &entry);
|
||||
|
||||
void insertCall (const std::shared_ptr<linphone::CallLog> &callLog);
|
||||
void insertMessageAtEnd (const std::shared_ptr<linphone::ChatMessage> &message);
|
||||
|
||||
void handleCallStateChanged (const std::shared_ptr<linphone::Call> &call, linphone::Call::State state);
|
||||
void handleIsComposingChanged (const std::shared_ptr<linphone::ChatRoom> &chatRoom);
|
||||
void handleMessageReceived (const std::shared_ptr<linphone::ChatMessage> &message);
|
||||
|
||||
bool mIsRemoteComposing = false;
|
||||
|
||||
mutable QList<ChatEntryData> mEntries;
|
||||
|
||||
std::shared_ptr<CoreHandlers> mCoreHandlers;
|
||||
std::shared_ptr<MessageHandlers> mMessageHandlers;
|
||||
|
||||
std::shared_ptr<linphone::ChatRoom> mChatRoom;
|
||||
};
|
||||
|
||||
Q_DECLARE_METATYPE(std::shared_ptr<ChatModel>);
|
||||
|
||||
#endif // CHAT_MODEL_H_
|
||||
|
|
@ -51,6 +51,7 @@ public:
|
|||
void mergeVcardModel (VcardModel *vcardModel);
|
||||
|
||||
Q_INVOKABLE VcardModel *cloneVcardModel () const;
|
||||
Presence::PresenceLevel getPresenceLevel () const;
|
||||
|
||||
signals:
|
||||
void contactUpdated ();
|
||||
|
|
@ -65,7 +66,7 @@ private:
|
|||
void updateSipAddresses (VcardModel *oldVcardModel);
|
||||
|
||||
Presence::PresenceStatus getPresenceStatus () const;
|
||||
Presence::PresenceLevel getPresenceLevel () const;
|
||||
|
||||
|
||||
VcardModel *mVcardModel = nullptr;
|
||||
std::shared_ptr<linphone::Friend> mLinphoneFriend;
|
||||
|
|
|
|||
|
|
@ -194,7 +194,7 @@ void CoreHandlers::onMessageReceived (
|
|||
|
||||
if (
|
||||
!app->hasFocus() ||
|
||||
!CoreManager::getInstance()->chatModelExists(
|
||||
!CoreManager::getInstance()->chatRoomModelExists(
|
||||
Utils::coreStringToAppString(chatRoom->getPeerAddress()->asStringUriOnly()),
|
||||
Utils::coreStringToAppString(chatRoom->getLocalAddress()->asStringUriOnly()),
|
||||
chatRoom->getSecurityLevel() == linphone::ChatRoomSecurityLevel::Encrypted
|
||||
|
|
|
|||
|
|
@ -29,7 +29,8 @@
|
|||
|
||||
#include "app/paths/Paths.hpp"
|
||||
#include "components/calls/CallsListModel.hpp"
|
||||
#include "components/chat/ChatModel.hpp"
|
||||
#include "components/chat-room/ChatRoomModel.hpp"
|
||||
#include "components/chat-room/ChatRoomListModel.hpp"
|
||||
#include "components/contact/VcardModel.hpp"
|
||||
#include "components/contacts/ContactsListModel.hpp"
|
||||
#include "components/contacts/ContactsImporterListModel.hpp"
|
||||
|
|
@ -100,6 +101,7 @@ CoreManager::~CoreManager(){
|
|||
|
||||
void CoreManager::initCoreManager(){
|
||||
mCallsListModel = new CallsListModel(this);
|
||||
mChatRoomListModel = new ChatRoomListModel(this);
|
||||
mContactsListModel = new ContactsListModel(this);
|
||||
mContactsImporterListModel = new ContactsImporterListModel(this);
|
||||
mAccountSettingsModel = new AccountSettingsModel(this);
|
||||
|
|
@ -120,13 +122,14 @@ CoreManager *CoreManager::getInstance (){
|
|||
return mInstance;
|
||||
}
|
||||
|
||||
shared_ptr<ChatModel> CoreManager::getChatModel (const QString &peerAddress, const QString &localAddress, const bool& isSecure) {
|
||||
/*
|
||||
shared_ptr<ChatRoomModel> CoreManager::getChatRoomModel (const QString &peerAddress, const QString &localAddress, const bool& isSecure) {
|
||||
if (peerAddress.isEmpty() || localAddress.isEmpty())
|
||||
return nullptr;
|
||||
|
||||
// Create a new chat model.
|
||||
QPair<bool, QPair<QString, QString>> chatModelId{isSecure,{ peerAddress, localAddress }};
|
||||
if (!mChatModels.contains(chatModelId)) {
|
||||
QPair<bool, QPair<QString, QString>> chatRoomModelId{isSecure,{ peerAddress, localAddress }};
|
||||
if (!mChatRoomModels.contains(chatRoomModelId)) {
|
||||
if (
|
||||
!mCore->createAddress(peerAddress.toStdString()) ||
|
||||
!mCore->createAddress(localAddress.toStdString())
|
||||
|
|
@ -136,31 +139,43 @@ shared_ptr<ChatModel> CoreManager::getChatModel (const QString &peerAddress, con
|
|||
return nullptr;
|
||||
}
|
||||
|
||||
auto deleter = [this, chatModelId](ChatModel *chatModel) {
|
||||
bool removed = mChatModels.remove(chatModelId);
|
||||
auto deleter = [this, chatRoomModelId](ChatRoomModel *chatRoomModel) {
|
||||
bool removed = mChatRoomModels.remove(chatRoomModelId);
|
||||
Q_ASSERT(removed);
|
||||
delete chatModel;
|
||||
delete chatRoomModel;
|
||||
};
|
||||
|
||||
shared_ptr<ChatModel> chatModel(new ChatModel(peerAddress, localAddress, isSecure), deleter);
|
||||
mChatModels[chatModelId] = chatModel;
|
||||
shared_ptr<ChatRoomModel> chatRoomModel(new ChatRoomModel(peerAddress, localAddress, isSecure), deleter);
|
||||
mChatRoomModels[chatRoomModelId] = chatRoomModel;
|
||||
|
||||
emit chatModelCreated(chatModel);
|
||||
emit chatRoomModelCreated(chatRoomModel);
|
||||
|
||||
return chatModel;
|
||||
return chatRoomModel;
|
||||
}
|
||||
|
||||
// Returns an existing chat model.
|
||||
shared_ptr<ChatModel> chatModel = mChatModels[chatModelId].lock();
|
||||
Q_CHECK_PTR(chatModel);
|
||||
return chatModel;
|
||||
shared_ptr<ChatRoomModel> chatRoomModel = mChatRoomModels[chatRoomModelId].lock();
|
||||
Q_CHECK_PTR(chatRoomModel);
|
||||
return chatRoomModel;
|
||||
}
|
||||
*/
|
||||
|
||||
shared_ptr<ChatRoomModel> CoreManager::getChatRoomModel (ChatRoomModel * data) {
|
||||
if(data){
|
||||
for(auto it = mChatRoomModels.begin() ; it != mChatRoomModels.end() ; ++it){
|
||||
auto a = it->lock();
|
||||
if(a.get() == data)
|
||||
return a;
|
||||
}
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
shared_ptr<ChatModel> CoreManager::getChatModel (std::shared_ptr<linphone::ChatRoom> chatRoom) {
|
||||
shared_ptr<ChatRoomModel> CoreManager::getChatRoomModel (std::shared_ptr<linphone::ChatRoom> chatRoom) {
|
||||
if (!chatRoom)
|
||||
return nullptr;
|
||||
auto pc = chatRoom->getCurrentParams();
|
||||
for(auto it = mChatModels.begin() ; it != mChatModels.end() ; ++it) {
|
||||
for(auto it = mChatRoomModels.begin() ; it != mChatRoomModels.end() ; ++it) {
|
||||
auto a = it->lock();
|
||||
auto pa = a->getChatRoom()->getCurrentParams();
|
||||
if( a->getChatRoom()->getConferenceAddress() == chatRoom->getConferenceAddress()
|
||||
|
|
@ -170,32 +185,34 @@ shared_ptr<ChatModel> CoreManager::getChatModel (std::shared_ptr<linphone::ChatR
|
|||
&& pa->encryptionEnabled() == pc->encryptionEnabled()
|
||||
){
|
||||
// Returns an existing chat model.
|
||||
shared_ptr<ChatModel> chatModel = a;
|
||||
Q_CHECK_PTR(chatModel);
|
||||
return chatModel;
|
||||
shared_ptr<ChatRoomModel> chatRoomModel = a;
|
||||
Q_CHECK_PTR(chatRoomModel);
|
||||
return chatRoomModel;
|
||||
}
|
||||
}
|
||||
|
||||
QPair<bool, QPair<QString, QString>> chatModelId{pc->encryptionEnabled(),
|
||||
QPair<bool, QPair<QString, QString>> chatRoomModelId{pc->encryptionEnabled(),
|
||||
{ QString::fromStdString(chatRoom->getPeerAddress()->asString())
|
||||
, QString::fromStdString(chatRoom->getLocalAddress()->asString()) }};
|
||||
|
||||
|
||||
auto deleter = [this, chatModelId](ChatModel *chatModel) {
|
||||
bool removed = mChatModels.remove(chatModelId);
|
||||
auto deleter = [this, chatRoomModelId](ChatRoomModel *chatRoomModel) {
|
||||
bool removed = mChatRoomModels.remove(chatRoomModelId);
|
||||
Q_ASSERT(removed);
|
||||
chatModel->deleteLater();
|
||||
chatRoomModel->deleteLater();
|
||||
};
|
||||
|
||||
shared_ptr<ChatModel> chatModel(new ChatModel(chatRoom), deleter);
|
||||
mChatModels[chatModelId] = chatModel;
|
||||
shared_ptr<ChatRoomModel> chatRoomModel(new ChatRoomModel(chatRoom), deleter);
|
||||
chatRoom->addListener(chatRoomModel);
|
||||
mChatRoomModels[chatRoomModelId] = chatRoomModel;
|
||||
|
||||
emit chatModelCreated(chatModel);
|
||||
emit chatRoomModelCreated(chatRoomModel);
|
||||
|
||||
return chatModel;
|
||||
return chatRoomModel;
|
||||
}
|
||||
bool CoreManager::chatModelExists (const QString &peerAddress, const QString &localAddress, const bool &isSecure) {
|
||||
return mChatModels.contains({isSecure, { peerAddress, localAddress}});
|
||||
|
||||
bool CoreManager::chatRoomModelExists (const QString &peerAddress, const QString &localAddress, const bool &isSecure) {
|
||||
return mChatRoomModels.contains({isSecure, { peerAddress, localAddress}});
|
||||
}
|
||||
|
||||
HistoryModel* CoreManager::getHistoryModel(){
|
||||
|
|
|
|||
|
|
@ -33,7 +33,8 @@ class QTimer;
|
|||
|
||||
class AccountSettingsModel;
|
||||
class CallsListModel;
|
||||
class ChatModel;
|
||||
class ChatRoomModel;
|
||||
class ChatRoomListModel;
|
||||
class ContactsListModel;
|
||||
class ContactsImporterListModel;
|
||||
class CoreHandlers;
|
||||
|
|
@ -67,9 +68,10 @@ public:
|
|||
return mHandlers;
|
||||
}
|
||||
|
||||
std::shared_ptr<ChatModel> getChatModel (const QString &peerAddress, const QString &localAddress, const bool &isSecure);
|
||||
std::shared_ptr<ChatModel> getChatModel (std::shared_ptr<linphone::ChatRoom> chatRoom);
|
||||
bool chatModelExists (const QString &sipAddress, const QString &localAddress, const bool &isSecure);
|
||||
//std::shared_ptr<ChatRoomModel> getChatRoomModel (const QString &peerAddress, const QString &localAddress, const bool &isSecure);
|
||||
std::shared_ptr<ChatRoomModel> getChatRoomModel (ChatRoomModel * data);// Get the shared pointer. This can be done becuase of unicity of ChatRoomModel
|
||||
std::shared_ptr<ChatRoomModel> getChatRoomModel (std::shared_ptr<linphone::ChatRoom> chatRoom);
|
||||
bool chatRoomModelExists (const QString &sipAddress, const QString &localAddress, const bool &isSecure);
|
||||
|
||||
HistoryModel* getHistoryModel();
|
||||
|
||||
|
|
@ -93,6 +95,12 @@ public:
|
|||
Q_CHECK_PTR(mCallsListModel);
|
||||
return mCallsListModel;
|
||||
}
|
||||
|
||||
ChatRoomListModel *getChatRoomListModel () const {
|
||||
Q_CHECK_PTR(mChatRoomListModel);
|
||||
return mChatRoomListModel;
|
||||
}
|
||||
|
||||
|
||||
ContactsListModel *getContactsListModel () const {
|
||||
Q_CHECK_PTR(mContactsListModel);
|
||||
|
|
@ -163,7 +171,7 @@ public slots:
|
|||
signals:
|
||||
void coreManagerInitialized ();
|
||||
|
||||
void chatModelCreated (const std::shared_ptr<ChatModel> &chatModel);
|
||||
void chatRoomModelCreated (const std::shared_ptr<ChatRoomModel> &chatRoomModel);
|
||||
void historyModelCreated (HistoryModel *historyModel);
|
||||
|
||||
void logsUploaded (const QString &url);
|
||||
|
|
@ -200,6 +208,7 @@ private:
|
|||
ContactsListModel *mContactsListModel = nullptr;
|
||||
ContactsImporterListModel *mContactsImporterListModel = nullptr;
|
||||
TimelineListModel *mTimelineListModel = nullptr;
|
||||
ChatRoomListModel *mChatRoomListModel = nullptr;
|
||||
|
||||
SipAddressesModel *mSipAddressesModel = nullptr;
|
||||
SettingsModel *mSettingsModel = nullptr;
|
||||
|
|
@ -207,7 +216,7 @@ private:
|
|||
|
||||
EventCountNotifier *mEventCountNotifier = nullptr;
|
||||
|
||||
QHash<QPair<bool, QPair<QString, QString> >, std::weak_ptr<ChatModel>> mChatModels;
|
||||
QHash<QPair<bool, QPair<QString, QString> >, std::weak_ptr<ChatRoomModel>> mChatRoomModels;
|
||||
HistoryModel * mHistoryModel = nullptr;
|
||||
LdapListModel *mLdapListModel = nullptr;
|
||||
|
||||
|
|
|
|||
|
|
@ -22,7 +22,7 @@
|
|||
|
||||
#include "components/call/CallModel.hpp"
|
||||
#include "components/calls/CallsListModel.hpp"
|
||||
#include "components/chat/ChatModel.hpp"
|
||||
#include "components/chat-room/ChatRoomModel.hpp"
|
||||
#include "components/core/CoreHandlers.hpp"
|
||||
#include "components/core/CoreManager.hpp"
|
||||
#include "components/history/HistoryModel.hpp"
|
||||
|
|
@ -38,8 +38,8 @@ using namespace std;
|
|||
AbstractEventCountNotifier::AbstractEventCountNotifier (QObject *parent) : QObject(parent) {
|
||||
CoreManager *coreManager = CoreManager::getInstance();
|
||||
QObject::connect(
|
||||
coreManager, &CoreManager::chatModelCreated,
|
||||
this, &AbstractEventCountNotifier::handleChatModelCreated
|
||||
coreManager, &CoreManager::chatRoomModelCreated,
|
||||
this, &AbstractEventCountNotifier::handleChatRoomModelCreated
|
||||
);
|
||||
QObject::connect(
|
||||
coreManager, &CoreManager::historyModelCreated,
|
||||
|
|
@ -95,19 +95,19 @@ int AbstractEventCountNotifier::getMissedCallCountFromLocal(const QString &local
|
|||
}
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
void AbstractEventCountNotifier::handleChatModelCreated (const shared_ptr<ChatModel> &chatModel) {
|
||||
ChatModel *chatModelPtr = chatModel.get();
|
||||
void AbstractEventCountNotifier::handleChatRoomModelCreated (const shared_ptr<ChatRoomModel> &chatRoomModel) {
|
||||
ChatRoomModel *chatRoomModelPtr = chatRoomModel.get();
|
||||
QObject::connect(
|
||||
chatModelPtr, &ChatModel::messageCountReset,
|
||||
chatRoomModelPtr, &ChatRoomModel::messageCountReset,
|
||||
this, &AbstractEventCountNotifier::updateUnreadMessageCount
|
||||
);
|
||||
QObject::connect(
|
||||
chatModelPtr, &ChatModel::focused,
|
||||
this, [this, chatModelPtr]() { handleResetMissedCalls(chatModelPtr); }
|
||||
chatRoomModelPtr, &ChatRoomModel::focused,
|
||||
this, [this, chatRoomModelPtr]() { handleResetMissedCalls(chatRoomModelPtr); }
|
||||
);
|
||||
QObject::connect(
|
||||
chatModelPtr, &ChatModel::messageCountReset,
|
||||
this, [this, chatModelPtr]() { handleResetMissedCalls(chatModelPtr); }
|
||||
chatRoomModelPtr, &ChatRoomModel::messageCountReset,
|
||||
this, [this, chatRoomModelPtr]() { handleResetMissedCalls(chatRoomModelPtr); }
|
||||
);
|
||||
}
|
||||
|
||||
|
|
@ -122,8 +122,8 @@ void AbstractEventCountNotifier::handleResetAllMissedCalls () {
|
|||
}
|
||||
|
||||
|
||||
void AbstractEventCountNotifier::handleResetMissedCalls (ChatModel *chatModel) {
|
||||
auto it = mMissedCalls.find({ Utils::cleanSipAddress(chatModel->getPeerAddress()), Utils::cleanSipAddress(chatModel->getLocalAddress()) });
|
||||
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();
|
||||
|
|
|
|||
|
|
@ -34,7 +34,7 @@ namespace linphone {
|
|||
}
|
||||
|
||||
class CallModel;
|
||||
class ChatModel;
|
||||
class ChatRoomModel;
|
||||
class HistoryModel;
|
||||
|
||||
class AbstractEventCountNotifier : public QObject {
|
||||
|
|
@ -67,12 +67,12 @@ private:
|
|||
|
||||
void internalnotifyEventCount ();
|
||||
|
||||
void handleChatModelCreated (const std::shared_ptr<ChatModel> &chatModel);
|
||||
void handleChatRoomModelCreated (const std::shared_ptr<ChatRoomModel> &chatRoomModel);
|
||||
void handleHistoryModelCreated (HistoryModel *historyModel);
|
||||
|
||||
|
||||
void handleResetAllMissedCalls ();
|
||||
void handleResetMissedCalls (ChatModel *chatModel);
|
||||
void handleResetMissedCalls (ChatRoomModel *chatRoomModel);
|
||||
void handleCallMissed (CallModel *callModel);
|
||||
|
||||
QHash<ConferenceId, int> mMissedCalls;
|
||||
|
|
|
|||
|
|
@ -29,6 +29,8 @@
|
|||
#include "app/App.hpp"
|
||||
#include "components/call/CallModel.hpp"
|
||||
#include "components/core/CoreManager.hpp"
|
||||
#include "components/timeline/TimelineModel.hpp"
|
||||
#include "components/timeline/TimelineListModel.hpp"
|
||||
#include "utils/Utils.hpp"
|
||||
|
||||
#include "Notifier.hpp"
|
||||
|
|
@ -267,12 +269,13 @@ void Notifier::notifyReceivedMessage (const shared_ptr<linphone::ChatMessage> &m
|
|||
if(! message->getFileTransferInformation() ){
|
||||
foreach(auto content, message->getContents()){
|
||||
if(content->isText())
|
||||
txt += content->getStringBuffer().c_str();
|
||||
txt += content->getUtf8Text().c_str();
|
||||
}
|
||||
}else
|
||||
txt = tr("newFileMessage");
|
||||
map["message"] = txt;
|
||||
shared_ptr<linphone::ChatRoom> chatRoom(message->getChatRoom());
|
||||
map["timelineModel"].setValue(CoreManager::getInstance()->getTimelineListModel()->getTimeline(chatRoom, true).get());
|
||||
map["peerAddress"] = Utils::coreStringToAppString(chatRoom->getPeerAddress()->asStringUriOnly());
|
||||
map["localAddress"] = Utils::coreStringToAppString(chatRoom->getLocalAddress()->asStringUriOnly());
|
||||
map["fullPeerAddress"] = QString::fromStdString(chatRoom->getPeerAddress()->asString());
|
||||
|
|
|
|||
54
linphone-app/src/components/participant/ParticipantModel.cpp
Normal file
54
linphone-app/src/components/participant/ParticipantModel.cpp
Normal file
|
|
@ -0,0 +1,54 @@
|
|||
/*
|
||||
* Copyright (c) 2021 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 <QQmlApplicationEngine>
|
||||
|
||||
#include "app/App.hpp"
|
||||
|
||||
#include "ParticipantModel.hpp"
|
||||
#include "utils/Utils.hpp"
|
||||
|
||||
// =============================================================================
|
||||
|
||||
using namespace std;
|
||||
|
||||
ParticipantModel::ParticipantModel (shared_ptr<linphone::Participant> linphoneParticipant, QObject *parent) : QObject(parent) {
|
||||
mLinphoneParticipant = linphoneParticipant;
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
QString ParticipantModel::getAddress() const{
|
||||
return Utils::coreStringToAppString(mLinphoneParticipant->getAddress()->asStringUriOnly());
|
||||
}
|
||||
|
||||
QDateTime ParticipantModel::getCreationTime() const{
|
||||
return QDateTime::fromSecsSinceEpoch(mLinphoneParticipant->getCreationTime());
|
||||
}
|
||||
|
||||
//std::list<std::shared_ptr<linphone::ParticipantDevice>> ParticipantModel::getDevices() const;
|
||||
bool ParticipantModel::isAdmin() const{
|
||||
return mLinphoneParticipant->isAdmin();
|
||||
}
|
||||
bool ParticipantModel::isFocus() const{
|
||||
return mLinphoneParticipant->isFocus();
|
||||
}
|
||||
//linphone::ChatRoomSecurityLevel ParticipantModel::getSecurityLevel() const;
|
||||
//std::shared_ptr<linphone::ParticipantDevice> ParticipantModel::findDevice(const std::shared_ptr<const linphone::Address> & address) const;
|
||||
62
linphone-app/src/components/participant/ParticipantModel.hpp
Normal file
62
linphone-app/src/components/participant/ParticipantModel.hpp
Normal file
|
|
@ -0,0 +1,62 @@
|
|||
/*
|
||||
* Copyright (c) 2021 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 PARTICIPANT_MODEL_H_
|
||||
#define PARTICIPANT_MODEL_H_
|
||||
|
||||
|
||||
#include <linphone++/linphone.hh>
|
||||
// =============================================================================
|
||||
#include <QObject>
|
||||
#include <QDateTime>
|
||||
#include <QString>
|
||||
|
||||
class ParticipantModel : public QObject {
|
||||
|
||||
Q_OBJECT;
|
||||
|
||||
Q_PROPERTY(QString address READ getAddress CONSTANT);
|
||||
Q_PROPERTY(QDateTime creationTime READ getCreationTime CONSTANT);
|
||||
Q_PROPERTY(bool admin READ isAdmin CONSTANT);
|
||||
Q_PROPERTY(bool focus READ isFocus CONSTANT);
|
||||
|
||||
public:
|
||||
ParticipantModel (std::shared_ptr<linphone::Participant> linphoneParticipant, QObject *parent = nullptr);
|
||||
|
||||
QString getAddress() const;
|
||||
QDateTime getCreationTime() const;
|
||||
//std::list<std::shared_ptr<linphone::ParticipantDevice>> getDevices() const;
|
||||
bool isAdmin() const;
|
||||
bool isFocus() const;
|
||||
//linphone::ChatRoomSecurityLevel getSecurityLevel() const;
|
||||
//std::shared_ptr<linphone::ParticipantDevice> findDevice(const std::shared_ptr<const linphone::Address> & address) const;
|
||||
|
||||
//signals:
|
||||
// void contactUpdated ();
|
||||
|
||||
|
||||
private:
|
||||
|
||||
std::shared_ptr<linphone::Participant> mLinphoneParticipant;
|
||||
};
|
||||
|
||||
Q_DECLARE_METATYPE(ParticipantModel *);
|
||||
|
||||
#endif // PARTICIPANT_MODEL_H_
|
||||
|
|
@ -0,0 +1,293 @@
|
|||
/*
|
||||
* 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 <QQuickWindow>
|
||||
|
||||
#include "app/App.hpp"
|
||||
#include "components/core/CoreManager.hpp"
|
||||
|
||||
#include "ChatRoomProxyModel.hpp"
|
||||
|
||||
// =============================================================================
|
||||
|
||||
using namespace std;
|
||||
|
||||
QString ChatRoomProxyModel::gCachedText;
|
||||
|
||||
// Fetch the L last filtered chat entries.
|
||||
class ChatRoomProxyModel::ChatRoomModelFilter : public QSortFilterProxyModel {
|
||||
public:
|
||||
ChatRoomModelFilter (QObject *parent) : QSortFilterProxyModel(parent) {}
|
||||
|
||||
ChatRoomModel::EntryType getEntryTypeFilter () {
|
||||
return mEntryTypeFilter;
|
||||
}
|
||||
|
||||
void setEntryTypeFilter (ChatRoomModel::EntryType type) {
|
||||
mEntryTypeFilter = type;
|
||||
invalidate();
|
||||
}
|
||||
|
||||
protected:
|
||||
bool filterAcceptsRow (int sourceRow, const QModelIndex &) const override {
|
||||
if (mEntryTypeFilter == ChatRoomModel::EntryType::GenericEntry)
|
||||
return true;
|
||||
|
||||
QModelIndex index = sourceModel()->index(sourceRow, 0, QModelIndex());
|
||||
const QVariantMap data = index.data().toMap();
|
||||
|
||||
return data["type"].toInt() == mEntryTypeFilter;
|
||||
}
|
||||
|
||||
private:
|
||||
ChatRoomModel::EntryType mEntryTypeFilter = ChatRoomModel::EntryType::GenericEntry;
|
||||
};
|
||||
|
||||
// =============================================================================
|
||||
|
||||
ChatRoomProxyModel::ChatRoomProxyModel (QObject *parent) : QSortFilterProxyModel(parent) {
|
||||
setSourceModel(new ChatRoomModelFilter(this));
|
||||
mIsSecure = false;
|
||||
|
||||
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);
|
||||
});
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
#define GET_CHAT_MODEL() \
|
||||
if (!mChatRoomModel) \
|
||||
return; \
|
||||
mChatRoomModel
|
||||
|
||||
#define CREATE_PARENT_MODEL_FUNCTION(METHOD) \
|
||||
void ChatRoomProxyModel::METHOD () { \
|
||||
GET_CHAT_MODEL()->METHOD(); \
|
||||
}
|
||||
|
||||
#define CREATE_PARENT_MODEL_FUNCTION_WITH_PARAM(METHOD, ARG_TYPE) \
|
||||
void ChatRoomProxyModel::METHOD (ARG_TYPE value) { \
|
||||
GET_CHAT_MODEL()->METHOD(value); \
|
||||
}
|
||||
|
||||
#define CREATE_PARENT_MODEL_FUNCTION_WITH_ID(METHOD) \
|
||||
void ChatRoomProxyModel::METHOD (int id) { \
|
||||
QModelIndex sourceIndex = mapToSource(index(id, 0)); \
|
||||
GET_CHAT_MODEL()->METHOD( \
|
||||
static_cast<ChatRoomModelFilter *>(sourceModel())->mapToSource(sourceIndex).row() \
|
||||
); \
|
||||
}
|
||||
|
||||
CREATE_PARENT_MODEL_FUNCTION(removeAllEntries);
|
||||
|
||||
CREATE_PARENT_MODEL_FUNCTION_WITH_PARAM(sendFileMessage, const QString &);
|
||||
CREATE_PARENT_MODEL_FUNCTION_WITH_PARAM(sendMessage, const QString &);
|
||||
|
||||
CREATE_PARENT_MODEL_FUNCTION_WITH_ID(downloadFile);
|
||||
CREATE_PARENT_MODEL_FUNCTION_WITH_ID(openFile);
|
||||
CREATE_PARENT_MODEL_FUNCTION_WITH_ID(openFileDirectory);
|
||||
CREATE_PARENT_MODEL_FUNCTION_WITH_ID(removeEntry);
|
||||
CREATE_PARENT_MODEL_FUNCTION_WITH_ID(resendMessage);
|
||||
|
||||
#undef GET_CHAT_MODEL
|
||||
#undef CREATE_PARENT_MODEL_FUNCTION
|
||||
#undef CREATE_PARENT_MODEL_FUNCTION_WITH_PARAM
|
||||
#undef CREATE_PARENT_MODEL_FUNCTION_WITH_ID
|
||||
|
||||
|
||||
void ChatRoomProxyModel::compose (const QString& text) {
|
||||
if (mChatRoomModel)
|
||||
mChatRoomModel->compose();
|
||||
gCachedText = text;
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
void ChatRoomProxyModel::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 ChatRoomProxyModel::setEntryTypeFilter (ChatRoomModel::EntryType type) {
|
||||
ChatRoomModelFilter *chatRoomModelFilter = static_cast<ChatRoomModelFilter *>(sourceModel());
|
||||
|
||||
if (chatRoomModelFilter->getEntryTypeFilter() != type) {
|
||||
chatRoomModelFilter->setEntryTypeFilter(type);
|
||||
emit entryTypeFilterChanged(type);
|
||||
}
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
bool ChatRoomProxyModel::filterAcceptsRow (int sourceRow, const QModelIndex &) const {
|
||||
return sourceModel()->rowCount() - sourceRow <= mMaxDisplayedEntries;
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
QString ChatRoomProxyModel::getPeerAddress () const {
|
||||
return mChatRoomModel ? mChatRoomModel->getPeerAddress() : QString("");
|
||||
}
|
||||
|
||||
void ChatRoomProxyModel::setPeerAddress (const QString &peerAddress) {
|
||||
mPeerAddress = peerAddress;
|
||||
//reload();
|
||||
}
|
||||
|
||||
QString ChatRoomProxyModel::getLocalAddress () const {
|
||||
return mChatRoomModel ? mChatRoomModel->getLocalAddress() : QString("");
|
||||
}
|
||||
|
||||
void ChatRoomProxyModel::setLocalAddress (const QString &localAddress) {
|
||||
mLocalAddress = localAddress;
|
||||
//reload();
|
||||
}
|
||||
|
||||
QString ChatRoomProxyModel::getFullPeerAddress () const {
|
||||
return mChatRoomModel ? mChatRoomModel->getFullPeerAddress() : QString("");
|
||||
}
|
||||
|
||||
void ChatRoomProxyModel::setFullPeerAddress (const QString &peerAddress) {
|
||||
mFullPeerAddress = peerAddress;
|
||||
//reload();
|
||||
}
|
||||
|
||||
QString ChatRoomProxyModel::getFullLocalAddress () const {
|
||||
return mChatRoomModel ? mChatRoomModel->getFullLocalAddress() : QString("");
|
||||
}
|
||||
|
||||
void ChatRoomProxyModel::setFullLocalAddress (const QString &localAddress) {
|
||||
mFullLocalAddress = localAddress;
|
||||
//reload();
|
||||
}
|
||||
|
||||
int ChatRoomProxyModel::getIsSecure () const {
|
||||
return mChatRoomModel ? mChatRoomModel->getIsSecure() : -1;
|
||||
}
|
||||
|
||||
void ChatRoomProxyModel::setIsSecure (const int &secure) {
|
||||
mIsSecure = secure;
|
||||
}
|
||||
|
||||
bool ChatRoomProxyModel::getIsRemoteComposing () const {
|
||||
return mChatRoomModel ? mChatRoomModel->getIsRemoteComposing() : false;
|
||||
}
|
||||
|
||||
QString ChatRoomProxyModel::getCachedText() const{
|
||||
return gCachedText;
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
void ChatRoomProxyModel::reload () {
|
||||
mMaxDisplayedEntries = EntriesChunkSize;
|
||||
|
||||
if (mChatRoomModel) {
|
||||
ChatRoomModel *chatRoomModel = mChatRoomModel.get();
|
||||
QObject::disconnect(chatRoomModel, &ChatRoomModel::isRemoteComposingChanged, this, &ChatRoomProxyModel::handleIsRemoteComposingChanged);
|
||||
QObject::disconnect(chatRoomModel, &ChatRoomModel::messageReceived, this, &ChatRoomProxyModel::handleMessageReceived);
|
||||
QObject::disconnect(chatRoomModel, &ChatRoomModel::messageSent, this, &ChatRoomProxyModel::handleMessageSent);
|
||||
}
|
||||
|
||||
//mChatRoomModel = CoreManager::getInstance()->getChatRoomModel(mPeerAddress, mLocalAddress, mIsSecure);
|
||||
//if(mChatRoom)
|
||||
mChatRoomModel = CoreManager::getInstance()->getChatRoomModel(mChatRoom);
|
||||
|
||||
|
||||
if (mChatRoomModel) {
|
||||
|
||||
ChatRoomModel *chatRoomModel = mChatRoomModel.get();
|
||||
QObject::connect(chatRoomModel, &ChatRoomModel::isRemoteComposingChanged, this, &ChatRoomProxyModel::handleIsRemoteComposingChanged);
|
||||
QObject::connect(chatRoomModel, &ChatRoomModel::messageReceived, this, &ChatRoomProxyModel::handleMessageReceived);
|
||||
QObject::connect(chatRoomModel, &ChatRoomModel::messageSent, this, &ChatRoomProxyModel::handleMessageSent);
|
||||
}
|
||||
|
||||
static_cast<ChatRoomModelFilter *>(sourceModel())->setSourceModel(mChatRoomModel.get());
|
||||
}
|
||||
void ChatRoomProxyModel::resetMessageCount(){
|
||||
if( mChatRoomModel){
|
||||
mChatRoomModel->resetMessageCount();
|
||||
}
|
||||
}
|
||||
|
||||
std::shared_ptr<ChatRoomModel> ChatRoomProxyModel::getChatRoomModel () const{
|
||||
return mChatRoomModel;
|
||||
|
||||
}
|
||||
void ChatRoomProxyModel::setChatRoomModel (std::shared_ptr<ChatRoomModel> chatRoomModel){
|
||||
mChatRoom = chatRoomModel->getChatRoom();
|
||||
reload();
|
||||
emit chatRoomModelChanged();
|
||||
}
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
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 ChatRoomProxyModel::handleIsActiveChanged (QWindow *window) {
|
||||
if (mChatRoomModel && window->isActive() && getParentWindow(this) == window) {
|
||||
mChatRoomModel->resetMessageCount();
|
||||
mChatRoomModel->focused();
|
||||
}
|
||||
}
|
||||
|
||||
void ChatRoomProxyModel::handleIsRemoteComposingChanged (bool status) {
|
||||
emit isRemoteComposingChanged(status);
|
||||
}
|
||||
|
||||
void ChatRoomProxyModel::handleMessageReceived (const shared_ptr<linphone::ChatMessage> &) {
|
||||
mMaxDisplayedEntries++;
|
||||
|
||||
QWindow *window = getParentWindow(this);
|
||||
if (window && window->isActive())
|
||||
mChatRoomModel->resetMessageCount();
|
||||
}
|
||||
|
||||
void ChatRoomProxyModel::handleMessageSent (const shared_ptr<linphone::ChatMessage> &) {
|
||||
mMaxDisplayedEntries++;
|
||||
}
|
||||
|
|
@ -0,0 +1,64 @@
|
|||
/*
|
||||
* Copyright (c) 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 PARTICIPANT_PROXY_MODEL_H_
|
||||
#define PARTICIPANT_PROXY_MODEL_H_
|
||||
|
||||
#include <QSortFilterProxyModel>
|
||||
|
||||
#include "ParticipantModel.hpp"
|
||||
|
||||
// =============================================================================
|
||||
|
||||
class QWindow;
|
||||
|
||||
class ParticipantProxyModel : public QSortFilterProxyModel {
|
||||
|
||||
Q_OBJECT
|
||||
|
||||
|
||||
public:
|
||||
ParticipantProxyModel (QObject *parent = Q_NULLPTR);
|
||||
|
||||
void reset();
|
||||
void update();
|
||||
std::shared_ptr<TimelineModel> getTimeline(std::shared_ptr<linphone::ChatRoom> chatRoom, const bool &create);
|
||||
|
||||
int rowCount (const QModelIndex &index = QModelIndex()) const override;
|
||||
|
||||
QHash<int, QByteArray> roleNames () const override;
|
||||
QVariant data (const QModelIndex &index, int role = Qt::DisplayRole) const override;
|
||||
|
||||
// Remove a chatroom
|
||||
Q_INVOKABLE void remove (TimelineModel *importer);
|
||||
|
||||
private:
|
||||
bool removeRow (int row, const QModelIndex &parent = QModelIndex());
|
||||
bool removeRows (int row, int count, const QModelIndex &parent = QModelIndex()) override;
|
||||
|
||||
|
||||
|
||||
void initTimeline ();
|
||||
void updateTimelines();
|
||||
|
||||
QList<std::shared_ptr<ParticipantModel>> mParticipantlines;
|
||||
};
|
||||
|
||||
#endif // PARTICIPANT_PROXY_MODEL_H_
|
||||
|
|
@ -137,6 +137,7 @@ QVariantMap AccountSettingsModel::getProxyConfigDescription (const shared_ptr<li
|
|||
map["route"] = Utils::coreStringToAppString(proxyConfig->getRoutes().front());
|
||||
else
|
||||
map["route"] = "";
|
||||
map["conferenceUri"] = Utils::coreStringToAppString(proxyConfig->getConferenceFactoryUri());
|
||||
map["contactParams"] = Utils::coreStringToAppString(proxyConfig->getContactParameters());
|
||||
map["avpfInterval"] = proxyConfig->getAvpfRrInterval();
|
||||
map["registerEnabled"] = proxyConfig->registerEnabled();
|
||||
|
|
@ -245,6 +246,7 @@ bool AccountSettingsModel::addOrUpdateProxyConfig (
|
|||
|
||||
proxyConfig->setPublishExpires(data["registrationDuration"].toInt());
|
||||
proxyConfig->setRoute(Utils::appStringToCoreString(data["route"].toString()));
|
||||
proxyConfig->setConferenceFactoryUri(Utils::appStringToCoreString(data["conferenceUri"].toString()));
|
||||
proxyConfig->setContactParameters(Utils::appStringToCoreString(data["contactParams"].toString()));
|
||||
proxyConfig->setAvpfRrInterval(uint8_t(data["avpfInterval"].toInt()));
|
||||
proxyConfig->enableRegister(data["registerEnabled"].toBool());
|
||||
|
|
|
|||
|
|
@ -24,7 +24,7 @@
|
|||
#include <QtDebug>
|
||||
|
||||
#include "components/call/CallModel.hpp"
|
||||
#include "components/chat/ChatModel.hpp"
|
||||
#include "components/chat-room/ChatRoomModel.hpp"
|
||||
#include "components/contact/ContactModel.hpp"
|
||||
#include "components/contact/VcardModel.hpp"
|
||||
#include "components/contacts/ContactsListModel.hpp"
|
||||
|
|
|
|||
|
|
@ -24,7 +24,7 @@
|
|||
#include <QtDebug>
|
||||
|
||||
#include "components/call/CallModel.hpp"
|
||||
#include "components/chat/ChatModel.hpp"
|
||||
#include "components/chat-room/ChatRoomModel.hpp"
|
||||
#include "components/contact/ContactModel.hpp"
|
||||
#include "components/contact/VcardModel.hpp"
|
||||
#include "components/contacts/ContactsListModel.hpp"
|
||||
|
|
@ -59,7 +59,7 @@ SipAddressesModel::SipAddressesModel (QObject *parent) : QAbstractListModel(pare
|
|||
|
||||
mCoreHandlers = coreManager->getHandlers();
|
||||
|
||||
QObject::connect(coreManager, &CoreManager::chatModelCreated, this, &SipAddressesModel::handleChatModelCreated);
|
||||
QObject::connect(coreManager, &CoreManager::chatRoomModelCreated, this, &SipAddressesModel::handleChatRoomModelCreated);
|
||||
QObject::connect(coreManager, &CoreManager::historyModelCreated, this, &SipAddressesModel::handleHistoryModelCreated);
|
||||
|
||||
ContactsListModel *contacts = CoreManager::getInstance()->getContactsListModel();
|
||||
|
|
@ -264,20 +264,20 @@ bool SipAddressesModel::removeRows (int row, int count, const QModelIndex &paren
|
|||
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
void SipAddressesModel::handleChatModelCreated (const shared_ptr<ChatModel> &chatModel) {
|
||||
ChatModel *ptr = chatModel.get();
|
||||
void SipAddressesModel::handleChatRoomModelCreated (const shared_ptr<ChatRoomModel> &chatRoomModel) {
|
||||
ChatRoomModel *ptr = chatRoomModel.get();
|
||||
|
||||
QObject::connect(ptr, &ChatModel::allEntriesRemoved, this, [this, ptr] {
|
||||
QObject::connect(ptr, &ChatRoomModel::allEntriesRemoved, this, [this, ptr] {
|
||||
handleAllEntriesRemoved(ptr);
|
||||
});
|
||||
QObject::connect(ptr, &ChatModel::lastEntryRemoved, this, [this, ptr] {
|
||||
QObject::connect(ptr, &ChatRoomModel::lastEntryRemoved, this, [this, ptr] {
|
||||
handleLastEntryRemoved(ptr);
|
||||
});
|
||||
QObject::connect(ptr, &ChatModel::messageCountReset, this, [this, ptr] {
|
||||
QObject::connect(ptr, &ChatRoomModel::messageCountReset, this, [this, ptr] {
|
||||
handleMessageCountReset(ptr);
|
||||
});
|
||||
|
||||
QObject::connect(ptr, &ChatModel::messageSent, this, &SipAddressesModel::handleMessageSent);
|
||||
QObject::connect(ptr, &ChatRoomModel::messageSent, this, &SipAddressesModel::handleMessageSent);
|
||||
}
|
||||
|
||||
void SipAddressesModel::handleHistoryModelCreated (HistoryModel *historyModel) {
|
||||
|
|
@ -365,12 +365,12 @@ void SipAddressesModel::handlePresenceReceived (
|
|||
updateObservers(sipAddress, status);
|
||||
}
|
||||
|
||||
void SipAddressesModel::handleAllEntriesRemoved (ChatModel *chatModel) {
|
||||
auto it = mPeerAddressToSipAddressEntry.find(chatModel->getPeerAddress());
|
||||
void SipAddressesModel::handleAllEntriesRemoved (ChatRoomModel *chatRoomModel) {
|
||||
auto it = mPeerAddressToSipAddressEntry.find(chatRoomModel->getPeerAddress());
|
||||
if (it == mPeerAddressToSipAddressEntry.end())
|
||||
return;
|
||||
|
||||
auto it2 = it->localAddressToConferenceEntry.find(Utils::cleanSipAddress(chatModel->getLocalAddress()));
|
||||
auto it2 = it->localAddressToConferenceEntry.find(Utils::cleanSipAddress(chatRoomModel->getLocalAddress()));
|
||||
if (it2 == it->localAddressToConferenceEntry.end())
|
||||
return;
|
||||
it->localAddressToConferenceEntry.erase(it2);
|
||||
|
|
@ -387,22 +387,22 @@ void SipAddressesModel::handleAllEntriesRemoved (ChatModel *chatModel) {
|
|||
emit dataChanged(index(row, 0), index(row, 0));
|
||||
}
|
||||
|
||||
void SipAddressesModel::handleLastEntryRemoved (ChatModel *chatModel) {
|
||||
auto it = mPeerAddressToSipAddressEntry.find(chatModel->getPeerAddress());
|
||||
void SipAddressesModel::handleLastEntryRemoved (ChatRoomModel *chatRoomModel) {
|
||||
auto it = mPeerAddressToSipAddressEntry.find(chatRoomModel->getPeerAddress());
|
||||
if (it == mPeerAddressToSipAddressEntry.end())
|
||||
return;
|
||||
|
||||
auto it2 = it->localAddressToConferenceEntry.find(Utils::cleanSipAddress(chatModel->getLocalAddress()));
|
||||
auto it2 = it->localAddressToConferenceEntry.find(Utils::cleanSipAddress(chatRoomModel->getLocalAddress()));
|
||||
if (it2 == it->localAddressToConferenceEntry.end())
|
||||
return;
|
||||
|
||||
int row = mRefs.indexOf(&(*it));
|
||||
Q_ASSERT(row != -1);
|
||||
|
||||
Q_ASSERT(chatModel->rowCount() > 0);
|
||||
const QVariantMap map = chatModel->data(
|
||||
chatModel->index(chatModel->rowCount() - 1, 0),
|
||||
ChatModel::ChatEntry
|
||||
Q_ASSERT(chatRoomModel->rowCount() > 0);
|
||||
const QVariantMap map = chatRoomModel->data(
|
||||
chatRoomModel->index(chatRoomModel->rowCount() - 1, 0),
|
||||
ChatRoomModel::ChatEntry
|
||||
).toMap();
|
||||
|
||||
// Update the timestamp with the new last chat message timestamp.
|
||||
|
|
@ -419,13 +419,13 @@ void SipAddressesModel::handleAllCallCountReset () {
|
|||
emit dataChanged(index(row, 0), index(row, 0));
|
||||
}
|
||||
}
|
||||
void SipAddressesModel::handleMessageCountReset (ChatModel *chatModel) {
|
||||
const QString &peerAddress = Utils::cleanSipAddress(chatModel->getPeerAddress());
|
||||
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(chatModel->getLocalAddress());
|
||||
const QString &localAddress = Utils::cleanSipAddress(chatRoomModel->getLocalAddress());
|
||||
auto it2 = it->localAddressToConferenceEntry.find(localAddress);
|
||||
if (it2 == it->localAddressToConferenceEntry.end())
|
||||
return;
|
||||
|
|
|
|||
|
|
@ -30,7 +30,7 @@
|
|||
|
||||
class QUrl;
|
||||
|
||||
class ChatModel;
|
||||
class ChatRoomModel;
|
||||
class CoreHandlers;
|
||||
class HistoryModel;
|
||||
|
||||
|
|
@ -94,7 +94,7 @@ private:
|
|||
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
void handleChatModelCreated (const std::shared_ptr<ChatModel> &chatModel);
|
||||
void handleChatRoomModelCreated (const std::shared_ptr<ChatRoomModel> &chatRoomModel);
|
||||
void handleHistoryModelCreated (HistoryModel *historyModel) ;
|
||||
|
||||
void handleContactAdded (ContactModel *contact);
|
||||
|
|
@ -107,10 +107,10 @@ private:
|
|||
void handleCallStateChanged (const std::shared_ptr<linphone::Call> &call, linphone::Call::State state);
|
||||
void handlePresenceReceived (const QString &sipAddress, const std::shared_ptr<const linphone::PresenceModel> &presenceModel);
|
||||
|
||||
void handleAllEntriesRemoved (ChatModel *chatModel);
|
||||
void handleLastEntryRemoved (ChatModel *chatModel);
|
||||
void handleAllEntriesRemoved (ChatRoomModel *chatRoomModel);
|
||||
void handleLastEntryRemoved (ChatRoomModel *chatRoomModel);
|
||||
|
||||
void handleMessageCountReset (ChatModel *chatModel);
|
||||
void handleMessageCountReset (ChatRoomModel *chatRoomModel);
|
||||
|
||||
void handleMessageSent (const std::shared_ptr<linphone::ChatMessage> &message);
|
||||
|
||||
|
|
|
|||
|
|
@ -32,21 +32,29 @@
|
|||
// =============================================================================
|
||||
|
||||
TimelineListModel::TimelineListModel (QObject *parent) : QAbstractListModel(parent) {
|
||||
initTimeline();
|
||||
//initTimeline();
|
||||
mSelectedCount = 0;
|
||||
updateTimelines ();
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
TimelineModel * TimelineListModel::getAt(const int& index){
|
||||
return mTimelines[index];
|
||||
return mTimelines[index].get();
|
||||
}
|
||||
|
||||
void TimelineListModel::reset(){
|
||||
initTimeline();
|
||||
//initTimeline();
|
||||
updateTimelines ();
|
||||
}
|
||||
|
||||
void TimelineListModel::update(){
|
||||
|
||||
updateTimelines ();
|
||||
}
|
||||
|
||||
void TimelineListModel::selectAll(const bool& selected){
|
||||
for(auto it = mTimelines.begin() ; it != mTimelines.end() ; ++it)
|
||||
(*it)->mSelected = selected;
|
||||
}
|
||||
int TimelineListModel::rowCount (const QModelIndex &) const {
|
||||
return mTimelines.count();
|
||||
|
|
@ -65,7 +73,7 @@ QVariant TimelineListModel::data (const QModelIndex &index, int role) const {
|
|||
return QVariant();
|
||||
|
||||
if (role == Qt::DisplayRole)
|
||||
return QVariant::fromValue(mTimelines[row]);
|
||||
return QVariant::fromValue(mTimelines[row].get());
|
||||
|
||||
return QVariant();
|
||||
}
|
||||
|
|
@ -88,8 +96,10 @@ bool TimelineListModel::removeRows (int row, int count, const QModelIndex &paren
|
|||
|
||||
beginRemoveRows(parent, row, limit);
|
||||
|
||||
for (int i = 0; i < count; ++i)
|
||||
delete mTimelines.takeAt(row);
|
||||
for (int i = 0; i < count; ++i){
|
||||
auto timeline = mTimelines.takeAt(row);
|
||||
timeline->getChatRoomModel()->getChatRoom()->removeListener(timeline);
|
||||
}
|
||||
|
||||
endRemoveRows();
|
||||
|
||||
|
|
@ -100,11 +110,12 @@ bool TimelineListModel::removeRows (int row, int count, const QModelIndex &paren
|
|||
// -----------------------------------------------------------------------------
|
||||
|
||||
void TimelineListModel::initTimeline () {
|
||||
/*
|
||||
CoreManager *coreManager = CoreManager::getInstance();
|
||||
auto currentAddress = coreManager->getAccountSettingsModel()->getUsedSipAddress();
|
||||
|
||||
std::list<std::shared_ptr<linphone::ChatRoom>> allChatRooms = coreManager->getCore()->getChatRooms();
|
||||
QList<TimelineModel*> models;
|
||||
QList<std::shared_ptr<TimelineModel>> models;
|
||||
for(auto itAllChatRooms = allChatRooms.begin() ; itAllChatRooms != allChatRooms.end() ; ++itAllChatRooms){
|
||||
if((*itAllChatRooms)->getMe()->getAddress()->weakEqual(currentAddress)){
|
||||
models << new TimelineModel(*itAllChatRooms);
|
||||
|
|
@ -115,7 +126,7 @@ void TimelineListModel::initTimeline () {
|
|||
mTimelines = models;
|
||||
|
||||
//endInsertRows();
|
||||
|
||||
*/
|
||||
/*
|
||||
initSipAddressesFromChat();
|
||||
initSipAddressesFromCalls();
|
||||
|
|
@ -135,25 +146,50 @@ void TimelineListModel::initTimeline () {
|
|||
*/
|
||||
}
|
||||
|
||||
TimelineModel * TimelineListModel::getTimeline(std::shared_ptr<linphone::ChatRoom> chatRoom, const bool &create){
|
||||
std::shared_ptr<TimelineModel> TimelineListModel::getTimeline(std::shared_ptr<linphone::ChatRoom> chatRoom, const bool &create){
|
||||
if(chatRoom){
|
||||
for(auto it = mTimelines.begin() ; it != mTimelines.end() ; ++it){
|
||||
if( (*it)->getChatModel()->getChatRoom() == chatRoom){
|
||||
if( (*it)->getChatRoomModel()->getChatRoom() == chatRoom){
|
||||
return *it;
|
||||
}
|
||||
}
|
||||
if(create)
|
||||
return new TimelineModel(chatRoom);
|
||||
if(create){
|
||||
std::shared_ptr<TimelineModel> model = std::make_shared<TimelineModel>(chatRoom);
|
||||
chatRoom->addListener(model);
|
||||
connect(model.get(), SIGNAL(selectedChanged(bool)), this, SLOT(selectedHasChanged(bool)));
|
||||
return model;
|
||||
}
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
void TimelineListModel::setSelectedCount(int selectedCount){
|
||||
if(mSelectedCount != selectedCount) {
|
||||
mSelectedCount = selectedCount;
|
||||
if( mSelectedCount <= 1)// Do not send signals when selection is higher than max : this is a transition state
|
||||
emit selectedCountChanged(mSelectedCount);
|
||||
}
|
||||
}
|
||||
|
||||
void TimelineListModel::selectedHasChanged(bool selected){
|
||||
if(selected) {
|
||||
if(mSelectedCount >= 1){// We have more selection than wanted : count select first and unselect after : the final signal will be send only on limit
|
||||
setSelectedCount(mSelectedCount+1);// It will not send a change signal
|
||||
for(auto it = mTimelines.begin() ; it != mTimelines.end() ; ++it)
|
||||
if(it->get() != sender())
|
||||
(*it)->setSelected(false);
|
||||
}else
|
||||
setSelectedCount(mSelectedCount+1);
|
||||
} else
|
||||
setSelectedCount(mSelectedCount-1);
|
||||
}
|
||||
|
||||
void TimelineListModel::updateTimelines () {
|
||||
CoreManager *coreManager = CoreManager::getInstance();
|
||||
auto currentAddress = coreManager->getAccountSettingsModel()->getUsedSipAddress();
|
||||
|
||||
std::list<std::shared_ptr<linphone::ChatRoom>> allChatRooms = coreManager->getCore()->getChatRooms();
|
||||
QList<TimelineModel*> models;
|
||||
QList<std::shared_ptr<TimelineModel> > models;
|
||||
for(auto itAllChatRooms = allChatRooms.begin() ; itAllChatRooms != allChatRooms.end() ; ++itAllChatRooms){
|
||||
if((*itAllChatRooms)->getMe()->getAddress()->weakEqual(currentAddress)){
|
||||
models << getTimeline(*itAllChatRooms, true);
|
||||
|
|
|
|||
|
|
@ -22,7 +22,7 @@
|
|||
#define TIMELINE_LIST_MODEL_H_
|
||||
|
||||
#include <QSortFilterProxyModel>
|
||||
#include "components/chat/ChatModel.hpp"
|
||||
#include "components/chat-room/ChatRoomModel.hpp"
|
||||
|
||||
class TimelineModel;
|
||||
// =============================================================================
|
||||
|
|
@ -30,13 +30,16 @@ class TimelineModel;
|
|||
class TimelineListModel : public QAbstractListModel {
|
||||
Q_OBJECT
|
||||
public:
|
||||
|
||||
Q_PROPERTY(int selectedCount MEMBER mSelectedCount WRITE setSelectedCount NOTIFY selectedCountChanged)
|
||||
|
||||
TimelineListModel (QObject *parent = Q_NULLPTR);
|
||||
|
||||
void reset();
|
||||
void update();
|
||||
void selectAll(const bool& selected);
|
||||
TimelineModel * getAt(const int& index);
|
||||
TimelineModel * getTimeline(std::shared_ptr<linphone::ChatRoom> chatRoom, const bool &create);
|
||||
std::shared_ptr<TimelineModel> getTimeline(std::shared_ptr<linphone::ChatRoom> chatRoom, const bool &create);
|
||||
|
||||
int rowCount (const QModelIndex &index = QModelIndex()) const override;
|
||||
|
||||
|
|
@ -45,6 +48,14 @@ public:
|
|||
|
||||
// Remove a chatroom
|
||||
Q_INVOKABLE void remove (TimelineModel *importer);
|
||||
int mSelectedCount;
|
||||
|
||||
void setSelectedCount(int selectedCount);
|
||||
public slots:
|
||||
void selectedHasChanged(bool selected);
|
||||
|
||||
signals:
|
||||
void selectedCountChanged(int selectedCount);
|
||||
|
||||
private:
|
||||
bool removeRow (int row, const QModelIndex &parent = QModelIndex());
|
||||
|
|
@ -55,7 +66,7 @@ private:
|
|||
void initTimeline ();
|
||||
void updateTimelines();
|
||||
|
||||
QList<TimelineModel*> mTimelines;
|
||||
QList<std::shared_ptr<TimelineModel>> mTimelines;
|
||||
};
|
||||
|
||||
#endif // TIMELINE_LIST_MODEL_H_
|
||||
|
|
|
|||
|
|
@ -21,7 +21,7 @@
|
|||
#include "components/core/CoreManager.hpp"
|
||||
#include "components/settings/AccountSettingsModel.hpp"
|
||||
#include "components/sip-addresses/SipAddressesModel.hpp"
|
||||
#include "components/chat/ChatModel.hpp"
|
||||
#include "components/chat-room/ChatRoomModel.hpp"
|
||||
#include "utils/Utils.hpp"
|
||||
|
||||
#include "TimelineModel.hpp"
|
||||
|
|
@ -32,29 +32,37 @@
|
|||
// =============================================================================
|
||||
|
||||
TimelineModel::TimelineModel (std::shared_ptr<linphone::ChatRoom> chatRoom, QObject *parent) : QObject(parent) {
|
||||
mChatModel = CoreManager::getInstance()->getChatModel(chatRoom);
|
||||
mChatRoomModel = CoreManager::getInstance()->getChatRoomModel(chatRoom);
|
||||
|
||||
QObject::connect(mChatRoomModel.get(), &ChatRoomModel::unreadMessagesCountChanged, this, &TimelineModel::updateUnreadCount);
|
||||
QObject::connect(mChatRoomModel.get(), &ChatRoomModel::missedCallsCountChanged, this, &TimelineModel::updateUnreadCount);
|
||||
//mTimestamp = QDateTime::fromMSecsSinceEpoch(mChatRoomModel->getChatRoom()->getLastUpdateTime());
|
||||
mSelected = false;
|
||||
}
|
||||
|
||||
TimelineModel::~TimelineModel(){
|
||||
}
|
||||
|
||||
QString TimelineModel::getFullPeerAddress() const{
|
||||
return mChatModel->getFullPeerAddress();
|
||||
return mChatRoomModel->getFullPeerAddress();
|
||||
}
|
||||
QString TimelineModel::getFullLocalAddress() const{
|
||||
return mChatModel->getLocalAddress();
|
||||
return mChatRoomModel->getLocalAddress();
|
||||
}
|
||||
|
||||
|
||||
QString TimelineModel::getUsername() const{
|
||||
std::string username = mChatModel->getChatRoom()->getSubject();
|
||||
std::string username = mChatRoomModel->getChatRoom()->getSubject();
|
||||
if(username != ""){
|
||||
return QString::fromStdString(username);
|
||||
}
|
||||
username = mChatModel->getChatRoom()->getPeerAddress()->getDisplayName();
|
||||
username = mChatRoomModel->getChatRoom()->getPeerAddress()->getDisplayName();
|
||||
if(username != "")
|
||||
return QString::fromStdString(username);
|
||||
username = mChatModel->getChatRoom()->getPeerAddress()->getUsername();
|
||||
username = mChatRoomModel->getChatRoom()->getPeerAddress()->getUsername();
|
||||
if(username != "")
|
||||
return QString::fromStdString(username);
|
||||
return QString::fromStdString(mChatModel->getChatRoom()->getPeerAddress()->asStringUriOnly());
|
||||
return QString::fromStdString(mChatRoomModel->getChatRoom()->getPeerAddress()->asStringUriOnly());
|
||||
}
|
||||
|
||||
QString TimelineModel::getAvatar() const{
|
||||
|
|
@ -65,6 +73,52 @@ int TimelineModel::getPresenceStatus() const{
|
|||
return 0;
|
||||
}
|
||||
|
||||
std::shared_ptr<ChatModel> TimelineModel::getChatModel() const{
|
||||
return mChatModel;
|
||||
ChatRoomModel *TimelineModel::getChatRoomModel() const{
|
||||
return mChatRoomModel.get();
|
||||
}
|
||||
|
||||
void TimelineModel::setSelected(const bool& selected){
|
||||
if(selected != mSelected){
|
||||
mSelected = selected;
|
||||
emit selectedChanged(mSelected);
|
||||
}
|
||||
}
|
||||
|
||||
void TimelineModel::updateUnreadCount(){
|
||||
if(mSelected){
|
||||
mChatRoomModel->resetMessageCount();
|
||||
}
|
||||
}
|
||||
//----------------------------------------------------------
|
||||
//------ CHAT ROOM HANDLERS
|
||||
//----------------------------------------------------------
|
||||
|
||||
void TimelineModel::onIsComposingReceived(const std::shared_ptr<linphone::ChatRoom> & chatRoom, const std::shared_ptr<const linphone::Address> & remoteAddress, bool isComposing){
|
||||
}
|
||||
void TimelineModel::onMessageReceived(const std::shared_ptr<linphone::ChatRoom> & chatRoom, const std::shared_ptr<linphone::ChatMessage> & message){}
|
||||
void TimelineModel::onNewEvent(const std::shared_ptr<linphone::ChatRoom> & chatRoom, const std::shared_ptr<const linphone::EventLog> & eventLog){}
|
||||
void TimelineModel::onChatMessageReceived(const std::shared_ptr<linphone::ChatRoom> & chatRoom, const std::shared_ptr<const linphone::EventLog> & eventLog){}
|
||||
void TimelineModel::onChatMessageSending(const std::shared_ptr<linphone::ChatRoom> & chatRoom, const std::shared_ptr<const linphone::EventLog> & eventLog){}
|
||||
void TimelineModel::onChatMessageSent(const std::shared_ptr<linphone::ChatRoom> & chatRoom, const std::shared_ptr<const linphone::EventLog> & eventLog){}
|
||||
void TimelineModel::onParticipantAdded(const std::shared_ptr<linphone::ChatRoom> & chatRoom, const std::shared_ptr<const linphone::EventLog> & eventLog){}
|
||||
void TimelineModel::onParticipantRemoved(const std::shared_ptr<linphone::ChatRoom> & chatRoom, const std::shared_ptr<const linphone::EventLog> & eventLog){}
|
||||
void TimelineModel::onParticipantAdminStatusChanged(const std::shared_ptr<linphone::ChatRoom> & chatRoom, const std::shared_ptr<const linphone::EventLog> & eventLog){}
|
||||
void TimelineModel::onStateChanged(const std::shared_ptr<linphone::ChatRoom> & chatRoom, linphone::ChatRoom::State newState){}
|
||||
void TimelineModel::onSecurityEvent(const std::shared_ptr<linphone::ChatRoom> & chatRoom, const std::shared_ptr<const linphone::EventLog> & eventLog){}
|
||||
void TimelineModel::onSubjectChanged(const std::shared_ptr<linphone::ChatRoom> & chatRoom, const std::shared_ptr<const linphone::EventLog> & eventLog)
|
||||
{
|
||||
emit usernameChanged();
|
||||
}
|
||||
void TimelineModel::onUndecryptableMessageReceived(const std::shared_ptr<linphone::ChatRoom> & chatRoom, const std::shared_ptr<linphone::ChatMessage> & message){}
|
||||
void TimelineModel::onParticipantDeviceAdded(const std::shared_ptr<linphone::ChatRoom> & chatRoom, const std::shared_ptr<const linphone::EventLog> & eventLog){}
|
||||
void TimelineModel::onParticipantDeviceRemoved(const std::shared_ptr<linphone::ChatRoom> & chatRoom, const std::shared_ptr<const linphone::EventLog> & eventLog){}
|
||||
void TimelineModel::onConferenceJoined(const std::shared_ptr<linphone::ChatRoom> & chatRoom, const std::shared_ptr<const linphone::EventLog> & eventLog){}
|
||||
void TimelineModel::onConferenceLeft(const std::shared_ptr<linphone::ChatRoom> & chatRoom, const std::shared_ptr<const linphone::EventLog> & eventLog){}
|
||||
void TimelineModel::onEphemeralEvent(const std::shared_ptr<linphone::ChatRoom> & chatRoom, const std::shared_ptr<const linphone::EventLog> & eventLog){}
|
||||
void TimelineModel::onEphemeralMessageTimerStarted(const std::shared_ptr<linphone::ChatRoom> & chatRoom, const std::shared_ptr<const linphone::EventLog> & eventLog){}
|
||||
void TimelineModel::onEphemeralMessageDeleted(const std::shared_ptr<linphone::ChatRoom> & chatRoom, const std::shared_ptr<const linphone::EventLog> & eventLog){}
|
||||
void TimelineModel::onConferenceAddressGeneration(const std::shared_ptr<linphone::ChatRoom> & chatRoom){}
|
||||
void TimelineModel::onParticipantRegistrationSubscriptionRequested(const std::shared_ptr<linphone::ChatRoom> & chatRoom, const std::shared_ptr<const linphone::Address> & participantAddress){}
|
||||
void TimelineModel::onParticipantRegistrationUnsubscriptionRequested(const std::shared_ptr<linphone::ChatRoom> & chatRoom, const std::shared_ptr<const linphone::Address> & participantAddress){}
|
||||
void TimelineModel::onChatMessageShouldBeStored(const std::shared_ptr<linphone::ChatRoom> & chatRoom, const std::shared_ptr<linphone::ChatMessage> & message){}
|
||||
void TimelineModel::onChatMessageParticipantImdnStateChanged(const std::shared_ptr<linphone::ChatRoom> & chatRoom, const std::shared_ptr<linphone::ChatMessage> & message, const std::shared_ptr<const linphone::ParticipantImdnState> & state){}
|
||||
|
|
|
|||
|
|
@ -30,23 +30,25 @@
|
|||
|
||||
#include "../contact/ContactModel.hpp"
|
||||
|
||||
class ChatModel;
|
||||
class ChatRoomModel;
|
||||
|
||||
class TimelineModel : public QObject {
|
||||
class TimelineModel : public QObject, public linphone::ChatRoomListener {
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
TimelineModel (std::shared_ptr<linphone::ChatRoom> chatRoom, QObject *parent = Q_NULLPTR);
|
||||
virtual ~TimelineModel();
|
||||
|
||||
Q_PROPERTY(QString fullPeerAddress READ getFullPeerAddress NOTIFY fullPeerAddressChanged)
|
||||
Q_PROPERTY(QString fullLocalAddress READ getFullLocalAddress NOTIFY fullLocalAddressChanged)
|
||||
Q_PROPERTY(std::shared_ptr<ChatModel> chatModel READ getChatModel CONSTANT)
|
||||
Q_PROPERTY(ChatRoomModel* chatRoomModel READ getChatRoomModel CONSTANT)
|
||||
|
||||
// Contact
|
||||
Q_PROPERTY(QString sipAddress READ getFullPeerAddress NOTIFY fullPeerAddressChanged)
|
||||
Q_PROPERTY(QString username READ getUsername NOTIFY usernameChanged)
|
||||
Q_PROPERTY(QString avatar READ getAvatar NOTIFY avatarChanged)
|
||||
Q_PROPERTY(int presenceStatus READ getPresenceStatus NOTIFY presenceStatusChanged)
|
||||
//Q_PROPERTY(QString sipAddress READ getFullPeerAddress NOTIFY fullPeerAddressChanged)
|
||||
//Q_PROPERTY(QString username READ getUsername NOTIFY usernameChanged)
|
||||
//Q_PROPERTY(QString avatar READ getAvatar NOTIFY avatarChanged)
|
||||
//Q_PROPERTY(int presenceStatus READ getPresenceStatus NOTIFY presenceStatusChanged)
|
||||
Q_PROPERTY(bool selected MEMBER mSelected WRITE setSelected NOTIFY selectedChanged)
|
||||
|
||||
|
||||
QString getFullPeerAddress() const;
|
||||
|
|
@ -56,19 +58,53 @@ public:
|
|||
QString getAvatar() const;
|
||||
int getPresenceStatus() const;
|
||||
|
||||
void setSelected(const bool& selected);
|
||||
|
||||
Q_INVOKABLE std::shared_ptr<ChatModel> getChatModel() const;
|
||||
|
||||
//Q_INVOKABLE std::shared_ptr<ChatRoomModel> getChatRoomModel() const;
|
||||
Q_INVOKABLE ChatRoomModel* getChatRoomModel() const;
|
||||
|
||||
QDateTime mTimestamp;
|
||||
std::shared_ptr<ChatModel> mChatModel;
|
||||
bool mSelected;
|
||||
//QDateTime mTimestamp;
|
||||
std::shared_ptr<ChatRoomModel> mChatRoomModel;
|
||||
//std::shared_ptr<linphone::ChatRoom> mChatRoom;
|
||||
|
||||
|
||||
virtual void onIsComposingReceived(const std::shared_ptr<linphone::ChatRoom> & chatRoom, const std::shared_ptr<const linphone::Address> & remoteAddress, bool isComposing) override;
|
||||
virtual void onMessageReceived(const std::shared_ptr<linphone::ChatRoom> & chatRoom, const std::shared_ptr<linphone::ChatMessage> & message) override;
|
||||
virtual void onNewEvent(const std::shared_ptr<linphone::ChatRoom> & chatRoom, const std::shared_ptr<const linphone::EventLog> & eventLog) override;
|
||||
virtual void onChatMessageReceived(const std::shared_ptr<linphone::ChatRoom> & chatRoom, const std::shared_ptr<const linphone::EventLog> & eventLog) override;
|
||||
virtual void onChatMessageSending(const std::shared_ptr<linphone::ChatRoom> & chatRoom, const std::shared_ptr<const linphone::EventLog> & eventLog) override;
|
||||
virtual void onChatMessageSent(const std::shared_ptr<linphone::ChatRoom> & chatRoom, const std::shared_ptr<const linphone::EventLog> & eventLog) override;
|
||||
virtual void onParticipantAdded(const std::shared_ptr<linphone::ChatRoom> & chatRoom, const std::shared_ptr<const linphone::EventLog> & eventLog) override;
|
||||
virtual void onParticipantRemoved(const std::shared_ptr<linphone::ChatRoom> & chatRoom, const std::shared_ptr<const linphone::EventLog> & eventLog) override;
|
||||
virtual void onParticipantAdminStatusChanged(const std::shared_ptr<linphone::ChatRoom> & chatRoom, const std::shared_ptr<const linphone::EventLog> & eventLog) override;
|
||||
virtual void onStateChanged(const std::shared_ptr<linphone::ChatRoom> & chatRoom, linphone::ChatRoom::State newState) override;
|
||||
virtual void onSecurityEvent(const std::shared_ptr<linphone::ChatRoom> & chatRoom, const std::shared_ptr<const linphone::EventLog> & eventLog) override;
|
||||
virtual void onSubjectChanged(const std::shared_ptr<linphone::ChatRoom> & chatRoom, const std::shared_ptr<const linphone::EventLog> & eventLog) override;
|
||||
virtual void onUndecryptableMessageReceived(const std::shared_ptr<linphone::ChatRoom> & chatRoom, const std::shared_ptr<linphone::ChatMessage> & message) override;
|
||||
virtual void onParticipantDeviceAdded(const std::shared_ptr<linphone::ChatRoom> & chatRoom, const std::shared_ptr<const linphone::EventLog> & eventLog) override;
|
||||
virtual void onParticipantDeviceRemoved(const std::shared_ptr<linphone::ChatRoom> & chatRoom, const std::shared_ptr<const linphone::EventLog> & eventLog) override;
|
||||
virtual void onConferenceJoined(const std::shared_ptr<linphone::ChatRoom> & chatRoom, const std::shared_ptr<const linphone::EventLog> & eventLog) override;
|
||||
virtual void onConferenceLeft(const std::shared_ptr<linphone::ChatRoom> & chatRoom, const std::shared_ptr<const linphone::EventLog> & eventLog) override;
|
||||
virtual void onEphemeralEvent(const std::shared_ptr<linphone::ChatRoom> & chatRoom, const std::shared_ptr<const linphone::EventLog> & eventLog) override;
|
||||
virtual void onEphemeralMessageTimerStarted(const std::shared_ptr<linphone::ChatRoom> & chatRoom, const std::shared_ptr<const linphone::EventLog> & eventLog) override;
|
||||
virtual void onEphemeralMessageDeleted(const std::shared_ptr<linphone::ChatRoom> & chatRoom, const std::shared_ptr<const linphone::EventLog> & eventLog) override;
|
||||
virtual void onConferenceAddressGeneration(const std::shared_ptr<linphone::ChatRoom> & chatRoom) override;
|
||||
virtual void onParticipantRegistrationSubscriptionRequested(const std::shared_ptr<linphone::ChatRoom> & chatRoom, const std::shared_ptr<const linphone::Address> & participantAddress) override;
|
||||
virtual void onParticipantRegistrationUnsubscriptionRequested(const std::shared_ptr<linphone::ChatRoom> & chatRoom, const std::shared_ptr<const linphone::Address> & participantAddress) override;
|
||||
virtual void onChatMessageShouldBeStored(const std::shared_ptr<linphone::ChatRoom> & chatRoom, const std::shared_ptr<linphone::ChatMessage> & message) override;
|
||||
virtual void onChatMessageParticipantImdnStateChanged(const std::shared_ptr<linphone::ChatRoom> & chatRoom, const std::shared_ptr<linphone::ChatMessage> & message, const std::shared_ptr<const linphone::ParticipantImdnState> & state) override;
|
||||
|
||||
public slots:
|
||||
void updateUnreadCount();
|
||||
|
||||
signals:
|
||||
void fullPeerAddressChanged();
|
||||
void fullLocalAddressChanged();
|
||||
void usernameChanged();
|
||||
void avatarChanged();
|
||||
void presenceStatusChanged();
|
||||
void selectedChanged(bool selected);
|
||||
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -37,39 +37,50 @@
|
|||
TimelineProxyModel::TimelineProxyModel (QObject *parent) : QSortFilterProxyModel(parent) {
|
||||
CoreManager *coreManager = CoreManager::getInstance();
|
||||
AccountSettingsModel *accountSettingsModel = coreManager->getAccountSettingsModel();
|
||||
setSourceModel(CoreManager::getInstance()->getTimelineListModel());
|
||||
TimelineListModel * model = CoreManager::getInstance()->getTimelineListModel();
|
||||
|
||||
connect(model, SIGNAL(selectedCountChanged(int)), this, SIGNAL(selectedCountChanged(int)));
|
||||
|
||||
setSourceModel(model);
|
||||
|
||||
QObject::connect(accountSettingsModel, &AccountSettingsModel::accountSettingsUpdated, this, [this]() {
|
||||
dynamic_cast<TimelineListModel*>(sourceModel())->update();
|
||||
invalidate();
|
||||
updateCurrentSelection();
|
||||
//updateCurrentSelection();
|
||||
});
|
||||
QObject::connect(coreManager->getSipAddressesModel(), &SipAddressesModel::sipAddressReset, this, [this]() {
|
||||
dynamic_cast<TimelineListModel*>(sourceModel())->reset();
|
||||
invalidate();// Invalidate and reload GUI if the model has been reset
|
||||
updateCurrentSelection();
|
||||
//updateCurrentSelection();
|
||||
});
|
||||
sort(0);
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
void TimelineProxyModel::setCurrentChatModel(std::shared_ptr<ChatModel> data){
|
||||
mCurrentChatModel = data;
|
||||
emit currentChatModelChanged(mCurrentChatModel);
|
||||
emit currentTimelineChanged(dynamic_cast<TimelineListModel*>(sourceModel())->getTimeline(mCurrentChatModel->getChatRoom(), false));
|
||||
/*
|
||||
void TimelineProxyModel::setCurrentChatRoomModel(ChatRoomModel *data){
|
||||
mCurrentChatRoomModel = CoreManager::getInstance()->getChatRoomModel(data);
|
||||
emit currentChatRoomModelChanged(mCurrentChatRoomModel);
|
||||
if(mCurrentChatRoomModel)
|
||||
emit currentTimelineChanged(dynamic_cast<TimelineListModel*>(sourceModel())->getTimeline(mCurrentChatRoomModel->getChatRoom(), false).get());
|
||||
else
|
||||
emit currentTimelineChanged(nullptr);
|
||||
}
|
||||
|
||||
std::shared_ptr<ChatModel> TimelineProxyModel::getCurrentChatModel()const{
|
||||
return mCurrentChatModel;
|
||||
ChatRoomModel *TimelineProxyModel::getCurrentChatRoomModel()const{
|
||||
return mCurrentChatRoomModel.get();
|
||||
}
|
||||
|
||||
void TimelineProxyModel::updateCurrentSelection(){
|
||||
auto currentAddress = CoreManager::getInstance()->getAccountSettingsModel()->getUsedSipAddress();
|
||||
if(mCurrentChatModel && !mCurrentChatModel->getChatRoom()->getMe()->getAddress()->weakEqual(currentAddress) ){
|
||||
setCurrentChatModel(nullptr);
|
||||
if(mCurrentChatRoomModel && !mCurrentChatRoomModel->getChatRoom()->getMe()->getAddress()->weakEqual(currentAddress) ){
|
||||
setCurrentChatRoomModel(nullptr);
|
||||
}
|
||||
}
|
||||
|
||||
*/
|
||||
void TimelineProxyModel::unselectAll(){
|
||||
dynamic_cast<TimelineListModel*>(sourceModel())->selectAll(false);
|
||||
}
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
bool TimelineProxyModel::filterAcceptsRow (int sourceRow, const QModelIndex &sourceParent) const {
|
||||
|
|
@ -81,5 +92,5 @@ bool TimelineProxyModel::lessThan (const QModelIndex &left, const QModelIndex &r
|
|||
const TimelineModel* a = sourceModel()->data(left).value<TimelineModel*>();
|
||||
const TimelineModel* b = sourceModel()->data(right).value<TimelineModel*>();
|
||||
|
||||
return a->mTimestamp <= b->mTimestamp;
|
||||
return a->getChatRoomModel()->mLastUpdateTime >= b->getChatRoomModel()->mLastUpdateTime ;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -24,7 +24,7 @@
|
|||
#include <QSortFilterProxyModel>
|
||||
// =============================================================================
|
||||
|
||||
#include "../chat/ChatModel.hpp"
|
||||
#include "../chat-room/ChatRoomModel.hpp"
|
||||
|
||||
class TimelineModel;
|
||||
|
||||
|
|
@ -35,17 +35,19 @@ class TimelineProxyModel : public QSortFilterProxyModel {
|
|||
public:
|
||||
TimelineProxyModel (QObject *parent = Q_NULLPTR);
|
||||
|
||||
Q_PROPERTY(std::shared_ptr<ChatModel> currentChatModel WRITE setCurrentChatModel READ getCurrentChatModel NOTIFY currentChatModelChanged)
|
||||
//Q_PROPERTY(ChatRoomModel *currentChatRoomModel WRITE setCurrentChatRoomModel READ getCurrentChatRoomModel NOTIFY currentChatRoomModelChanged)
|
||||
|
||||
void updateCurrentSelection();
|
||||
//void updateCurrentSelection();
|
||||
|
||||
Q_INVOKABLE void setCurrentChatModel(std::shared_ptr<ChatModel> data);
|
||||
std::shared_ptr<ChatModel> getCurrentChatModel() const;
|
||||
//Q_INVOKABLE void setCurrentChatRoomModel(ChatRoomModel *data);
|
||||
//ChatRoomModel *getCurrentChatRoomModel() const;
|
||||
Q_INVOKABLE void unselectAll();
|
||||
//Q_INVOKABLE TimelineModel * getTimeline();
|
||||
|
||||
signals:
|
||||
void currentChatModelChanged(std::shared_ptr<ChatModel> currentChatModel);
|
||||
void currentTimelineChanged(TimelineModel * currentTimeline);
|
||||
|
||||
void selectedCountChanged(int selectedCount);
|
||||
// void currentChatRoomModelChanged(std::shared_ptr<ChatRoomModel> currentChatRoomModel);
|
||||
// void currentTimelineChanged(TimelineModel * currentTimeline);
|
||||
|
||||
protected:
|
||||
|
||||
|
|
@ -57,7 +59,7 @@ protected:
|
|||
void handleLocalAddressChanged (const QString &localAddress);
|
||||
|
||||
|
||||
std::shared_ptr<ChatModel> mCurrentChatModel;
|
||||
//std::shared_ptr<ChatRoomModel> mCurrentChatRoomModel;
|
||||
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -47,7 +47,7 @@ function getComponentFromEntry (chatEntry) {
|
|||
return 'FileMessage.qml'
|
||||
}
|
||||
|
||||
if (chatEntry.type === Linphone.ChatModel.CallEntry) {
|
||||
if (chatEntry.type === Linphone.ChatRoomModel.CallEntry) {
|
||||
return 'Event.qml'
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -11,28 +11,28 @@ Row {
|
|||
property string _type: {
|
||||
var status = $chatEntry.status
|
||||
|
||||
if (status === ChatModel.CallStatusSuccess) {
|
||||
if (status === ChatRoomModel.CallStatusSuccess) {
|
||||
if (!$chatEntry.isStart) {
|
||||
return 'ended_call'
|
||||
}
|
||||
return $chatEntry.isOutgoing ? 'outgoing_call' : 'incoming_call'
|
||||
}
|
||||
if (status === ChatModel.CallStatusDeclined) {
|
||||
if (status === ChatRoomModel.CallStatusDeclined) {
|
||||
return $chatEntry.isOutgoing ? 'declined_outgoing_call' : 'declined_incoming_call'
|
||||
}
|
||||
if (status === ChatModel.CallStatusMissed) {
|
||||
if (status === ChatRoomModel.CallStatusMissed) {
|
||||
return $chatEntry.isOutgoing ? 'missed_outgoing_call' : 'missed_incoming_call'
|
||||
}
|
||||
if (status === ChatModel.CallStatusAborted) {
|
||||
if (status === ChatRoomModel.CallStatusAborted) {
|
||||
return $chatEntry.isOutgoing ? 'outgoing_call' : 'incoming_call'
|
||||
}
|
||||
if (status === ChatModel.CallStatusEarlyAborted) {
|
||||
if (status === ChatRoomModel.CallStatusEarlyAborted) {
|
||||
return $chatEntry.isOutgoing ? 'missed_outgoing_call' : 'missed_incoming_call'
|
||||
}
|
||||
if (status === ChatModel.CallStatusAcceptedElsewhere) {
|
||||
if (status === ChatRoomModel.CallStatusAcceptedElsewhere) {
|
||||
return $chatEntry.isOutgoing ? 'outgoing_call' : 'incoming_call'
|
||||
}
|
||||
if (status === ChatModel.CallStatusDeclinedElsewhere) {
|
||||
if (status === ChatRoomModel.CallStatusDeclinedElsewhere) {
|
||||
return $chatEntry.isOutgoing ? 'declined_outgoing_call' : 'declined_incoming_call'
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -48,12 +48,12 @@ Row {
|
|||
id: rectangle
|
||||
|
||||
readonly property bool isError: Utils.includes([
|
||||
ChatModel.MessageStatusFileTransferError,
|
||||
ChatModel.MessageStatusNotDelivered,
|
||||
ChatRoomModel.MessageStatusFileTransferError,
|
||||
ChatRoomModel.MessageStatusNotDelivered,
|
||||
], $chatEntry.status)
|
||||
readonly property bool isUploaded: $chatEntry.status === ChatModel.MessageStatusDelivered
|
||||
readonly property bool isDelivered: $chatEntry.status === ChatModel.MessageStatusDeliveredToUser
|
||||
readonly property bool isRead: $chatEntry.status === ChatModel.MessageStatusDisplayed
|
||||
readonly property bool isUploaded: $chatEntry.status === ChatRoomModel.MessageStatusDelivered
|
||||
readonly property bool isDelivered: $chatEntry.status === ChatRoomModel.MessageStatusDeliveredToUser
|
||||
readonly property bool isRead: $chatEntry.status === ChatRoomModel.MessageStatusDisplayed
|
||||
|
||||
color: $chatEntry.isOutgoing
|
||||
? ChatStyle.entry.message.outgoing.backgroundColor
|
||||
|
|
@ -200,7 +200,7 @@ Row {
|
|||
|
||||
to: $chatEntry.fileSize
|
||||
value: $chatEntry.fileOffset || 0
|
||||
visible: $chatEntry.status === ChatModel.MessageStatusInProgress || $chatEntry.status === ChatModel.MessageStatusFileTransferInProgress
|
||||
visible: $chatEntry.status === ChatRoomModel.MessageStatusInProgress || $chatEntry.status === ChatRoomModel.MessageStatusFileTransferInProgress
|
||||
|
||||
background: Rectangle {
|
||||
color: ChatStyle.entry.message.file.status.bar.background.color
|
||||
|
|
@ -292,7 +292,7 @@ Row {
|
|||
|
||||
MouseArea {
|
||||
anchors.fill: parent
|
||||
visible: (rectangle.isError || $chatEntry.status === ChatModel.MessageStatusIdle) && $chatEntry.isOutgoing
|
||||
visible: (rectangle.isError || $chatEntry.status === ChatRoomModel.MessageStatusIdle) && $chatEntry.isOutgoing
|
||||
onClicked: proxyModel.resendMessage(index)
|
||||
}
|
||||
}
|
||||
|
|
@ -319,7 +319,7 @@ Row {
|
|||
|
||||
sourceComponent: $chatEntry.isOutgoing
|
||||
? (
|
||||
$chatEntry.status === ChatModel.MessageStatusInProgress || $chatEntry.status === ChatModel.MessageStatusFileTransferInProgress
|
||||
$chatEntry.status === ChatRoomModel.MessageStatusInProgress || $chatEntry.status === ChatRoomModel.MessageStatusFileTransferInProgress
|
||||
? indicator
|
||||
: icon
|
||||
) : undefined
|
||||
|
|
|
|||
|
|
@ -38,7 +38,7 @@ RowLayout {
|
|||
// 2. Previous entry is a call event. => Visible.
|
||||
// 3. I have sent a message before my contact. => Visible.
|
||||
// 4. One hour between two incoming messages. => Visible.
|
||||
return previousEntry.type !== ChatModel.MessageEntry ||
|
||||
return previousEntry.type !== ChatRoomModel.MessageEntry ||
|
||||
previousEntry.isOutgoing ||
|
||||
$chatEntry.timestamp.getTime() - previousEntry.timestamp.getTime() > 3600
|
||||
}
|
||||
|
|
|
|||
|
|
@ -35,12 +35,12 @@ Item {
|
|||
Icon {
|
||||
id: iconId
|
||||
readonly property var isError: Utils.includes([
|
||||
ChatModel.MessageStatusFileTransferError,
|
||||
ChatModel.MessageStatusNotDelivered,
|
||||
ChatRoomModel.MessageStatusFileTransferError,
|
||||
ChatRoomModel.MessageStatusNotDelivered,
|
||||
], $chatEntry.status)
|
||||
readonly property bool isUploaded: $chatEntry.status === ChatModel.MessageStatusDelivered
|
||||
readonly property bool isDelivered: $chatEntry.status === ChatModel.MessageStatusDeliveredToUser
|
||||
readonly property bool isRead: $chatEntry.status === ChatModel.MessageStatusDisplayed
|
||||
readonly property bool isUploaded: $chatEntry.status === ChatRoomModel.MessageStatusDelivered
|
||||
readonly property bool isDelivered: $chatEntry.status === ChatRoomModel.MessageStatusDeliveredToUser
|
||||
readonly property bool isRead: $chatEntry.status === ChatRoomModel.MessageStatusDisplayed
|
||||
|
||||
icon: isError
|
||||
? 'chat_error'
|
||||
|
|
@ -50,7 +50,7 @@ Item {
|
|||
MouseArea {
|
||||
id:retryAction
|
||||
anchors.fill: parent
|
||||
visible: iconId.isError || $chatEntry.status === ChatModel.MessageStatusIdle
|
||||
visible: iconId.isError || $chatEntry.status === ChatRoomModel.MessageStatusIdle
|
||||
onClicked: proxyModel.resendMessage(index)
|
||||
}
|
||||
|
||||
|
|
@ -83,7 +83,7 @@ Item {
|
|||
height: ChatStyle.entry.lineHeight
|
||||
width: ChatStyle.entry.message.outgoing.areaSize
|
||||
|
||||
sourceComponent: $chatEntry.status === ChatModel.MessageStatusInProgress || $chatEntry.status === ChatModel.MessageStatusFileTransferInProgress
|
||||
sourceComponent: $chatEntry.status === ChatRoomModel.MessageStatusInProgress || $chatEntry.status === ChatRoomModel.MessageStatusFileTransferInProgress
|
||||
? indicator
|
||||
: iconComponent
|
||||
}
|
||||
|
|
|
|||
|
|
@ -43,14 +43,17 @@ Rectangle {
|
|||
Layout.preferredWidth: ContactStyle.contentHeight
|
||||
|
||||
//image: _contact && _contact.vcard.avatar
|
||||
image: entry.avatar
|
||||
image: (entry.contactModel?entry.contactModel.vcard.avatar:entry.avatar?entry.avatar: '')
|
||||
|
||||
presenceLevel: entry.presenceStatus != null
|
||||
? Presence.getPresenceLevel(entry.presenceStatus)
|
||||
: -1
|
||||
presenceLevel: (entry.contactModel ? Presence.getPresenceLevel(entry.contactModel.presenceStatus)
|
||||
: entry.presenceStatus ? Presence.getPresenceLevel(entry.presenceStatus)
|
||||
:-1)
|
||||
|
||||
//username: LinphoneUtils.getContactUsername(_contact || entry.sipAddress || entry.fullPeerAddress || entry.peerAddress || '')
|
||||
username: entry.username
|
||||
username: (entry.contactModel ? entry.contactModel.vcard.username
|
||||
:entry.username?entry.username:
|
||||
LinphoneUtils.getContactUsername(entry.sipAddress || entry.fullPeerAddress || entry.peerAddress || '')
|
||||
)
|
||||
}
|
||||
|
||||
ContactDescription {
|
||||
|
|
@ -61,17 +64,18 @@ Rectangle {
|
|||
Layout.leftMargin: ContactStyle.spacing
|
||||
|
||||
//sipAddress: entry.sipAddress || entry.fullPeerAddress || entry.peerAddress || ''
|
||||
sipAddress: entry.sipAddress
|
||||
sipAddress: (entry.contactModel ? entry.contactModel.vcard.sipAddress
|
||||
:entry.sipAddress || entry.fullPeerAddress || entry.peerAddress || '')
|
||||
username: avatar.username
|
||||
}
|
||||
|
||||
ContactMessageCounter {
|
||||
Layout.alignment: Qt.AlignTop
|
||||
|
||||
count: Number(entry.unreadMessageCount) + Number(entry.missedCallCount)
|
||||
count: Number(entry.unreadMessagesCount) + Number(entry.missedCallsCount)
|
||||
isComposing: Boolean(entry.isComposing)
|
||||
|
||||
visible: item.displayUnreadMessageCount
|
||||
visible: (entry.unreadMessagesCount !== null || entry.missedCallsCount !== null) && item.displayUnreadMessageCount
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -13,7 +13,8 @@ Notification {
|
|||
icon: 'message_sign'
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
|
||||
readonly property TimelineModel timelineModel: notificationData && notificationData.timelineModel
|
||||
readonly property string peerAddress: notificationData && notificationData.peerAddress || ''
|
||||
readonly property string localAddress: notificationData && notificationData.localAddress || ''
|
||||
readonly property string fullPeerAddress: notificationData && notificationData.fullPeerAddress || ''
|
||||
|
|
@ -22,7 +23,7 @@ Notification {
|
|||
// ---------------------------------------------------------------------------
|
||||
|
||||
Loader {
|
||||
active: Boolean(notification.peerAddress) && Boolean(notification.localAddress)
|
||||
active: timelineModel//Boolean(notification.peerAddress) && Boolean(notification.localAddress)
|
||||
anchors {
|
||||
fill: parent
|
||||
|
||||
|
|
@ -37,7 +38,8 @@ Notification {
|
|||
Contact {
|
||||
Layout.fillWidth: true
|
||||
|
||||
entry: SipAddressesModel.getSipAddressObserver(notification.fullPeerAddress, notification.fullLocalAddress)
|
||||
//entry: SipAddressesModel.getSipAddressObserver(notification.fullPeerAddress, notification.fullLocalAddress)
|
||||
entry:notification.timelineModel.getChatRoomModel()
|
||||
}
|
||||
|
||||
Rectangle {
|
||||
|
|
@ -75,10 +77,11 @@ Notification {
|
|||
onClicked: notification._close(function () {
|
||||
AccountSettingsModel.setDefaultProxyConfigFromSipAddress(notification.localAddress)
|
||||
notification.notificationData.window.setView('Conversation', {
|
||||
chatRoomModel:notification.timelineModel.getChatRoomModel()/*,
|
||||
peerAddress: notification.peerAddress,
|
||||
localAddress: notification.localAddress,
|
||||
fullPeerAddress: notification.fullPeerAddress,
|
||||
fullLocalAddress: notification.fullLocalAddress
|
||||
fullLocalAddress: notification.fullLocalAddress*/
|
||||
})
|
||||
})
|
||||
}
|
||||
|
|
|
|||
|
|
@ -44,8 +44,8 @@ Rectangle {
|
|||
|
||||
Connections {
|
||||
target: model
|
||||
|
||||
onCurrentTimelineChanged:entrySelected(currentTimeline)
|
||||
onSelectedCountChanged:if(selectedCount<=0) view.currentIndex = -1
|
||||
// onCurrentTimelineChanged:entrySelected(currentTimeline)
|
||||
}
|
||||
/*
|
||||
Connections {
|
||||
|
|
@ -113,7 +113,7 @@ Rectangle {
|
|||
width: parent ? parent.width : 0
|
||||
|
||||
Contact {
|
||||
readonly property bool isSelected: view.currentIndex === index
|
||||
property bool isSelected: modelData.selected //view.currentIndex === index
|
||||
|
||||
anchors.fill: parent
|
||||
color: isSelected
|
||||
|
|
@ -126,7 +126,7 @@ Rectangle {
|
|||
displayUnreadMessageCount: SettingsModel.chatEnabled
|
||||
//entry: $timelineEntry
|
||||
//entry: SipAddressesModel.getSipAddressObserver(modelData.fullPeerAddress, modelData.fullLocalAddress)
|
||||
entry: modelData
|
||||
entry: modelData.chatRoomModel
|
||||
sipAddressColor: isSelected
|
||||
? TimelineStyle.contact.sipAddress.color.selected
|
||||
: TimelineStyle.contact.sipAddress.color.normal
|
||||
|
|
@ -149,15 +149,14 @@ Rectangle {
|
|||
MouseArea {
|
||||
anchors.fill: parent
|
||||
onClicked: {
|
||||
view.currentIndex = index
|
||||
//timeline.model.setCurrentChatModel(modelData.getChatModel())// using member doesn't work
|
||||
timeline.model.currentChatModel = modelData.chatModel
|
||||
//timeline.entrySelected(modelData)
|
||||
//timeline.model.unselectAll()
|
||||
modelData.selected = true
|
||||
view.currentIndex = index;
|
||||
timeline.entrySelected(modelData)
|
||||
//timeline.entrySelected($timelineEntry.sipAddress, $timelineEntry.isSecure)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// onCountChanged: Logic.handleCountChanged(count)
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -189,10 +189,10 @@ Window {
|
|||
id: chat
|
||||
|
||||
Chat {
|
||||
proxyModel: ChatProxyModel {
|
||||
proxyModel: ChatRoomProxyModel {
|
||||
Component.onCompleted: {
|
||||
if (!SettingsModel.chatEnabled) {
|
||||
setEntryTypeFilter(ChatModel.CallEntry)
|
||||
setEntryTypeFilter(ChatRoomModel.CallEntry)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -205,7 +205,7 @@ Window {
|
|||
|
||||
Connections {
|
||||
target: SettingsModel
|
||||
onChatEnabledChanged: proxyModel.setEntryTypeFilter(status ? ChatModel.GenericEntry : ChatModel.CallEntry)
|
||||
onChatEnabledChanged: proxyModel.setEntryTypeFilter(status ? ChatRoomModel.GenericEntry : ChatRoomModel.CallEntry)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -151,7 +151,7 @@ ColumnLayout {
|
|||
|
||||
ActionButton {
|
||||
icon: 'call_chat_unsecure'
|
||||
onClicked: {console.log("A");actions.itemAt(3).open()}
|
||||
onClicked: {actions.itemAt(3).open()}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -181,23 +181,15 @@ ColumnLayout {
|
|||
peerAddress: sipAddress,
|
||||
localAddress: AccountSettingsModel.sipAddress,
|
||||
fullPeerAddress: sipAddress,
|
||||
fullLocalAddress: AccountSettingsModel.fullSipAddress,
|
||||
secure:false
|
||||
fullLocalAddress: AccountSettingsModel.fullSipAddress
|
||||
})
|
||||
},
|
||||
function (sipAddress) {
|
||||
console.log("B")
|
||||
if(CallsListModel.launchSecureChat(sipAddress)){
|
||||
console.log("C")
|
||||
window.setView('Conversation', {
|
||||
peerAddress: sipAddress,
|
||||
localAddress: AccountSettingsModel.sipAddress,
|
||||
fullPeerAddress: sipAddress,
|
||||
fullLocalAddress: AccountSettingsModel.fullSipAddress,
|
||||
secure:true
|
||||
//Logic.manageAccounts()
|
||||
window.attachVirtualWindow(Qt.resolvedUrl('Dialogs/ManageChatRoom.qml'), {
|
||||
//window.setView('Dialogs/ManageChatRoom', {
|
||||
participantAddress: sipAddress
|
||||
})
|
||||
}else
|
||||
console.log("D")
|
||||
}
|
||||
]
|
||||
|
||||
|
|
|
|||
|
|
@ -33,7 +33,7 @@ function removeAllEntries () {
|
|||
descriptionText: qsTr('removeAllEntriesDescription'),
|
||||
}, function (status) {
|
||||
if (status) {
|
||||
chatProxyModel.removeAllEntries()
|
||||
chatRoomProxyModel.removeAllEntries()
|
||||
}
|
||||
})
|
||||
}
|
||||
|
|
@ -56,12 +56,12 @@ function getUsername () {
|
|||
}
|
||||
|
||||
function updateChatFilter (button) {
|
||||
var ChatModel = Linphone.ChatModel
|
||||
var ChatRoomModel = Linphone.ChatRoomModel
|
||||
if (button === 0) {
|
||||
chatProxyModel.setEntryTypeFilter(ChatModel.GenericEntry)
|
||||
chatRoomProxyModel.setEntryTypeFilter(ChatRoomModel.GenericEntry)
|
||||
} else if (button === 1) {
|
||||
chatProxyModel.setEntryTypeFilter(ChatModel.CallEntry)
|
||||
chatRoomProxyModel.setEntryTypeFilter(ChatRoomModel.CallEntry)
|
||||
} else {
|
||||
chatProxyModel.setEntryTypeFilter(ChatModel.MessageEntry)
|
||||
chatRoomProxyModel.setEntryTypeFilter(ChatRoomModel.MessageEntry)
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -12,13 +12,17 @@ import 'Conversation.js' as Logic
|
|||
|
||||
ColumnLayout {
|
||||
id: conversation
|
||||
|
||||
/*
|
||||
property string peerAddress
|
||||
property string localAddress
|
||||
property string fullPeerAddress
|
||||
property string fullLocalAddress
|
||||
property int isSecure
|
||||
property var chatModel
|
||||
property int isSecure*/
|
||||
property ChatRoomModel chatRoomModel
|
||||
property string peerAddress : chatRoomModel.getPeerAddress()
|
||||
property string localAddress : chatRoomModel.getLocalAddress()
|
||||
property string fullPeerAddress : chatRoomModel.getFullPeerAddress()
|
||||
property string fullLocalAddress : chatRoomModel.getFullLocalAddress()
|
||||
|
||||
readonly property var _sipAddressObserver: SipAddressesModel.getSipAddressObserver((fullPeerAddress?fullPeerAddress:peerAddress), (fullLocalAddress?fullLocalAddress:localAddress))
|
||||
|
||||
|
|
@ -56,7 +60,8 @@ ColumnLayout {
|
|||
conversation._sipAddressObserver.presenceStatus
|
||||
)
|
||||
|
||||
username: Logic.getUsername()
|
||||
//username: Logic.getUsername()
|
||||
username: chatRoomModel.username
|
||||
}
|
||||
|
||||
ContactDescription {
|
||||
|
|
@ -91,6 +96,14 @@ ColumnLayout {
|
|||
|
||||
onClicked: CallsListModel.launchAudioCall(conversation.peerAddress)
|
||||
}
|
||||
ActionButton {
|
||||
icon: 'call_chat_unsecure'
|
||||
onClicked: {
|
||||
window.attachVirtualWindow(Qt.resolvedUrl('Dialogs/ManageChatRoom.qml'), {
|
||||
//window.setView('Dialogs/ManageChatRoom', {
|
||||
chatRoomModel:conversation.chatRoomModel
|
||||
})}
|
||||
}
|
||||
}
|
||||
|
||||
ActionBar {
|
||||
|
|
@ -163,17 +176,16 @@ ColumnLayout {
|
|||
Layout.fillHeight: true
|
||||
Layout.fillWidth: true
|
||||
|
||||
proxyModel: ChatProxyModel {
|
||||
id: chatProxyModel
|
||||
proxyModel: ChatRoomProxyModel {
|
||||
id: chatRoomProxyModel
|
||||
|
||||
Component.onCompleted: {
|
||||
if (!SettingsModel.chatEnabled) {
|
||||
setEntryTypeFilter(ChatModel.CallEntry)
|
||||
setEntryTypeFilter(ChatRoomModel.CallEntry)
|
||||
}
|
||||
resetMessageCount()
|
||||
}
|
||||
isSecure: conversation.isSecure
|
||||
chatModel: conversation.chatModel
|
||||
chatRoomModel: conversation.chatRoomModel
|
||||
peerAddress: conversation.peerAddress
|
||||
fullPeerAddress: conversation.fullPeerAddress
|
||||
fullLocalAddress: conversation.fullLocalAddress
|
||||
|
|
@ -184,7 +196,7 @@ ColumnLayout {
|
|||
|
||||
Connections {
|
||||
target: SettingsModel
|
||||
onChatEnabledChanged: chatProxyModel.setEntryTypeFilter(status ? ChatModel.GenericEntry : ChatModel.CallEntry)
|
||||
onChatEnabledChanged: chatRoomProxyModel.setEntryTypeFilter(status ? ChatRoomModel.GenericEntry : ChatRoomModel.CallEntry)
|
||||
}
|
||||
|
||||
Connections {
|
||||
|
|
|
|||
142
linphone-app/ui/views/App/Main/Dialogs/ManageChatRoom.qml
Normal file
142
linphone-app/ui/views/App/Main/Dialogs/ManageChatRoom.qml
Normal file
|
|
@ -0,0 +1,142 @@
|
|||
import QtQuick 2.7
|
||||
|
||||
import Common 1.0
|
||||
import Linphone 1.0
|
||||
import Utils 1.0
|
||||
|
||||
import App.Styles 1.0
|
||||
|
||||
|
||||
// =============================================================================
|
||||
|
||||
DialogPlus {
|
||||
property ChatRoomModel chatRoomModel
|
||||
property var participantAddress : (chatRoomModel?chatRoomModel.getParticipants(): null)
|
||||
|
||||
buttons: [
|
||||
TextButtonA {
|
||||
text: 'cancel'
|
||||
|
||||
onClicked: exit(0)
|
||||
},
|
||||
TextButtonB {
|
||||
text: 'del'
|
||||
visible:chatRoomModel
|
||||
|
||||
onClicked: {
|
||||
if(chatRoomModel){
|
||||
chatRoomModel.leaveChatRoom()
|
||||
exit(0)
|
||||
}
|
||||
}
|
||||
},
|
||||
TextButtonB {
|
||||
text: 'ok'
|
||||
|
||||
onClicked: {
|
||||
if(chatRoomModel && CallsListModel.createSecureChat(subject.text, participantAddress))
|
||||
exit(0)
|
||||
}
|
||||
}
|
||||
]
|
||||
|
||||
centeredButtons: true
|
||||
|
||||
height: ManageAccountsStyle.height
|
||||
width: ManageAccountsStyle.width
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
Form {
|
||||
anchors.fill: parent
|
||||
orientation: Qt.Vertical
|
||||
|
||||
FormLine {
|
||||
|
||||
FormGroup {
|
||||
label: 'Details'
|
||||
|
||||
FormLine {
|
||||
FormGroup {
|
||||
label: 'Subject*'
|
||||
TextField {
|
||||
id:subject
|
||||
placeholderText :"Subject"
|
||||
text:(chatRoomModel?chatRoomModel.getSubject():'')
|
||||
Keys.onReturnPressed: nextItemInFocusChain().forceActiveFocus()
|
||||
error : text == ''
|
||||
TooltipArea{
|
||||
text : 'Current subject of the ChatRoom. It cannot be empty'
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
FormLine {
|
||||
FormGroup {
|
||||
label: 'Participants : '+participantAddress
|
||||
/*
|
||||
ScrollableListViewField {
|
||||
width: parent.width
|
||||
height: ManageAccountsStyle.accountSelector.height
|
||||
|
||||
radius: 0
|
||||
|
||||
ScrollableListView {
|
||||
id: view
|
||||
|
||||
property string textRole: 'fullSipAddress' // Used by delegate.
|
||||
|
||||
anchors.fill: parent
|
||||
model: AccountSettingsModel.accounts
|
||||
|
||||
onModelChanged: currentIndex = Utils.findIndex(AccountSettingsModel.accounts, function (account) {
|
||||
return account.sipAddress === AccountSettingsModel.sipAddress
|
||||
})
|
||||
|
||||
delegate: CommonItemDelegate {
|
||||
id: item
|
||||
container: view
|
||||
flattenedModel: modelData
|
||||
itemIcon: ''//Start with no error and let some time before getting status with the below timer
|
||||
width: parent.width
|
||||
|
||||
Timer{// This timer is used to synchronize registration state by proxy, without having to deal with change signals
|
||||
interval: 1000; running: item.visible; repeat: true
|
||||
onTriggered:itemIcon= Logic.getItemIcon(flattenedModel)
|
||||
}
|
||||
|
||||
ActionButton {
|
||||
icon: 'options'
|
||||
iconSize: 30
|
||||
anchors.fill: parent
|
||||
visible:false
|
||||
//TODO handle click and jump to proxy config settings
|
||||
}
|
||||
|
||||
onClicked: {
|
||||
container.currentIndex = index
|
||||
if(flattenedModel.proxyConfig)
|
||||
AccountSettingsModel.setDefaultProxyConfig(flattenedModel.proxyConfig)
|
||||
else
|
||||
AccountSettingsModel.setDefaultProxyConfig()
|
||||
}
|
||||
|
||||
MessageCounter {
|
||||
anchors.fill: parent
|
||||
count: flattenedModel.unreadMessageCount+flattenedModel.missedCallCount
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
*/
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -114,7 +114,7 @@ function updateSelectedEntry (view, props) {
|
|||
timeline.resetSelectedEntry()
|
||||
} else if (view === 'Contacts') {
|
||||
item.contactsEntry.select()
|
||||
timeline.resetSelectedEntry()
|
||||
//timeline.resetSelectedEntry()
|
||||
} else {
|
||||
menu.resetSelectedEntry()
|
||||
/*
|
||||
|
|
|
|||
|
|
@ -264,13 +264,13 @@ ApplicationWindow {
|
|||
Layout.fillWidth: true
|
||||
model: TimelineProxyModel{}
|
||||
|
||||
onEntrySelected: (entry?setView('Conversation', {
|
||||
onEntrySelected: (entry?setView('Conversation', {/*
|
||||
isSecure:-1,
|
||||
peerAddress: entry.fullPeerAddress,
|
||||
fullPeerAddress: entry.fullPeerAddress,
|
||||
fullLocalAddress: AccountSettingsModel.fullSipAddress,
|
||||
localAddress: AccountSettingsModel.sipAddress,
|
||||
chatModel:entry.chatModel
|
||||
localAddress: AccountSettingsModel.sipAddress,*/
|
||||
chatRoomModel:entry.chatRoomModel
|
||||
|
||||
}):
|
||||
setView('HistoryView', {})
|
||||
|
|
|
|||
|
|
@ -50,6 +50,7 @@ function initForm (account) {
|
|||
)
|
||||
|
||||
route.text = config.route
|
||||
conferenceUri.text = config.conferenceUri
|
||||
contactParams.text = config.contactParams
|
||||
avpfInterval.text = config.avpfInterval
|
||||
registerEnabled.checked = config.registerEnabled
|
||||
|
|
@ -70,7 +71,7 @@ function initForm (account) {
|
|||
}
|
||||
|
||||
function formIsValid () {
|
||||
return dialog._sipAddressOk && dialog._serverAddressOk && dialog._routeOk
|
||||
return dialog._sipAddressOk && dialog._serverAddressOk && dialog._routeOk && dialog._conferenceUriOk
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
|
|
@ -82,6 +83,7 @@ function validProxyConfig () {
|
|||
registrationDuration: registrationDuration.text,
|
||||
transport: transport.currentText,
|
||||
route: route.text,
|
||||
conferenceUri: conferenceUri.text,
|
||||
contactParams: contactParams.text,
|
||||
avpfInterval: avpfInterval.text,
|
||||
registerEnabled: registerEnabled.checked,
|
||||
|
|
@ -104,6 +106,9 @@ function validProxyConfig () {
|
|||
function handleRouteChanged (route) {
|
||||
dialog._routeOk = route.length === 0 || Linphone.SipAddressesModel.addressIsValid(route)
|
||||
}
|
||||
function handleConferenceUriChanged (uri) {
|
||||
dialog._conferenceUriOk = route.length === 0 || Linphone.SipAddressesModel.addressIsValid(uri)
|
||||
}
|
||||
|
||||
function handleServerAddressChanged (address) {
|
||||
if (address.length === 0) {
|
||||
|
|
|
|||
|
|
@ -16,6 +16,7 @@ DialogPlus {
|
|||
property bool _sipAddressOk: false
|
||||
property bool _serverAddressOk: false
|
||||
property bool _routeOk: false
|
||||
property bool _conferenceUriOk: false
|
||||
|
||||
buttons: [
|
||||
TextButtonA {
|
||||
|
|
@ -123,6 +124,21 @@ DialogPlus {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
FormLine {
|
||||
FormGroup {
|
||||
label: 'Conference URI'
|
||||
|
||||
TextField {
|
||||
id: conferenceUri
|
||||
|
||||
error: dialog._conferenceUriOk ? '' : 'invalid conference uri'
|
||||
|
||||
onTextChanged: Logic.handleConferenceUriChanged(text)
|
||||
Keys.onReturnPressed: nextItemInFocusChain().forceActiveFocus()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
FormLine {
|
||||
FormGroup {
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue