/* * Copyright (c) 2010-2024 Belledonne Communications SARL. * * This file is part of linphone-desktop * (see https://www.linphone.org). * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ #include "ChatModel.hpp" #include #include "core/path/Paths.hpp" #include "model/core/CoreModel.hpp" #include "model/setting/SettingsModel.hpp" #include "model/tool/ToolModel.hpp" #include "tool/Utils.hpp" DEFINE_ABSTRACT_OBJECT(ChatModel) ChatModel::ChatModel(const std::shared_ptr &chatroom, QObject *parent) : ::Listener(chatroom, parent) { // lDebug() << "[ChatModel] new" << this << " / SDKModel=" << chatroom.get(); mustBeInLinphoneThread(getClassName()); auto coreModel = CoreModel::getInstance(); if (coreModel) connect(coreModel.get(), &CoreModel::chatRoomRead, this, [this](const std::shared_ptr &core, std::shared_ptr chatroom) { if (chatroom == mMonitor) emit messagesRead(); }); } ChatModel::~ChatModel() { mustBeInLinphoneThread("~" + getClassName()); disconnect(CoreModel::getInstance().get(), &CoreModel::chatRoomRead, this, nullptr); } QDateTime ChatModel::getLastUpdateTime() { // TODO : vérifier unité return QDateTime::fromSecsSinceEpoch(mMonitor->getLastUpdateTime()); } std::list> ChatModel::getSharedMedias() const { return mMonitor->getMediaContents(); } std::list> ChatModel::getSharedDocuments() const { return mMonitor->getDocumentContents(); } std::list> ChatModel::getHistory() const { return mMonitor->getHistoryEvents(0); } std::list> ChatModel::getHistoryRange(int begin, int end) { return mMonitor->getHistoryRangeEvents(begin, end); } std::list> ChatModel::getHistoryRangeBetween(const std::shared_ptr firstEvent, const std::shared_ptr lastEvent, int filters) { return mMonitor->getHistoryRangeBetween(firstEvent, lastEvent, filters); } std::list> ChatModel::getHistoryRangeNear(int before, int after, const std::shared_ptr event, int filters) { return mMonitor->getHistoryRangeNear(before, after, event, filters); } std::list> ChatModel::getChatMessageHistory() const { auto history = mMonitor->getHistory(0, (int)linphone::ChatRoom::HistoryFilter::ChatMessage); std::list> res; for (auto &eventLog : history) { auto chatMessage = eventLog->getChatMessage(); if (chatMessage) res.push_back(chatMessage); } return res; } int ChatModel::getHistorySizeEvents() const { return mMonitor->getHistoryEventsSize(); } QString ChatModel::getIdentifier() const { return Utils::coreStringToAppString(mMonitor->getIdentifier()); } QString ChatModel::getTitle() { if (mMonitor->hasCapability((int)linphone::ChatRoom::Capabilities::Basic)) { return ToolModel::getDisplayName(mMonitor->getPeerAddress()); } else { if (mMonitor->hasCapability((int)linphone::ChatRoom::Capabilities::OneToOne)) { auto participants = mMonitor->getParticipants(); if (participants.size() > 0) { auto peer = participants.front(); return peer ? ToolModel::getDisplayName(peer->getAddress()) : ""; } else { return ""; } } else if (mMonitor->hasCapability((int)linphone::ChatRoom::Capabilities::Conference)) { return Utils::coreStringToAppString(mMonitor->getSubject()); } } return QString(); } QString ChatModel::getPeerAddress() const { return Utils::coreStringToAppString(mMonitor->getPeerAddress()->asStringUriOnly()); } int ChatModel::getCapabilities() const { return mMonitor->getCapabilities(); } bool ChatModel::hasCapability(int capability) const { return mMonitor->hasCapability(capability); } std::shared_ptr ChatModel::getLastChatMessage() { return mMonitor->getLastMessageInHistory(); } int ChatModel::getUnreadMessagesCount() const { return mMonitor->getUnreadMessagesCount(); } void ChatModel::markAsRead() { mMonitor->markAsRead(); emit messagesRead(); } void ChatModel::setMuted(bool muted) { mMonitor->setMuted(muted); emit mutedChanged(muted); } void ChatModel::enableEphemeral(bool enable) { mMonitor->enableEphemeral(enable); emit ephemeralEnableChanged(enable); } void ChatModel::setEphemeralLifetime(int time) { mMonitor->setEphemeralLifetime(time); emit ephemeralLifetimeChanged(time); enableEphemeral(time != 0); } void ChatModel::deleteHistory() { mMonitor->deleteHistory(); emit historyDeleted(); } void ChatModel::deleteMessage(std::shared_ptr message) { mMonitor->deleteMessage(message); } void ChatModel::leave() { mMonitor->leave(); } void ChatModel::deleteChatRoom() { CoreModel::getInstance()->getCore()->deleteChatRoom(mMonitor); } std::shared_ptr ChatModel::createVoiceRecordingMessage(const std::shared_ptr &recorder) { return mMonitor->createVoiceRecordingMessage(recorder); } std::shared_ptr ChatModel::createReplyMessage(const std::shared_ptr &message) { return mMonitor->createReplyMessage(message); } std::shared_ptr ChatModel::createForwardMessage(const std::shared_ptr &message) { return mMonitor->createForwardMessage(message); } std::shared_ptr ChatModel::createTextMessageFromText(QString text) { return mMonitor->createMessageFromUtf8(Utils::appStringToCoreString(text)); } std::shared_ptr ChatModel::createMessage(QString text, QList> filesContent) { auto message = mMonitor->createEmptyMessage(); for (auto &content : filesContent) { message->addFileContent(content->getContent()); } if (!text.isEmpty()) message->addUtf8TextContent(Utils::appStringToCoreString(text)); return message; } std::shared_ptr ChatModel::searchMessageByText(QString text, std::shared_ptr from, bool forward) { return mMonitor->searchChatMessageByText(Utils::appStringToCoreString(text), from, forward ? linphone::SearchDirection::Down : linphone::SearchDirection::Up); } void ChatModel::compose() { mMonitor->composeTextMessage(); } linphone::ChatRoom::State ChatModel::getState() const { return mMonitor->getState(); } void ChatModel::setSubject(QString subject) const { return mMonitor->setSubject(Utils::appStringToCoreString(subject)); } void ChatModel::removeParticipantAtIndex(int index) const { auto participant = *std::next(mMonitor->getParticipants().begin(), index); mMonitor->removeParticipant(participant); } void ChatModel::toggleParticipantAdminStatusAtIndex(int index) const { auto participant = *std::next(mMonitor->getParticipants().begin(), index); mMonitor->setParticipantAdminStatus(participant, !participant->isAdmin()); } void ChatModel::setParticipantAddresses(const QStringList &addresses) const { QSet s{addresses.cbegin(), addresses.cend()}; for (auto p : mMonitor->getParticipants()) { auto address = Utils::coreStringToAppString(p->getAddress()->asStringUriOnly()); if (s.contains(address)) s.remove(address); else mMonitor->removeParticipant(p); } for (const auto &a : s) { auto address = linphone::Factory::get()->createAddress(Utils::appStringToCoreString(a)); if (address) mMonitor->addParticipant(address); } } //---------------------------------------------------------------// void ChatModel::onIsComposingReceived(const std::shared_ptr &chatRoom, const std::shared_ptr &remoteAddress, bool isComposing) { emit isComposingReceived(chatRoom, remoteAddress, isComposing); } void ChatModel::onMessageReceived(const std::shared_ptr &chatRoom, const std::shared_ptr &message) { emit messageReceived(chatRoom, message); } void ChatModel::onMessagesReceived(const std::shared_ptr &chatRoom, const std::list> &chatMessages) { emit messagesReceived(chatRoom, chatMessages); } void ChatModel::onNewEvent(const std::shared_ptr &chatRoom, const std::shared_ptr &eventLog) { emit newEvent(chatRoom, eventLog); } void ChatModel::onNewEvents(const std::shared_ptr &chatRoom, const std::list> &eventLogs) { emit newEvents(chatRoom, eventLogs); } void ChatModel::onChatMessageReceived(const std::shared_ptr &chatRoom, const std::shared_ptr &eventLog) { emit chatMessageReceived(chatRoom, eventLog); } void ChatModel::onChatMessagesReceived(const std::shared_ptr &chatRoom, const std::list> &eventLogs) { emit chatMessagesReceived(chatRoom, eventLogs); } void ChatModel::onChatMessageSending(const std::shared_ptr &chatRoom, const std::shared_ptr &eventLog) { emit chatMessageSending(chatRoom, eventLog); } void ChatModel::onChatMessageSent(const std::shared_ptr &chatRoom, const std::shared_ptr &eventLog) { emit chatMessageSent(chatRoom, eventLog); } void ChatModel::onParticipantAdded(const std::shared_ptr &chatRoom, const std::shared_ptr &eventLog) { emit participantAdded(chatRoom, eventLog); } void ChatModel::onParticipantRemoved(const std::shared_ptr &chatRoom, const std::shared_ptr &eventLog) { emit participantRemoved(chatRoom, eventLog); } void ChatModel::onParticipantAdminStatusChanged(const std::shared_ptr &chatRoom, const std::shared_ptr &eventLog) { emit participantAdminStatusChanged(chatRoom, eventLog); } void ChatModel::onStateChanged(const std::shared_ptr &chatRoom, linphone::ChatRoom::State newState) { emit stateChanged(chatRoom, newState); } void ChatModel::onSecurityEvent(const std::shared_ptr &chatRoom, const std::shared_ptr &eventLog) { emit securityEvent(chatRoom, eventLog); } void ChatModel::onSubjectChanged(const std::shared_ptr &chatRoom, const std::shared_ptr &eventLog) { emit subjectChanged(chatRoom, eventLog); } void ChatModel::onUndecryptableMessageReceived(const std::shared_ptr &chatRoom, const std::shared_ptr &message) { emit undecryptableMessageReceived(chatRoom, message); } void ChatModel::onParticipantDeviceAdded(const std::shared_ptr &chatRoom, const std::shared_ptr &eventLog) { emit participantDeviceAdded(chatRoom, eventLog); } void ChatModel::onParticipantDeviceRemoved(const std::shared_ptr &chatRoom, const std::shared_ptr &eventLog) { emit participantDeviceRemoved(chatRoom, eventLog); } void ChatModel::onParticipantDeviceStateChanged(const std::shared_ptr &chatRoom, const std::shared_ptr &eventLog, linphone::ParticipantDevice::State state) { emit participantDeviceStateChanged(chatRoom, eventLog, state); } void ChatModel::onParticipantDeviceMediaAvailabilityChanged(const std::shared_ptr &chatRoom, const std::shared_ptr &eventLog) { emit participantDeviceMediaAvailabilityChanged(chatRoom, eventLog); } void ChatModel::onConferenceJoined(const std::shared_ptr &chatRoom, const std::shared_ptr &eventLog) { emit conferenceJoined(chatRoom, eventLog); } void ChatModel::onConferenceLeft(const std::shared_ptr &chatRoom, const std::shared_ptr &eventLog) { emit conferenceLeft(chatRoom, eventLog); } void ChatModel::onEphemeralEvent(const std::shared_ptr &chatRoom, const std::shared_ptr &eventLog) { emit ephemeralEvent(chatRoom, eventLog); } void ChatModel::onEphemeralMessageTimerStarted(const std::shared_ptr &chatRoom, const std::shared_ptr &eventLog) { emit ephemeralMessageTimerStarted(chatRoom, eventLog); } void ChatModel::onEphemeralMessageDeleted(const std::shared_ptr &chatRoom, const std::shared_ptr &eventLog) { emit ephemeralMessageDeleted(chatRoom, eventLog); } void ChatModel::onConferenceAddressGeneration(const std::shared_ptr &chatRoom) { emit conferenceAddressGeneration(chatRoom); } void ChatModel::onParticipantRegistrationSubscriptionRequested( const std::shared_ptr &chatRoom, const std::shared_ptr &participantAddress) { emit participantRegistrationSubscriptionRequested(chatRoom, participantAddress); } void ChatModel::onParticipantRegistrationUnsubscriptionRequested( const std::shared_ptr &chatRoom, const std::shared_ptr &participantAddress) { emit participantRegistrationUnsubscriptionRequested(chatRoom, participantAddress); } void ChatModel::onChatMessageShouldBeStored(const std::shared_ptr &chatRoom, const std::shared_ptr &message) { emit chatMessageShouldBeStored(chatRoom, message); } void ChatModel::onChatMessageParticipantImdnStateChanged( const std::shared_ptr &chatRoom, const std::shared_ptr &message, const std::shared_ptr &state) { emit chatMessageParticipantImdnStateChanged(chatRoom, message, state); } void ChatModel::onChatRoomRead(const std::shared_ptr &chatRoom) { emit chatRoomRead(chatRoom); } void ChatModel::onNewMessageReaction(const std::shared_ptr &chatRoom, const std::shared_ptr &message, const std::shared_ptr &reaction) { // emit onNewMessageReaction(chatRoom, message, reaction); }