This commit is contained in:
Julien Wadel 2022-03-31 20:11:08 +02:00
parent 6c88ec6ab4
commit b893c78399
99 changed files with 1775 additions and 1425 deletions

View file

@ -126,6 +126,9 @@ set(SOURCES
src/app/providers/ImageProvider.cpp
src/app/providers/ExternalImageProvider.cpp
src/app/providers/ThumbnailProvider.cpp
src/app/proxyModel/ProxyListModel.cpp
#src/app/proxyModel/ProxyMapModel.cpp
#src/app/proxyModel/ProxyModel.cpp
src/app/translator/DefaultTranslator.cpp
src/components/assistant/AssistantModel.cpp
src/components/authentication/AuthenticationNotifier.cpp
@ -138,10 +141,11 @@ set(SOURCES
src/components/chat/ChatModel.cpp
src/components/chat-events/ChatCallModel.cpp
src/components/chat-events/ChatEvent.cpp
src/components/chat-events/ChatMessageListener.cpp
src/components/chat-events/ChatMessageModel.cpp
src/components/chat-events/ChatNoticeModel.cpp
src/components/chat-room/ChatRoomListener.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
@ -154,7 +158,7 @@ set(SOURCES
src/components/conferenceInfo/ConferenceInfoListModel.cpp
src/components/conferenceInfo/ConferenceInfoMapModel.cpp
src/components/conferenceInfo/ConferenceInfoProxyModel.cpp
src/components/conferenceScheduler/ConferenceSchedulerModel.cpp
src/components/conferenceScheduler/ConferenceSchedulerHandler.cpp
src/components/contact/ContactModel.cpp
src/components/contact/VcardModel.cpp
src/components/contacts/ContactsImporterModel.cpp
@ -243,6 +247,9 @@ set(HEADERS
src/app/providers/ImageProvider.hpp
src/app/providers/ExternalImageProvider.hpp
src/app/providers/ThumbnailProvider.hpp
src/app/proxyModel/ProxyListModel.hpp
#src/app/proxyModel/ProxyMapModel.hpp
#src/app/proxyModel/ProxyModel.hpp
src/app/single-application/SingleApplication.hpp
src/app/translator/DefaultTranslator.hpp
src/components/assistant/AssistantModel.hpp
@ -256,10 +263,11 @@ set(HEADERS
src/components/chat/ChatModel.hpp
src/components/chat-events/ChatCallModel.hpp
src/components/chat-events/ChatEvent.hpp
src/components/chat-events/ChatMessageListener.hpp
src/components/chat-events/ChatMessageModel.hpp
src/components/chat-events/ChatNoticeModel.hpp
src/components/chat-room/ChatRoomListener.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
@ -273,7 +281,7 @@ set(HEADERS
src/components/conferenceInfo/ConferenceInfoListModel.hpp
src/components/conferenceInfo/ConferenceInfoMapModel.hpp
src/components/conferenceInfo/ConferenceInfoProxyModel.hpp
src/components/conferenceScheduler/ConferenceSchedulerModel.hpp
src/components/conferenceScheduler/ConferenceSchedulerHandler.hpp
src/components/contact/ContactModel.hpp
src/components/contact/VcardModel.hpp
src/components/contacts/ContactsImporterModel.hpp

View file

@ -607,14 +607,14 @@ void App::registerTypes () {
qRegisterMetaType<ChatRoomModel::EntryType>();
qRegisterMetaType<shared_ptr<linphone::SearchResult>>();
qRegisterMetaType<std::list<std::shared_ptr<linphone::SearchResult> > >();
qRegisterMetaType<std::shared_ptr<ChatMessageModel>>();
qRegisterMetaType<std::shared_ptr<ChatRoomModel>>();
qRegisterMetaType<std::shared_ptr<ParticipantListModel>>();
qRegisterMetaType<std::shared_ptr<ParticipantDeviceModel>>();
qRegisterMetaType<std::shared_ptr<ChatMessageModel>>();
qRegisterMetaType<std::shared_ptr<ChatNoticeModel>>();
qRegisterMetaType<std::shared_ptr<ChatCallModel>>();
qRegisterMetaType<std::shared_ptr<ConferenceInfoModel>>();
qRegisterMetaType<QSharedPointer<ChatMessageModel>>();
qRegisterMetaType<QSharedPointer<ChatRoomModel>>();
qRegisterMetaType<QSharedPointer<ParticipantListModel>>();
qRegisterMetaType<QSharedPointer<ParticipantDeviceModel>>();
qRegisterMetaType<QSharedPointer<ChatMessageModel>>();
qRegisterMetaType<QSharedPointer<ChatNoticeModel>>();
qRegisterMetaType<QSharedPointer<ChatCallModel>>();
qRegisterMetaType<QSharedPointer<ConferenceInfoModel>>();
//qRegisterMetaType<std::shared_ptr<ChatEvent>>();
LinphoneEnums::registerMetaTypes();

View file

@ -164,6 +164,7 @@ void Logger::log (QtMsgType type, const QMessageLogContext &context, const QStri
mMutex.lock();
fprintf(stdout, format, dateTime.constData(), QThread::currentThread(), contextStr, localMsg.constData());
fflush(stdout);
if( level == BCTBX_LOG_FATAL)
QMessageBox::critical(nullptr, "Linphone will crash", msg); // Print an error message before sending msg to bctoolbox
bctbx_log(Constants::QtDomain, level, "QT: %s%s", contextStr, localMsg.constData());

View file

@ -0,0 +1,120 @@
/*
* Copyright (c) 2022 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 "ProxyListModel.hpp"
#include <QDebug>
// =============================================================================
ProxyListModel::ProxyListModel (QObject *parent) : QAbstractListModel(parent) {
}
int ProxyListModel::rowCount (const QModelIndex &) const {
return mList.count();
}
QHash<int, QByteArray> ProxyListModel::roleNames () const {
QHash<int, QByteArray> roles;
roles[Qt::DisplayRole] = "modelData";
return roles;
}
QVariant ProxyListModel::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].get());
return QVariant();
}
QSharedPointer<QObject> ProxyListModel::getAt(const int& index) const{
return mList[index];
}
// -----------------------------------------------------------------------------
void ProxyListModel::add(QSharedPointer<QObject> item){
int row = mList.count();
beginInsertRows(QModelIndex(), row, row);
mList << item;
endInsertRows();
}
void ProxyListModel::prepend(QSharedPointer<QObject> item){
mList.prepend(item);
}
void ProxyListModel::prepend(QList<QSharedPointer<QObject>> items){
beginInsertRows(QModelIndex(), 0, items.size()-1);
items << mList;
mList = items;
endInsertRows();
}
bool ProxyListModel::remove(QObject *itemToRemove) {
bool removed = false;
qInfo() << QStringLiteral("Removing ") << itemToRemove->metaObject()->className() << QStringLiteral(" : ") << itemToRemove;
int index = 0;
for(auto item : mList)
if( item.get() == itemToRemove) {
removed = removeRow(index);
break;
}else
++index;
if( !removed)
qWarning() << QStringLiteral("Unable to remove ") << itemToRemove->metaObject()->className() << QStringLiteral(" : ") << itemToRemove;
return removed;
}
bool ProxyListModel::remove(QSharedPointer<QObject> itemToRemove){
return remove(itemToRemove.get());
}
bool ProxyListModel::removeRow (int row, const QModelIndex &parent) {
return removeRows(row, 1, parent);
}
bool ProxyListModel::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);
endRemoveRows();
return true;
}
void ProxyListModel::resetData(){
beginResetModel();
mList.clear();
endResetModel();
}
// -----------------------------------------------------------------------------

View file

@ -0,0 +1,87 @@
/*
* Copyright (c) 2022 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 _PROXY_LIST_MODEL_H_
#define _PROXY_LIST_MODEL_H_
#include <QAbstractListModel>
#include <QSharedPointer>
// =============================================================================
class ProxyListModel : public QAbstractListModel {
Q_OBJECT
public:
ProxyListModel (QObject *parent = Q_NULLPTR);
virtual int rowCount (const QModelIndex &index = QModelIndex()) const override;
virtual QHash<int, QByteArray> roleNames () const override;
virtual QVariant data (const QModelIndex &index, int role = Qt::DisplayRole) const override;
QSharedPointer<QObject> getAt(const int& index) const;
template <class T>
QList<QSharedPointer<T>> getSharedList(){
QList<QSharedPointer<T>> newList;
for(auto item : mList)
newList << item.objectCast<T>();
return newList;
}
// Add functions
virtual void add(QSharedPointer<QObject> item);
template <class T>
void add(QSharedPointer<T> item){
add(item.template objectCast<QObject>());
}
//virtual void add(QList<QSharedPointer<QObject>> item);
virtual void prepend(QSharedPointer<QObject> item);
template <class T>
void prepend(QSharedPointer<T> item){
prepend(item.template objectCast<QObject>());
}
virtual void prepend(QList<QSharedPointer<QObject>> items);
template <class T>
void prepend(QList<QSharedPointer<T>> items){
beginInsertRows(QModelIndex(), 0, items.size()-1);
items << mList;
mList = items;
endInsertRows();
}
// Remove functions
Q_INVOKABLE virtual bool remove(QObject *itemToRemove) ;
virtual bool remove(QSharedPointer<QObject> itemToRemove) ;
virtual bool removeRow (int row, const QModelIndex &parent = QModelIndex());
virtual bool removeRows (int row, int count, const QModelIndex &parent = QModelIndex()) override;
Q_INVOKABLE virtual void resetData();
protected:
QList<QSharedPointer<QObject>> mList;
};
#endif

View file

@ -0,0 +1,93 @@
/*
* 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 "ConferenceInfoMapModel.hpp"
#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 "ConferenceInfoProxyModel.hpp"
#include "ConferenceInfoListModel.hpp"
#include "ConferenceInfoModel.hpp"
// =============================================================================
ConferenceInfoMapModel::ConferenceInfoMapModel (QObject *parent) : QAbstractListModel(parent) {
auto conferenceInfos = CoreManager::getInstance()->getCore()->getConferenceInformationList();
auto me = CoreManager::getInstance()->getCore()->getDefaultAccount()->getParams()->getIdentityAddress();
for(auto conferenceInfo : conferenceInfos){
std::list<std::shared_ptr<linphone::Address>> participants = conferenceInfo->getParticipants();
bool haveMe = conferenceInfo->getOrganizer()->weakEqual(me);
if(!haveMe)
haveMe = (std::find_if(participants.begin(), participants.end(), [me](const std::shared_ptr<linphone::Address>& address){
return me->weakEqual(address);
}) != participants.end());
if(haveMe){
auto conferenceInfoModel = ConferenceInfoModel::create( conferenceInfo );
QDate t = conferenceInfoModel->getDateTime().date();
if( !mMappedList.contains(t))
mMappedList[t] = new ConferenceInfoProxyModel(new ConferenceInfoListModel(), this);
mMappedList[t]->add(conferenceInfoModel);
}
}
}
int ConferenceInfoMapModel::rowCount (const QModelIndex &) const {
return mMappedList.size();
}
QHash<int, QByteArray> ConferenceInfoMapModel::roleNames () const {
QHash<int, QByteArray> roles;
roles[Qt::DisplayRole] = "modelData";
roles[Qt::DisplayRole + 1] = "date";
return roles;
}
QVariant ConferenceInfoMapModel::data (const QModelIndex &index, int role) const {
int row = index.row();
if (!index.isValid() || row < 0 || row >= mMappedList.size())
return QVariant();
auto it = mMappedList.begin() + row;
if (role == Qt::DisplayRole)
return QVariant::fromValue(*it);
else if( role == Qt::DisplayRole+1)
return QVariant::fromValue(it.key());
return QVariant();
}
// -----------------------------------------------------------------------------
void ConferenceInfoMapModel::setConferenceInfoFilter (int filterMode){
for(auto list : mMappedList){
list->setConferenceInfoFilter(filterMode);
}
}

View file

@ -18,34 +18,33 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef _CHAT_ROOM_LIST_MODEL_H_
#define _CHAT_ROOM_LIST_MODEL_H_
#ifndef _CONFERENCE_INFO_MAP_MODEL_H_
#define _CONFERENCE_INFO_MAP_MODEL_H_
#include <linphone++/linphone.hh>
#include <QAbstractListModel>
#include <QDate>
// =============================================================================
class ChatRoomModel;
class ConferenceInfoProxyModel;
class ChatRoomListModel : public QAbstractListModel {
Q_OBJECT;
class ConferenceInfoMapModel : public QAbstractListModel {
Q_OBJECT
public:
ChatRoomListModel (QObject *parent = Q_NULLPTR);
ConferenceInfoMapModel (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;
Q_INVOKABLE void setConferenceInfoFilter (int filterMode);
private:
bool removeRow (int row, const QModelIndex &parent = QModelIndex());
bool removeRows (int row, int count, const QModelIndex &parent = QModelIndex()) override;
QList<ChatRoomModel *> mList;
QMap<QDate, ConferenceInfoProxyModel*> mMappedList;
};
#endif // _CHAT_ROOM_LIST_MODEL_H_
Q_DECLARE_METATYPE(ConferenceInfoMapModel*)
#endif

View file

@ -0,0 +1,76 @@
/*
* Copyright (c) 2022 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 "ProxyModel.hpp"
// =============================================================================
using namespace std;
ProxyModel::ProxyModel (QObject *parent) : QSortFilterProxyModel(parent) {
mFilterMode = 0;
sort(0, Qt::DescendingOrder);
}
ProxyModel::ProxyModel (QAbstractItemModel * model, const int& defaultFilterMode, QObject *parent) : QSortFilterProxyModel(parent) {
mFilterMode = defaultFilterMode;
setSourceModel(model);
sort(0, Qt::DescendingOrder);
}
int ProxyModel::getFilterMode () const {
return mFilterMode;
}
void ProxyModel::setFilterMode (int filterMode) {
if (getFilterMode() != filterMode) {
mFilterMode = filterMode;
invalidate();
emit filterModeChanged(filterMode);
}
}
bool ProxyModel::filterAcceptsRow (int sourceRow, const QModelIndex &sourceParent) const {
return true;
}
bool ProxyModel::lessThan (const QModelIndex &left, const QModelIndex &right) const {
Q_UNUSED(left)
Q_UNUSED(right)
return true;
}
QVariant ProxyModel::getAt(int row){
QModelIndex sourceIndex = mapToSource(this->index(row, 0));
return sourceModel()->data(sourceIndex);
}
QAbstractItemModel *ProxyModel::getModel(){
return sourceModel();
}
void ProxyModel::setModel(QAbstractItemModel * model){
setSourceModel(model);
emit modelChanged();
}
void ProxyModel::add(std::shared_ptr<QAbstractItemModel> model){
emit added(model);
}

View file

@ -0,0 +1,63 @@
/*
* Copyright (c) 2022 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 PROXY_MODEL_H_
#define PROXY_MODEL_H_
#include <QSortFilterProxyModel>
#include <memory>
// =============================================================================
class ProxyModel : public QSortFilterProxyModel {
Q_OBJECT
public:
Q_PROPERTY(int filterMode READ getFilterMode WRITE setFilterMode SIGNAL filterModeChanged)
Q_PROPERTY(QAbstractItemModel * model READ getModel WRITE setModel SIGNAL modelChanged)
ProxyModel (QObject *parent = Q_NULLPTR);
ProxyModel (QAbstractItemModel * list, const int& defaultFilterMode, QObject *parent = Q_NULLPTR);
int getFilterMode () const;
void setFilterMode (int filterMode);
Q_INVOKABLE QVariant getAt(int row);
QAbstractItemModel *getModel();
void setModel(QAbstractItemModel * model);
//void add(std::shared_ptr<QObject> model);
public slots:
void add(std::shared_ptr<QAbstractItemModel> model);
signals:
void filterModeChanged(int);
void modelChanged();
void added(std::shared_ptr<QAbstractItemModel> model);
protected:
bool filterAcceptsRow (int sourceRow, const QModelIndex &sourceParent) const override;
bool lessThan (const QModelIndex &left, const QModelIndex &right) const override;
private:
int mFilterMode;
};
#endif

View file

@ -40,7 +40,7 @@
#include "conferenceInfo/ConferenceInfoModel.hpp"
#include "conferenceInfo/ConferenceInfoListModel.hpp"
#include "conferenceInfo/ConferenceInfoProxyModel.hpp"
#include "conferenceScheduler/ConferenceSchedulerModel.hpp"
#include "conferenceScheduler/ConferenceSchedulerHandler.hpp"
#include "contact/ContactModel.hpp"
#include "contact/VcardModel.hpp"
#include "contacts/ContactsListModel.hpp"

View file

@ -119,7 +119,7 @@ QString CallModel::getFullLocalAddress () const {
ContactModel *CallModel::getContactModel() const{
QString cleanedAddress = mCall ? Utils::cleanSipAddress(Utils::coreStringToAppString(mCall->getRemoteAddress()->asString())) : "";
return CoreManager::getInstance()->getContactsListModel()->findContactModelFromSipAddress(cleanedAddress);
return CoreManager::getInstance()->getContactsListModel()->findContactModelFromSipAddress(cleanedAddress).get();
}
ChatRoomModel * CallModel::getChatRoomModel() const{
@ -791,7 +791,7 @@ void CallModel::callEnded(){
auto chatRoom = core->searchChatRoom(params, mCall->getCallLog()->getLocalAddress()
, mCall->getRemoteAddress()
, participants);
std::shared_ptr<ChatRoomModel> chatRoomModel= CoreManager::getInstance()->getTimelineListModel()->getChatRoomModel(chatRoom, false);
QSharedPointer<ChatRoomModel> chatRoomModel= CoreManager::getInstance()->getTimelineListModel()->getChatRoomModel(chatRoom, false);
if(chatRoomModel)
chatRoomModel->callEnded(mCall);
}

View file

@ -49,9 +49,9 @@ namespace {
constexpr int DelayBeforeRemoveCall = 3000;
}
static inline int findCallIndex (QList<CallModel *> &list, const shared_ptr<linphone::Call> &call) {
auto it = find_if(list.begin(), list.end(), [call](CallModel *callModel) {
return call == callModel->getCall();
static inline int findCallIndex (QList<QSharedPointer<QObject>> &list, const shared_ptr<linphone::Call> &call) {
auto it = find_if(list.begin(), list.end(), [call](QSharedPointer<QObject> callModel) {
return call == callModel.objectCast<CallModel>()->getCall();
});
Q_ASSERT(it != list.end());
@ -59,13 +59,13 @@ static inline int findCallIndex (QList<CallModel *> &list, const shared_ptr<linp
return int(distance(list.begin(), it));
}
static inline int findCallIndex (QList<CallModel *> &list, const CallModel &callModel) {
static inline int findCallIndex (QList<QSharedPointer<QObject>> &list, const CallModel &callModel) {
return ::findCallIndex(list, callModel.getCall());
}
// -----------------------------------------------------------------------------
CallsListModel::CallsListModel (QObject *parent) : QAbstractListModel(parent) {
CallsListModel::CallsListModel (QObject *parent) : ProxyListModel(parent) {
mCoreHandlers = CoreManager::getInstance()->getHandlers();
QObject::connect(
mCoreHandlers.get(), &CoreHandlers::callStateChanged,
@ -73,34 +73,12 @@ CallsListModel::CallsListModel (QObject *parent) : QAbstractListModel(parent) {
);
}
int CallsListModel::rowCount (const QModelIndex &) const {
return mList.count();
}
QHash<int, QByteArray> CallsListModel::roleNames () const {
QHash<int, QByteArray> roles;
roles[Qt::DisplayRole] = "$call";
return roles;
}
QVariant CallsListModel::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();
}
CallModel *CallsListModel::findCallModelFromPeerAddress (const QString &peerAddress) const {
std::shared_ptr<linphone::Address> address = Utils::interpretUrl(peerAddress);
auto it = find_if(mList.begin(), mList.end(), [address](CallModel *callModel) {
return callModel->getRemoteAddress()->weakEqual(address);
auto it = find_if(mList.begin(), mList.end(), [address](QSharedPointer<QObject> callModel) {
return callModel.objectCast<CallModel>()->getRemoteAddress()->weakEqual(address);
});
return it != mList.end() ? *it : nullptr;
return it != mList.end() ? it->objectCast<CallModel>().get() : nullptr;
}
// -----------------------------------------------------------------------------
@ -310,7 +288,7 @@ QVariantMap CallsListModel::createChatRoom(const QString& subject, const int& se
shared_ptr<linphone::Core> core = CoreManager::getInstance()->getCore();
std::shared_ptr<linphone::ChatRoom> chatRoom;
QList< std::shared_ptr<linphone::Address>> admins;
std::shared_ptr<TimelineModel> timeline;
QSharedPointer<TimelineModel> timeline;
auto timelineList = CoreManager::getInstance()->getTimelineListModel();
QString localAddressStr = (localAddress ? Utils::coreStringToAppString(localAddress->asStringUriOnly()) : "local");
qInfo() << "ChatRoom creation of " << subject << " at " << securityLevel << " security, from " << localAddressStr << " and with " << participants;
@ -386,7 +364,6 @@ QVariantMap CallsListModel::createConference(ConferenceInfoModel * conferenceInf
shared_ptr<linphone::Core> core = CoreManager::getInstance()->getCore();
std::shared_ptr<linphone::Conference> conference;
QList< std::shared_ptr<linphone::Address>> admins;
std::shared_ptr<TimelineModel> timeline;
auto timelineList = CoreManager::getInstance()->getTimelineListModel();
qInfo() << "Conference creation of " << conferenceInfo->getSubject() << " at " << securityLevel << " security";// and with " << conferenceInfo->getConferenceInfo()->getParticipants().size();
auto conferenceScheduler = core->createConferenceScheduler();
@ -487,26 +464,6 @@ void CallsListModel::handleCallStateChanged (const shared_ptr<linphone::Call> &c
}
}
bool CallsListModel::removeRow (int row, const QModelIndex &parent) {
return removeRows(row, 1, parent);
}
bool CallsListModel::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;
}
// -----------------------------------------------------------------------------
void CallsListModel::addCall (const shared_ptr<linphone::Call> &call) {
@ -521,21 +478,11 @@ void CallsListModel::addCall (const shared_ptr<linphone::Call> &call) {
}
}
CallModel *callModel = new CallModel(call);
QSharedPointer<CallModel> callModel = QSharedPointer<CallModel>::create(call);
qInfo() << QStringLiteral("Add call:") << callModel->getFullLocalAddress() << callModel->getFullPeerAddress();
App::getInstance()->getEngine()->setObjectOwnership(callModel, QQmlEngine::CppOwnership);
App::getInstance()->getEngine()->setObjectOwnership(callModel.get(), QQmlEngine::CppOwnership);
// This connection is (only) useful for `CallsListProxyModel`.
QObject::connect(callModel, &CallModel::isInConferenceChanged, this, [this, callModel](bool) {
int id = findCallIndex(mList, *callModel);
emit dataChanged(index(id, 0), index(id, 0));
});
int row = mList.count();
beginInsertRows(QModelIndex(), row, row);
mList << callModel;
endInsertRows();
add(callModel);
emit layoutChanged();
}
@ -546,21 +493,18 @@ void CallsListModel::addDummyCall () {
App::smartShowWindow(callsWindow);
}
CallModel *callModel = new CallModel(nullptr);
QSharedPointer<CallModel> callModel = QSharedPointer<CallModel>::create(nullptr);
qInfo() << QStringLiteral("Add call:") << callModel->getFullLocalAddress() << callModel->getFullPeerAddress();
App::getInstance()->getEngine()->setObjectOwnership(callModel, QQmlEngine::CppOwnership);
App::getInstance()->getEngine()->setObjectOwnership(callModel.get(), QQmlEngine::CppOwnership);
// This connection is (only) useful for `CallsListProxyModel`.
QObject::connect(callModel, &CallModel::isInConferenceChanged, this, [this, callModel](bool) {
QObject::connect(callModel.get(), &CallModel::isInConferenceChanged, this, [this, callModel](bool) {
int id = findCallIndex(mList, *callModel);
emit dataChanged(index(id, 0), index(id, 0));
});
int row = mList.count();
beginInsertRows(QModelIndex(), row, row);
mList << callModel;
endInsertRows();
add(callModel);
emit layoutChanged();
}
@ -582,9 +526,5 @@ void CallsListModel::removeCall (const shared_ptr<linphone::Call> &call) {
}
void CallsListModel::removeCallCb (CallModel *callModel) {
qInfo() << QStringLiteral("Removing call:") << callModel;
int index = mList.indexOf(callModel);
if (index == -1 || !removeRow(index))
qWarning() << QStringLiteral("Unable to remove call:") << callModel;
remove(callModel);
}

View file

@ -22,10 +22,10 @@
#define CALLS_LIST_MODEL_H_
#include <linphone++/linphone.hh>
#include <QAbstractListModel>
#include "components/call/CallModel.hpp"
#include "utils/LinphoneEnums.hpp"
#include "app/proxyModel/ProxyListModel.hpp"
// =============================================================================
@ -34,16 +34,12 @@ class CoreHandlers;
class ConferenceModel;
class ConferenceInfoModel;
class CallsListModel : public QAbstractListModel {
class CallsListModel : public ProxyListModel {
Q_OBJECT
public:
CallsListModel (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;
CallModel *findCallModelFromPeerAddress (const QString &peerAddress) const;
void askForTransfer (CallModel *callModel);
@ -79,8 +75,6 @@ signals:
void callMissed (CallModel *callModel);
private:
bool removeRow (int row, const QModelIndex &parent = QModelIndex());
bool removeRows (int row, int count, const QModelIndex &parent = QModelIndex()) override;
void handleCallStateChanged (const std::shared_ptr<linphone::Call> &call, linphone::Call::State state);
@ -89,7 +83,6 @@ private:
void removeCall (const std::shared_ptr<linphone::Call> &call);
void removeCallCb (CallModel *callModel);
QList<CallModel *> mList;
QList<std::shared_ptr<ConferenceModel>> mConferences;
std::shared_ptr<CoreHandlers> mCoreHandlers;

View file

@ -64,16 +64,6 @@ void Camera::resetWindowId() {
CoreManager::getInstance()->getCore()->setNativeVideoWindowId(NULL);
}
class SafeFramebuffer : public QQuickFramebufferObject::Renderer{
public:
SafeFramebuffer(){}
QOpenGLFramebufferObject *createFramebufferObject (const QSize &size) override{
return new QOpenGLFramebufferObject(size);
}
void render () override{}
void synchronize (QQuickFramebufferObject *item) override{}
};
QQuickFramebufferObject::Renderer *Camera::createRenderer () const {
QQuickFramebufferObject::Renderer * renderer = NULL;
if(mIsPreview){

View file

@ -30,20 +30,21 @@
ChatCallModel::ChatCallModel ( std::shared_ptr<linphone::CallLog> callLog, const bool& isStart, QObject * parent) : ChatEvent(ChatRoomModel::EntryType::CallEntry, parent) {
App::getInstance()->getEngine()->setObjectOwnership(this, QQmlEngine::CppOwnership);// Avoid QML to destroy it when passing by Q_INVOKABLE
mCallLog = callLog;
mIsStart = isStart;
if(isStart){
mTimestamp = QDateTime::fromMSecsSinceEpoch(callLog->getStartDate() * 1000);
setIsStart(true);
}else{
mTimestamp = QDateTime::fromMSecsSinceEpoch((callLog->getStartDate() + callLog->getDuration()) * 1000);
setIsStart(false);
}
mIsOutgoing = (mCallLog->getDir() == linphone::Call::Dir::Outgoing);
mStatus = (LinphoneEnums::fromLinphone(mCallLog->getStatus()));
}
ChatCallModel::~ChatCallModel(){
}
std::shared_ptr<ChatCallModel> ChatCallModel::create(std::shared_ptr<linphone::CallLog> callLog, const bool& isStart, QObject * parent){
auto model = std::make_shared<ChatCallModel>(callLog, isStart, parent);
QSharedPointer<ChatCallModel> ChatCallModel::create(std::shared_ptr<linphone::CallLog> callLog, const bool& isStart, QObject * parent){
auto model = QSharedPointer<ChatCallModel>::create(callLog, isStart, parent);
if(model ){
model->update();
model->mSelf = model;

View file

@ -31,7 +31,7 @@ class ChatCallModel : public ChatEvent {
Q_OBJECT
public:
static std::shared_ptr<ChatCallModel> create(std::shared_ptr<linphone::CallLog> chatLog, const bool& isStart, QObject * parent = nullptr);// Call it instead constructor
static QSharedPointer<ChatCallModel> create(std::shared_ptr<linphone::CallLog> chatLog, const bool& isStart, QObject * parent = nullptr);// Call it instead constructor
ChatCallModel (std::shared_ptr<linphone::CallLog> eventLog, const bool& isStart, QObject * parent = nullptr);
virtual ~ChatCallModel();
@ -62,8 +62,8 @@ signals:
private:
std::shared_ptr<linphone::CallLog> mCallLog;
std::weak_ptr<ChatCallModel> mSelf; // Used to pass to functions that need a shared_ptr
QWeakPointer<ChatCallModel> mSelf; // Used to pass to functions that need a shared_ptr
};
Q_DECLARE_METATYPE(std::shared_ptr<ChatCallModel>)
Q_DECLARE_METATYPE(QSharedPointer<ChatCallModel>)
Q_DECLARE_METATYPE(ChatCallModel*)
#endif

View file

@ -0,0 +1,60 @@
/*
* Copyright (c) 2022 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 "ChatMessageListener.hpp"
#include <QQmlApplicationEngine>
#include <algorithm>
#include "ChatMessageModel.hpp"
// =============================================================================
// =============================================================================
ChatMessageListener::ChatMessageListener(QObject* parent) : QObject(parent){
}
void ChatMessageListener::onFileTransferRecv(const std::shared_ptr<linphone::ChatMessage> & message, const std::shared_ptr<linphone::Content> & content, const std::shared_ptr<const linphone::Buffer> & buffer){
emit fileTransferRecv(message, content, buffer);
}
void ChatMessageListener::onFileTransferSendChunk(const std::shared_ptr<linphone::ChatMessage> & message, const std::shared_ptr<linphone::Content> & content, size_t offset, size_t size, const std::shared_ptr<linphone::Buffer> & buffer){
emit fileTransferSendChunk(message, content, offset, size, buffer);
}
std::shared_ptr<linphone::Buffer> ChatMessageListener::onFileTransferSend(const std::shared_ptr<linphone::ChatMessage> & message, const std::shared_ptr<linphone::Content> & content, size_t offset, size_t size) {
emit fileTransferSend(message, content, offset, size);
return nullptr;
}
void ChatMessageListener::onFileTransferProgressIndication (const std::shared_ptr<linphone::ChatMessage> &message, const std::shared_ptr<linphone::Content> & content, size_t offset, size_t total){
emit fileTransferProgressIndication(message, content, offset, total);
}
void ChatMessageListener::onMsgStateChanged (const std::shared_ptr<linphone::ChatMessage> &message, linphone::ChatMessage::State state){
emit msgStateChanged(message, state);
}
void ChatMessageListener::onParticipantImdnStateChanged(const std::shared_ptr<linphone::ChatMessage> & message, const std::shared_ptr<const linphone::ParticipantImdnState> & state){
emit participantImdnStateChanged(message, state);
}
void ChatMessageListener::onEphemeralMessageTimerStarted(const std::shared_ptr<linphone::ChatMessage> & message){
emit ephemeralMessageTimerStarted(message);
}
void ChatMessageListener::onEphemeralMessageDeleted(const std::shared_ptr<linphone::ChatMessage> & message){
emit ephemeralMessageDeleted(message);
}

View file

@ -0,0 +1,59 @@
/*
* 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_MESSAGE_LISTENER_H
#define CHAT_MESSAGE_LISTENER_H
#include "utils/LinphoneEnums.hpp"
#include <QDateTime>
// =============================================================================
class ChatMessageModel;
class ChatMessageListener : public QObject, public linphone::ChatMessageListener {
Q_OBJECT
public:
ChatMessageListener(QObject * parent = nullptr);
virtual ~ChatMessageListener(){}
virtual void onFileTransferRecv(const std::shared_ptr<linphone::ChatMessage> & message, const std::shared_ptr<linphone::Content> & content, const std::shared_ptr<const linphone::Buffer> & buffer) override;
virtual void onFileTransferSendChunk(const std::shared_ptr<linphone::ChatMessage> & message, const std::shared_ptr<linphone::Content> & content, size_t offset, size_t size, const std::shared_ptr<linphone::Buffer> & buffer) override;
virtual std::shared_ptr<linphone::Buffer> onFileTransferSend(const std::shared_ptr<linphone::ChatMessage> & message, const std::shared_ptr<linphone::Content> & content, size_t offset, size_t size) override;
virtual void onFileTransferProgressIndication (const std::shared_ptr<linphone::ChatMessage> &message, const std::shared_ptr<linphone::Content> &, size_t offset, size_t) override;
virtual void onMsgStateChanged (const std::shared_ptr<linphone::ChatMessage> &message, linphone::ChatMessage::State state) override;
virtual void onParticipantImdnStateChanged(const std::shared_ptr<linphone::ChatMessage> & message, const std::shared_ptr<const linphone::ParticipantImdnState> & state) override;
virtual void onEphemeralMessageTimerStarted(const std::shared_ptr<linphone::ChatMessage> & message) override;
virtual void onEphemeralMessageDeleted(const std::shared_ptr<linphone::ChatMessage> & message) override;
signals:
void fileTransferRecv(const std::shared_ptr<linphone::ChatMessage> & message, const std::shared_ptr<linphone::Content> & content, const std::shared_ptr<const linphone::Buffer> & buffer);
void fileTransferSendChunk(const std::shared_ptr<linphone::ChatMessage> & message, const std::shared_ptr<linphone::Content> & content, size_t offset, size_t size, const std::shared_ptr<linphone::Buffer> & buffer);
std::shared_ptr<linphone::Buffer> fileTransferSend (const std::shared_ptr<linphone::ChatMessage> &,const std::shared_ptr<linphone::Content> &,size_t,size_t);
void fileTransferProgressIndication (const std::shared_ptr<linphone::ChatMessage> &message, const std::shared_ptr<linphone::Content> &, size_t offset, size_t);
void msgStateChanged (const std::shared_ptr<linphone::ChatMessage> &message, linphone::ChatMessage::State state);
void participantImdnStateChanged(const std::shared_ptr<linphone::ChatMessage> & message, const std::shared_ptr<const linphone::ParticipantImdnState> & state);
void ephemeralMessageTimerStarted(const std::shared_ptr<linphone::ChatMessage> & message);
void ephemeralMessageDeleted(const std::shared_ptr<linphone::ChatMessage> & message);
};
Q_DECLARE_METATYPE(ChatMessageListener*)
#endif

View file

@ -34,6 +34,8 @@
#include <QUrlQuery>
#include <QImageReader>
#include "ChatMessageListener.hpp"
#include "app/App.hpp"
#include "app/paths/Paths.hpp"
#include "components/contact/ContactModel.hpp"
@ -52,53 +54,20 @@
#include "utils/Utils.hpp"
#include "utils/Constants.hpp"
void ChatMessageModel::connectTo(ChatMessageListener * listener){
connect(listener, &ChatMessageListener::fileTransferRecv, this, &ChatMessageModel::onFileTransferRecv);
connect(listener, &ChatMessageListener::fileTransferSendChunk, this, &ChatMessageModel::onFileTransferSendChunk);
connect(listener, &ChatMessageListener::fileTransferSend, this, &ChatMessageModel::onFileTransferSend);
connect(listener, &ChatMessageListener::fileTransferProgressIndication, this, &ChatMessageModel::onFileTransferProgressIndication);
connect(listener, &ChatMessageListener::msgStateChanged, this, &ChatMessageModel::onMsgStateChanged);
connect(listener, &ChatMessageListener::participantImdnStateChanged, this, &ChatMessageModel::onParticipantImdnStateChanged);
connect(listener, &ChatMessageListener::ephemeralMessageTimerStarted, this, &ChatMessageModel::onEphemeralMessageTimerStarted);
connect(listener, &ChatMessageListener::ephemeralMessageDeleted, this, &ChatMessageModel::onEphemeralMessageDeleted);
connect(listener, &ChatMessageListener::participantImdnStateChanged, this->getParticipantImdnStates().get(), &ParticipantImdnStateListModel::onParticipantImdnStateChanged);
}
// =============================================================================
// =============================================================================
ChatMessageListener::ChatMessageListener(ChatMessageModel * model, QObject* parent) : QObject(parent){
connect(this, &ChatMessageListener::fileTransferRecv, model, &ChatMessageModel::onFileTransferRecv);
connect(this, &ChatMessageListener::fileTransferSendChunk, model, &ChatMessageModel::onFileTransferSendChunk);
connect(this, &ChatMessageListener::fileTransferSend, model, &ChatMessageModel::onFileTransferSend);
connect(this, &ChatMessageListener::fileTransferProgressIndication, model, &ChatMessageModel::onFileTransferProgressIndication);
connect(this, &ChatMessageListener::msgStateChanged, model, &ChatMessageModel::onMsgStateChanged);
connect(this, &ChatMessageListener::participantImdnStateChanged, model, &ChatMessageModel::onParticipantImdnStateChanged);
connect(this, &ChatMessageListener::ephemeralMessageTimerStarted, model, &ChatMessageModel::onEphemeralMessageTimerStarted);
connect(this, &ChatMessageListener::ephemeralMessageDeleted, model, &ChatMessageModel::onEphemeralMessageDeleted);
connect(this, &ChatMessageListener::participantImdnStateChanged, model->getParticipantImdnStates().get(), &ParticipantImdnStateListModel::onParticipantImdnStateChanged);
}
void ChatMessageListener::onFileTransferRecv(const std::shared_ptr<linphone::ChatMessage> & message, const std::shared_ptr<linphone::Content> & content, const std::shared_ptr<const linphone::Buffer> & buffer){
emit fileTransferRecv(message, content, buffer);
}
void ChatMessageListener::onFileTransferSendChunk(const std::shared_ptr<linphone::ChatMessage> & message, const std::shared_ptr<linphone::Content> & content, size_t offset, size_t size, const std::shared_ptr<linphone::Buffer> & buffer){
emit fileTransferSendChunk(message, content, offset, size, buffer);
}
std::shared_ptr<linphone::Buffer> ChatMessageListener::onFileTransferSend(const std::shared_ptr<linphone::ChatMessage> & message, const std::shared_ptr<linphone::Content> & content, size_t offset, size_t size) {
emit fileTransferSend(message, content, offset, size);
return nullptr;
}
void ChatMessageListener::onFileTransferProgressIndication (const std::shared_ptr<linphone::ChatMessage> &message, const std::shared_ptr<linphone::Content> & content, size_t offset, size_t total){
emit fileTransferProgressIndication(message, content, offset, total);
}
void ChatMessageListener::onMsgStateChanged (const std::shared_ptr<linphone::ChatMessage> &message, linphone::ChatMessage::State state){
emit msgStateChanged(message, state);
}
void ChatMessageListener::onParticipantImdnStateChanged(const std::shared_ptr<linphone::ChatMessage> & message, const std::shared_ptr<const linphone::ParticipantImdnState> & state){
emit participantImdnStateChanged(message, state);
}
void ChatMessageListener::onEphemeralMessageTimerStarted(const std::shared_ptr<linphone::ChatMessage> & message){
emit ephemeralMessageTimerStarted(message);
}
void ChatMessageListener::onEphemeralMessageDeleted(const std::shared_ptr<linphone::ChatMessage> & message){
emit ephemeralMessageDeleted(message);
}
// =============================================================================
ChatMessageModel::AppDataManager::AppDataManager(const QString& appdata){
if(!appdata.isEmpty()){
for(QString pair : appdata.split(';')){
@ -121,8 +90,9 @@ QString ChatMessageModel::AppDataManager::toString(){
ChatMessageModel::ChatMessageModel ( std::shared_ptr<linphone::ChatMessage> chatMessage, QObject * parent) : ChatEvent(ChatRoomModel::EntryType::MessageEntry, parent) {
App::getInstance()->getEngine()->setObjectOwnership(this, QQmlEngine::CppOwnership);// Avoid QML to destroy it
if(chatMessage){
mParticipantImdnStateListModel = std::make_shared<ParticipantImdnStateListModel>(chatMessage);
mChatMessageListener = std::make_shared<ChatMessageListener>(this, parent);
mParticipantImdnStateListModel = QSharedPointer<ParticipantImdnStateListModel>::create(chatMessage);
mChatMessageListener = std::make_shared<ChatMessageListener>(parent);
connectTo(mChatMessageListener.get());
mChatMessage = chatMessage;
mChatMessage->addListener(mChatMessageListener);
if( mChatMessage->isReply()){
@ -130,7 +100,7 @@ ChatMessageModel::ChatMessageModel ( std::shared_ptr<linphone::ChatMessage> chat
if( replyMessage)// Reply message could be inexistant (for example : when locally deleted)
mReplyChatMessageModel = create(replyMessage, parent);
}
connect(this, &ChatMessageModel::remove, dynamic_cast<ChatRoomModel*>(parent), &ChatRoomModel::removeEntry);
connect(this, &ChatMessageModel::remove, qobject_cast<ChatRoomModel*>(parent), &ChatRoomModel::removeEntry);
std::list<std::shared_ptr<linphone::Content>> contents = chatMessage->getContents();
QString txt;
@ -144,22 +114,23 @@ ChatMessageModel::ChatMessageModel ( std::shared_ptr<linphone::ChatMessage> chat
mTimestamp = QDateTime::fromMSecsSinceEpoch(chatMessage->getTime() * 1000);
mContentListModel = std::make_shared<ContentListModel>(this);
mContentListModel = QSharedPointer<ContentListModel>::create(this);
}
ChatMessageModel::~ChatMessageModel(){
if(mChatMessage)
mChatMessage->removeListener(mChatMessageListener);
}
std::shared_ptr<ChatMessageModel> ChatMessageModel::create(std::shared_ptr<linphone::ChatMessage> chatMessage, QObject * parent){
auto model = std::make_shared<ChatMessageModel>(chatMessage, parent);
QSharedPointer<ChatMessageModel> ChatMessageModel::create(std::shared_ptr<linphone::ChatMessage> chatMessage, QObject * parent){
auto model = QSharedPointer<ChatMessageModel>::create(chatMessage, parent);
return model;
}
std::shared_ptr<linphone::ChatMessage> ChatMessageModel::getChatMessage(){
return mChatMessage;
}
std::shared_ptr<ContentModel> ChatMessageModel::getContentModel(std::shared_ptr<linphone::Content> content){
QSharedPointer<ContentModel> ChatMessageModel::getContentModel(std::shared_ptr<linphone::Content> content){
return mContentListModel->getContentModel(content);
}
@ -189,7 +160,7 @@ QString ChatMessageModel::getToSipAddress() const{
}
ContactModel * ChatMessageModel::getContactModel() const{
return mChatMessage ? CoreManager::getInstance()->getContactsListModel()->findContactModelFromSipAddress(Utils::coreStringToAppString(mChatMessage->getFromAddress()->asString())) : nullptr;
return mChatMessage ? CoreManager::getInstance()->getContactsListModel()->findContactModelFromSipAddress(Utils::coreStringToAppString(mChatMessage->getFromAddress()->asString())).get() : nullptr;
}
bool ChatMessageModel::isEphemeral() const{
@ -219,7 +190,7 @@ ParticipantImdnStateProxyModel * ChatMessageModel::getProxyImdnStates(){
return proxy;
}
std::shared_ptr<ParticipantImdnStateListModel> ChatMessageModel::getParticipantImdnStates() const{
QSharedPointer<ParticipantImdnStateListModel> ChatMessageModel::getParticipantImdnStates() const{
return mParticipantImdnStateListModel;
}
@ -227,7 +198,7 @@ ContentProxyModel * ChatMessageModel::getContentsProxy(){
return new ContentProxyModel(this);
}
std::shared_ptr<ContentListModel> ChatMessageModel::getContents() const{
QSharedPointer<ContentListModel> ChatMessageModel::getContents() const{
return mContentListModel;
}
@ -320,7 +291,7 @@ void ChatMessageModel::onFileTransferProgressIndication (const std::shared_ptr<l
if (total == offset && mChatMessage && !mChatMessage->isOutgoing()) {
mContentListModel->downloaded();
bool allAreDownloaded = true;
for(auto content : mContentListModel->getContents())
for(auto content : mContentListModel->getSharedList<ContentModel>())
allAreDownloaded &= content->mWasDownloaded;
setWasDownloaded(allAreDownloaded);
App::getInstance()->getNotifier()->notifyReceivedFileMessage(message, content);

View file

@ -44,41 +44,17 @@ public:
#include "components/participant-imdn/ParticipantImdnStateListModel.hpp"
class ChatMessageModel;
class ChatMessageListener;
class ParticipantImdnStateProxyModel;
class ParticipantImdnStateListModel;
class ContentModel;
class ContentListModel;
class ContentProxyModel;
class ChatMessageListener : public QObject, public linphone::ChatMessageListener {
Q_OBJECT
public:
ChatMessageListener(ChatMessageModel * model, QObject * parent = nullptr);
virtual ~ChatMessageListener(){}
virtual void onFileTransferRecv(const std::shared_ptr<linphone::ChatMessage> & message, const std::shared_ptr<linphone::Content> & content, const std::shared_ptr<const linphone::Buffer> & buffer) override;
virtual void onFileTransferSendChunk(const std::shared_ptr<linphone::ChatMessage> & message, const std::shared_ptr<linphone::Content> & content, size_t offset, size_t size, const std::shared_ptr<linphone::Buffer> & buffer) override;
virtual std::shared_ptr<linphone::Buffer> onFileTransferSend(const std::shared_ptr<linphone::ChatMessage> & message, const std::shared_ptr<linphone::Content> & content, size_t offset, size_t size) override;
virtual void onFileTransferProgressIndication (const std::shared_ptr<linphone::ChatMessage> &message, const std::shared_ptr<linphone::Content> &, size_t offset, size_t) override;
virtual void onMsgStateChanged (const std::shared_ptr<linphone::ChatMessage> &message, linphone::ChatMessage::State state) override;
virtual void onParticipantImdnStateChanged(const std::shared_ptr<linphone::ChatMessage> & message, const std::shared_ptr<const linphone::ParticipantImdnState> & state) override;
virtual void onEphemeralMessageTimerStarted(const std::shared_ptr<linphone::ChatMessage> & message) override;
virtual void onEphemeralMessageDeleted(const std::shared_ptr<linphone::ChatMessage> & message) override;
signals:
void fileTransferRecv(const std::shared_ptr<linphone::ChatMessage> & message, const std::shared_ptr<linphone::Content> & content, const std::shared_ptr<const linphone::Buffer> & buffer);
void fileTransferSendChunk(const std::shared_ptr<linphone::ChatMessage> & message, const std::shared_ptr<linphone::Content> & content, size_t offset, size_t size, const std::shared_ptr<linphone::Buffer> & buffer);
std::shared_ptr<linphone::Buffer> fileTransferSend (const std::shared_ptr<linphone::ChatMessage> &,const std::shared_ptr<linphone::Content> &,size_t,size_t);
void fileTransferProgressIndication (const std::shared_ptr<linphone::ChatMessage> &message, const std::shared_ptr<linphone::Content> &, size_t offset, size_t);
void msgStateChanged (const std::shared_ptr<linphone::ChatMessage> &message, linphone::ChatMessage::State state);
void participantImdnStateChanged(const std::shared_ptr<linphone::ChatMessage> & message, const std::shared_ptr<const linphone::ParticipantImdnState> & state);
void ephemeralMessageTimerStarted(const std::shared_ptr<linphone::ChatMessage> & message);
void ephemeralMessageDeleted(const std::shared_ptr<linphone::ChatMessage> & message);
};
class ChatMessageModel : public ChatEvent {
Q_OBJECT
public:
static std::shared_ptr<ChatMessageModel> create(std::shared_ptr<linphone::ChatMessage> chatMessage, QObject * parent = nullptr);// Call it instead constructor
static QSharedPointer<ChatMessageModel> create(std::shared_ptr<linphone::ChatMessage> chatMessage, QObject * parent = nullptr);// Call it instead constructor
ChatMessageModel (std::shared_ptr<linphone::ChatMessage> chatMessage, QObject * parent = nullptr);
virtual ~ChatMessageModel();
@ -119,7 +95,7 @@ public:
std::shared_ptr<linphone::ChatMessage> getChatMessage();
std::shared_ptr<ContentModel> getContentModel(std::shared_ptr<linphone::Content> content);
QSharedPointer<ContentModel> getContentModel(std::shared_ptr<linphone::Content> content);
//----------------------------------------------------------------------------
@ -135,9 +111,9 @@ public:
LinphoneEnums::ChatMessageState getState() const;
bool isOutgoing() const;
Q_INVOKABLE ParticipantImdnStateProxyModel * getProxyImdnStates();
std::shared_ptr<ParticipantImdnStateListModel> getParticipantImdnStates() const;
QSharedPointer<ParticipantImdnStateListModel> getParticipantImdnStates() const;
Q_INVOKABLE ContentProxyModel * getContentsProxy();
std::shared_ptr<ContentListModel> getContents() const;
QSharedPointer<ContentListModel> getContents() const;
bool isReply() const;
ChatMessageModel * getReplyChatMessageModel() const;
@ -184,15 +160,16 @@ signals:
private:
std::shared_ptr<ContentModel> mFileTransfertContent;
void connectTo(ChatMessageListener * listener);
std::shared_ptr<linphone::ChatMessage> mChatMessage;
std::shared_ptr<ParticipantImdnStateListModel> mParticipantImdnStateListModel;
std::shared_ptr<ChatMessageListener> mChatMessageListener;
std::shared_ptr<ContentListModel> mContentListModel;
std::shared_ptr<ChatMessageListener> mChatMessageListener; // This is passed to linpĥone object and must be in shared_ptr
std::shared_ptr<ChatMessageModel> mReplyChatMessageModel;
QSharedPointer<ContentListModel> mContentListModel;
QSharedPointer<ContentModel> mFileTransfertContent;
QSharedPointer<ParticipantImdnStateListModel> mParticipantImdnStateListModel;
QSharedPointer<ChatMessageModel> mReplyChatMessageModel;
};
Q_DECLARE_METATYPE(ChatMessageModel*)
Q_DECLARE_METATYPE(std::shared_ptr<ChatMessageModel>)
Q_DECLARE_METATYPE(ChatMessageListener*)
Q_DECLARE_METATYPE(QSharedPointer<ChatMessageModel>)
#endif

View file

@ -31,6 +31,7 @@
ChatNoticeModel::ChatNoticeModel ( std::shared_ptr<linphone::EventLog> eventLog, QObject * parent) : ChatEvent(ChatRoomModel::EntryType::NoticeEntry, parent) {
App::getInstance()->getEngine()->setObjectOwnership(this, QQmlEngine::CppOwnership);// Avoid QML to destroy it when passing by Q_INVOKABLE
mEventLog = eventLog;
setEventLogType(LinphoneEnums::fromLinphone(mEventLog->getType()));
mTimestamp = QDateTime::fromMSecsSinceEpoch(eventLog->getCreationTime() * 1000);
}
@ -45,8 +46,8 @@ ChatNoticeModel::ChatNoticeModel ( NoticeType noticeType, const QDateTime& times
ChatNoticeModel::~ChatNoticeModel(){
}
std::shared_ptr<ChatNoticeModel> ChatNoticeModel::create(std::shared_ptr<linphone::EventLog> eventLog, QObject * parent){
auto model = std::make_shared<ChatNoticeModel>(eventLog, parent);
QSharedPointer<ChatNoticeModel> ChatNoticeModel::create(std::shared_ptr<linphone::EventLog> eventLog, QObject * parent){
auto model = QSharedPointer<ChatNoticeModel>::create(eventLog, parent);
if(model && model->update()){
model->mSelf = model;
return model;
@ -54,8 +55,8 @@ std::shared_ptr<ChatNoticeModel> ChatNoticeModel::create(std::shared_ptr<linphon
return nullptr;
}
std::shared_ptr<ChatNoticeModel> ChatNoticeModel::create(NoticeType noticeType, const QDateTime& timestamp, const QString& txt, QObject * parent){
auto model = std::make_shared<ChatNoticeModel>(noticeType, timestamp, txt, parent);
QSharedPointer<ChatNoticeModel> ChatNoticeModel::create(NoticeType noticeType, const QDateTime& timestamp, const QString& txt, QObject * parent){
auto model = QSharedPointer<ChatNoticeModel>::create(noticeType, timestamp, txt, parent);
if(model ){
model->mSelf = model;
return model;

View file

@ -38,8 +38,8 @@ public:
};
Q_ENUM(NoticeType);
static std::shared_ptr<ChatNoticeModel> create(std::shared_ptr<linphone::EventLog> eventLog, QObject * parent = nullptr);// Call it instead constructor
static std::shared_ptr<ChatNoticeModel> create(NoticeType noticeType, const QDateTime& timestamp,const QString& txt, QObject * parent = nullptr);
static QSharedPointer<ChatNoticeModel> create(std::shared_ptr<linphone::EventLog> eventLog, QObject * parent = nullptr);// Call it instead constructor
static QSharedPointer<ChatNoticeModel> create(NoticeType noticeType, const QDateTime& timestamp,const QString& txt, QObject * parent = nullptr);
ChatNoticeModel (std::shared_ptr<linphone::EventLog> eventLog, QObject * parent = nullptr);
ChatNoticeModel (NoticeType noticeType, const QDateTime& timestamp, const QString& txt, QObject * parent = nullptr);
virtual ~ChatNoticeModel();
@ -70,10 +70,10 @@ signals:
private:
std::shared_ptr<linphone::EventLog> mEventLog;
std::weak_ptr<ChatNoticeModel> mSelf; // Used to pass to functions that need a shared_ptr
QWeakPointer<ChatNoticeModel> mSelf; // Used to pass to functions that need a shared_ptr
};
Q_DECLARE_METATYPE(std::shared_ptr<ChatNoticeModel>)
Q_DECLARE_METATYPE(QSharedPointer<ChatNoticeModel>)
Q_DECLARE_METATYPE(ChatNoticeModel*)
#endif

View file

@ -1,96 +0,0 @@
/*
* 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;
}
// -----------------------------------------------------------------------------

View file

@ -0,0 +1,108 @@
/*
* Copyright (c) 2022 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 "ChatRoomListener.hpp"
#include "../calls/CallsListModel.hpp"
#include <QDebug>
#include <qqmlapplicationengine.h>
#include <QTimer>
ChatRoomListener::ChatRoomListener(QObject * parent): QObject(parent){
}
//---------------------------------------------------------------------------------------------------
void ChatRoomListener::onIsComposingReceived(const std::shared_ptr<linphone::ChatRoom> & chatRoom, const std::shared_ptr<const linphone::Address> & remoteAddress, bool isComposing){
emit isComposingReceived(chatRoom, remoteAddress, isComposing);
}
void ChatRoomListener::onMessageReceived(const std::shared_ptr<linphone::ChatRoom> & chatRoom, const std::shared_ptr<linphone::ChatMessage> & message){
emit messageReceived(chatRoom, message);
}
void ChatRoomListener::onNewEvent(const std::shared_ptr<linphone::ChatRoom> & chatRoom, const std::shared_ptr<const linphone::EventLog> & eventLog){
emit newEvent(chatRoom, eventLog);
}
void ChatRoomListener::onChatMessageReceived(const std::shared_ptr<linphone::ChatRoom> & chatRoom, const std::shared_ptr<const linphone::EventLog> & eventLog){
emit chatMessageReceived(chatRoom, eventLog);
}
void ChatRoomListener::onChatMessageSending(const std::shared_ptr<linphone::ChatRoom> & chatRoom, const std::shared_ptr<const linphone::EventLog> & eventLog){
emit chatMessageSending(chatRoom, eventLog);
}
void ChatRoomListener::onChatMessageSent(const std::shared_ptr<linphone::ChatRoom> & chatRoom, const std::shared_ptr<const linphone::EventLog> & eventLog){
emit chatMessageSent(chatRoom, eventLog);
}
void ChatRoomListener::onParticipantAdded(const std::shared_ptr<linphone::ChatRoom> & chatRoom, const std::shared_ptr<const linphone::EventLog> & eventLog){
emit participantAdded(chatRoom, eventLog);
}
void ChatRoomListener::onParticipantRemoved(const std::shared_ptr<linphone::ChatRoom> & chatRoom, const std::shared_ptr<const linphone::EventLog> & eventLog){
emit participantRemoved(chatRoom, eventLog);
}
void ChatRoomListener::onParticipantAdminStatusChanged(const std::shared_ptr<linphone::ChatRoom> & chatRoom, const std::shared_ptr<const linphone::EventLog> & eventLog){
emit participantAdminStatusChanged(chatRoom, eventLog);
}
void ChatRoomListener::onStateChanged(const std::shared_ptr<linphone::ChatRoom> & chatRoom, linphone::ChatRoom::State newState){
emit stateChanged(chatRoom, newState);
}
void ChatRoomListener::onSecurityEvent(const std::shared_ptr<linphone::ChatRoom> & chatRoom, const std::shared_ptr<const linphone::EventLog> & eventLog){
emit securityEvent(chatRoom, eventLog);
}
void ChatRoomListener::onSubjectChanged(const std::shared_ptr<linphone::ChatRoom> & chatRoom, const std::shared_ptr<const linphone::EventLog> & eventLog){
emit subjectChanged(chatRoom, eventLog);
}
void ChatRoomListener::onUndecryptableMessageReceived(const std::shared_ptr<linphone::ChatRoom> & chatRoom, const std::shared_ptr<linphone::ChatMessage> & message){
emit undecryptableMessageReceived(chatRoom, message);
}
void ChatRoomListener::onParticipantDeviceAdded(const std::shared_ptr<linphone::ChatRoom> & chatRoom, const std::shared_ptr<const linphone::EventLog> & eventLog){
emit participantDeviceAdded(chatRoom, eventLog);
}
void ChatRoomListener::onParticipantDeviceRemoved(const std::shared_ptr<linphone::ChatRoom> & chatRoom, const std::shared_ptr<const linphone::EventLog> & eventLog){
emit participantDeviceRemoved(chatRoom, eventLog);
}
void ChatRoomListener::onConferenceJoined(const std::shared_ptr<linphone::ChatRoom> & chatRoom, const std::shared_ptr<const linphone::EventLog> & eventLog){
emit conferenceJoined(chatRoom, eventLog);
}
void ChatRoomListener::onConferenceLeft(const std::shared_ptr<linphone::ChatRoom> & chatRoom, const std::shared_ptr<const linphone::EventLog> & eventLog){
emit conferenceLeft(chatRoom, eventLog);
}
void ChatRoomListener::onEphemeralEvent(const std::shared_ptr<linphone::ChatRoom> & chatRoom, const std::shared_ptr<const linphone::EventLog> & eventLog){
emit ephemeralEvent(chatRoom, eventLog);
}
void ChatRoomListener::onEphemeralMessageTimerStarted(const std::shared_ptr<linphone::ChatRoom> & chatRoom, const std::shared_ptr<const linphone::EventLog> & eventLog){
emit ephemeralMessageTimerStarted(chatRoom, eventLog);
}
void ChatRoomListener::onEphemeralMessageDeleted(const std::shared_ptr<linphone::ChatRoom> & chatRoom, const std::shared_ptr<const linphone::EventLog> & eventLog){
emit ephemeralMessageDeleted(chatRoom, eventLog);
}
void ChatRoomListener::onConferenceAddressGeneration(const std::shared_ptr<linphone::ChatRoom> & chatRoom){
emit conferenceAddressGeneration(chatRoom);
}
void ChatRoomListener::onParticipantRegistrationSubscriptionRequested(const std::shared_ptr<linphone::ChatRoom> & chatRoom, const std::shared_ptr<const linphone::Address> & participantAddress){
emit participantRegistrationSubscriptionRequested(chatRoom, participantAddress);
}
void ChatRoomListener::onParticipantRegistrationUnsubscriptionRequested(const std::shared_ptr<linphone::ChatRoom> & chatRoom, const std::shared_ptr<const linphone::Address> & participantAddress){
emit participantRegistrationUnsubscriptionRequested(chatRoom, participantAddress);
}
void ChatRoomListener::onChatMessageShouldBeStored(const std::shared_ptr<linphone::ChatRoom> & chatRoom, const std::shared_ptr<linphone::ChatMessage> & message){
emit chatMessageShouldBeStored(chatRoom, message);
}
void ChatRoomListener::onChatMessageParticipantImdnStateChanged(const std::shared_ptr<linphone::ChatRoom> & chatRoom, const std::shared_ptr<linphone::ChatMessage> & message, const std::shared_ptr<const linphone::ParticipantImdnState> & state){
emit chatMessageParticipantImdnStateChanged(chatRoom, message, state);
}

View file

@ -0,0 +1,93 @@
/*
* Copyright (c) 2022 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 CHATROOM_LISTENER_H_
#define CHATROOM_LISTENER_H_
// =============================================================================
#include <QObject>
#include <linphone++/chat_room.hh>
#include <linphone++/chat_room_listener.hh>
class ChatRoomModel;
class TimelineModel;
class ChatRoomListener : public QObject, public linphone::ChatRoomListener {
Q_OBJECT
public:
ChatRoomListener(QObject * parent = nullptr);
virtual ~ChatRoomListener(){}
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:
void isComposingReceived(const std::shared_ptr<linphone::ChatRoom> & chatRoom, const std::shared_ptr<const linphone::Address> & remoteAddress, bool isComposing);
void messageReceived(const std::shared_ptr<linphone::ChatRoom> & chatRoom, const std::shared_ptr<linphone::ChatMessage> & message);
void newEvent(const std::shared_ptr<linphone::ChatRoom> & chatRoom, const std::shared_ptr<const linphone::EventLog> & eventLog);
void chatMessageReceived(const std::shared_ptr<linphone::ChatRoom> & chatRoom, const std::shared_ptr<const linphone::EventLog> & eventLog);
void chatMessageSending(const std::shared_ptr<linphone::ChatRoom> & chatRoom, const std::shared_ptr<const linphone::EventLog> & eventLog);
void chatMessageSent(const std::shared_ptr<linphone::ChatRoom> & chatRoom, const std::shared_ptr<const linphone::EventLog> & eventLog);
void participantAdded(const std::shared_ptr<linphone::ChatRoom> & chatRoom, const std::shared_ptr<const linphone::EventLog> & eventLog);
void participantRemoved(const std::shared_ptr<linphone::ChatRoom> & chatRoom, const std::shared_ptr<const linphone::EventLog> & eventLog);
void participantAdminStatusChanged(const std::shared_ptr<linphone::ChatRoom> & chatRoom, const std::shared_ptr<const linphone::EventLog> & eventLog);
void stateChanged(const std::shared_ptr<linphone::ChatRoom> & chatRoom, linphone::ChatRoom::State newState);
void securityEvent(const std::shared_ptr<linphone::ChatRoom> & chatRoom, const std::shared_ptr<const linphone::EventLog> & eventLog);
void subjectChanged(const std::shared_ptr<linphone::ChatRoom> & chatRoom, const std::shared_ptr<const linphone::EventLog> & eventLog);
void undecryptableMessageReceived(const std::shared_ptr<linphone::ChatRoom> & chatRoom, const std::shared_ptr<linphone::ChatMessage> & message);
void participantDeviceAdded(const std::shared_ptr<linphone::ChatRoom> & chatRoom, const std::shared_ptr<const linphone::EventLog> & eventLog);
void participantDeviceRemoved(const std::shared_ptr<linphone::ChatRoom> & chatRoom, const std::shared_ptr<const linphone::EventLog> & eventLog);
void conferenceJoined(const std::shared_ptr<linphone::ChatRoom> & chatRoom, const std::shared_ptr<const linphone::EventLog> & eventLog);
void conferenceLeft(const std::shared_ptr<linphone::ChatRoom> & chatRoom, const std::shared_ptr<const linphone::EventLog> & eventLog);
void ephemeralEvent(const std::shared_ptr<linphone::ChatRoom> & chatRoom, const std::shared_ptr<const linphone::EventLog> & eventLog);
void ephemeralMessageTimerStarted(const std::shared_ptr<linphone::ChatRoom> & chatRoom, const std::shared_ptr<const linphone::EventLog> & eventLog);
void ephemeralMessageDeleted(const std::shared_ptr<linphone::ChatRoom> & chatRoom, const std::shared_ptr<const linphone::EventLog> & eventLog);
void conferenceAddressGeneration(const std::shared_ptr<linphone::ChatRoom> & chatRoom);
void participantRegistrationSubscriptionRequested(const std::shared_ptr<linphone::ChatRoom> & chatRoom, const std::shared_ptr<const linphone::Address> & participantAddress);
void participantRegistrationUnsubscriptionRequested(const std::shared_ptr<linphone::ChatRoom> & chatRoom, const std::shared_ptr<const linphone::Address> & participantAddress);
void chatMessageShouldBeStored(const std::shared_ptr<linphone::ChatRoom> & chatRoom, const std::shared_ptr<linphone::ChatMessage> & message);
void chatMessageParticipantImdnStateChanged(const std::shared_ptr<linphone::ChatRoom> & chatRoom, const std::shared_ptr<linphone::ChatMessage> & message, const std::shared_ptr<const linphone::ParticipantImdnState> & state);
};
#endif

View file

@ -1,5 +1,5 @@
/*
* Copyright (c) 2010-2020 Belledonne Communications SARL.
* Copyright (c) 2010-2022 Belledonne Communications SARL.
*
* This file is part of linphone-desktop
* (see https://www.linphone.org).
@ -34,6 +34,8 @@
#include <QImageReader>
#include <qqmlapplicationengine.h>
#include "ChatRoomListener.hpp"
#include "app/App.hpp"
#include "app/paths/Paths.hpp"
#include "app/providers/ThumbnailProvider.hpp"
@ -74,114 +76,37 @@ using namespace std;
// -----------------------------------------------------------------------------
ChatRoomModelListener::ChatRoomModelListener(ChatRoomModel * model, QObject* parent) : QObject(parent){
connect(this, &ChatRoomModelListener::isComposingReceived, model, &ChatRoomModel::onIsComposingReceived);
connect(this, &ChatRoomModelListener::messageReceived, model, &ChatRoomModel::onMessageReceived);
connect(this, &ChatRoomModelListener::newEvent, model, &ChatRoomModel::onNewEvent);
connect(this, &ChatRoomModelListener::chatMessageReceived, model, &ChatRoomModel::onChatMessageReceived);
connect(this, &ChatRoomModelListener::chatMessageSending, model, &ChatRoomModel::onChatMessageSending);
connect(this, &ChatRoomModelListener::chatMessageSent, model, &ChatRoomModel::onChatMessageSent);
connect(this, &ChatRoomModelListener::participantAdded, model, &ChatRoomModel::onParticipantAdded);
connect(this, &ChatRoomModelListener::participantRemoved, model, &ChatRoomModel::onParticipantRemoved);
connect(this, &ChatRoomModelListener::participantAdminStatusChanged, model, &ChatRoomModel::onParticipantAdminStatusChanged);
connect(this, &ChatRoomModelListener::stateChanged, model, &ChatRoomModel::onStateChanged);
connect(this, &ChatRoomModelListener::securityEvent, model, &ChatRoomModel::onSecurityEvent);
connect(this, &ChatRoomModelListener::subjectChanged, model, &ChatRoomModel::onSubjectChanged);
connect(this, &ChatRoomModelListener::undecryptableMessageReceived, model, &ChatRoomModel::onUndecryptableMessageReceived);
connect(this, &ChatRoomModelListener::participantDeviceAdded, model, &ChatRoomModel::onParticipantDeviceAdded);
connect(this, &ChatRoomModelListener::participantDeviceRemoved, model, &ChatRoomModel::onParticipantDeviceRemoved);
connect(this, &ChatRoomModelListener::conferenceJoined, model, &ChatRoomModel::onConferenceJoined);
connect(this, &ChatRoomModelListener::conferenceLeft, model, &ChatRoomModel::onConferenceLeft);
connect(this, &ChatRoomModelListener::ephemeralEvent, model, &ChatRoomModel::onEphemeralEvent);
connect(this, &ChatRoomModelListener::ephemeralMessageTimerStarted, model, &ChatRoomModel::onEphemeralMessageTimerStarted);
connect(this, &ChatRoomModelListener::ephemeralMessageDeleted, model, &ChatRoomModel::onEphemeralMessageDeleted);
connect(this, &ChatRoomModelListener::conferenceAddressGeneration, model, &ChatRoomModel::onConferenceAddressGeneration);
connect(this, &ChatRoomModelListener::participantRegistrationSubscriptionRequested, model, &ChatRoomModel::onParticipantRegistrationSubscriptionRequested);
connect(this, &ChatRoomModelListener::participantRegistrationUnsubscriptionRequested, model, &ChatRoomModel::onParticipantRegistrationUnsubscriptionRequested);
connect(this, &ChatRoomModelListener::chatMessageShouldBeStored, model, &ChatRoomModel::onChatMessageShouldBeStored);
connect(this, &ChatRoomModelListener::chatMessageParticipantImdnStateChanged, model, &ChatRoomModel::onChatMessageParticipantImdnStateChanged);
}
void ChatRoomModelListener::onIsComposingReceived(const std::shared_ptr<linphone::ChatRoom> & chatRoom, const std::shared_ptr<const linphone::Address> & remoteAddress, bool isComposing){
emit isComposingReceived(chatRoom, remoteAddress, isComposing);
}
void ChatRoomModelListener::onMessageReceived(const std::shared_ptr<linphone::ChatRoom> & chatRoom, const std::shared_ptr<linphone::ChatMessage> & message){
emit messageReceived(chatRoom, message);
}
void ChatRoomModelListener::onNewEvent(const std::shared_ptr<linphone::ChatRoom> & chatRoom, const std::shared_ptr<const linphone::EventLog> & eventLog){
emit newEvent(chatRoom, eventLog);
}
void ChatRoomModelListener::onChatMessageReceived(const std::shared_ptr<linphone::ChatRoom> & chatRoom, const std::shared_ptr<const linphone::EventLog> & eventLog){
emit chatMessageReceived(chatRoom, eventLog);
}
void ChatRoomModelListener::onChatMessageSending(const std::shared_ptr<linphone::ChatRoom> & chatRoom, const std::shared_ptr<const linphone::EventLog> & eventLog){
emit chatMessageSending(chatRoom, eventLog);
}
void ChatRoomModelListener::onChatMessageSent(const std::shared_ptr<linphone::ChatRoom> & chatRoom, const std::shared_ptr<const linphone::EventLog> & eventLog){
emit chatMessageSent(chatRoom, eventLog);
}
void ChatRoomModelListener::onParticipantAdded(const std::shared_ptr<linphone::ChatRoom> & chatRoom, const std::shared_ptr<const linphone::EventLog> & eventLog){
emit participantAdded(chatRoom, eventLog);
}
void ChatRoomModelListener::onParticipantRemoved(const std::shared_ptr<linphone::ChatRoom> & chatRoom, const std::shared_ptr<const linphone::EventLog> & eventLog){
emit participantRemoved(chatRoom, eventLog);
}
void ChatRoomModelListener::onParticipantAdminStatusChanged(const std::shared_ptr<linphone::ChatRoom> & chatRoom, const std::shared_ptr<const linphone::EventLog> & eventLog){
emit participantAdminStatusChanged(chatRoom, eventLog);
}
void ChatRoomModelListener::onStateChanged(const std::shared_ptr<linphone::ChatRoom> & chatRoom, linphone::ChatRoom::State newState){
emit stateChanged(chatRoom, newState);
}
void ChatRoomModelListener::onSecurityEvent(const std::shared_ptr<linphone::ChatRoom> & chatRoom, const std::shared_ptr<const linphone::EventLog> & eventLog){
emit securityEvent(chatRoom, eventLog);
}
void ChatRoomModelListener::onSubjectChanged(const std::shared_ptr<linphone::ChatRoom> & chatRoom, const std::shared_ptr<const linphone::EventLog> & eventLog){
emit subjectChanged(chatRoom, eventLog);
}
void ChatRoomModelListener::onUndecryptableMessageReceived(const std::shared_ptr<linphone::ChatRoom> & chatRoom, const std::shared_ptr<linphone::ChatMessage> & message){
emit undecryptableMessageReceived(chatRoom, message);
}
void ChatRoomModelListener::onParticipantDeviceAdded(const std::shared_ptr<linphone::ChatRoom> & chatRoom, const std::shared_ptr<const linphone::EventLog> & eventLog){
emit participantDeviceAdded(chatRoom, eventLog);
}
void ChatRoomModelListener::onParticipantDeviceRemoved(const std::shared_ptr<linphone::ChatRoom> & chatRoom, const std::shared_ptr<const linphone::EventLog> & eventLog){
emit participantDeviceRemoved(chatRoom, eventLog);
}
void ChatRoomModelListener::onConferenceJoined(const std::shared_ptr<linphone::ChatRoom> & chatRoom, const std::shared_ptr<const linphone::EventLog> & eventLog){
emit conferenceJoined(chatRoom, eventLog);
}
void ChatRoomModelListener::onConferenceLeft(const std::shared_ptr<linphone::ChatRoom> & chatRoom, const std::shared_ptr<const linphone::EventLog> & eventLog){
emit conferenceLeft(chatRoom, eventLog);
}
void ChatRoomModelListener::onEphemeralEvent(const std::shared_ptr<linphone::ChatRoom> & chatRoom, const std::shared_ptr<const linphone::EventLog> & eventLog){
emit ephemeralEvent(chatRoom, eventLog);
}
void ChatRoomModelListener::onEphemeralMessageTimerStarted(const std::shared_ptr<linphone::ChatRoom> & chatRoom, const std::shared_ptr<const linphone::EventLog> & eventLog){
emit ephemeralMessageTimerStarted(chatRoom, eventLog);
}
void ChatRoomModelListener::onEphemeralMessageDeleted(const std::shared_ptr<linphone::ChatRoom> & chatRoom, const std::shared_ptr<const linphone::EventLog> & eventLog){
emit ephemeralMessageDeleted(chatRoom, eventLog);
}
void ChatRoomModelListener::onConferenceAddressGeneration(const std::shared_ptr<linphone::ChatRoom> & chatRoom){
emit conferenceAddressGeneration(chatRoom);
}
void ChatRoomModelListener::onParticipantRegistrationSubscriptionRequested(const std::shared_ptr<linphone::ChatRoom> & chatRoom, const std::shared_ptr<const linphone::Address> & participantAddress){
emit participantRegistrationSubscriptionRequested(chatRoom, participantAddress);
}
void ChatRoomModelListener::onParticipantRegistrationUnsubscriptionRequested(const std::shared_ptr<linphone::ChatRoom> & chatRoom, const std::shared_ptr<const linphone::Address> & participantAddress){
emit participantRegistrationUnsubscriptionRequested(chatRoom, participantAddress);
}
void ChatRoomModelListener::onChatMessageShouldBeStored(const std::shared_ptr<linphone::ChatRoom> & chatRoom, const std::shared_ptr<linphone::ChatMessage> & message){
emit chatMessageShouldBeStored(chatRoom, message);
}
void ChatRoomModelListener::onChatMessageParticipantImdnStateChanged(const std::shared_ptr<linphone::ChatRoom> & chatRoom, const std::shared_ptr<linphone::ChatMessage> & message, const std::shared_ptr<const linphone::ParticipantImdnState> & state){
emit chatMessageParticipantImdnStateChanged(chatRoom, message, state);
void ChatRoomModel::connectTo(ChatRoomListener * listener){
connect(listener, &ChatRoomListener::isComposingReceived, this, &ChatRoomModel::onIsComposingReceived);
connect(listener, &ChatRoomListener::messageReceived, this, &ChatRoomModel::onMessageReceived);
connect(listener, &ChatRoomListener::newEvent, this, &ChatRoomModel::onNewEvent);
connect(listener, &ChatRoomListener::chatMessageReceived, this, &ChatRoomModel::onChatMessageReceived);
connect(listener, &ChatRoomListener::chatMessageSending, this, &ChatRoomModel::onChatMessageSending);
connect(listener, &ChatRoomListener::chatMessageSent, this, &ChatRoomModel::onChatMessageSent);
connect(listener, &ChatRoomListener::participantAdded, this, &ChatRoomModel::onParticipantAdded);
connect(listener, &ChatRoomListener::participantRemoved, this, &ChatRoomModel::onParticipantRemoved);
connect(listener, &ChatRoomListener::participantAdminStatusChanged, this, &ChatRoomModel::onParticipantAdminStatusChanged);
connect(listener, &ChatRoomListener::stateChanged, this, &ChatRoomModel::onStateChanged);
connect(listener, &ChatRoomListener::securityEvent, this, &ChatRoomModel::onSecurityEvent);
connect(listener, &ChatRoomListener::subjectChanged, this, &ChatRoomModel::onSubjectChanged);
connect(listener, &ChatRoomListener::undecryptableMessageReceived, this, &ChatRoomModel::onUndecryptableMessageReceived);
connect(listener, &ChatRoomListener::participantDeviceAdded, this, &ChatRoomModel::onParticipantDeviceAdded);
connect(listener, &ChatRoomListener::participantDeviceRemoved, this, &ChatRoomModel::onParticipantDeviceRemoved);
connect(listener, &ChatRoomListener::conferenceJoined, this, &ChatRoomModel::onConferenceJoined);
connect(listener, &ChatRoomListener::conferenceLeft, this, &ChatRoomModel::onConferenceLeft);
connect(listener, &ChatRoomListener::ephemeralEvent, this, &ChatRoomModel::onEphemeralEvent);
connect(listener, &ChatRoomListener::ephemeralMessageTimerStarted, this, &ChatRoomModel::onEphemeralMessageTimerStarted);
connect(listener, &ChatRoomListener::ephemeralMessageDeleted, this, &ChatRoomModel::onEphemeralMessageDeleted);
connect(listener, &ChatRoomListener::conferenceAddressGeneration, this, &ChatRoomModel::onConferenceAddressGeneration);
connect(listener, &ChatRoomListener::participantRegistrationSubscriptionRequested, this, &ChatRoomModel::onParticipantRegistrationSubscriptionRequested);
connect(listener, &ChatRoomListener::participantRegistrationUnsubscriptionRequested, this, &ChatRoomModel::onParticipantRegistrationUnsubscriptionRequested);
connect(listener, &ChatRoomListener::chatMessageShouldBeStored, this, &ChatRoomModel::onChatMessageShouldBeStored);
connect(listener, &ChatRoomListener::chatMessageParticipantImdnStateChanged, this, &ChatRoomModel::onChatMessageParticipantImdnStateChanged);
}
// -----------------------------------------------------------------------------
std::shared_ptr<ChatRoomModel> ChatRoomModel::create(std::shared_ptr<linphone::ChatRoom> chatRoom){
std::shared_ptr<ChatRoomModel> model = std::make_shared<ChatRoomModel>(chatRoom);
QSharedPointer<ChatRoomModel> ChatRoomModel::create(std::shared_ptr<linphone::ChatRoom> chatRoom){
QSharedPointer<ChatRoomModel> model = QSharedPointer<ChatRoomModel>::create(chatRoom);
if(model){
model->mSelf = model;
//chatRoom->addListener(model);
@ -190,17 +115,18 @@ std::shared_ptr<ChatRoomModel> ChatRoomModel::create(std::shared_ptr<linphone::C
return nullptr;
}
ChatRoomModel::ChatRoomModel (std::shared_ptr<linphone::ChatRoom> chatRoom, QObject * parent) : QAbstractListModel(parent){
ChatRoomModel::ChatRoomModel (std::shared_ptr<linphone::ChatRoom> chatRoom, QObject * parent) : ProxyListModel(parent){
App::getInstance()->getEngine()->setObjectOwnership(this, QQmlEngine::CppOwnership);// Avoid QML to destroy it when passing by Q_INVOKABLE
CoreManager *coreManager = CoreManager::getInstance();
mCoreHandlers = coreManager->getHandlers();
mChatRoom = chatRoom;
mChatRoomModelListener = std::make_shared<ChatRoomModelListener>(this, parent);
mChatRoom->addListener(mChatRoomModelListener);
mChatRoomListener = std::make_shared<ChatRoomListener>(parent);
connectTo(mChatRoomListener.get());
mChatRoom->addListener(mChatRoomListener);
// Get messages.
mEntries.clear();
mList.clear();
setUnreadMessagesCount(mChatRoom->getUnreadMessagesCount());
setMissedCallsCount(0);
@ -227,13 +153,13 @@ ChatRoomModel::ChatRoomModel (std::shared_ptr<linphone::ChatRoom> chatRoom, QObj
//QObject::connect(this, &ChatRoomModel::messageCountReset, coreManager, &CoreManager::eventCountChanged );
if(mChatRoom){
mParticipantListModel = std::make_shared<ParticipantListModel>(this);
mParticipantListModel = QSharedPointer<ParticipantListModel>::create(this);
connect(mParticipantListModel.get(), &ParticipantListModel::participantsChanged, this, &ChatRoomModel::fullPeerAddressChanged);
auto participants = mChatRoom->getParticipants();
for(auto participant : participants){
auto contact = CoreManager::getInstance()->getContactsListModel()->findContactModelFromSipAddress(Utils::coreStringToAppString((participant)->getAddress()->asString()));
if(contact) {
connect(contact, &ContactModel::contactUpdated, this, &ChatRoomModel::fullPeerAddressChanged);
connect(contact.get(), &ContactModel::contactUpdated, this, &ChatRoomModel::fullPeerAddressChanged);
}
}
// Get Max updatetime from chat room and last call event
@ -252,7 +178,7 @@ ChatRoomModel::ChatRoomModel (std::shared_ptr<linphone::ChatRoom> chatRoom, QObj
ChatRoomModel::~ChatRoomModel () {
mParticipantListModel = nullptr;
if(mChatRoom ){
mChatRoom->removeListener(mChatRoomModelListener);
mChatRoom->removeListener(mChatRoomListener);
if(mDeleteChatRoom){
mDeleteChatRoom = false;
if(CoreManager::getInstance()->getCore() ){
@ -269,6 +195,7 @@ ChatRoomModel::~ChatRoomModel () {
mChatRoom = nullptr;
}
QHash<int, QByteArray> ChatRoomModel::roleNames () const {
QHash<int, QByteArray> roles;
roles[Roles::ChatEntry] = "$chatEntry";
@ -276,57 +203,38 @@ QHash<int, QByteArray> ChatRoomModel::roleNames () const {
return roles;
}
int ChatRoomModel::rowCount (const QModelIndex &) const {
return mEntries.count();
}
QVariant ChatRoomModel::data (const QModelIndex &index, int role) const {
int row = index.row();
if (!index.isValid() || row < 0 || row >= mEntries.count())
if (!index.isValid() || row < 0 || row >= mList.count())
return QVariant();
switch (role) {
case Roles::ChatEntry: {
ChatEvent * ce = mEntries[row].get();
if( ce->mType == EntryType::MessageEntry)
return QVariant::fromValue(dynamic_cast<ChatMessageModel*>(ce));
else if( ce->mType == EntryType::NoticeEntry)
return QVariant::fromValue(dynamic_cast<ChatNoticeModel*>(ce));
else if( ce->mType == EntryType::CallEntry)
return QVariant::fromValue(dynamic_cast<ChatCallModel*>(ce));
else
return QVariant();
}
case Roles::SectionDate:
return QVariant::fromValue(mEntries[row]->getTimestamp().date());
case Roles::ChatEntry: return QVariant::fromValue(mList[row].get());
case Roles::SectionDate: return QVariant::fromValue(mList[row].objectCast<ChatEvent>()->getTimestamp().date());
}
return QVariant();
}
bool ChatRoomModel::removeRow (int row, const QModelIndex &) {
return removeRows(row, 1);
}
bool ChatRoomModel::removeRows (int row, int count, const QModelIndex &parent) {
int limit = row + count - 1;
if (row < 0 || count < 0 || limit >= mEntries.count())
if (row < 0 || count < 0 || limit >= mList.count())
return false;
beginRemoveRows(parent, row, limit);
for (int i = 0; i < count; ++i) {
mEntries[row]->deleteEvent();
mEntries.removeAt(row);
mList[row].objectCast<ChatEvent>()->deleteEvent();
mList.removeAt(row);
}
endRemoveRows();
if (mEntries.count() == 0)
if (mList.count() == 0)
emit allEntriesRemoved(mSelf.lock());
else if (limit == mEntries.count())
else if (limit == mList.count())
emit lastEntryRemoved();
emit focused();// Removing rows is like having focus. Don't wait asynchronous events.
return true;
@ -338,7 +246,7 @@ void ChatRoomModel::removeAllEntries () {
auto core = CoreManager::getInstance()->getCore();
bool standardChatEnabled = CoreManager::getInstance()->getSettingsModel()->getStandardChatEnabled();
beginResetModel();
mEntries.clear();
mList.clear();
mChatRoom->deleteHistory();
if( isOneToOne() && // Remove calls only if chat room is one-one and not secure (if available)
( !standardChatEnabled || !isSecure())
@ -356,15 +264,7 @@ void ChatRoomModel::removeAllEntries () {
}
void ChatRoomModel::removeEntry(ChatEvent* entry){
auto it = mEntries.begin();
while(it != mEntries.end() && (*it).get() != entry)
++it;
if( it != mEntries.end() ){
int row = it - mEntries.begin();
//mEntries.indexOf(entry);
if(row >=0)
removeRow(row);
}
remove(entry);
}
void ChatRoomModel::emitFullPeerAddressChanged(){
@ -608,9 +508,10 @@ void ChatRoomModel::updateLastUpdateTime(){
if( mChatRoom ){
QDateTime lastDateTime = QDateTime::fromMSecsSinceEpoch(mChatRoom->getLastUpdateTime()*1000);
QDateTime lastCallTime = lastDateTime;
for(auto e : mEntries){
if(e->mType == CallEntry && e->getTimestamp() > lastCallTime)
lastCallTime = e->getTimestamp();
for(auto e : mList){
auto chatEvent = e.objectCast<ChatEvent>();
if(chatEvent->mType == CallEntry && chatEvent->getTimestamp() > lastCallTime)
lastCallTime = chatEvent->getTimestamp();
}
setLastUpdateTime(lastCallTime);
}
@ -727,7 +628,7 @@ void ChatRoomModel::sendMessage (const QString &message) {
_messages.back()->addContent(content);
}
}
auto fileContents = CoreManager::getInstance()->getChatModel()->getContentListModel()->getContents();
auto fileContents = CoreManager::getInstance()->getChatModel()->getContentListModel()->getSharedList<ContentModel>();
for(auto content : fileContents){
if(isBasicChatRoom && _messages.back()->getContents().size() > 0) // Basic chat rooms don't support multipart
_messages.push_back(mChatRoom->createEmptyMessage());
@ -813,7 +714,7 @@ public:
ChatRoomModel::EntryType mType;
std::shared_ptr<linphone::Object> mObject;
static void getLimitedSelection(QList<std::shared_ptr<ChatEvent> > *resultEntries, QList<EntrySorterHelper>& entries, const int& minEntries, ChatRoomModel * chatRoomModel) {// Sort and return a selection with at least 'minEntries'
static void getLimitedSelection(QList<QSharedPointer<ChatEvent> > *resultEntries, QList<EntrySorterHelper>& entries, const int& minEntries, ChatRoomModel * chatRoomModel) {// Sort and return a selection with at least 'minEntries'
// Sort list
std::sort(entries.begin(), entries.end(), [](const EntrySorterHelper& a, const EntrySorterHelper& b) {
return a.mTime < b.mTime;
@ -884,7 +785,7 @@ void ChatRoomModel::updateNewMessageNotice(const int& count){
}
mUnreadMessageNotice = ChatNoticeModel::create(ChatNoticeModel::NoticeType::NoticeUnreadMessages, lastUnreadMessage, QString::number(count));
beginInsertRows(QModelIndex(), 0, 0);
mEntries.prepend(mUnreadMessageNotice);
mList.prepend(mUnreadMessageNotice);
endInsertRows();
qDebug() << "New message notice timestamp to :" << lastUnreadMessage.toString();
}
@ -897,17 +798,19 @@ int ChatRoomModel::loadTillMessage(ChatMessageModel * message){
qDebug() << "Load history till message : " << message->getChatMessage()->getMessageId().c_str();
auto linphoneMessage = message->getChatMessage();
// First find on current list
auto entry = std::find_if(mEntries.begin(), mEntries.end(), [linphoneMessage](const std::shared_ptr<ChatEvent>& entry ){
return entry->mType == ChatRoomModel::EntryType::MessageEntry && dynamic_cast<ChatMessageModel*>(entry.get())->getChatMessage() == linphoneMessage;
auto entry = std::find_if(mList.begin(), mList.end(), [linphoneMessage](const QSharedPointer<QObject>& entry ){
auto chatEventEntry = entry.objectCast<ChatEvent>();
return chatEventEntry->mType == ChatRoomModel::EntryType::MessageEntry && chatEventEntry.objectCast<ChatMessageModel>()->getChatMessage() == linphoneMessage;
});
// if not find, load more entries and find it in new entries.
if( entry == mEntries.end()){
if( entry == mList.end()){
int newEntries = loadMoreEntries();
while( newEntries > 0){// no more new entries
int entryCount = 0;
entry = mEntries.begin();
entry = mList.begin();
auto chatEventEntry = entry->objectCast<ChatEvent>();
while(entryCount < newEntries &&
((*entry)->mType != ChatRoomModel::EntryType::MessageEntry || dynamic_cast<ChatMessageModel*>(entry->get())->getChatMessage() != linphoneMessage)
(chatEventEntry->mType != ChatRoomModel::EntryType::MessageEntry || chatEventEntry.objectCast<ChatMessageModel>()->getChatMessage() != linphoneMessage)
){
++entryCount;
++entry;
@ -919,7 +822,7 @@ int ChatRoomModel::loadTillMessage(ChatMessageModel * message){
newEntries = loadMoreEntries();// continue
}
}else{
int entryCount = entry - mEntries.begin();
int entryCount = entry - mList.begin();
qDebug() << "Find message at " << entryCount;
return entryCount;
}
@ -928,19 +831,13 @@ int ChatRoomModel::loadTillMessage(ChatMessageModel * message){
return -1;
}
void ChatRoomModel::resetEntries(){
beginResetModel();
mEntries.clear();
endResetModel();
}
void ChatRoomModel::initEntries(){
if( mEntries.size() > mLastEntriesStep)
resetEntries();
if(mEntries.size() == 0) {
if( mList.size() > mLastEntriesStep)
resetData();
if(mList.size() == 0) {
qDebug() << "Internal Entries : Init";
// On call : reinitialize all entries. This allow to free up memory
QList<std::shared_ptr<ChatEvent> > entries;
QList<QSharedPointer<ChatEvent> > entries;
QList<EntrySorterHelper> prepareEntries;
// Get chat messages
for (auto &message : mChatRoom->getHistory(mFirstLastEntriesStep)) {
@ -966,9 +863,10 @@ void ChatRoomModel::initEntries(){
qDebug() << "Internal Entries : Built";
if(entries.size() >0){
beginInsertRows(QModelIndex(),0, entries.size()-1);
mEntries = entries;
updateNewMessageNotice(mChatRoom->getUnreadMessagesCount());
for(auto e : entries)
mList.push_back(e);
endInsertRows();
updateNewMessageNotice(mChatRoom->getUnreadMessagesCount());
}
qDebug() << "Internal Entries : End";
}
@ -987,16 +885,17 @@ int ChatRoomModel::loadMoreEntries(){
int currentRowCount = rowCount();
int newEntries = 0;
do{
QList<std::shared_ptr<ChatEvent> > entries;
QList<QSharedPointer<ChatEvent> > entries;
QList<EntrySorterHelper> prepareEntries;
// Get current event count for each type
QVector<int> entriesCounts;
entriesCounts.resize(3);
for(auto itEntries = mEntries.begin() ; itEntries != mEntries.end() ; ++itEntries){
if( (*itEntries)->mType == MessageEntry)
for(auto itEntries = mList.begin() ; itEntries != mList.end() ; ++itEntries){
auto chatEvent = itEntries->objectCast<ChatEvent>();
if( chatEvent->mType == MessageEntry)
++entriesCounts[0];
else if( (*itEntries)->mType == CallEntry){
if(dynamic_cast<ChatCallModel*>((*itEntries).get())->mIsStart)
else if( chatEvent->mType == CallEntry){
if(chatEvent.objectCast<ChatCallModel>()->mIsStart)
++entriesCounts[1];
} else
++entriesCounts[2];
@ -1004,10 +903,10 @@ int ChatRoomModel::loadMoreEntries(){
// Messages
for (auto &message : mChatRoom->getHistoryRange(entriesCounts[0], entriesCounts[0]+mLastEntriesStep)){
auto itEntries = mEntries.begin();
auto itEntries = mList.begin();
bool haveEntry = false;
while(!haveEntry && itEntries != mEntries.end()){
auto entry = dynamic_cast<ChatMessageModel*>(itEntries->get());
while(!haveEntry && itEntries != mList.end()){
auto entry = itEntries->objectCast<ChatMessageModel>();
haveEntry = (entry && entry->getChatMessage() == message);
++itEntries;
}
@ -1036,10 +935,10 @@ int ChatRoomModel::loadMoreEntries(){
}
// Notices
for (auto &eventLog : mChatRoom->getHistoryRangeEvents(entriesCounts[2], entriesCounts[2]+mLastEntriesStep)){
auto itEntries = mEntries.begin();
auto itEntries = mList.begin();
bool haveEntry = false;
while(!haveEntry && itEntries != mEntries.end()){
auto entry = dynamic_cast<ChatNoticeModel*>(itEntries->get());
while(!haveEntry && itEntries != mList.end()){
auto entry = itEntries->objectCast<ChatNoticeModel>();
haveEntry = (entry && entry->getEventLog() && entry->getEventLog() == eventLog);
++itEntries;
}
@ -1050,7 +949,7 @@ int ChatRoomModel::loadMoreEntries(){
if(entries.size() >0){
beginInsertRows(QModelIndex(), 0, entries.size()-1);
for(auto entry : entries)
mEntries.prepend(entry);
mList.prepend(entry);
endInsertRows();
//emit layoutChanged();
updateLastUpdateTime();
@ -1080,20 +979,16 @@ void ChatRoomModel::callEnded(std::shared_ptr<linphone::Call> call){
void ChatRoomModel::insertCall (const std::shared_ptr<linphone::CallLog> &callLog) {
if(mIsInitialized){
std::shared_ptr<ChatCallModel> model = ChatCallModel::create(callLog, true, this);
QSharedPointer<ChatCallModel> model = ChatCallModel::create(callLog, true, this);
if(model){
int row = mEntries.count();
int row = mList.count();
beginInsertRows(QModelIndex(), row, row);
mEntries << model;
mList << model;
endInsertRows();
if (callLog->getStatus() == linphone::Call::Status::Success) {
model = ChatCallModel::create(callLog, false, this);
if(model){
int row = mEntries.count();
beginInsertRows(QModelIndex(), row, row);
mEntries << model;
endInsertRows();
}
if(model)
add(model);
}
updateLastUpdateTime();
}
@ -1102,9 +997,9 @@ void ChatRoomModel::insertCall (const std::shared_ptr<linphone::CallLog> &callLo
void ChatRoomModel::insertCalls (const QList<std::shared_ptr<linphone::CallLog> > &calls) {
if(mIsInitialized){
QList<std::shared_ptr<ChatEvent> > entries;
QList<QSharedPointer<QObject> > entries;
for(auto callLog : calls) {
std::shared_ptr<ChatCallModel> model = ChatCallModel::create(callLog, true, this);
QSharedPointer<ChatCallModel> model = ChatCallModel::create(callLog, true, this);
if(model){
entries << model;
if (callLog->getStatus() == linphone::Call::Status::Success) {
@ -1116,10 +1011,7 @@ void ChatRoomModel::insertCalls (const QList<std::shared_ptr<linphone::CallLog>
}
}
if(entries.size() > 0){
beginInsertRows(QModelIndex(), 0, entries.size()-1);
entries << mEntries;
mEntries = entries;
endInsertRows();
prepend(entries);
emit layoutChanged();
}
}
@ -1127,30 +1019,24 @@ void ChatRoomModel::insertCalls (const QList<std::shared_ptr<linphone::CallLog>
void ChatRoomModel::insertMessageAtEnd (const std::shared_ptr<linphone::ChatMessage> &message) {
if(mIsInitialized){
std::shared_ptr<ChatMessageModel> model = ChatMessageModel::create(message, this);
QSharedPointer<ChatMessageModel> model = ChatMessageModel::create(message, this);
if(model){
setUnreadMessagesCount(mChatRoom->getUnreadMessagesCount());
int row = mEntries.count();
beginInsertRows(QModelIndex(), row, row);
mEntries << model;
endInsertRows();
add(model);
}
}
}
void ChatRoomModel::insertMessages (const QList<std::shared_ptr<linphone::ChatMessage> > &messages) {
if(mIsInitialized){
QList<std::shared_ptr<ChatEvent> > entries;
QList<QSharedPointer<QObject> > entries;
for(auto message : messages) {
std::shared_ptr<ChatMessageModel> model = ChatMessageModel::create(message, this);
QSharedPointer<ChatMessageModel> model = ChatMessageModel::create(message, this);
if(model)
entries << model;
}
if(entries.size() > 0){
beginInsertRows(QModelIndex(), 0, entries.size()-1);
entries << mEntries;
mEntries = entries;
endInsertRows();
prepend(entries);
setUnreadMessagesCount(mChatRoom->getUnreadMessagesCount());
emit layoutChanged();
}
@ -1159,32 +1045,23 @@ void ChatRoomModel::insertMessages (const QList<std::shared_ptr<linphone::ChatMe
void ChatRoomModel::insertNotice (const std::shared_ptr<linphone::EventLog> &eventLog) {
if(mIsInitialized){
std::shared_ptr<ChatNoticeModel> model = ChatNoticeModel::create(eventLog, this);
if(model){
int row = mEntries.count();
beginInsertRows(QModelIndex(), row, row);
mEntries << model;
endInsertRows();
}
QSharedPointer<ChatNoticeModel> model = ChatNoticeModel::create(eventLog, this);
if(model)
add(model);
}
}
void ChatRoomModel::insertNotices (const QList<std::shared_ptr<linphone::EventLog>> &eventLogs) {
if(mIsInitialized){
QList<std::shared_ptr<ChatEvent> > entries;
QList<QSharedPointer<QObject> > entries;
for(auto eventLog : eventLogs) {
std::shared_ptr<ChatNoticeModel> model = ChatNoticeModel::create(eventLog, this);
QSharedPointer<ChatNoticeModel> model = ChatNoticeModel::create(eventLog, this);
if(model) {
entries << model;
}
}
if(entries.size() > 0){
beginInsertRows(QModelIndex(), 0, entries.size()-1);
entries << mEntries;
mEntries = entries;
endInsertRows();
prepend(entries);
emit layoutChanged();
}
}

View file

@ -22,7 +22,7 @@
#define CHAT_ROOM_MODEL_H_
#include <linphone++/linphone.hh>
#include <QAbstractListModel>
#include "app/proxyModel/ProxyListModel.hpp"
#include <QDateTime>
// =============================================================================
@ -37,70 +37,9 @@ class ContactModel;
class ChatRoomModel;
class ChatMessageModel;
class ChatNoticeModel;
class ChatRoomListener;
class ChatRoomModelListener : public QObject, public linphone::ChatRoomListener {
Q_OBJECT
public:
ChatRoomModelListener(ChatRoomModel * model, QObject * parent = nullptr);
virtual ~ChatRoomModelListener(){}
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:
void isComposingReceived(const std::shared_ptr<linphone::ChatRoom> & chatRoom, const std::shared_ptr<const linphone::Address> & remoteAddress, bool isComposing);
void messageReceived(const std::shared_ptr<linphone::ChatRoom> & chatRoom, const std::shared_ptr<linphone::ChatMessage> & message);
void newEvent(const std::shared_ptr<linphone::ChatRoom> & chatRoom, const std::shared_ptr<const linphone::EventLog> & eventLog);
void chatMessageReceived(const std::shared_ptr<linphone::ChatRoom> & chatRoom, const std::shared_ptr<const linphone::EventLog> & eventLog);
void chatMessageSending(const std::shared_ptr<linphone::ChatRoom> & chatRoom, const std::shared_ptr<const linphone::EventLog> & eventLog);
void chatMessageSent(const std::shared_ptr<linphone::ChatRoom> & chatRoom, const std::shared_ptr<const linphone::EventLog> & eventLog);
void participantAdded(const std::shared_ptr<linphone::ChatRoom> & chatRoom, const std::shared_ptr<const linphone::EventLog> & eventLog);
void participantRemoved(const std::shared_ptr<linphone::ChatRoom> & chatRoom, const std::shared_ptr<const linphone::EventLog> & eventLog);
void participantAdminStatusChanged(const std::shared_ptr<linphone::ChatRoom> & chatRoom, const std::shared_ptr<const linphone::EventLog> & eventLog);
void stateChanged(const std::shared_ptr<linphone::ChatRoom> & chatRoom, linphone::ChatRoom::State newState);
void securityEvent(const std::shared_ptr<linphone::ChatRoom> & chatRoom, const std::shared_ptr<const linphone::EventLog> & eventLog);
void subjectChanged(const std::shared_ptr<linphone::ChatRoom> & chatRoom, const std::shared_ptr<const linphone::EventLog> & eventLog);
void undecryptableMessageReceived(const std::shared_ptr<linphone::ChatRoom> & chatRoom, const std::shared_ptr<linphone::ChatMessage> & message);
void participantDeviceAdded(const std::shared_ptr<linphone::ChatRoom> & chatRoom, const std::shared_ptr<const linphone::EventLog> & eventLog);
void participantDeviceRemoved(const std::shared_ptr<linphone::ChatRoom> & chatRoom, const std::shared_ptr<const linphone::EventLog> & eventLog);
void conferenceJoined(const std::shared_ptr<linphone::ChatRoom> & chatRoom, const std::shared_ptr<const linphone::EventLog> & eventLog);
void conferenceLeft(const std::shared_ptr<linphone::ChatRoom> & chatRoom, const std::shared_ptr<const linphone::EventLog> & eventLog);
void ephemeralEvent(const std::shared_ptr<linphone::ChatRoom> & chatRoom, const std::shared_ptr<const linphone::EventLog> & eventLog);
void ephemeralMessageTimerStarted(const std::shared_ptr<linphone::ChatRoom> & chatRoom, const std::shared_ptr<const linphone::EventLog> & eventLog);
void ephemeralMessageDeleted(const std::shared_ptr<linphone::ChatRoom> & chatRoom, const std::shared_ptr<const linphone::EventLog> & eventLog);
void conferenceAddressGeneration(const std::shared_ptr<linphone::ChatRoom> & chatRoom);
void participantRegistrationSubscriptionRequested(const std::shared_ptr<linphone::ChatRoom> & chatRoom, const std::shared_ptr<const linphone::Address> & participantAddress);
void participantRegistrationUnsubscriptionRequested(const std::shared_ptr<linphone::ChatRoom> & chatRoom, const std::shared_ptr<const linphone::Address> & participantAddress);
void chatMessageShouldBeStored(const std::shared_ptr<linphone::ChatRoom> & chatRoom, const std::shared_ptr<linphone::ChatMessage> & message);
void chatMessageParticipantImdnStateChanged(const std::shared_ptr<linphone::ChatRoom> & chatRoom, const std::shared_ptr<linphone::ChatMessage> & message, const std::shared_ptr<const linphone::ParticipantImdnState> & state);
};
class ChatRoomModel : public QAbstractListModel {
class MessageHandlers;
class ChatRoomModel : public ProxyListModel {
Q_OBJECT
@ -154,16 +93,13 @@ public:
Q_PROPERTY(bool entriesLoading READ isEntriesLoading WRITE setEntriesLoading NOTIFY entriesLoadingChanged)
static std::shared_ptr<ChatRoomModel> create(std::shared_ptr<linphone::ChatRoom> chatRoom);
static QSharedPointer<ChatRoomModel> create(std::shared_ptr<linphone::ChatRoom> chatRoom);
ChatRoomModel (std::shared_ptr<linphone::ChatRoom> chatRoom, QObject * parent = nullptr);
~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;
void removeAllEntries ();
@ -231,7 +167,6 @@ public:
Q_INVOKABLE void forwardMessage(ChatMessageModel * model);
void compose ();
Q_INVOKABLE void resetMessageCount ();
Q_INVOKABLE void resetEntries();
void initEntries();
Q_INVOKABLE int loadMoreEntries(); // return new entries count
void callEnded(std::shared_ptr<linphone::Call> call);
@ -297,7 +232,7 @@ signals:
void entriesLoadingChanged(const bool& loading);
void moreEntriesLoaded(const int& count);
void allEntriesRemoved (std::shared_ptr<ChatRoomModel> model);
void allEntriesRemoved (QSharedPointer<ChatRoomModel> model);
void lastEntryRemoved ();
void messageSent (const std::shared_ptr<linphone::ChatMessage> &message);
@ -343,6 +278,8 @@ signals:
void conferenceLeft(const std::shared_ptr<linphone::ChatRoom> & chatRoom, const std::shared_ptr<const linphone::EventLog> & eventLog);
private:
void connectTo(ChatRoomListener * listener);
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
@ -350,21 +287,19 @@ private:
//void handleIsComposingChanged (const std::shared_ptr<linphone::ChatRoom> &chatRoom);
//void handleMessageReceived (const std::shared_ptr<linphone::ChatMessage> &message);
//bool mIsRemoteComposing = false;
std::shared_ptr<ChatNoticeModel> mUnreadMessageNotice;
QList<std::shared_ptr<ChatEvent> > mEntries;
std::shared_ptr<ParticipantListModel> mParticipantListModel;
std::shared_ptr<CoreHandlers> mCoreHandlers;
std::shared_ptr<MessageHandlers> mMessageHandlers;
QMap<std::shared_ptr<const linphone::Address>, QString> mComposers; // Store all addresses that are composing with its username
std::shared_ptr<linphone::ChatRoom> mChatRoom;
std::shared_ptr<ChatRoomModelListener> mChatRoomModelListener;
std::shared_ptr<ChatRoomListener> mChatRoomListener; // This need to be a shared_ptr because of adding it to linphone
std::shared_ptr<CoreHandlers> mCoreHandlers; // This need to be a shared_ptr because of adding it to linphone
std::shared_ptr<ChatMessageModel> mReplyModel;
QMap<std::shared_ptr<const linphone::Address>, QString> mComposers; // Store all addresses that are composing with its username
std::weak_ptr<ChatRoomModel> mSelf;
QSharedPointer<ParticipantListModel> mParticipantListModel;
QSharedPointer<ChatMessageModel> mReplyModel;
QSharedPointer<ChatNoticeModel> mUnreadMessageNotice;
QWeakPointer<ChatRoomModel> mSelf;
};
Q_DECLARE_METATYPE(std::shared_ptr<ChatRoomModel>)
Q_DECLARE_METATYPE(QSharedPointer<ChatRoomModel>)
#endif // CHAT_ROOM_MODEL_H_

View file

@ -146,7 +146,7 @@ private:
QString mFilterText;
std::shared_ptr<ChatRoomModel> mChatRoomModel;
QSharedPointer<ChatRoomModel> mChatRoomModel;
static constexpr int EntriesChunkSize = 50;
};

View file

@ -40,10 +40,10 @@
ChatModel::ChatModel(QObject * parent ) : QObject(parent){
App::getInstance()->getEngine()->setObjectOwnership(this, QQmlEngine::CppOwnership);// Avoid QML to destroy it when passing by Q_INVOKABLE
mContents = std::make_shared<ContentListModel>(nullptr);
mContents = QSharedPointer<ContentListModel>::create(nullptr);
}
std::shared_ptr<ContentListModel> ChatModel::getContentListModel() const {
QSharedPointer<ContentListModel> ChatModel::getContentListModel() const {
return mContents;
}

View file

@ -28,6 +28,8 @@
#include <QObject>
#include <QDateTime>
#include <QString>
#include <QSharedPointer>
class ContentListModel;
class ChatModel : public QObject{
@ -36,13 +38,13 @@ public:
ChatModel(QObject * parent = nullptr);
// Getters
std::shared_ptr<ContentListModel> getContentListModel() const;
QSharedPointer<ContentListModel> getContentListModel() const;
// Tools
Q_INVOKABLE void clear();
private:
std::shared_ptr<ContentListModel> mContents;
QSharedPointer<ContentListModel> mContents;
};
#endif

View file

@ -35,7 +35,7 @@
// =============================================================================
ConferenceInfoListModel::ConferenceInfoListModel (QObject *parent) : QAbstractListModel(parent) {
ConferenceInfoListModel::ConferenceInfoListModel (QObject *parent) : ProxyListModel(parent) {
//auto conferenceInfos = CoreManager::getInstance()->getCore()->getConferenceInformationList();
//for(auto conferenceInfo : conferenceInfos){
// auto conferenceInfoModel = ConferenceInfoModel::create( conferenceInfo );
@ -44,60 +44,8 @@ ConferenceInfoListModel::ConferenceInfoListModel (QObject *parent) : QAbstractLi
// }
}
int ConferenceInfoListModel::rowCount (const QModelIndex &) const {
return mList.size();
}
QHash<int, QByteArray> ConferenceInfoListModel::roleNames () const {
QHash<int, QByteArray> roles;
roles[Qt::DisplayRole] = "$conferenceInfo";
return roles;
}
QVariant ConferenceInfoListModel::data (const QModelIndex &index, int role) const {
int row = index.row();
if (!index.isValid() || row < 0 || row >= mList.size())
return QVariant();
auto it = mList.begin() + row;
if (role == Qt::DisplayRole)
return QVariant::fromValue(it->get());
return QVariant();
}
ConferenceInfoModel* ConferenceInfoListModel::getAt(const int& index) const {
return mList[index].get();
}
// -----------------------------------------------------------------------------
void ConferenceInfoListModel::add(std::shared_ptr<ConferenceInfoModel> conferenceInfoModel){
int row = mList.size();
beginInsertRows(QModelIndex(), row,row);
mList << conferenceInfoModel;
endInsertRows();
}
// Should not be called as item that need to be removed are usually a cell, not a row
bool ConferenceInfoListModel::removeRow (int row, const QModelIndex &parent) {
return removeRows(row, 1, parent);
}
bool ConferenceInfoListModel::removeRows (int row, int count, const QModelIndex &parent) {
/*
int limit = row + count - 1;
if (row < 0 || count < 0 || limit >= mMappedList.count())
return false;
beginRemoveRows(parent, row, limit);
for (int i = 0; i < count; ++i)
mMappedList.takeAt(row)->deleteLater();
endRemoveRows();
*/
return true;
return ProxyListModel::getAt(index).objectCast<ConferenceInfoModel>().get();
}
// -----------------------------------------------------------------------------

View file

@ -1,5 +1,5 @@
/*
* Copyright (c) 2021 Belledonne Communications SARL.
* Copyright (c) 2021-2022 Belledonne Communications SARL.
*
* This file is part of linphone-desktop
* (see https://www.linphone.org).
@ -22,33 +22,20 @@
#define _CONFERENCE_INFO_LIST_MODEL_H_
#include <linphone++/linphone.hh>
#include <QAbstractListModel>
#include "app/proxyModel/ProxyListModel.hpp"
#include <QDate>
// =============================================================================
class ConferenceInfoModel;
class ConferenceInfoListModel : public QAbstractListModel {
class ConferenceInfoListModel : public ProxyListModel {
Q_OBJECT
public:
ConferenceInfoListModel (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;
ConferenceInfoModel* getAt(const int& index) const;
void add(std::shared_ptr<ConferenceInfoModel> conferenceInfoModel);
private:
bool removeRow (int row, const QModelIndex &parent = QModelIndex());
bool removeRows (int row, int count, const QModelIndex &parent = QModelIndex()) override;
QList<std::shared_ptr<ConferenceInfoModel>> mList;
//QMap<QDate, QList<ConferenceInfoModel*>> mMappedList;
};
Q_DECLARE_METATYPE(QList<ConferenceInfoModel*>*)
#endif

View file

@ -32,6 +32,7 @@
#include "components/settings/SettingsModel.hpp"
#include "utils/Utils.hpp"
#include "ConferenceInfoProxyModel.hpp"
#include "ConferenceInfoListModel.hpp"
#include "ConferenceInfoModel.hpp"
@ -51,7 +52,7 @@ ConferenceInfoMapModel::ConferenceInfoMapModel (QObject *parent) : QAbstractList
auto conferenceInfoModel = ConferenceInfoModel::create( conferenceInfo );
QDate t = conferenceInfoModel->getDateTime().date();
if( !mMappedList.contains(t))
mMappedList[t] = new ConferenceInfoListModel();
mMappedList[t] = new ConferenceInfoProxyModel(new ConferenceInfoListModel(), this);
mMappedList[t]->add(conferenceInfoModel);
}
}
@ -84,3 +85,9 @@ QVariant ConferenceInfoMapModel::data (const QModelIndex &index, int role) const
}
// -----------------------------------------------------------------------------
void ConferenceInfoMapModel::setConferenceInfoFilter (int filterMode){
for(auto list : mMappedList){
list->setConferenceInfoFilter(filterMode);
}
}

View file

@ -27,7 +27,7 @@
// =============================================================================
class ConferenceInfoListModel;
class ConferenceInfoProxyModel;
class ConferenceInfoMapModel : public QAbstractListModel {
Q_OBJECT
@ -39,9 +39,11 @@ public:
QHash<int, QByteArray> roleNames () const override;
QVariant data (const QModelIndex &index, int role = Qt::DisplayRole) const override;
Q_INVOKABLE void setConferenceInfoFilter (int filterMode);
private:
QMap<QDate, ConferenceInfoListModel*> mMappedList;
QMap<QDate, ConferenceInfoProxyModel*> mMappedList;
};
Q_DECLARE_METATYPE(ConferenceInfoMapModel*)

View file

@ -45,7 +45,7 @@
#include "components/contact/ContactModel.hpp"
#include "components/contact/VcardModel.hpp"
#include "components/contacts/ContactsListModel.hpp"
#include "components/conferenceScheduler/ConferenceSchedulerModel.hpp"
#include "components/conferenceScheduler/ConferenceSchedulerHandler.hpp"
#include "components/core/CoreHandlers.hpp"
#include "components/core/CoreManager.hpp"
#include "components/notifier/Notifier.hpp"
@ -73,8 +73,8 @@ using namespace std;
// -----------------------------------------------------------------------------
// -----------------------------------------------------------------------------
std::shared_ptr<ConferenceInfoModel> ConferenceInfoModel::create(std::shared_ptr<linphone::ConferenceInfo> conferenceInfo){
std::shared_ptr<ConferenceInfoModel> model = std::make_shared<ConferenceInfoModel>(conferenceInfo);
QSharedPointer<ConferenceInfoModel> ConferenceInfoModel::create(std::shared_ptr<linphone::ConferenceInfo> conferenceInfo){
QSharedPointer<ConferenceInfoModel> model = QSharedPointer<ConferenceInfoModel>::create(conferenceInfo);
if(model){
model->mSelf = model;
//chatRoom->addListener(model);
@ -113,9 +113,7 @@ QDateTime ConferenceInfoModel::getDateTime() const{
}
int ConferenceInfoModel::getDuration() const{
int duration = mConferenceInfo->getDuration();
qWarning() << "Duration: " << duration;
return duration;
return mConferenceInfo->getDuration();
}
QDateTime ConferenceInfoModel::getEndDateTime() const{
@ -203,10 +201,10 @@ void ConferenceInfoModel::createConference(const int& securityLevel, const int&
qInfo() << "Conference creation of " << getSubject() << " at " << securityLevel << " security, organized by " << getOrganizer();// and with " << conferenceInfo->getConferenceInfo()->getParticipants().size();
if( true || isScheduled()){
mConferenceSchedulerModel = ConferenceSchedulerModel::create(this);
connect(mConferenceSchedulerModel.get(), &ConferenceSchedulerModel::invitationsSent, this, &ConferenceInfoModel::onInvitationsSent);
mConferenceSchedulerHandler = ConferenceSchedulerHandler::create(this);
connect(mConferenceSchedulerHandler.get(), &ConferenceSchedulerHandler::invitationsSent, this, &ConferenceInfoModel::onInvitationsSent);
mConferenceSchedulerModel->getConferenceScheduler()->setInfo(mConferenceInfo);
mConferenceSchedulerHandler->getConferenceScheduler()->setInfo(mConferenceInfo);
}else{
auto conferenceParameters = core->createConferenceParams(nullptr);
conferenceParameters->enableAudio(true);
@ -235,6 +233,6 @@ void ConferenceInfoModel::createConference(const int& securityLevel, const int&
void ConferenceInfoModel::onInvitationsSent(const std::list<std::shared_ptr<linphone::Address>> & failedInvitations) {
mConferenceSchedulerModel->getConferenceScheduler()->removeListener(mConferenceSchedulerModel);
mConferenceSchedulerHandler->getConferenceScheduler()->removeListener(mConferenceSchedulerHandler);
emit invitationsSent();
}

View file

@ -24,9 +24,10 @@
#include <linphone++/linphone.hh>
#include <QDateTime>
#include <QObject>
#include <QSharedPointer>
class ParticipantListModel;
class ConferenceSchedulerModel;
class ConferenceSchedulerHandler;
class ConferenceInfoModel : public QObject {
Q_OBJECT
@ -45,7 +46,7 @@ public:
//Q_PROPERTY(participants READ getParticipants WRITE setParticipants NOTIFY participantsChanged)
static std::shared_ptr<ConferenceInfoModel> create(std::shared_ptr<linphone::ConferenceInfo> conferenceInfo);
static QSharedPointer<ConferenceInfoModel> create(std::shared_ptr<linphone::ConferenceInfo> conferenceInfo);
ConferenceInfoModel (QObject * parent = nullptr);
ConferenceInfoModel (std::shared_ptr<linphone::ConferenceInfo> conferenceInfo, QObject * parent = nullptr);
~ConferenceInfoModel ();
@ -96,12 +97,13 @@ signals:
private:
std::shared_ptr<linphone::ConferenceInfo> mConferenceInfo;
std::shared_ptr<ConferenceSchedulerModel> mConferenceSchedulerModel = nullptr;
std::weak_ptr<ConferenceInfoModel> mSelf; // For Linphone listener
std::shared_ptr<ConferenceSchedulerHandler> mConferenceSchedulerHandler = nullptr;
QWeakPointer<ConferenceInfoModel> mSelf; // For Linphone listener
bool mIsScheduled = true;
};
Q_DECLARE_METATYPE(std::shared_ptr<ConferenceInfoModel>)
Q_DECLARE_METATYPE(QSharedPointer<ConferenceInfoModel>)
Q_DECLARE_METATYPE(ConferenceInfoModel*)
#endif

View file

@ -30,12 +30,54 @@
using namespace std;
ConferenceInfoProxyModel::ConferenceInfoProxyModel (QObject *parent) : QSortFilterProxyModel(parent) {
mEntryTypeFilter = ConferenceType::Scheduled;
setSourceModel(new ConferenceInfoMapModel());
sort(0, Qt::DescendingOrder);
}
ConferenceInfoProxyModel::ConferenceInfoProxyModel (ConferenceInfoListModel * list, QObject *parent) : QSortFilterProxyModel(parent) {
mEntryTypeFilter = ConferenceType::Scheduled;
setSourceModel(list);
sort(0, Qt::DescendingOrder);
}
int ConferenceInfoProxyModel::getConferenceInfoFilter () {
return mEntryTypeFilter;
}
void ConferenceInfoProxyModel::setConferenceInfoFilter (int filterMode) {
if (getConferenceInfoFilter() != filterMode) {
mEntryTypeFilter = filterMode;
invalidate();
emit conferenceInfoFilterChanged(filterMode);
}
}
bool ConferenceInfoProxyModel::filterAcceptsRow (int sourceRow, const QModelIndex &sourceParent) const {
return true;
/*
bool show = false;
QModelIndex index = sourceModel()->index(sourceRow, 0, QModelIndex());
const ConferenceInfoListModel* ics = sourceModel()->data(index).value<ConferenceInfoListModel*>();
if( mEntryTypeFilter == ConferenceType::Ended && ics->eventModel.value<ChatCallModel*>() != nullptr)
show = true;
else if( mEntryTypeFilter == ChatRoomModel::EntryType::MessageEntry && eventModel.value<ChatMessageModel*>() != nullptr)
show = true;
else if( mEntryTypeFilter == ChatRoomModel::EntryType::NoticeEntry && eventModel.value<ChatNoticeModel*>() != nullptr)
show = true;
}
if( show && mFilterText != ""){
QModelIndex index = sourceModel()->index(sourceRow, 0, sourceParent);
auto eventModel = sourceModel()->data(index);
ChatMessageModel * chatModel = eventModel.value<ChatMessageModel*>();
if( chatModel){
QRegularExpression search(QRegularExpression::escape(mFilterText), QRegularExpression::CaseInsensitiveOption | QRegularExpression::UseUnicodePropertiesOption);
show = chatModel->mContent.contains(search);
}
}
return show;*/
}
bool ConferenceInfoProxyModel::lessThan (const QModelIndex &left, const QModelIndex &right) const {
@ -48,4 +90,8 @@ bool ConferenceInfoProxyModel::lessThan (const QModelIndex &left, const QModelIn
QVariant ConferenceInfoProxyModel::getAt(int row){
QModelIndex sourceIndex = mapToSource(this->index(row, 0));
return sourceModel()->data(sourceIndex);
}
void ConferenceInfoProxyModel::add(QSharedPointer<ConferenceInfoModel> conferenceInfoModel){
qobject_cast<ConferenceInfoListModel*>(sourceModel())->add(conferenceInfoModel);
}

View file

@ -22,23 +22,42 @@
#define CONFERENCE_INFO_PROXY_MODEL_H_
#include <QSortFilterProxyModel>
#include <QSharedPointer>
#include "ConferenceInfoModel.hpp"
// =============================================================================
class QWindow;
class ConferenceInfoListModel;
class ConferenceInfoProxyModel : public QSortFilterProxyModel {
class ChatRoomModelFilter;
Q_OBJECT
public:
Q_PROPERTY(int conferenceInfoFilter READ getConferenceInfoFilter WRITE setConferenceInfoFilter NOTIFY conferenceInfoFilterChanged)
enum ConferenceType {
Ended,
Scheduled,
Invitations
};
Q_ENUM(ConferenceType)
ConferenceInfoProxyModel (QObject *parent = Q_NULLPTR);
ConferenceInfoProxyModel (ConferenceInfoListModel * list, QObject *parent = Q_NULLPTR);
int getConferenceInfoFilter ();
Q_INVOKABLE void setConferenceInfoFilter (int filterMode);
Q_INVOKABLE QVariant getAt(int row);
void add(QSharedPointer<ConferenceInfoModel> conferenceInfoModel);
signals:
void conferenceInfoFilterChanged(int);
protected:
bool filterAcceptsRow (int sourceRow, const QModelIndex &sourceParent) const override;
@ -49,7 +68,8 @@ private:
ConferenceInfoModel *getConferenceInfoModel() const;
void setConferenceInfoModel (ConferenceInfoModel *conferenceInfoModel);
std::shared_ptr<ConferenceInfoModel> mConferenceInfoModel;
int mEntryTypeFilter;
QSharedPointer<ConferenceInfoModel> mConferenceInfoModel;
};
#endif

View file

@ -18,15 +18,15 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include "ConferenceSchedulerModel.hpp"
#include "ConferenceSchedulerHandler.hpp"
#include <QQmlApplicationEngine>
#include "app/App.hpp"
#include "components/core/CoreManager.hpp"
// =============================================================================
std::shared_ptr<ConferenceSchedulerModel> ConferenceSchedulerModel::create( QObject *parent){
std::shared_ptr<ConferenceSchedulerModel> model = std::make_shared<ConferenceSchedulerModel>(parent);
std::shared_ptr<ConferenceSchedulerHandler> ConferenceSchedulerHandler::create( QObject *parent){
std::shared_ptr<ConferenceSchedulerHandler> model = std::make_shared<ConferenceSchedulerHandler>(parent);
if(model){
model->mSelf = model;
model->mConferenceScheduler->addListener(model);
@ -35,21 +35,21 @@ std::shared_ptr<ConferenceSchedulerModel> ConferenceSchedulerModel::create( QObj
return nullptr;
}
ConferenceSchedulerModel::ConferenceSchedulerModel (QObject * parent) : QObject(parent){
ConferenceSchedulerHandler::ConferenceSchedulerHandler (QObject * parent) : QObject(parent){
App::getInstance()->getEngine()->setObjectOwnership(this, QQmlEngine::CppOwnership);// Avoid QML to destroy it when passing by Q_INVOKABLE
mConferenceScheduler = CoreManager::getInstance()->getCore()->createConferenceScheduler();
}
ConferenceSchedulerModel::~ConferenceSchedulerModel () {
ConferenceSchedulerHandler::~ConferenceSchedulerHandler () {
}
std::shared_ptr<linphone::ConferenceScheduler> ConferenceSchedulerModel::getConferenceScheduler(){
std::shared_ptr<linphone::ConferenceScheduler> ConferenceSchedulerHandler::getConferenceScheduler(){
return mConferenceScheduler;
}
void ConferenceSchedulerModel::onStateChanged(const std::shared_ptr<linphone::ConferenceScheduler> & conferenceScheduler, linphone::ConferenceSchedulerState state) {
void ConferenceSchedulerHandler::onStateChanged(const std::shared_ptr<linphone::ConferenceScheduler> & conferenceScheduler, linphone::ConferenceSchedulerState state) {
emit stateChanged(state);
qWarning() << "ConferenceSchedulerModel::onStateChanged : " << (int)state;
qWarning() << "ConferenceSchedulerHandler::onStateChanged : " << (int)state;
if( state == linphone::ConferenceSchedulerState::Ready) {
std::shared_ptr<linphone::ChatRoomParams> params = CoreManager::getInstance()->getCore()->createDefaultChatRoomParams();
params->setBackend(linphone::ChatRoomBackend::Basic);
@ -57,6 +57,6 @@ void ConferenceSchedulerModel::onStateChanged(const std::shared_ptr<linphone::Co
}
}
void ConferenceSchedulerModel::onInvitationsSent(const std::shared_ptr<linphone::ConferenceScheduler> & conferenceScheduler, const std::list<std::shared_ptr<linphone::Address>> & failedInvitations) {
void ConferenceSchedulerHandler::onInvitationsSent(const std::shared_ptr<linphone::ConferenceScheduler> & conferenceScheduler, const std::list<std::shared_ptr<linphone::Address>> & failedInvitations) {
emit invitationsSent(failedInvitations);
}

View file

@ -18,22 +18,22 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef CONFERENCE_SCHEDULER_MODEL_H_
#define CONFERENCE_SCHEDULER_MODEL_H_
#ifndef CONFERENCE_SCHEDULER_HANDLER_H_
#define CONFERENCE_SCHEDULER_HANDLER_H_
#include <linphone++/linphone.hh>
#include <QDateTime>
#include <QObject>
class ConferenceSchedulerModel : public QObject
class ConferenceSchedulerHandler : public QObject
, public linphone::ConferenceSchedulerListener
{
Q_OBJECT
public:
static std::shared_ptr<ConferenceSchedulerModel> create(QObject *parent = Q_NULLPTR);
ConferenceSchedulerModel (QObject * parent = nullptr);
~ConferenceSchedulerModel ();
static std::shared_ptr<ConferenceSchedulerHandler> create(QObject *parent = Q_NULLPTR);
ConferenceSchedulerHandler (QObject * parent = nullptr);
~ConferenceSchedulerHandler ();
std::shared_ptr<linphone::ConferenceScheduler> getConferenceScheduler();
virtual void onStateChanged(const std::shared_ptr<linphone::ConferenceScheduler> & conferenceScheduler, linphone::ConferenceSchedulerState state) override;
@ -45,10 +45,10 @@ signals:
private:
std::shared_ptr<linphone::ConferenceScheduler> mConferenceScheduler;
std::weak_ptr<ConferenceSchedulerModel> mSelf; // Used for Linphone Listener
std::weak_ptr<ConferenceSchedulerHandler> mSelf; // Used for Linphone Listener
};
Q_DECLARE_METATYPE(std::shared_ptr<ConferenceSchedulerModel>)
Q_DECLARE_METATYPE(std::shared_ptr<ConferenceSchedulerHandler>)
#endif

View file

@ -31,7 +31,7 @@
using namespace std;
ContactsImporterListModel::ContactsImporterListModel (QObject *parent) : QAbstractListModel(parent) {
ContactsImporterListModel::ContactsImporterListModel (QObject *parent) : ProxyListModel(parent) {
// Init contacts with linphone friends list.
mMaxContactsImporterId = -1;
QQmlEngine *engine = App::getInstance()->getEngine();
@ -53,10 +53,10 @@ ContactsImporterListModel::ContactsImporterListModel (QObject *parent) : QAbstra
QString pluginID = Utils::coreStringToAppString(config->getString(section, *keyName, ""));
PluginDataAPI* data = static_cast<PluginDataAPI*>(PluginsManager::createInstance(pluginID));
if(data) {
ContactsImporterModel * model = new ContactsImporterModel(data, this);
auto model = QSharedPointer<ContactsImporterModel>::create(data, this);
// See: http://doc.qt.io/qt-5/qtqml-cppintegration-data.html#data-ownership
// The returned value must have a explicit parent or a QQmlEngine::CppOwnership.
engine->setObjectOwnership(model, QQmlEngine::CppOwnership);
engine->setObjectOwnership(model.get(), QQmlEngine::CppOwnership);
model->setIdentity(id);
model->loadConfiguration();// Read the configuration contacts inside the plugin
addContactsImporter(model);
@ -64,38 +64,11 @@ ContactsImporterListModel::ContactsImporterListModel (QObject *parent) : QAbstra
}
}
}
}
}
// GUI methods
int ContactsImporterListModel::rowCount (const QModelIndex &) const {
return mList.count();
}
QHash<int, QByteArray> ContactsImporterListModel::roleNames () const {
QHash<int, QByteArray> roles;
roles[Qt::DisplayRole] = "$contactsImporter";
return roles;
}
QVariant ContactsImporterListModel::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 ContactsImporterListModel::removeRow (int row, const QModelIndex &parent) {
return removeRows(row, 1, parent);
}
bool ContactsImporterListModel::removeRows (int row, int count, const QModelIndex &parent) {
int limit = row + count - 1;
@ -105,9 +78,7 @@ bool ContactsImporterListModel::removeRows (int row, int count, const QModelInde
beginRemoveRows(parent, row, limit);
for (int i = 0; i < count; ++i) {
ContactsImporterModel *contactsImporter = dynamic_cast<ContactsImporterModel*>(mList.takeAt(row));
emit contactsImporterRemoved(contactsImporter);
contactsImporter->deleteLater();
emit contactsImporterRemoved(mList.takeAt(row).objectCast<ContactsImporterModel>());
}
endRemoveRows();
@ -117,27 +88,23 @@ bool ContactsImporterListModel::removeRows (int row, int count, const QModelInde
// -----------------------------------------------------------------------------
ContactsImporterModel *ContactsImporterListModel::findContactsImporterModelFromId (const int &id) const {
auto it = find_if(mList.begin(), mList.end(), [id](PluginsModel *contactsImporterModel) {
return contactsImporterModel->getIdentity() == id;
QSharedPointer<ContactsImporterModel> ContactsImporterListModel::findContactsImporterModelFromId (const int &id) const {
auto it = find_if(mList.begin(), mList.end(), [id](QSharedPointer<QObject> contactsImporterModel) {
return contactsImporterModel.objectCast<ContactsImporterModel>()->getIdentity() == id;
});
return it != mList.end() ? dynamic_cast<ContactsImporterModel*>(*it) : nullptr;
}
QList<PluginsModel*> ContactsImporterListModel::getList(){
return mList;
return it != mList.end() ? it->objectCast<ContactsImporterModel>() : nullptr;
}
// -----------------------------------------------------------------------------
ContactsImporterModel *ContactsImporterListModel::createContactsImporter(QVariantMap data){
ContactsImporterModel *contactsImporter = nullptr;
QSharedPointer<ContactsImporterModel> contactsImporter = nullptr;
if( data.contains("pluginID")){
PluginDataAPI * dataInstance = static_cast<PluginDataAPI*>(PluginsManager::createInstance(data["pluginID"].toString()));
if(dataInstance) {
// get default values
contactsImporter = new ContactsImporterModel(dataInstance, this);
App::getInstance()->getEngine()->setObjectOwnership(contactsImporter, QQmlEngine::CppOwnership);
contactsImporter = QSharedPointer<ContactsImporterModel>::create(dataInstance, this);
App::getInstance()->getEngine()->setObjectOwnership(contactsImporter.get(), QQmlEngine::CppOwnership);
QVariantMap newData = ContactsImporterPluginsManager::getDefaultValues(data["pluginID"].toString());// Start with defaults from plugin
QVariantMap InstanceFields = contactsImporter->getFields();
for(auto field = InstanceFields.begin() ; field != InstanceFields.end() ; ++field)// Insert or Update with the defaults of an instance
@ -147,64 +114,64 @@ ContactsImporterModel *ContactsImporterListModel::createContactsImporter(QVarian
contactsImporter->setIdentity(++mMaxContactsImporterId);
contactsImporter->setFields(newData);
int row = mList.count();
beginInsertRows(QModelIndex(), row, row);
addContactsImporter(contactsImporter);
endInsertRows();
emit layoutChanged();
emit contactsImporterAdded(contactsImporter);
}
}
return contactsImporter;
return contactsImporter.get();
}
ContactsImporterModel *ContactsImporterListModel::addContactsImporter (QVariantMap data, int pId) {
ContactsImporterModel *contactsImporter = findContactsImporterModelFromId(pId);
ContactsImporterModel* ContactsImporterListModel::addContactsImporter (QVariantMap data, int pId) {
auto contactsImporter = findContactsImporterModelFromId(pId);
if (contactsImporter) {
contactsImporter->setFields(data);
return contactsImporter;
return contactsImporter.get();
}else
return createContactsImporter(data);
}
void ContactsImporterListModel::removeContactsImporter (ContactsImporterModel *contactsImporter) {
int index = mList.indexOf(contactsImporter);
if (index >=0){
if( contactsImporter->getIdentity() >=0 ){// Remove from configuration
int id = contactsImporter->getIdentity();
string section = Utils::appStringToCoreString(PluginsManager::gPluginsConfigSection+"_"+QString::number(id)+"_"+QString::number(PluginDataAPI::CONTACTS));
CoreManager::getInstance()->getCore()->getConfig()->cleanSection(section);
if( id == mMaxContactsImporterId)// Decrease mMaxContactsImporterId in a safe way
--mMaxContactsImporterId;
}
removeRow(index);
int index = 0;
for(auto importer : mList){
if( importer.get() == contactsImporter){
if( contactsImporter->getIdentity() >=0 ){// Remove from configuration
int id = contactsImporter->getIdentity();
string section = Utils::appStringToCoreString(PluginsManager::gPluginsConfigSection+"_"+QString::number(id)+"_"+QString::number(PluginDataAPI::CONTACTS));
CoreManager::getInstance()->getCore()->getConfig()->cleanSection(section);
if( id == mMaxContactsImporterId)// Decrease mMaxContactsImporterId in a safe way
--mMaxContactsImporterId;
}
removeRow(index);
return;
}else
++index;
}
}
void ContactsImporterListModel::importContacts(const int &pId){
if( pId >=0) {
ContactsImporterModel *contactsImporter = findContactsImporterModelFromId(pId);
auto contactsImporter = findContactsImporterModelFromId(pId);
if( contactsImporter)
contactsImporter->importContacts();
}else // Import from all current connectors
for(auto importer : mList)
dynamic_cast<ContactsImporterModel*>(importer)->importContacts();
qobject_cast<ContactsImporterModel*>(importer.get())->importContacts();
}
// -----------------------------------------------------------------------------
void ContactsImporterListModel::addContactsImporter (ContactsImporterModel *contactsImporter) {
void ContactsImporterListModel::addContactsImporter (QSharedPointer<ContactsImporterModel> contactsImporter) {
// Connect all update signals
QObject::connect(contactsImporter, &ContactsImporterModel::fieldsChanged, this, [this, contactsImporter]() {
QObject::connect(contactsImporter.get(), &ContactsImporterModel::fieldsChanged, this, [this, contactsImporter]() {
emit contactsImporterUpdated(contactsImporter);
});
QObject::connect(contactsImporter, &ContactsImporterModel::identityChanged, this, [this, contactsImporter]() {
QObject::connect(contactsImporter.get(), &ContactsImporterModel::identityChanged, this, [this, contactsImporter]() {
emit contactsImporterUpdated(contactsImporter);
});
mList << contactsImporter;
add(contactsImporter);
}
//-----------------------------------------------------------------------------------

View file

@ -23,7 +23,7 @@
#include <memory>
#include <QAbstractListModel>
#include "app/proxyModel/ProxyListModel.hpp"
// =============================================================================
@ -32,23 +32,15 @@ class PluginsModel;
// Store all connectors
class ContactsImporterListModel : public QAbstractListModel {
Q_OBJECT;
class ContactsImporterListModel : public ProxyListModel {
Q_OBJECT
public:
ContactsImporterListModel (QObject *parent = Q_NULLPTR);
int rowCount (const QModelIndex &index = QModelIndex()) const override;
virtual bool removeRows (int row, int count, const QModelIndex &parent = QModelIndex()) override;
QHash<int, QByteArray> roleNames () const override;
QVariant data (const QModelIndex &index, int role = Qt::DisplayRole) const override;
bool removeRow (int row, const QModelIndex &parent = QModelIndex());
bool removeRows (int row, int count, const QModelIndex &parent = QModelIndex()) override;
ContactsImporterModel *findContactsImporterModelFromId (const int &id) const;
QList<PluginsModel*> getList();
QSharedPointer<ContactsImporterModel> findContactsImporterModelFromId (const int &id) const;
Q_INVOKABLE ContactsImporterModel *createContactsImporter(QVariantMap data);
Q_INVOKABLE ContactsImporterModel *addContactsImporter (QVariantMap data, int id=-1);
@ -57,14 +49,13 @@ public:
//-----------------------------------------------------------------------------------
signals:
void contactsImporterAdded (ContactsImporterModel *contact);
void contactsImporterRemoved (const ContactsImporterModel *contact);
void contactsImporterUpdated (ContactsImporterModel *contact);
void contactsImporterAdded (QSharedPointer<ContactsImporterModel>);
void contactsImporterRemoved (QSharedPointer<ContactsImporterModel>);
void contactsImporterUpdated (QSharedPointer<ContactsImporterModel>);
private:
void addContactsImporter (ContactsImporterModel *contactsImporter);
void addContactsImporter (QSharedPointer<ContactsImporterModel> contactsImporter);
QList<PluginsModel *> mList;
int mMaxContactsImporterId; // Used to ensure unicity on ID when creating a connector
};

View file

@ -31,181 +31,145 @@
using namespace std;
ContactsListModel::ContactsListModel (QObject *parent) : QAbstractListModel(parent) {
mLinphoneFriends = CoreManager::getInstance()->getCore()->getFriendsLists().front();
// Clean friends.
{
list<shared_ptr<linphone::Friend>> toRemove;
for (const auto &linphoneFriend : mLinphoneFriends->getFriends()) {
if (!linphoneFriend->getVcard())
toRemove.push_back(linphoneFriend);
}
for (const auto &linphoneFriend : toRemove) {
qWarning() << QStringLiteral("Remove one friend without vcard.");
mLinphoneFriends->removeFriend(linphoneFriend);
}
}
// Init contacts with linphone friends list.
QQmlEngine *engine = App::getInstance()->getEngine();
for (const auto &linphoneFriend : mLinphoneFriends->getFriends()) {
ContactModel *contact = new ContactModel(this, linphoneFriend);
// See: http://doc.qt.io/qt-5/qtqml-cppintegration-data.html#data-ownership
// The returned value must have a explicit parent or a QQmlEngine::CppOwnership.
engine->setObjectOwnership(contact, QQmlEngine::CppOwnership);
addContact(contact);
}
}
int ContactsListModel::rowCount (const QModelIndex &) const {
return mList.count();
}
QHash<int, QByteArray> ContactsListModel::roleNames () const {
QHash<int, QByteArray> roles;
roles[Qt::DisplayRole] = "$contact";
return roles;
}
QVariant ContactsListModel::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 ContactsListModel::removeRow (int row, const QModelIndex &parent) {
return removeRows(row, 1, parent);
ContactsListModel::ContactsListModel (QObject *parent) : ProxyListModel(parent) {
mLinphoneFriends = CoreManager::getInstance()->getCore()->getFriendsLists().front();
// Clean friends.
{
list<shared_ptr<linphone::Friend>> toRemove;
for (const auto &linphoneFriend : mLinphoneFriends->getFriends()) {
if (!linphoneFriend->getVcard())
toRemove.push_back(linphoneFriend);
}
for (const auto &linphoneFriend : toRemove) {
qWarning() << QStringLiteral("Remove one friend without vcard.");
mLinphoneFriends->removeFriend(linphoneFriend);
}
}
// Init contacts with linphone friends list.
QQmlEngine *engine = App::getInstance()->getEngine();
for (const auto &linphoneFriend : mLinphoneFriends->getFriends()) {
auto contact = QSharedPointer<ContactModel>::create(this, linphoneFriend);
// See: http://doc.qt.io/qt-5/qtqml-cppintegration-data.html#data-ownership
// The returned value must have a explicit parent or a QQmlEngine::CppOwnership.
engine->setObjectOwnership(contact.get(), QQmlEngine::CppOwnership);
addContact(contact);
}
}
bool ContactsListModel::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) {
ContactModel *contact = mList.takeAt(row);
for(auto address : contact->getVcardModel()->getSipAddresses()){
mOptimizedSearch.remove(address.toString());
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) {
QSharedPointer<ContactModel> contact = mList.takeAt(row).objectCast<ContactModel>();
for(auto address : contact->getVcardModel()->getSipAddresses()){
mOptimizedSearch.remove(address.toString());
}
mLinphoneFriends->removeFriend(contact->mLinphoneFriend);
emit contactRemoved(contact);
}
mLinphoneFriends->removeFriend(contact->mLinphoneFriend);
emit contactRemoved(contact);
contact->deleteLater();
}
endRemoveRows();
return true;
endRemoveRows();
return true;
}
// -----------------------------------------------------------------------------
ContactModel *ContactsListModel::findContactModelFromSipAddress (const QString &sipAddress) const {
QSharedPointer<ContactModel> ContactsListModel::findContactModelFromSipAddress (const QString &sipAddress) const {
if(mOptimizedSearch.contains(sipAddress))
return mOptimizedSearch[sipAddress];
else
return nullptr;
/*
/*
auto it = find_if(mList.begin(), mList.end(), [&sipAddress](ContactModel *contactModel) {
return contactModel->getVcardModel()->getSipAddresses().contains(sipAddress);
return contactModel->getVcardModel()->getSipAddresses().contains(sipAddress);
});
return it != mList.end() ? *it : nullptr;
*/
}
ContactModel *ContactsListModel::findContactModelFromUsername (const QString &username) const {
auto it = find_if(mList.begin(), mList.end(), [&username](ContactModel *contactModel) {
return contactModel->getVcardModel()->getUsername() == username;
});
return it != mList.end() ? *it : nullptr;
QSharedPointer<ContactModel> ContactsListModel::findContactModelFromUsername (const QString &username) const {
auto it = find_if(mList.begin(), mList.end(), [&username](QSharedPointer<QObject> contactModel) {
return qobject_cast<ContactModel*>(contactModel.get())->getVcardModel()->getUsername() == username;
});
return it != mList.end() ? it->objectCast<ContactModel>() : nullptr;
}
// -----------------------------------------------------------------------------
ContactModel *ContactsListModel::addContact (VcardModel *vcardModel) {
// Try to merge vcardModel to an existing contact.
ContactModel *contact = findContactModelFromUsername(vcardModel->getUsername());
if (contact) {
contact->mergeVcardModel(vcardModel);
return contact;
}
contact = new ContactModel(this, vcardModel);
App::getInstance()->getEngine()->setObjectOwnership(contact, QQmlEngine::CppOwnership);
if (mLinphoneFriends->addFriend(contact->mLinphoneFriend) != linphone::FriendList::Status::OK) {
qWarning() << QStringLiteral("Unable to add contact from vcard:") << vcardModel;
contact->deleteLater();
return nullptr;
}
qInfo() << QStringLiteral("Add contact from vcard:") << contact << vcardModel;
// Make sure new subscribe is issued.
mLinphoneFriends->updateSubscriptions();
int row = mList.count();
beginInsertRows(QModelIndex(), row, row);
addContact(contact);
endInsertRows();
emit layoutChanged();
emit contactAdded(contact);
return contact;
// Try to merge vcardModel to an existing contact.
auto contact = findContactModelFromUsername(vcardModel->getUsername());
if (contact) {
contact->mergeVcardModel(vcardModel);
return contact.get();
}
contact = QSharedPointer<ContactModel>::create(this, vcardModel);
App::getInstance()->getEngine()->setObjectOwnership(contact.get(), QQmlEngine::CppOwnership);
if (mLinphoneFriends->addFriend(contact->mLinphoneFriend) != linphone::FriendList::Status::OK) {
qWarning() << QStringLiteral("Unable to add contact from vcard:") << vcardModel;
return nullptr;
}
qInfo() << QStringLiteral("Add contact from vcard:") << contact.get() << vcardModel;
// Make sure new subscribe is issued.
mLinphoneFriends->updateSubscriptions();
addContact(contact);
emit layoutChanged();
emit contactAdded(contact);
return contact.get();
}
void ContactsListModel::removeContact (ContactModel *contact) {
qInfo() << QStringLiteral("Removing contact:") << contact;
int index = mList.indexOf(contact);
if (index == -1 || !removeRow(index))
qWarning() << QStringLiteral("Unable to remove contact:") << contact;
void ContactsListModel::removeContact (ContactModel *contact){
remove(contact);
}
// -----------------------------------------------------------------------------
void ContactsListModel::cleanAvatars () {
qInfo() << QStringLiteral("Delete all avatars.");
for (const auto &contact : mList) {
VcardModel *vcardModel = contact->cloneVcardModel();
vcardModel->setAvatar(QString(""));
contact->setVcardModel(vcardModel);
}
qInfo() << QStringLiteral("Delete all avatars.");
for (const auto &item : mList) {
auto contact = qobject_cast<ContactModel*>(item.get());
VcardModel *vcardModel = contact->cloneVcardModel();
vcardModel->setAvatar(QString(""));
contact->setVcardModel(vcardModel);
}
}
// -----------------------------------------------------------------------------
void ContactsListModel::addContact (ContactModel *contact) {
QObject::connect(contact, &ContactModel::contactUpdated, this, [this, contact]() {
emit contactUpdated(contact);
});
QObject::connect(contact, &ContactModel::sipAddressAdded, this, [this, contact](const QString &sipAddress) {
mOptimizedSearch[sipAddress] = contact;
emit sipAddressAdded(contact, sipAddress);
});
QObject::connect(contact, &ContactModel::sipAddressRemoved, this, [this, contact](const QString &sipAddress) {
mOptimizedSearch.remove(sipAddress);
emit sipAddressRemoved(contact, sipAddress);
});
mList << contact;
for(auto address : contact->getVcardModel()->getSipAddresses()){
void ContactsListModel::addContact (QSharedPointer<ContactModel> contact) {
QObject::connect(contact.get(), &ContactModel::contactUpdated, this, [this, contact]() {
emit contactUpdated(contact);
});
QObject::connect(contact.get(), &ContactModel::sipAddressAdded, this, [this, contact](const QString &sipAddress) {
mOptimizedSearch[sipAddress] = contact;
emit sipAddressAdded(contact, sipAddress);
});
QObject::connect(contact.get(), &ContactModel::sipAddressRemoved, this, [this, contact](const QString &sipAddress) {
mOptimizedSearch.remove(sipAddress);
emit sipAddressRemoved(contact, sipAddress);
});
add(contact);
for(auto address : contact->getVcardModel()->getSipAddresses()){
mOptimizedSearch[address.toString()] = contact;
}
}

View file

@ -23,55 +23,48 @@
#include <memory>
#include <QAbstractListModel>
#include "app/proxyModel/ProxyListModel.hpp"
// =============================================================================
namespace linphone {
class FriendList;
class FriendList;
}
class ContactModel;
class VcardModel;
class ContactsListModel : public QAbstractListModel {
friend class SipAddressesModel;
Q_OBJECT;
class ContactsListModel : public ProxyListModel {
friend class SipAddressesModel;
Q_OBJECT;
public:
ContactsListModel (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;
bool removeRow (int row, const QModelIndex &parent = QModelIndex());
bool removeRows (int row, int count, const QModelIndex &parent = QModelIndex()) override;
ContactModel *findContactModelFromSipAddress (const QString &sipAddress) const;
ContactModel *findContactModelFromUsername (const QString &username) const;
Q_INVOKABLE ContactModel *addContact (VcardModel *vcardModel);
Q_INVOKABLE void removeContact (ContactModel *contact);
Q_INVOKABLE void cleanAvatars ();
ContactsListModel (QObject *parent = Q_NULLPTR);
bool removeRows (int row, int count, const QModelIndex &parent = QModelIndex()) override;
QSharedPointer<ContactModel> findContactModelFromSipAddress (const QString &sipAddress) const;
QSharedPointer<ContactModel> findContactModelFromUsername (const QString &username) const;
Q_INVOKABLE ContactModel *addContact (VcardModel *vcardModel);
Q_INVOKABLE void removeContact (ContactModel *contact);
Q_INVOKABLE void cleanAvatars ();
signals:
void contactAdded (ContactModel *contact);
void contactRemoved (const ContactModel *contact);
void contactUpdated (ContactModel *contact);
void sipAddressAdded (ContactModel *contact, const QString &sipAddress);
void sipAddressRemoved (ContactModel *contact, const QString &sipAddress);
void contactAdded (QSharedPointer<ContactModel>);
void contactRemoved (QSharedPointer<ContactModel>);
void contactUpdated (QSharedPointer<ContactModel>);
void sipAddressAdded (QSharedPointer<ContactModel>, const QString &sipAddress);
void sipAddressRemoved (QSharedPointer<ContactModel>, const QString &sipAddress);
private:
void addContact (ContactModel *contact);
QList<ContactModel *> mList;
QMap<QString, ContactModel*> mOptimizedSearch;
std::shared_ptr<linphone::FriendList> mLinphoneFriends;
void addContact (QSharedPointer<ContactModel> contact);
QMap<QString, QSharedPointer<ContactModel>> mOptimizedSearch;
std::shared_ptr<linphone::FriendList> mLinphoneFriends;
};
#endif // CONTACTS_LIST_MODEL_H_

View file

@ -31,50 +31,25 @@
// =============================================================================
ContentListModel::ContentListModel (ChatMessageModel * message) : QAbstractListModel(message) {
ContentListModel::ContentListModel (ChatMessageModel * message) : ProxyListModel(message) {
mParent = message;
if(message){
std::list<std::shared_ptr<linphone::Content>> contents = message->getChatMessage()->getContents() ;
for(auto content : contents){
auto contentModel = std::make_shared<ContentModel>(content, message);
auto contentModel = QSharedPointer<ContentModel>::create(content, message);
connect(this, &ContentListModel::updateTransferDataRequested, contentModel.get(), &ContentModel::updateTransferData);
mList << contentModel;
}
}
}
int ContentListModel::rowCount (const QModelIndex &index) const{
return mList.count();
}
int ContentListModel::count(){
return mList.count();
}
QHash<int, QByteArray> ContentListModel::roleNames () const {
QHash<int, QByteArray> roles;
roles[Qt::DisplayRole] = "modelData";
return roles;
}
QVariant ContentListModel::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].get());
return QVariant();
}
std::shared_ptr<ContentModel> ContentListModel::add(std::shared_ptr<linphone::Content> content){
int row = mList.count();
auto contentModel = std::make_shared<ContentModel>(content, mParent);
beginInsertRows(QModelIndex(), row, row);
mList << contentModel;
endInsertRows();
QSharedPointer<ContentModel> ContentListModel::add(std::shared_ptr<linphone::Content> content){
auto contentModel = QSharedPointer<ContentModel>::create(content, mParent);
ProxyListModel::add(contentModel);
emit contentsChanged();
return contentModel;
}
@ -120,64 +95,44 @@ void ContentListModel::remove(ContentModel * model){
}
}
bool ContentListModel::removeRow (int row, const QModelIndex &parent){
return removeRows(row, 1, parent);
}
bool ContentListModel::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);
endRemoveRows();
return true;
}
void ContentListModel::clear(){
// Delete thumbnails
for(auto contentModel : mList){
contentModel->removeThumbnail();
contentModel.objectCast<ContentModel>()->removeThumbnail();
}
beginResetModel();
mList.clear();
endResetModel();
resetData();
}
void ContentListModel::removeDownloadedFiles(){
for(auto contentModel : mList){
for(auto model : mList){
auto contentModel = model.objectCast<ContentModel>();
contentModel->removeDownloadedFile();
contentModel->removeThumbnail();
}
}
std::shared_ptr<ContentModel> ContentListModel::getContentModel(std::shared_ptr<linphone::Content> content){
for(auto c : mList)
QSharedPointer<ContentModel> ContentListModel::getContentModel(std::shared_ptr<linphone::Content> content){
for(auto item : mList){
auto c = item.objectCast<ContentModel>();
if(c->getContent() == content)
return c;
}
if(content->isFileTransfer() || content->isFile() || content->isFileEncrypted()){
for(auto c : mList)// Content object can be different for file (like while data transfer)
for(auto item : mList){// Content object can be different for file (like while data transfer)
auto c = item.objectCast<ContentModel>();
if(c->getContent()->getFilePath() == content->getFilePath())
return c;
}
}
return nullptr;
}
QList<std::shared_ptr<ContentModel>> ContentListModel::getContents(){
return mList;
}
void ContentListModel::updateContent(std::shared_ptr<linphone::Content> oldContent, std::shared_ptr<linphone::Content> newContent){
int row = 0;
for(auto content = mList.begin() ; content != mList.end() ; ++content, ++row){
if( (*content)->getContent() == oldContent){
mList.replace(row, std::make_shared<ContentModel>(newContent, (*content)->getChatMessageModel()));
auto contentModel = content->objectCast<ContentModel>();
if( contentModel->getContent() == oldContent){
mList.replace(row, QSharedPointer<ContentModel>::create(newContent, contentModel->getChatMessageModel()));
emit dataChanged(index(row,0), index(row,0));
return;
}
@ -190,15 +145,15 @@ void ContentListModel::updateContents(ChatMessageModel * messageModel){
beginResetModel();
for(auto content : contents){
if( count >= mList.size()){// New content
mList.insert(count, std::make_shared<ContentModel>(content, messageModel));
}else if(mList.at(count)->getContent() != content){ // This content is not at its place
mList.insert(count, QSharedPointer<ContentModel>::create(content, messageModel));
}else if(mList.at(count).objectCast<ContentModel>()->getContent() != content){ // This content is not at its place
int c = count + 1;
while( c < mList.size() && mList.at(c)->getContent() != content)
while( c < mList.size() && mList.at(c).objectCast<ContentModel>()->getContent() != content)
++c;
if( c < mList.size()){// Found => swap position
mList.swap(count, c);
}else{// content is new
mList.insert(count, std::make_shared<ContentModel>(content, messageModel));
mList.insert(count, QSharedPointer<ContentModel>::create(content, messageModel));
}
}
++count;
@ -214,5 +169,5 @@ void ContentListModel::updateAllTransferData(){
void ContentListModel::downloaded(){
for(auto content : mList)
content->createThumbnail();
content.objectCast<ContentModel>()->createThumbnail();
}

View file

@ -29,29 +29,27 @@
#include <QString>
#include <QAbstractListModel>
#include "app/proxyModel/ProxyListModel.hpp"
class ContentModel;
class ChatMessageModel;
class ContentListModel : public QAbstractListModel {
class ContentListModel : public ProxyListModel {
Q_OBJECT
public:
ContentListModel (ChatMessageModel * message);
int rowCount (const QModelIndex &index = QModelIndex()) const override;
int count();
virtual QHash<int, QByteArray> roleNames () const override;
virtual QVariant data (const QModelIndex &index, int role = Qt::DisplayRole) const override;
std::shared_ptr<ContentModel> add(std::shared_ptr<linphone::Content> content);
QSharedPointer<ContentModel> add(std::shared_ptr<linphone::Content> content);
void addFile(const QString& path);
Q_INVOKABLE void remove(ContentModel * model);
void clear();
void removeDownloadedFiles();
std::shared_ptr<ContentModel> getContentModel(std::shared_ptr<linphone::Content> content);// Return the contentModel by checking Content, or if it is the same file.
QList<std::shared_ptr<ContentModel>> getContents();
QSharedPointer<ContentModel> getContentModel(std::shared_ptr<linphone::Content> content);// Return the contentModel by checking Content, or if it is the same file.
void updateContent(std::shared_ptr<linphone::Content> oldContent, std::shared_ptr<linphone::Content> newContent);
void updateContents(ChatMessageModel * messageModel);
@ -63,10 +61,7 @@ signals:
void contentsChanged();
private:
bool removeRow (int row, const QModelIndex &parent = QModelIndex());
virtual bool removeRows (int row, int count, const QModelIndex &parent = QModelIndex()) override;
QList<std::shared_ptr<ContentModel>> mList;
ChatMessageModel * mParent;
};

View file

@ -27,6 +27,7 @@
#include <QObject>
#include <QDateTime>
#include <QString>
#include <QSharedPointer>
#include "components/chat-events/ChatMessageModel.hpp"
class ChatMessageModel;
@ -97,8 +98,8 @@ private:
std::shared_ptr<linphone::Content> mContent;
ChatMessageModel* mChatMessageModel;
ChatMessageModel::AppDataManager mAppData; // Used if there is no Chat Message model set.
std::shared_ptr<ConferenceInfoModel> mConferenceInfoModel;
QSharedPointer<ConferenceInfoModel> mConferenceInfoModel;
};
Q_DECLARE_METATYPE(std::shared_ptr<ContentModel>)
Q_DECLARE_METATYPE(QSharedPointer<ContentModel>)
#endif

View file

@ -51,7 +51,7 @@ void ContentProxyModel::setContentListModel(ContentListModel * model){
}
void ContentProxyModel::addFile(const QString& path){
ContentListModel* model = dynamic_cast<ContentListModel*>(sourceModel());
ContentListModel* model = qobject_cast<ContentListModel*>(sourceModel());
model->addFile(path);
}
@ -89,9 +89,9 @@ bool ContentProxyModel::lessThan (const QModelIndex &left, const QModelIndex &ri
);
}
void ContentProxyModel::remove(ContentModel * model){
dynamic_cast<ContentListModel*>(sourceModel())->remove(model);
qobject_cast<ContentListModel*>(sourceModel())->remove(model);
}
void ContentProxyModel::clear(){
dynamic_cast<ContentListModel*>(sourceModel())->clear();
qobject_cast<ContentListModel*>(sourceModel())->clear();
}

View file

@ -32,7 +32,7 @@ class QMutex;
class CoreHandlers :
public QObject,
public linphone::CoreListener {
Q_OBJECT;
Q_OBJECT
public:
CoreHandlers (CoreManager *coreManager);
@ -158,13 +158,6 @@ private:
const std::shared_ptr<linphone::Core> &core,
const std::shared_ptr<linphone::Friend> &linphoneFriend
) override;
void onRegistrationStateChanged (
const std::shared_ptr<linphone::Core> &core,
const std::shared_ptr<linphone::ProxyConfig> &proxyConfig,
linphone::RegistrationState state,
const std::string &message
) override;
void onTransferStateChanged (
const std::shared_ptr<linphone::Core> &core,

View file

@ -31,7 +31,6 @@
#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"
@ -94,7 +93,6 @@ CoreManager::~CoreManager(){
void CoreManager::initCoreManager(){
mCallsListModel = new CallsListModel(this);
mChatModel = new ChatModel(this);
mChatRoomListModel = new ChatRoomListModel(this);
mContactsListModel = new ContactsListModel(this);
mContactsImporterListModel = new ContactsImporterListModel(this);
mAccountSettingsModel = new AccountSettingsModel(this);
@ -295,7 +293,7 @@ void CoreManager::updateUserAgent(){
forceRefreshRegisters(); // After setting a new device name, REGISTER need to take account it.
}
void CoreManager::handleChatRoomCreated(const std::shared_ptr<ChatRoomModel> &chatRoomModel){
void CoreManager::handleChatRoomCreated(const QSharedPointer<ChatRoomModel> &chatRoomModel){
emit chatRoomModelCreated(chatRoomModel);
}

View file

@ -36,7 +36,6 @@ class AccountSettingsModel;
class CallsListModel;
class ChatModel;
class ChatRoomModel;
class ChatRoomListModel;
class ContactsListModel;
class ContactsImporterListModel;
class CoreHandlers;
@ -72,12 +71,6 @@ public:
return mHandlers;
}
//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, const bool& create = true);
//bool chatRoomModelExists (const QString &sipAddress, const QString &localAddress, const bool &isSecure);
//bool chatRoomModelExists (std::shared_ptr<linphone::ChatRoom> chatRoom);
HistoryModel* getHistoryModel();
RecorderManager* getRecorderManager();
@ -101,12 +94,6 @@ public:
Q_CHECK_PTR(mCallsListModel);
return mCallsListModel;
}
/* Timelines
ChatRoomListModel *getChatRoomListModel () const {
Q_CHECK_PTR(mChatRoomListModel);
return mChatRoomListModel;
}*/
ContactsListModel *getContactsListModel () const {
Q_CHECK_PTR(mContactsListModel);
@ -184,12 +171,12 @@ public slots:
void stopIterate();
void setLastRemoteProvisioningState(const linphone::ConfiguringState& state);
void createLinphoneCore (const QString &configPath);// In order to delay creation
void handleChatRoomCreated(const std::shared_ptr<ChatRoomModel> &chatRoomModel);
void handleChatRoomCreated(const QSharedPointer<ChatRoomModel> &chatRoomModel);
signals:
void coreManagerInitialized ();
void chatRoomModelCreated (const std::shared_ptr<ChatRoomModel> &chatRoomModel);
void chatRoomModelCreated (const QSharedPointer<ChatRoomModel> &chatRoomModel);
void historyModelCreated (HistoryModel *historyModel);
void recorderManagerCreated(RecorderManager *recorderModel);
@ -219,7 +206,7 @@ private:
static QString getDownloadUrl ();
std::shared_ptr<linphone::Core> mCore;
std::shared_ptr<CoreHandlers> mHandlers;
std::shared_ptr<CoreHandlers> mHandlers; // It is used for handling linphone. Keep it to shared_ptr.
bool mStarted = false;
linphone::ConfiguringState mLastRemoteProvisioningState;
@ -228,7 +215,6 @@ private:
ContactsListModel *mContactsListModel = nullptr;
ContactsImporterListModel *mContactsImporterListModel = nullptr;
TimelineListModel *mTimelineListModel = nullptr;
ChatRoomListModel *mChatRoomListModel = nullptr;
ChatModel *mChatModel = nullptr;
SipAddressesModel *mSipAddressesModel = nullptr;
@ -236,10 +222,7 @@ private:
AccountSettingsModel *mAccountSettingsModel = nullptr;
EventCountNotifier *mEventCountNotifier = nullptr;
//QHash<QPair<bool, QPair<QString, QString> >, std::weak_ptr<ChatRoomModel>> mChatRoomModels;
//QHash<std::shared_ptr<linphone::ChatRoom>, std::weak_ptr<ChatRoomModel>> mChatRoomModels;
//QList<QPair<std::shared_ptr<linphone::ChatRoom>, std::weak_ptr<ChatRoomModel>>> mChatRoomModels;
HistoryModel * mHistoryModel = nullptr;
LdapListModel *mLdapListModel = nullptr;
RecorderManager* mRecorderManager = nullptr;

View file

@ -100,7 +100,7 @@ int AbstractEventCountNotifier::getMissedCallCountFromLocal(const QString &local
}
// -----------------------------------------------------------------------------
void AbstractEventCountNotifier::handleChatRoomModelCreated (const shared_ptr<ChatRoomModel> &chatRoomModel) {
void AbstractEventCountNotifier::handleChatRoomModelCreated (const QSharedPointer<ChatRoomModel> &chatRoomModel) {
ChatRoomModel *chatRoomModelPtr = chatRoomModel.get();
QObject::connect(
chatRoomModelPtr, &ChatRoomModel::messageCountReset,

View file

@ -21,7 +21,7 @@
#ifndef ABSTRACT_EVENT_COUNT_NOTIFIER_H_
#define ABSTRACT_EVENT_COUNT_NOTIFIER_H_
#include <memory>
#include <QSharedPointer>
#include <QHash>
#include <QObject>
@ -73,7 +73,7 @@ private:
void internalnotifyEventCount ();
void handleChatRoomModelCreated (const std::shared_ptr<ChatRoomModel> &chatRoomModel);
void handleChatRoomModelCreated (const QSharedPointer<ChatRoomModel> &chatRoomModel);
void handleHistoryModelCreated (HistoryModel *historyModel);
QHash<ConferenceId, int> mMissedCalls;

View file

@ -35,6 +35,7 @@ using namespace std;
LdapModel::LdapModel (std::shared_ptr<linphone::Ldap> ldap, QObject *parent ) : QObject(parent){
mLdap = ldap;
mIsValid = false;
if(mLdap)
mLdapParams = ldap->getParams()->clone();
else{

View file

@ -40,8 +40,6 @@ bool ImageProxyModel::filterAcceptsRow (
) const {
Q_UNUSED(sourceRow)
Q_UNUSED(sourceParent)
//const QModelIndex index = sourceModel()->index(sourceRow, 0, sourceParent);
//const ParticipantDeviceModel *device = index.data().value<ParticipantDeviceModel *>();
return true;
}

View file

@ -42,7 +42,6 @@ ParticipantImdnStateListModel::ParticipantImdnStateListModel (std::shared_ptr<li
for(auto imdn : imdns){
if(imdn->getParticipant()){
auto deviceModel = std::make_shared<ParticipantImdnStateModel>(imdn);
//connect(this, &ParticipantDeviceListModel::securityLevelChanged, deviceModel.get(), &ParticipantDeviceModel::onSecurityLevelChanged);
mList << deviceModel;
}
}

View file

@ -32,8 +32,8 @@
ParticipantImdnStateModel::ParticipantImdnStateModel (const std::shared_ptr<const linphone::ParticipantImdnState> imdn, QObject * parent) : QObject(parent) {
App::getInstance()->getEngine()->setObjectOwnership(this, QQmlEngine::CppOwnership);// Avoid QML to destroy it when passing by Q_INVOKABLE
setState(LinphoneEnums::fromLinphone(imdn->getState()));
setStateChangeTime(QDateTime::fromSecsSinceEpoch(imdn->getStateChangeTime())) ;
mState = (LinphoneEnums::fromLinphone(imdn->getState()));
mStateChangeTime = (QDateTime::fromSecsSinceEpoch(imdn->getStateChangeTime())) ;
auto participant = imdn->getParticipant();
if(participant)
mAddress = imdn->getParticipant()->getAddress()->clone();

View file

@ -39,8 +39,6 @@ bool ParticipantImdnStateProxyModel::filterAcceptsRow (
) const {
Q_UNUSED(sourceRow)
Q_UNUSED(sourceParent)
//const QModelIndex index = sourceModel()->index(sourceRow, 0, sourceParent);
//const ParticipantDeviceModel *device = index.data().value<ParticipantDeviceModel *>();
return true;
}

View file

@ -32,10 +32,11 @@
ParticipantDeviceListModel::ParticipantDeviceListModel (std::shared_ptr<linphone::Participant> participant, QObject *parent) : QAbstractListModel(parent) {
std::list<std::shared_ptr<linphone::ParticipantDevice>> devices = participant->getDevices() ;
auto previewModel = ParticipantDeviceModel::create(nullptr, true);
mList << previewModel;
for(auto device : devices){
auto deviceModel = std::make_shared<ParticipantDeviceModel>(device, false);
auto deviceModel = ParticipantDeviceModel::create(device, false);
connect(this, &ParticipantDeviceListModel::securityLevelChanged, deviceModel.get(), &ParticipantDeviceModel::onSecurityLevelChanged);
connect(this, &ParticipantDeviceListModel::participantDeviceMediaAvailabilityChanged, deviceModel.get(), &ParticipantDeviceModel::videoEnabledChanged);
mList << deviceModel;
}
}
@ -44,8 +45,16 @@ ParticipantDeviceListModel::ParticipantDeviceListModel (CallModel * callModel, Q
if(callModel && callModel->isConference()) {
mCallModel = callModel;
auto conferenceModel = callModel->getConferenceModel();
auto previewModel = ParticipantDeviceModel::create(nullptr, true);
mList << previewModel;
std::list<std::shared_ptr<linphone::ParticipantDevice>> devices = conferenceModel->getConference()->getParticipantDeviceList();
for(auto device : devices){
auto deviceModel = ParticipantDeviceModel::create(device, false);
connect(this, &ParticipantDeviceListModel::securityLevelChanged, deviceModel.get(), &ParticipantDeviceModel::onSecurityLevelChanged);
mList << deviceModel;
}
/*
mList << std::make_shared<ParticipantDeviceModel>(callModel, true);// Add Me in device list
mList << ParticipantDeviceModel::create(callModel, true);// Add Me in device list
qWarning() << "Me devices : " << conferenceModel->getConference()->getMe()->getDevices().size();
// auto meDevices = conferenceModel->getConference()->getMe()->getDevices();
// if(meDevices.size() > 0)
@ -56,7 +65,6 @@ ParticipantDeviceListModel::ParticipantDeviceListModel (CallModel * callModel, Q
*/
connect(conferenceModel.get(), &ConferenceModel::participantDeviceAdded, this, &ParticipantDeviceListModel::onParticipantDeviceAdded);
connect(conferenceModel.get(), &ConferenceModel::participantDeviceRemoved, this, &ParticipantDeviceListModel::onParticipantDeviceRemoved);
connect(conferenceModel.get(), &ConferenceModel::participantDeviceMediaAvailabilityChanged, this, &ParticipantDeviceListModel::onParticipantDeviceMediaAvailabilityChanged);
connect(conferenceModel.get(), &ConferenceModel::conferenceStateChanged, this, &ParticipantDeviceListModel::onConferenceStateChanged);
}
}
@ -73,13 +81,14 @@ int ParticipantDeviceListModel::count(){
void ParticipantDeviceListModel::updateDevices(std::shared_ptr<linphone::Participant> participant){
std::list<std::shared_ptr<linphone::ParticipantDevice>> devices = participant->getDevices() ;
auto previewModel = ParticipantDeviceModel::create(nullptr, true);
beginResetModel();
qWarning() << "Update devices from participant";
mList.clear();
mList << previewModel;
for(auto device : devices){
auto deviceModel = std::make_shared<ParticipantDeviceModel>(device, false);
auto deviceModel = ParticipantDeviceModel::create(device, false);
connect(this, &ParticipantDeviceListModel::securityLevelChanged, deviceModel.get(), &ParticipantDeviceModel::onSecurityLevelChanged);
connect(this, &ParticipantDeviceListModel::participantDeviceMediaAvailabilityChanged, deviceModel.get(), &ParticipantDeviceModel::videoEnabledChanged);
mList << deviceModel;
}
endResetModel();
@ -88,6 +97,7 @@ void ParticipantDeviceListModel::updateDevices(std::shared_ptr<linphone::Partici
}
void ParticipantDeviceListModel::updateDevices(const std::list<std::shared_ptr<linphone::ParticipantDevice>>& devices, const bool& isMe){
/*
QList<std::shared_ptr<ParticipantDeviceModel>> devicesToAdd;
//auto meDevices = mCallModel->getConferenceModel()->getConference()->getMe()->getDevices();
for(auto device : devices){
@ -100,9 +110,8 @@ void ParticipantDeviceListModel::updateDevices(const std::list<std::shared_ptr<l
return deviceAddress == activeDevice->getDevice()->getAddress();
});
if(exist == mList.end()){
auto deviceModel = std::make_shared<ParticipantDeviceModel>(device, isMe);
auto deviceModel = ParticipantDeviceModel::create(device, isMe);
connect(this, &ParticipantDeviceListModel::securityLevelChanged, deviceModel.get(), &ParticipantDeviceModel::onSecurityLevelChanged);
connect(this, &ParticipantDeviceListModel::participantDeviceMediaAvailabilityChanged, deviceModel.get(), &ParticipantDeviceModel::videoEnabledChanged);
devicesToAdd << deviceModel;
}
//}
@ -115,6 +124,7 @@ void ParticipantDeviceListModel::updateDevices(const std::list<std::shared_ptr<l
endInsertRows();
emit countChanged();
}
*/
}
QHash<int, QByteArray> ParticipantDeviceListModel::roleNames () const {
@ -168,10 +178,9 @@ void ParticipantDeviceListModel::onParticipantDeviceAdded(const std::shared_ptr<
for(auto realParticipantDevice : devices){
if( realParticipantDevice == participantDevice){
int row = mList.count();
beginInsertRows(QModelIndex(), row, row);
auto deviceModel = std::make_shared<ParticipantDeviceModel>(realParticipantDevice, false);
auto deviceModel = ParticipantDeviceModel::create(realParticipantDevice, false);
connect(this, &ParticipantDeviceListModel::securityLevelChanged, deviceModel.get(), &ParticipantDeviceModel::onSecurityLevelChanged);
connect(this, &ParticipantDeviceListModel::participantDeviceMediaAvailabilityChanged, deviceModel.get(), &ParticipantDeviceModel::videoEnabledChanged);
beginInsertRows(QModelIndex(), row, row);
mList << deviceModel;
endInsertRows();
emit countChanged();
@ -205,9 +214,6 @@ void ParticipantDeviceListModel::onParticipantDeviceLeft(const std::shared_ptr<c
qWarning() << "onParticipantDeviceLeft is not yet implemented. Current participants count: " << mList.size();
}
void ParticipantDeviceListModel::onParticipantDeviceMediaAvailabilityChanged(const std::shared_ptr<const linphone::ParticipantDevice> & participantDevice) {
emit participantDeviceMediaAvailabilityChanged();
}
void ParticipantDeviceListModel::onConferenceStateChanged(linphone::Conference::State newState){
if(newState == linphone::Conference::State::Created){
if(mCallModel && mCallModel->isConference()) {
@ -221,7 +227,7 @@ void ParticipantDeviceListModel::onConferenceStateChanged(linphone::Conference::
if(devices.size() > 0 && mList.size() == 1){
//qWarning() << "Adding Me in list. Count=" << mList.size();
beginInsertRows(QModelIndex(), 0, 0);
mList.push_front(std::make_shared<ParticipantDeviceModel>(mCallModel, true));// Add Me in device list
mList.push_front(ParticipantDeviceModel::create(mCallModel, true));// Add Me in device list
endInsertRows();
emit countChanged();
emit layoutChanged();

View file

@ -55,13 +55,11 @@ public slots:
void onParticipantDeviceRemoved(const std::shared_ptr<const linphone::ParticipantDevice> & participantDevice);
void onParticipantDeviceJoined(const std::shared_ptr<const linphone::ParticipantDevice> & participantDevice);
void onParticipantDeviceLeft(const std::shared_ptr<const linphone::ParticipantDevice> & participantDevice);
void onParticipantDeviceMediaAvailabilityChanged(const std::shared_ptr<const linphone::ParticipantDevice> & participantDevice);
void onConferenceStateChanged(linphone::Conference::State newState);
signals:
void securityLevelChanged(std::shared_ptr<const linphone::Address> device);
void countChanged();
void participantDeviceMediaAvailabilityChanged();
private:
bool removeRow (int row, const QModelIndex &parent = QModelIndex());

View file

@ -33,13 +33,34 @@ ParticipantDeviceModel::ParticipantDeviceModel (std::shared_ptr<linphone::Partic
mParticipantDevice = device;
mCall = nullptr;
}
/*
ParticipantDeviceModel::ParticipantDeviceModel (CallModel * call, const bool& isMe, QObject *parent) : QObject(parent) {
App::getInstance()->getEngine()->setObjectOwnership(this, QQmlEngine::CppOwnership);// Avoid QML to destroy it when passing by Q_INVOKABLE
mIsMe = isMe;
mCall = call;
connect(call, &CallModel::statusChanged, this, &ParticipantDeviceModel::videoEnabledChanged);
if( call)
connect(call, &CallModel::statusChanged, this, &ParticipantDeviceModel::videoEnabledChanged);
}*/
std::shared_ptr<ParticipantDeviceModel> ParticipantDeviceModel::create(std::shared_ptr<linphone::ParticipantDevice> device, const bool& isMe, QObject *parent){
std::shared_ptr<ParticipantDeviceModel> model = std::make_shared<ParticipantDeviceModel>(device, isMe, parent);
if(model){
model->mSelf = model;
if(device)
device->addListener(model);
return model;
}
return nullptr;
}
/*
std::shared_ptr<ParticipantDeviceModel> ParticipantDeviceModel::create(CallModel * call, const bool& isMe, QObject *parent){
std::shared_ptr<ParticipantDeviceModel> model = std::make_shared<ParticipantDeviceModel>(call, isMe, parent);
if(model){
model->mSelf = model;
return model;
}
return nullptr;
}*/
// -----------------------------------------------------------------------------
@ -81,4 +102,19 @@ bool ParticipantDeviceModel::isMe() const{
void ParticipantDeviceModel::onSecurityLevelChanged(std::shared_ptr<const linphone::Address> device){
if(!device || mParticipantDevice && mParticipantDevice->getAddress()->weakEqual(device))
emit securityLevelChanged();
}
//--------------------------------------------------------------------
void ParticipantDeviceModel::onIsSpeakingChanged(const std::shared_ptr<linphone::ParticipantDevice> & participantDevice, bool isSpeaking) {
}
void ParticipantDeviceModel::onIsMuted(const std::shared_ptr<linphone::ParticipantDevice> & participantDevice, bool isMuted) {
}
void ParticipantDeviceModel::onConferenceJoined(const std::shared_ptr<linphone::ParticipantDevice> & participantDevice) {
}
void ParticipantDeviceModel::onConferenceLeft(const std::shared_ptr<linphone::ParticipantDevice> & participantDevice) {
}
void ParticipantDeviceModel::onStreamCapabilityChanged(const std::shared_ptr<linphone::ParticipantDevice> & participantDevice, linphone::MediaDirection direction, linphone::StreamType streamType) {
}
void ParticipantDeviceModel::onStreamAvailabilityChanged(const std::shared_ptr<linphone::ParticipantDevice> & participantDevice, bool available, linphone::StreamType streamType) {
emit videoEnabledChanged();
}

View file

@ -30,12 +30,16 @@
class CallModel;
class ParticipantDeviceModel : public QObject {
class ParticipantDeviceModel : public QObject, public linphone::ParticipantDeviceListener {
Q_OBJECT
public:
ParticipantDeviceModel (std::shared_ptr<linphone::ParticipantDevice> device, const bool& isMe = false, QObject *parent = nullptr);
ParticipantDeviceModel (CallModel * call, const bool& isMe = true, QObject *parent = nullptr);
//ParticipantDeviceModel (CallModel * call, const bool& isMe = true, QObject *parent = nullptr);
static std::shared_ptr<ParticipantDeviceModel> create(std::shared_ptr<linphone::ParticipantDevice> device, const bool& isMe = false, QObject *parent = nullptr);
//static std::shared_ptr<ParticipantDeviceModel> create(CallModel * call, const bool& isMe = true, QObject *parent = nullptr);
Q_PROPERTY(QString name READ getName CONSTANT)
Q_PROPERTY(QString address READ getAddress CONSTANT)
@ -54,6 +58,14 @@ public:
std::shared_ptr<linphone::ParticipantDevice> getDevice();
//void deviceSecurityLevelChanged(std::shared_ptr<const linphone::Address> device);
virtual void onIsSpeakingChanged(const std::shared_ptr<linphone::ParticipantDevice> & participantDevice, bool isSpeaking) override;
virtual void onIsMuted(const std::shared_ptr<linphone::ParticipantDevice> & participantDevice, bool isMuted) override;
virtual void onConferenceJoined(const std::shared_ptr<linphone::ParticipantDevice> & participantDevice) override;
virtual void onConferenceLeft(const std::shared_ptr<linphone::ParticipantDevice> & participantDevice) override;
virtual void onStreamCapabilityChanged(const std::shared_ptr<linphone::ParticipantDevice> & participantDevice, linphone::MediaDirection direction, linphone::StreamType streamType) override;
virtual void onStreamAvailabilityChanged(const std::shared_ptr<linphone::ParticipantDevice> & participantDevice, bool available, linphone::StreamType streamType) override;
public slots:
void onSecurityLevelChanged(std::shared_ptr<const linphone::Address> device);
@ -67,7 +79,7 @@ private:
std::shared_ptr<linphone::ParticipantDevice> mParticipantDevice;
CallModel * mCall;
std::weak_ptr<ParticipantDeviceModel> mSelf;
};
//Q_DECLARE_METATYPE(ParticipantModel *);

View file

@ -39,9 +39,10 @@ bool ParticipantDeviceProxyModel::filterAcceptsRow (
) const {
Q_UNUSED(sourceRow)
Q_UNUSED(sourceParent)
//const QModelIndex index = sourceModel()->index(sourceRow, 0, sourceParent);
//const ParticipantDeviceModel *device = index.data().value<ParticipantDeviceModel *>();
return true;
const QModelIndex index = sourceModel()->index(sourceRow, 0, sourceParent);
const ParticipantDeviceModel *device = index.data().value<ParticipantDeviceModel *>();
return device && (isShowMe() || !device->isMe());
}
bool ParticipantDeviceProxyModel::lessThan (const QModelIndex &left, const QModelIndex &right) const {
@ -63,12 +64,16 @@ CallModel * ParticipantDeviceProxyModel::getCallModel() const{
}
int ParticipantDeviceProxyModel::getCount() const{
ParticipantDeviceListModel* devices = dynamic_cast<ParticipantDeviceListModel*>(sourceModel());
ParticipantDeviceListModel* devices = qobject_cast<ParticipantDeviceListModel*>(sourceModel());
if(devices)
return devices->rowCount();
else
return 0;
}
bool ParticipantDeviceProxyModel::isShowMe() const{
return mShowMe;
}
void ParticipantDeviceProxyModel::setCallModel(CallModel * callModel){
mCallModel = callModel;
@ -83,4 +88,11 @@ void ParticipantDeviceProxyModel::setParticipant(ParticipantModel * participant)
connect(sourceModel, &ParticipantDeviceListModel::countChanged, this, &ParticipantDeviceProxyModel::countChanged);
setSourceModel(sourceModel);
emit countChanged();
}
void ParticipantDeviceProxyModel::setShowMe(const bool& show){
if( mShowMe != show) {
mShowMe = show;
emit showMeChanged();
}
}

View file

@ -40,19 +40,24 @@ class ParticipantDeviceProxyModel : public QSortFilterProxyModel {
public:
Q_PROPERTY(CallModel * callModel READ getCallModel WRITE setCallModel NOTIFY callModelChanged)
Q_PROPERTY(int count READ getCount NOTIFY countChanged)
Q_PROPERTY(bool showMe READ isShowMe WRITE setShowMe NOTIFY showMeChanged)
ParticipantDeviceProxyModel (QObject *parent = nullptr);
Q_INVOKABLE ParticipantDeviceModel* getAt(int row);
CallModel * getCallModel() const;
Q_INVOKABLE int getCount() const;
bool isShowMe() const;
void setCallModel(CallModel * callModel);
void setParticipant(ParticipantModel * participant);
void setShowMe(const bool& show);
signals:
void callModelChanged();
void countChanged();
void showMeChanged();
protected:
virtual bool filterAcceptsRow (int sourceRow, const QModelIndex &sourceParent) const override;
@ -60,7 +65,7 @@ protected:
std::shared_ptr<ParticipantDeviceListModel> mDevices;
CallModel * mCallModel;
bool mShowMe = false;
};
#endif

View file

@ -45,7 +45,7 @@ ParticipantModel::ParticipantModel (shared_ptr<linphone::Participant> linphonePa
// -----------------------------------------------------------------------------
ContactModel *ParticipantModel::getContactModel() const{
return CoreManager::getInstance()->getContactsListModel()->findContactModelFromSipAddress(getSipAddress());
return CoreManager::getInstance()->getContactsListModel()->findContactModelFromSipAddress(getSipAddress()).get();
}
int ParticipantModel::getSecurityLevel() const{

View file

@ -46,12 +46,12 @@ ChatRoomModel *ParticipantProxyModel::getChatRoomModel() const{
}
ParticipantListModel * ParticipantProxyModel::getParticipantListModel() const{
return dynamic_cast<ParticipantListModel*>(sourceModel());
return qobject_cast<ParticipantListModel*>(sourceModel());
}
QStringList ParticipantProxyModel::getSipAddresses() const{
QStringList participants;
ParticipantListModel * list = dynamic_cast<ParticipantListModel*>(sourceModel());
ParticipantListModel * list = qobject_cast<ParticipantListModel*>(sourceModel());
for(int i = 0 ; i < list->rowCount() ; ++i)
participants << list->getAt(i)->getSipAddress();
return participants;
@ -59,14 +59,14 @@ QStringList ParticipantProxyModel::getSipAddresses() const{
QVariantList ParticipantProxyModel::getParticipants() const{
QVariantList participants;
ParticipantListModel * list = dynamic_cast<ParticipantListModel*>(sourceModel());
ParticipantListModel * list = qobject_cast<ParticipantListModel*>(sourceModel());
for(int i = 0 ; i < list->rowCount() ; ++i)
participants << QVariant::fromValue(list->getAt(i));
return participants;
}
int ParticipantProxyModel::getCount() const{
return dynamic_cast<ParticipantListModel*>(sourceModel())->rowCount();
return qobject_cast<ParticipantListModel*>(sourceModel())->rowCount();
}
bool ParticipantProxyModel::getShowMe() const{
@ -102,7 +102,7 @@ void ParticipantProxyModel::setShowMe(const bool& show){
}
void ParticipantProxyModel::addAddress(const QString& address){
ParticipantListModel * participantsModel = dynamic_cast<ParticipantListModel*>(sourceModel());
ParticipantListModel * participantsModel = qobject_cast<ParticipantListModel*>(sourceModel());
if(!participantsModel->contains(address)){
std::shared_ptr<ParticipantModel> participant = std::make_shared<ParticipantModel>(nullptr);
participant->setSipAddress(address);
@ -122,7 +122,7 @@ void ParticipantProxyModel::removeModel(ParticipantModel * participant){
QString sipAddress = participant->getSipAddress();
if(mChatRoomModel && mChatRoomModel->getChatRoom() && participant->getParticipant() )
mChatRoomModel->getChatRoom()->removeParticipant(participant->getParticipant()); // Remove already added
ParticipantListModel * participantsModel = dynamic_cast<ParticipantListModel*>(sourceModel());
ParticipantListModel * participantsModel = qobject_cast<ParticipantListModel*>(sourceModel());
participantsModel->remove(participant);
emit countChanged();
emit addressRemoved(sipAddress);

View file

@ -71,11 +71,6 @@ signals:
void addressRemoved(QString sipAddress);
private:
/*
bool removeRow (int row, const QModelIndex &parent = QModelIndex());
bool removeRows (int row, int count, const QModelIndex &parent = QModelIndex()) override;*/
//std::shared_ptr<ParticipantListModel> mParticipantListModel;
ChatRoomModel *mChatRoomModel;
bool mShowMe = true;
};

View file

@ -48,7 +48,7 @@ std::shared_ptr<linphone::Address> SearchResultModel::getAddress() const{
}
ContactModel * SearchResultModel::getContactModel() const{
return CoreManager::getInstance()->getContactsListModel()->findContactModelFromSipAddress(getAddressStringUriOnly());
return CoreManager::getInstance()->getContactsListModel()->findContactModelFromSipAddress(getAddressStringUriOnly()).get();
}

View file

@ -42,7 +42,7 @@ SearchSipAddressesProxyModel::SearchSipAddressesProxyModel (QObject *parent) : Q
// -----------------------------------------------------------------------------
SearchSipAddressesModel * SearchSipAddressesProxyModel::getModel(){
return dynamic_cast<SearchSipAddressesModel*>(sourceModel());
return qobject_cast<SearchSipAddressesModel*>(sourceModel());
}
void SearchSipAddressesProxyModel::setFilter (const QString &pattern){

View file

@ -69,6 +69,7 @@ AccountSettingsModel::AccountSettingsModel (QObject *parent) : QObject(parent) {
QObject::connect(this, &AccountSettingsModel::accountSettingsUpdated, this, &AccountSettingsModel::fullSipAddressChanged);
QObject::connect(this, &AccountSettingsModel::accountSettingsUpdated, this, &AccountSettingsModel::registrationStateChanged);
QObject::connect(this, &AccountSettingsModel::accountSettingsUpdated, this, &AccountSettingsModel::conferenceURIChanged);
QObject::connect(this, &AccountSettingsModel::accountSettingsUpdated, this, &AccountSettingsModel::videoConferenceURIChanged);
QObject::connect(this, &AccountSettingsModel::accountSettingsUpdated, this, &AccountSettingsModel::primaryDisplayNameChanged);
QObject::connect(this, &AccountSettingsModel::accountSettingsUpdated, this, &AccountSettingsModel::primaryUsernameChanged);
QObject::connect(this, &AccountSettingsModel::accountSettingsUpdated, this, &AccountSettingsModel::primarySipAddressChanged);
@ -157,6 +158,8 @@ QVariantMap AccountSettingsModel::getAccountDescription (const shared_ptr<linpho
else
map["route"] = "";
map["conferenceUri"] = Utils::coreStringToAppString(accountParams->getConferenceFactoryUri());
auto address = accountParams->getAudioVideoConferenceFactoryAddress();
map["videoConferenceUri"] = address ? Utils::coreStringToAppString(address->asString()) : "";
map["contactParams"] = Utils::coreStringToAppString(accountParams->getContactParameters());
map["avpfInterval"] = accountParams->getAvpfRrInterval();
map["registerEnabled"] = accountParams->registerEnabled();
@ -197,6 +200,17 @@ QString AccountSettingsModel::getConferenceURI() const{
return account ? Utils::coreStringToAppString(account->getParams()->getConferenceFactoryUri()) : "";
}
QString AccountSettingsModel::getVideoConferenceURI() const{
shared_ptr<linphone::Core> core = CoreManager::getInstance()->getCore();
shared_ptr<linphone::Account> account = core->getDefaultAccount();
if(account) {
auto address = account->getParams()->getAudioVideoConferenceFactoryAddress();
return address ? Utils::coreStringToAppString(address->asString()) : "";
}else
return "";
}
void AccountSettingsModel::setDefaultAccount (const shared_ptr<linphone::Account> &account) {
shared_ptr<linphone::Core> core = CoreManager::getInstance()->getCore();
if (mSelectedAccount != account) {
@ -302,9 +316,13 @@ bool AccountSettingsModel::addOrUpdateAccount(
routes.push_back(Utils::interpretUrl(data["route"].toString()));
accountParams->setRoutesAddresses(routes);
}
QString conferenceURI = data["conferenceUri"].toString();
if(!conferenceURI.isEmpty())
accountParams->setConferenceFactoryUri(Utils::appStringToCoreString(conferenceURI));
QString txt = data["conferenceUri"].toString();
if(!txt.isEmpty())
accountParams->setConferenceFactoryUri(Utils::appStringToCoreString(txt));
txt = data["videoConferenceUri"].toString();
if(!txt.isEmpty())
accountParams->setAudioVideoConferenceFactoryAddress(Utils::interpretUrl(txt));
if(data.contains("contactParams"))
accountParams->setContactParameters(Utils::appStringToCoreString(data["contactParams"].toString()));
if(data.contains("avpfInterval"))

View file

@ -40,6 +40,7 @@ class AccountSettingsModel : public QObject {
Q_PROPERTY(RegistrationState registrationState READ getRegistrationState NOTIFY registrationStateChanged)
Q_PROPERTY(QString conferenceURI READ getConferenceURI NOTIFY conferenceURIChanged)
Q_PROPERTY(QString videoConferenceURI READ getVideoConferenceURI NOTIFY videoConferenceURIChanged)
// Default info.
Q_PROPERTY(QString primaryDisplayName READ getPrimaryDisplayName WRITE setPrimaryDisplayName NOTIFY primaryDisplayNameChanged)
@ -70,6 +71,7 @@ public:
Q_INVOKABLE QVariantMap getAccountDescription (const std::shared_ptr<linphone::Account> &account);
QString getConferenceURI() const;
QString getVideoConferenceURI() const;
Q_INVOKABLE void setDefaultAccount (const std::shared_ptr<linphone::Account> &account = nullptr);
Q_INVOKABLE void setDefaultAccountFromSipAddress (const QString &sipAddress);
@ -95,6 +97,7 @@ signals:
void fullSipAddressChanged();
void registrationStateChanged();
void conferenceURIChanged();
void videoConferenceURIChanged();
void primaryDisplayNameChanged();
void primaryUsernameChanged();
@ -102,8 +105,6 @@ signals:
void accountsChanged();
void accountSettingsUpdated ();
void defaultAccountChanged();
void publishPresenceChanged();

View file

@ -27,7 +27,7 @@ SipAddressObserver::SipAddressObserver (const QString &peerAddress, const QStrin
mLocalAddress = localAddress;
}
void SipAddressObserver::setContact (ContactModel *contact) {
void SipAddressObserver::setContact (QSharedPointer<ContactModel> contact) {
if (contact == mContact)
return;

View file

@ -23,6 +23,8 @@
#include "components/presence/Presence.hpp"
#include <QSharedPointer>
// =============================================================================
class ContactModel;
@ -50,7 +52,7 @@ public:
int securityLevel = 1;
signals:
void contactChanged (ContactModel *contact);
void contactChanged (QSharedPointer<ContactModel>);
void presenceStatusChanged (const Presence::PresenceStatus &presenceStatus);
void unreadMessageCountChanged (int unreadMessageCount);
@ -66,10 +68,10 @@ private:
// ---------------------------------------------------------------------------
ContactModel *getContact () const {
return mContact;
return mContact.get();
}
void setContact (ContactModel *contact);
void setContact (QSharedPointer<ContactModel> contact);
// ---------------------------------------------------------------------------
@ -90,7 +92,7 @@ private:
QString mPeerAddress;
QString mLocalAddress;
ContactModel *mContact = nullptr;
QSharedPointer<ContactModel> mContact;
Presence::PresenceStatus mPresenceStatus = Presence::PresenceStatus::Offline;
int mUnreadMessageCount = 0;
};

View file

@ -45,7 +45,7 @@ using namespace std;
static inline QVariantMap buildVariantMap (const SipAddressesModel::SipAddressEntry &sipAddressEntry) {
return QVariantMap{
{ "sipAddress", sipAddressEntry.sipAddress },
{ "contactModel", QVariant::fromValue(sipAddressEntry.contact) },
{ "contactModel", QVariant::fromValue(sipAddressEntry.contact.get()) },
{ "presenceStatus", sipAddressEntry.presenceStatus },
{ "__localToConferenceEntry", QVariant::fromValue(&sipAddressEntry.localAddressToConferenceEntry) }
};
@ -120,7 +120,7 @@ QVariantMap SipAddressesModel::find (const QString &sipAddress) const {
ContactModel *SipAddressesModel::mapSipAddressToContact (const QString &sipAddress) const {
QString cleanedAddress = Utils::cleanSipAddress(sipAddress);
auto it = mPeerAddressToSipAddressEntry.find(cleanedAddress);
return it == mPeerAddressToSipAddressEntry.end() ? nullptr : it->contact;
return it == mPeerAddressToSipAddressEntry.end() ? nullptr : it->contact.get();
}
// -----------------------------------------------------------------------------
@ -268,7 +268,7 @@ bool SipAddressesModel::removeRows (int row, int count, const QModelIndex &paren
// -----------------------------------------------------------------------------
void SipAddressesModel::handleChatRoomModelCreated (const shared_ptr<ChatRoomModel> &chatRoomModel) {
void SipAddressesModel::handleChatRoomModelCreated (const QSharedPointer<ChatRoomModel> &chatRoomModel) {
ChatRoomModel *ptr = chatRoomModel.get();
QObject::connect(ptr, &ChatRoomModel::allEntriesRemoved, this, [this, ptr] {
@ -289,30 +289,30 @@ void SipAddressesModel::handleHistoryModelCreated (HistoryModel *historyModel) {
handleAllCallCountReset();
});
}
void SipAddressesModel::handleContactAdded (ContactModel *contact) {
void SipAddressesModel::handleContactAdded (QSharedPointer<ContactModel> contact) {
for (const auto &sipAddress : contact->getVcardModel()->getSipAddresses()) {
addOrUpdateSipAddress(sipAddress.toString(), contact);
}
}
void SipAddressesModel::handleContactRemoved (const ContactModel *contact) {
void SipAddressesModel::handleContactRemoved (QSharedPointer<ContactModel> contact) {
for (const auto &sipAddress : contact->getVcardModel()->getSipAddresses())
removeContactOfSipAddress(sipAddress.toString());
}
void SipAddressesModel::handleSipAddressAdded (ContactModel *contact, const QString &sipAddress) {
void SipAddressesModel::handleSipAddressAdded (QSharedPointer<ContactModel> contact, const QString &sipAddress) {
ContactModel *mappedContact = mapSipAddressToContact(sipAddress);
if (mappedContact) {
qWarning() << "Unable to map sip address" << sipAddress << "to" << contact << "- already used by" << mappedContact;
qWarning() << "Unable to map sip address" << sipAddress << "to" << contact.get() << "- already used by" << mappedContact;
return;
}
addOrUpdateSipAddress(sipAddress, contact);
}
void SipAddressesModel::handleSipAddressRemoved (ContactModel *contact, const QString &sipAddress) {
void SipAddressesModel::handleSipAddressRemoved (QSharedPointer<ContactModel> contact, const QString &sipAddress) {
ContactModel *mappedContact = mapSipAddressToContact(sipAddress);
if (contact != mappedContact) {
qWarning() << "Unable to remove sip address" << sipAddress << "of" << contact << "- already used by" << mappedContact;
if (contact.get() != mappedContact) {
qWarning() << "Unable to remove sip address" << sipAddress << "of" << contact.get() << "- already used by" << mappedContact;
return;
}
@ -467,7 +467,7 @@ void SipAddressesModel::handleIsComposingChanged (const shared_ptr<linphone::Cha
}
// -----------------------------------------------------------------------------
void SipAddressesModel::addOrUpdateSipAddress (SipAddressEntry &sipAddressEntry, ContactModel *contact) {
void SipAddressesModel::addOrUpdateSipAddress (SipAddressEntry &sipAddressEntry, QSharedPointer<ContactModel> contact) {
const QString &sipAddress = sipAddressEntry.sipAddress;
sipAddressEntry.contact = contact;
@ -547,10 +547,10 @@ void SipAddressesModel::removeContactOfSipAddress (const QString &sipAddress) {
}
// Try to map other contact on this sip address.
ContactModel *contactModel = CoreManager::getInstance()->getContactsListModel()->findContactModelFromSipAddress(sipAddress);
auto contactModel = CoreManager::getInstance()->getContactsListModel()->findContactModelFromSipAddress(sipAddress);
updateObservers(sipAddress, contactModel);
qInfo() << QStringLiteral("Map new contact on sip address: `%1`.").arg(sipAddress) << contactModel;
qInfo() << QStringLiteral("Map new contact on sip address: `%1`.").arg(sipAddress) << contactModel.get();
addOrUpdateSipAddress(*it, contactModel);
int row = mRefs.indexOf(&(*it));
@ -630,7 +630,7 @@ void SipAddressesModel::initSipAddressesFromCalls () {
void SipAddressesModel::initSipAddressesFromContacts () {
for (auto &contact : CoreManager::getInstance()->getContactsListModel()->mList)
handleContactAdded(contact);
handleContactAdded(contact.objectCast<ContactModel>());
}
void SipAddressesModel::initRefs () {
@ -640,7 +640,7 @@ void SipAddressesModel::initRefs () {
// -----------------------------------------------------------------------------
void SipAddressesModel::updateObservers (const QString &sipAddress, ContactModel *contact) {
void SipAddressesModel::updateObservers (const QString &sipAddress, QSharedPointer<ContactModel> contact) {
for (auto &observer : mObservers.values(sipAddress))
observer->setContact(contact);
}

View file

@ -23,6 +23,7 @@
#include <QAbstractListModel>
#include <QDateTime>
#include <QSharedPointer>
#include "SipAddressObserver.hpp"
@ -47,7 +48,7 @@ public:
struct SipAddressEntry {
QString sipAddress;
ContactModel *contact;
QSharedPointer<ContactModel> contact;
Presence::PresenceStatus presenceStatus;
QHash<QString, ConferenceEntry> localAddressToConferenceEntry;
};
@ -96,14 +97,14 @@ private:
// ---------------------------------------------------------------------------
void handleChatRoomModelCreated (const std::shared_ptr<ChatRoomModel> &chatRoomModel);
void handleChatRoomModelCreated (const QSharedPointer<ChatRoomModel> &chatRoomModel);
void handleHistoryModelCreated (HistoryModel *historyModel) ;
void handleContactAdded (ContactModel *contact);
void handleContactRemoved (const ContactModel *contact);
void handleContactAdded (QSharedPointer<ContactModel> contact);
void handleContactRemoved (QSharedPointer<ContactModel> contact);
void handleSipAddressAdded (ContactModel *contact, const QString &sipAddress);
void handleSipAddressRemoved (ContactModel *contact, const QString &sipAddress);
void handleSipAddressAdded (QSharedPointer<ContactModel> contact, const QString &sipAddress);
void handleSipAddressRemoved (QSharedPointer<ContactModel> contact, const QString &sipAddress);
void handleMessageReceived (const std::shared_ptr<linphone::ChatMessage> &message);
void handleCallStateChanged (const std::shared_ptr<linphone::Call> &call, linphone::Call::State state);
@ -122,7 +123,7 @@ private:
// A sip address exists in this list if a contact is linked to it, or a call, or a message.
void addOrUpdateSipAddress (SipAddressEntry &sipAddressEntry, ContactModel *contact);
void addOrUpdateSipAddress (SipAddressEntry &sipAddressEntry, QSharedPointer<ContactModel> contact);
void addOrUpdateSipAddress (SipAddressEntry &sipAddressEntry, const std::shared_ptr<linphone::Call> &call);
void addOrUpdateSipAddress (SipAddressEntry &sipAddressEntry, const std::shared_ptr<linphone::ChatMessage> &message);
@ -144,7 +145,7 @@ private:
void initRefs ();
void updateObservers (const QString &sipAddress, ContactModel *contact);
void updateObservers (const QString &sipAddress, QSharedPointer<ContactModel> contact);
void updateObservers (const QString &sipAddress, const Presence::PresenceStatus &presenceStatus);
void updateObservers (const QString &peerAddress, const QString &localAddress, int messageCount, int missedCallCount);

View file

@ -38,7 +38,7 @@
// =============================================================================
TimelineListModel::TimelineListModel (QObject *parent) : QAbstractListModel(parent) {
TimelineListModel::TimelineListModel (QObject *parent) : ProxyListModel(parent) {
mSelectedCount = 0;
CoreHandlers* coreHandlers= CoreManager::getInstance()->getHandlers().get();
connect(coreHandlers, &CoreHandlers::chatRoomStateChanged, this, &TimelineListModel::onChatRoomStateChanged);
@ -55,10 +55,6 @@ TimelineListModel::TimelineListModel (QObject *parent) : QAbstractListModel(pare
// -----------------------------------------------------------------------------
TimelineModel * TimelineListModel::getAt(const int& index){
return mTimelines[index].get();
}
void TimelineListModel::reset(){
updateTimelines ();
}
@ -68,54 +64,25 @@ void TimelineListModel::update(){
}
void TimelineListModel::selectAll(const bool& selected){
for(auto it = mTimelines.begin() ; it != mTimelines.end() ; ++it)
(*it)->setSelected(selected);
}
int TimelineListModel::rowCount (const QModelIndex &) const {
return mTimelines.count();
}
QHash<int, QByteArray> TimelineListModel::roleNames () const {
QHash<int, QByteArray> roles;
roles[Qt::DisplayRole] = "$timelines";
return roles;
}
QVariant TimelineListModel::data (const QModelIndex &index, int role) const {
int row = index.row();
if (!index.isValid() || row < 0 || row >= mTimelines.count())
return QVariant();
if (role == Qt::DisplayRole)// && !mTimelines[row]->getChatRoomModel()->mDeleteChatRoom)
return QVariant::fromValue(mTimelines[row].get());
return QVariant();
for(auto it = mList.begin() ; it != mList.end() ; ++it)
it->objectCast<TimelineModel>()->setSelected(selected);
}
// -----------------------------------------------------------------------------
// -----------------------------------------------------------------------------
bool TimelineListModel::removeRow (int row, const QModelIndex &parent) {
return removeRows(row, 1, parent);
}
bool TimelineListModel::removeRows (int row, int count, const QModelIndex &parent) {
QVector<std::shared_ptr<TimelineModel> > oldTimelines;
QVector<QSharedPointer<TimelineModel> > oldTimelines;
oldTimelines.reserve(count);
int limit = row + count - 1;
if (row < 0 || count < 0 || limit >= mTimelines.count())
if (row < 0 || count < 0 || limit >= mList.count())
return false;
beginRemoveRows(parent, row, limit);
for (int i = 0; i < count; ++i){
auto timeline = mTimelines.takeAt(row);
timeline->getChatRoomModel()->getChatRoom()->removeListener(timeline);
auto timeline = mList.takeAt(row).objectCast<TimelineModel>();
timeline->disconnectChatRoomListener();
oldTimelines.push_back(timeline);
}
@ -131,15 +98,16 @@ bool TimelineListModel::removeRows (int row, int count, const QModelIndex &paren
// -----------------------------------------------------------------------------
std::shared_ptr<TimelineModel> TimelineListModel::getTimeline(std::shared_ptr<linphone::ChatRoom> chatRoom, const bool &create){
QSharedPointer<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)->getChatRoomModel()->getChatRoom() == chatRoom){
return *it;
for(auto it = mList.begin() ; it != mList.end() ; ++it){
auto timeline = it->objectCast<TimelineModel>();
if( timeline->getChatRoomModel()->getChatRoom() == chatRoom){
return timeline;
}
}
if(create){
std::shared_ptr<TimelineModel> model = TimelineModel::create(chatRoom);
QSharedPointer<TimelineModel> model = TimelineModel::create(chatRoom);
if(model){
//std::shared_ptr<TimelineModel> model = std::make_shared<TimelineModel>(chatRoom);
connect(model.get(), SIGNAL(selectedChanged(bool)), this, SLOT(onSelectedHasChanged(bool)));
@ -155,7 +123,7 @@ std::shared_ptr<TimelineModel> TimelineListModel::getTimeline(std::shared_ptr<li
/*
std::shared_ptr<TimelineModel> TimelineListModel::getTimeline(std::shared_ptr<linphone::Conference> conference, const bool &create){
if(chatRoom){
for(auto it = mTimelines.begin() ; it != mTimelines.end() ; ++it){
for(auto it = mList.begin() ; it != mList.end() ; ++it){
if( (*it)->isConference() && (*it)->getConferenceModel()->getConference() == conference){
return *it;
}
@ -178,8 +146,8 @@ QVariantList TimelineListModel::getLastChatRooms(const int& maxCount) const{
QDateTime currentDateTime = QDateTime::currentDateTime();
bool doTest = true;
for(auto timeline : mTimelines){
auto chatRoom = timeline->getChatRoomModel();
for(auto timeline : mList){
auto chatRoom = timeline.objectCast<TimelineModel>()->getChatRoomModel();
if(chatRoom && chatRoom->isCurrentAccount() && chatRoom->isOneToOne() && !chatRoom->haveEncryption()) {
sortedData.insert(chatRoom->mLastUpdateTime.secsTo(currentDateTime),chatRoom);
}
@ -200,14 +168,15 @@ QVariantList TimelineListModel::getLastChatRooms(const int& maxCount) const{
return contacts;
}
std::shared_ptr<ChatRoomModel> TimelineListModel::getChatRoomModel(std::shared_ptr<linphone::ChatRoom> chatRoom, const bool& create){
QSharedPointer<ChatRoomModel> TimelineListModel::getChatRoomModel(std::shared_ptr<linphone::ChatRoom> chatRoom, const bool& create){
if(chatRoom ){
for(auto timeline : mTimelines){
if(timeline->mChatRoomModel->getChatRoom() == chatRoom)
return timeline->mChatRoomModel;
for(auto timeline : mList){
auto model = timeline.objectCast<TimelineModel>()->mChatRoomModel;
if(model->getChatRoom() == chatRoom)
return model;
}
if(create){
std::shared_ptr<TimelineModel> model = TimelineModel::create(chatRoom);
QSharedPointer<TimelineModel> model = TimelineModel::create(chatRoom);
if(model){
connect(model.get(), SIGNAL(selectedChanged(bool)), this, SLOT(onSelectedHasChanged(bool)));
connect(model->getChatRoomModel(), &ChatRoomModel::allEntriesRemoved, this, &TimelineListModel::removeChatRoomModel);
@ -221,18 +190,15 @@ std::shared_ptr<ChatRoomModel> TimelineListModel::getChatRoomModel(std::shared_p
return nullptr;
}
std::shared_ptr<ChatRoomModel> TimelineListModel::getChatRoomModel(ChatRoomModel * chatRoom){
for(auto timeline : mTimelines){
if(timeline->mChatRoomModel.get() == chatRoom)
return timeline->mChatRoomModel;
QSharedPointer<ChatRoomModel> TimelineListModel::getChatRoomModel(ChatRoomModel * chatRoom){
for(auto timeline : mList){
auto model = timeline.objectCast<TimelineModel>()->mChatRoomModel;
if(model == chatRoom)
return model;
}
return nullptr;
}
int TimelineListModel::getCount() const{
return mTimelines.size();
}
//-------------------------------------------------------------------------------------------------
void TimelineListModel::setSelectedCount(int selectedCount){
@ -247,9 +213,9 @@ void TimelineListModel::onSelectedHasChanged(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)
for(auto it = mList.begin() ; it != mList.end() ; ++it)
if(it->get() != sender())
(*it)->setSelected(false);
it->objectCast<TimelineModel>()->setSelected(false);
}else
setSelectedCount(mSelectedCount+1);
emit selectedChanged(qobject_cast<TimelineModel*>(sender()));
@ -270,11 +236,11 @@ void TimelineListModel::updateTimelines () {
});
//Remove no more chat rooms
auto itTimeline = mTimelines.begin();
while(itTimeline != mTimelines.end()) {
auto itTimeline = mList.begin();
while(itTimeline != mList.end()) {
auto itDbTimeline = allChatRooms.begin();
if(*itTimeline) {
auto chatRoomModel = (*itTimeline)->getChatRoomModel();
auto chatRoomModel = itTimeline->objectCast<TimelineModel>()->getChatRoomModel();
if(chatRoomModel) {
auto timeline = chatRoomModel->getChatRoom();
if( timeline ) {
@ -288,14 +254,14 @@ void TimelineListModel::updateTimelines () {
}else
itDbTimeline = allChatRooms.end();
if( itDbTimeline == allChatRooms.end()){
int index = itTimeline - mTimelines.begin();
int index = itTimeline - mList.begin();
if(index>0){
--itTimeline;
removeRow(index);
++itTimeline;
}else{
removeRow(0);
itTimeline = mTimelines.begin();
itTimeline = mList.begin();
}
}else
++itTimeline;
@ -308,7 +274,7 @@ void TimelineListModel::updateTimelines () {
auto haveTimeline = getTimeline(dbChatRoom, false);
if(!haveTimeline && dbChatRoom){// Create a new Timeline if needed
std::shared_ptr<TimelineModel> model = TimelineModel::create(dbChatRoom, callLogs);
QSharedPointer<TimelineModel> model = TimelineModel::create(dbChatRoom, callLogs);
if( model){
connect(model.get(), SIGNAL(selectedChanged(bool)), this, SLOT(onSelectedHasChanged(bool)));
connect(model->getChatRoomModel(), &ChatRoomModel::allEntriesRemoved, this, &TimelineListModel::removeChatRoomModel);
@ -319,29 +285,19 @@ void TimelineListModel::updateTimelines () {
CoreManager::getInstance()->updateUnreadMessageCount();
}
void TimelineListModel::add (std::shared_ptr<TimelineModel> timeline){
void TimelineListModel::add (QSharedPointer<TimelineModel> timeline){
connect(timeline->getChatRoomModel(), &ChatRoomModel::lastUpdateTimeChanged, this, &TimelineListModel::updated);
int row = mTimelines.count();
beginInsertRows(QModelIndex(), row, row);
mTimelines << timeline;
endInsertRows();
ProxyListModel::add(timeline);
emit layoutChanged();
emit countChanged();
}
void TimelineListModel::remove (TimelineModel* model) {
}
void TimelineListModel::remove(std::shared_ptr<TimelineModel> model){
int index = mTimelines.indexOf(model);
if (index >=0){
removeRow(index);
}
}
void TimelineListModel::removeChatRoomModel(std::shared_ptr<ChatRoomModel> model){
void TimelineListModel::removeChatRoomModel(QSharedPointer<ChatRoomModel> model){
if(!model || (model->getChatRoom()->isEmpty() && (model->isReadOnly() || !model->isGroupEnabled()))){
auto itTimeline = mTimelines.begin();
while(itTimeline != mTimelines.end()) {
if((*itTimeline)->mChatRoomModel == model){
auto itTimeline = mList.begin();
while(itTimeline != mList.end()) {
auto timeline = itTimeline->objectCast<TimelineModel>();
if(timeline->mChatRoomModel == model){
if(model)
model->deleteChatRoom();
remove(*itTimeline);
@ -364,7 +320,7 @@ void TimelineListModel::select(ChatRoomModel * chatRoomModel){
void TimelineListModel::onChatRoomStateChanged(const std::shared_ptr<linphone::ChatRoom> &chatRoom,linphone::ChatRoom::State state){
if( state == linphone::ChatRoom::State::Created
&& !getTimeline(chatRoom, false)){// Create a new Timeline if needed
std::shared_ptr<TimelineModel> model = TimelineModel::create(chatRoom);
QSharedPointer<TimelineModel> model = TimelineModel::create(chatRoom);
if(model){
connect(model.get(), SIGNAL(selectedChanged(bool)), this, SLOT(onSelectedHasChanged(bool)));
connect(model->getChatRoomModel(), &ChatRoomModel::allEntriesRemoved, this, &TimelineListModel::removeChatRoomModel);
@ -399,8 +355,6 @@ void TimelineListModel::onCallCreated(const std::shared_ptr<linphone::Call> &cal
bool createSecureChatRoom = false;
SettingsModel * settingsModel = CoreManager::getInstance()->getSettingsModel();
if( settingsModel->getSecureChatEnabled() &&
(!settingsModel->getStandardChatEnabled() || (settingsModel->getStandardChatEnabled() && isEncrypted))
){
@ -413,7 +367,8 @@ void TimelineListModel::onCallCreated(const std::shared_ptr<linphone::Call> &cal
, nullptr//callLog->getRemoteAddress()
, participants);
if(chatRoom){
for(auto timeline : mTimelines){
for(auto item : mList){
auto timeline = item.objectCast<TimelineModel>();
if( chatRoom == timeline->mChatRoomModel->getChatRoom()){
found = true;
if(isOutgoing)// If outgoing, we switch to this chat room

View file

@ -22,49 +22,44 @@
#define TIMELINE_LIST_MODEL_H_
#include <QSortFilterProxyModel>
#include <QSharedPointer>
#include "app/proxyModel/ProxyListModel.hpp"
#include "components/chat-room/ChatRoomModel.hpp"
class TimelineModel;
// =============================================================================
class TimelineListModel : public QAbstractListModel {
class TimelineListModel : public ProxyListModel {
Q_OBJECT
public:
Q_PROPERTY(int selectedCount MEMBER mSelectedCount WRITE setSelectedCount NOTIFY selectedCountChanged)
Q_PROPERTY(int count READ getCount NOTIFY countChanged)
Q_PROPERTY(int count READ rowCount NOTIFY countChanged)
TimelineListModel (QObject *parent = Q_NULLPTR);
void reset();
void selectAll(const bool& selected);
TimelineModel * getAt(const int& index);
std::shared_ptr<TimelineModel> getTimeline(std::shared_ptr<linphone::ChatRoom> chatRoom, const bool &create);
QSharedPointer<TimelineModel> getTimeline(std::shared_ptr<linphone::ChatRoom> chatRoom, const bool &create);
//std::shared_ptr<TimelineModel> getTimeline(std::shared_ptr<linphone::Conference> chatRoom, const bool &create);
Q_INVOKABLE QVariantList getLastChatRooms(const int& maxCount) const;
std::shared_ptr<ChatRoomModel> getChatRoomModel(std::shared_ptr<linphone::ChatRoom> chatRoom, const bool &create);
std::shared_ptr<ChatRoomModel> getChatRoomModel(ChatRoomModel * chatRoom);
int getCount() const;
QSharedPointer<ChatRoomModel> getChatRoomModel(std::shared_ptr<linphone::ChatRoom> chatRoom, const bool &create);
QSharedPointer<ChatRoomModel> getChatRoomModel(ChatRoomModel * chatRoom);
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;
void add (std::shared_ptr<TimelineModel> timeline); // Use to add a timeline that is not in Linphone list (like empty chat rooms that were hide by configuration)
// Remove a chatroom
Q_INVOKABLE void remove (TimelineModel *importer);
void remove(std::shared_ptr<TimelineModel> model);
void add (QSharedPointer<TimelineModel> timeline); // Use to add a timeline that is not in Linphone list (like empty chat rooms that were hide by configuration)
Q_INVOKABLE void select(ChatRoomModel * chatRoomModel);
int mSelectedCount;
void setSelectedCount(int selectedCount);
int mSelectedCount;
bool mAutoSelectAfterCreation = false;// Request to select the next chat room after creation
void setSelectedCount(int selectedCount);
public slots:
void update();
void removeChatRoomModel(std::shared_ptr<ChatRoomModel> model);
void removeChatRoomModel(QSharedPointer<ChatRoomModel> model);
void onSelectedHasChanged(bool selected);
void onChatRoomStateChanged(const std::shared_ptr<linphone::ChatRoom> &chatRoom,linphone::ChatRoom::State state);
void onCallStateChanged (const std::shared_ptr<linphone::Call> &call, linphone::Call::State state) ;
@ -80,12 +75,9 @@ signals:
void updated();
private:
bool removeRow (int row, const QModelIndex &parent = QModelIndex());
bool removeRows (int row, int count, const QModelIndex &parent = QModelIndex()) override;
virtual bool removeRows (int row, int count, const QModelIndex &parent) override;
void updateTimelines();
QList<std::shared_ptr<TimelineModel>> mTimelines;
};
#endif // TIMELINE_LIST_MODEL_H_

View file

@ -22,6 +22,7 @@
#include "components/settings/AccountSettingsModel.hpp"
#include "components/sip-addresses/SipAddressesModel.hpp"
#include "components/chat-room/ChatRoomModel.hpp"
#include "components/chat-room/ChatRoomListener.hpp"
#include "utils/Utils.hpp"
#include "app/App.hpp"
@ -34,14 +35,40 @@
#include <qqmlapplicationengine.h>
#include <QTimer>
void TimelineModel::connectTo(ChatRoomListener * listener){
connect(listener, &ChatRoomListener::isComposingReceived, this, &TimelineModel::onIsComposingReceived);
connect(listener, &ChatRoomListener::messageReceived, this, &TimelineModel::onMessageReceived);
connect(listener, &ChatRoomListener::newEvent, this, &TimelineModel::onNewEvent);
connect(listener, &ChatRoomListener::chatMessageReceived, this, &TimelineModel::onChatMessageReceived);
connect(listener, &ChatRoomListener::chatMessageSending, this, &TimelineModel::onChatMessageSending);
connect(listener, &ChatRoomListener::chatMessageSent, this, &TimelineModel::onChatMessageSent);
connect(listener, &ChatRoomListener::participantAdded, this, &TimelineModel::onParticipantAdded);
connect(listener, &ChatRoomListener::participantRemoved, this, &TimelineModel::onParticipantRemoved);
connect(listener, &ChatRoomListener::participantAdminStatusChanged, this, &TimelineModel::onParticipantAdminStatusChanged);
connect(listener, &ChatRoomListener::stateChanged, this, &TimelineModel::onStateChanged);
connect(listener, &ChatRoomListener::securityEvent, this, &TimelineModel::onSecurityEvent);
connect(listener, &ChatRoomListener::subjectChanged, this, &TimelineModel::onSubjectChanged);
connect(listener, &ChatRoomListener::undecryptableMessageReceived, this, &TimelineModel::onUndecryptableMessageReceived);
connect(listener, &ChatRoomListener::participantDeviceAdded, this, &TimelineModel::onParticipantDeviceAdded);
connect(listener, &ChatRoomListener::participantDeviceRemoved, this, &TimelineModel::onParticipantDeviceRemoved);
connect(listener, &ChatRoomListener::conferenceJoined, this, &TimelineModel::onConferenceJoined);
connect(listener, &ChatRoomListener::conferenceLeft, this, &TimelineModel::onConferenceLeft);
connect(listener, &ChatRoomListener::ephemeralEvent, this, &TimelineModel::onEphemeralEvent);
connect(listener, &ChatRoomListener::ephemeralMessageTimerStarted, this, &TimelineModel::onEphemeralMessageTimerStarted);
connect(listener, &ChatRoomListener::ephemeralMessageDeleted, this, &TimelineModel::onEphemeralMessageDeleted);
connect(listener, &ChatRoomListener::conferenceAddressGeneration, this, &TimelineModel::onConferenceAddressGeneration);
connect(listener, &ChatRoomListener::participantRegistrationSubscriptionRequested, this, &TimelineModel::onParticipantRegistrationSubscriptionRequested);
connect(listener, &ChatRoomListener::participantRegistrationUnsubscriptionRequested, this, &TimelineModel::onParticipantRegistrationUnsubscriptionRequested);
connect(listener, &ChatRoomListener::chatMessageShouldBeStored, this, &TimelineModel::onChatMessageShouldBeStored);
connect(listener, &ChatRoomListener::chatMessageParticipantImdnStateChanged, this, &TimelineModel::onChatMessageParticipantImdnStateChanged);
}
// =============================================================================
std::shared_ptr<TimelineModel> TimelineModel::create(std::shared_ptr<linphone::ChatRoom> chatRoom, const std::list<std::shared_ptr<linphone::CallLog>>& callLogs, QObject *parent){
QSharedPointer<TimelineModel> TimelineModel::create(std::shared_ptr<linphone::ChatRoom> chatRoom, const std::list<std::shared_ptr<linphone::CallLog>>& callLogs, QObject *parent){
if((!chatRoom || chatRoom->getState() != linphone::ChatRoom::State::Terminated) && (!CoreManager::getInstance()->getTimelineListModel() || !CoreManager::getInstance()->getTimelineListModel()->getTimeline(chatRoom, false)) ) {
std::shared_ptr<TimelineModel> model = std::make_shared<TimelineModel>(chatRoom, parent);
QSharedPointer<TimelineModel> model = QSharedPointer<TimelineModel>::create(chatRoom, parent);
if(model && model->getChatRoomModel()){
model->mSelf = model;
chatRoom->addListener(model);
// Get Max updatetime from chat room and last call event
auto timelineChatRoom = model->getChatRoomModel();
std::shared_ptr<linphone::CallLog> lastCall = nullptr;
@ -85,6 +112,11 @@ TimelineModel::TimelineModel (std::shared_ptr<linphone::ChatRoom> chatRoom, QObj
QObject::connect(this, &TimelineModel::selectedChanged, this, &TimelineModel::updateUnreadCount);
QObject::connect(CoreManager::getInstance()->getAccountSettingsModel(), &AccountSettingsModel::defaultAccountChanged, this, &TimelineModel::onDefaultAccountChanged);
}
if(chatRoom){
mChatRoomListener = std::make_shared<ChatRoomListener>(this);
connectTo(mChatRoomListener.get());
chatRoom->addListener(mChatRoomListener);
}
mSelected = false;
}
@ -132,7 +164,7 @@ void TimelineModel::setSelected(const bool& selected){
<< ", isReadOnly:" << mChatRoomModel->isReadOnly()
<< ", state:" << mChatRoomModel->getState();
}else
mChatRoomModel->resetEntries();// Cleanup leaving chat room
mChatRoomModel->resetData();// Cleanup leaving chat room
emit selectedChanged(mSelected);
}
}
@ -146,6 +178,13 @@ void TimelineModel::onDefaultAccountChanged(){
if( mSelected && !mChatRoomModel->isCurrentAccount())
setSelected(false);
}
void TimelineModel::disconnectChatRoomListener(){
if( mChatRoomModel && mChatRoomListener){
mChatRoomModel->getChatRoom()->removeListener(mChatRoomListener);
}
}
//----------------------------------------------------------
//------ CHAT ROOM HANDLERS
//----------------------------------------------------------

View file

@ -25,18 +25,20 @@
// =============================================================================
#include <QObject>
#include <QDateTime>
#include <QSharedPointer>
#include <linphone++/chat_room.hh>
#include "../contact/ContactModel.hpp"
class ChatRoomModel;
class ChatRoomListener;
class TimelineModel : public QObject, public linphone::ChatRoomListener {
class TimelineModel : public QObject {
Q_OBJECT
public:
static std::shared_ptr<TimelineModel> create(std::shared_ptr<linphone::ChatRoom> chatRoom, const std::list<std::shared_ptr<linphone::CallLog>>& callLogs = std::list<std::shared_ptr<linphone::CallLog>>(), QObject *parent = Q_NULLPTR);
static QSharedPointer<TimelineModel> create(std::shared_ptr<linphone::ChatRoom> chatRoom, const std::list<std::shared_ptr<linphone::CallLog>>& callLogs = std::list<std::shared_ptr<linphone::CallLog>>(), QObject *parent = Q_NULLPTR);
TimelineModel (std::shared_ptr<linphone::ChatRoom> chatRoom, QObject *parent = Q_NULLPTR);
virtual ~TimelineModel();
@ -62,35 +64,37 @@ public:
void setSelected(const bool& selected);
Q_INVOKABLE ChatRoomModel* getChatRoomModel() const;
void disconnectChatRoomListener();
bool mSelected;
std::shared_ptr<ChatRoomModel> mChatRoomModel;
QSharedPointer<ChatRoomModel> mChatRoomModel;
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;
virtual void onIsComposingReceived(const std::shared_ptr<linphone::ChatRoom> & chatRoom, const std::shared_ptr<const linphone::Address> & remoteAddress, bool isComposing);
virtual void onMessageReceived(const std::shared_ptr<linphone::ChatRoom> & chatRoom, const std::shared_ptr<linphone::ChatMessage> & message);
virtual void onNewEvent(const std::shared_ptr<linphone::ChatRoom> & chatRoom, const std::shared_ptr<const linphone::EventLog> & eventLog);
virtual void onChatMessageReceived(const std::shared_ptr<linphone::ChatRoom> & chatRoom, const std::shared_ptr<const linphone::EventLog> & eventLog);
virtual void onChatMessageSending(const std::shared_ptr<linphone::ChatRoom> & chatRoom, const std::shared_ptr<const linphone::EventLog> & eventLog);
virtual void onChatMessageSent(const std::shared_ptr<linphone::ChatRoom> & chatRoom, const std::shared_ptr<const linphone::EventLog> & eventLog);
virtual void onParticipantAdded(const std::shared_ptr<linphone::ChatRoom> & chatRoom, const std::shared_ptr<const linphone::EventLog> & eventLog);
virtual void onParticipantRemoved(const std::shared_ptr<linphone::ChatRoom> & chatRoom, const std::shared_ptr<const linphone::EventLog> & eventLog);
virtual void onParticipantAdminStatusChanged(const std::shared_ptr<linphone::ChatRoom> & chatRoom, const std::shared_ptr<const linphone::EventLog> & eventLog);
virtual void onStateChanged(const std::shared_ptr<linphone::ChatRoom> & chatRoom, linphone::ChatRoom::State newState);
virtual void onSecurityEvent(const std::shared_ptr<linphone::ChatRoom> & chatRoom, const std::shared_ptr<const linphone::EventLog> & eventLog);
virtual void onSubjectChanged(const std::shared_ptr<linphone::ChatRoom> & chatRoom, const std::shared_ptr<const linphone::EventLog> & eventLog);
virtual void onUndecryptableMessageReceived(const std::shared_ptr<linphone::ChatRoom> & chatRoom, const std::shared_ptr<linphone::ChatMessage> & message);
virtual void onParticipantDeviceAdded(const std::shared_ptr<linphone::ChatRoom> & chatRoom, const std::shared_ptr<const linphone::EventLog> & eventLog);
virtual void onParticipantDeviceRemoved(const std::shared_ptr<linphone::ChatRoom> & chatRoom, const std::shared_ptr<const linphone::EventLog> & eventLog);
virtual void onConferenceJoined(const std::shared_ptr<linphone::ChatRoom> & chatRoom, const std::shared_ptr<const linphone::EventLog> & eventLog);
virtual void onConferenceLeft(const std::shared_ptr<linphone::ChatRoom> & chatRoom, const std::shared_ptr<const linphone::EventLog> & eventLog);
virtual void onEphemeralEvent(const std::shared_ptr<linphone::ChatRoom> & chatRoom, const std::shared_ptr<const linphone::EventLog> & eventLog);
virtual void onEphemeralMessageTimerStarted(const std::shared_ptr<linphone::ChatRoom> & chatRoom, const std::shared_ptr<const linphone::EventLog> & eventLog);
virtual void onEphemeralMessageDeleted(const std::shared_ptr<linphone::ChatRoom> & chatRoom, const std::shared_ptr<const linphone::EventLog> & eventLog);
virtual void onConferenceAddressGeneration(const std::shared_ptr<linphone::ChatRoom> & chatRoom);
virtual void onParticipantRegistrationSubscriptionRequested(const std::shared_ptr<linphone::ChatRoom> & chatRoom, const std::shared_ptr<const linphone::Address> & participantAddress);
virtual void onParticipantRegistrationUnsubscriptionRequested(const std::shared_ptr<linphone::ChatRoom> & chatRoom, const std::shared_ptr<const linphone::Address> & participantAddress);
virtual void onChatMessageShouldBeStored(const std::shared_ptr<linphone::ChatRoom> & chatRoom, const std::shared_ptr<linphone::ChatMessage> & message);
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);
public slots:
void updateUnreadCount();
@ -108,8 +112,9 @@ signals:
private:
std::weak_ptr<TimelineModel> mSelf;
void connectTo(ChatRoomListener * listener);
std::shared_ptr<ChatRoomListener> mChatRoomListener;
};
#endif // TIMELINE_MODEL_H_
#endif

View file

@ -47,12 +47,12 @@ TimelineProxyModel::TimelineProxyModel (QObject *parent) : QSortFilterProxyModel
connect(model, &TimelineListModel::countChanged, this, &TimelineProxyModel::countChanged);
QObject::connect(accountSettingsModel, &AccountSettingsModel::defaultAccountChanged, this, [this]() {
dynamic_cast<TimelineListModel*>(sourceModel())->update();
qobject_cast<TimelineListModel*>(sourceModel())->update();
invalidate();
//updateCurrentSelection();
});
QObject::connect(coreManager->getSipAddressesModel(), &SipAddressesModel::sipAddressReset, this, [this]() {
dynamic_cast<TimelineListModel*>(sourceModel())->reset();
qobject_cast<TimelineListModel*>(sourceModel())->reset();
invalidate();// Invalidate and reload GUI if the model has been reset
//updateCurrentSelection();
});
@ -63,12 +63,8 @@ TimelineProxyModel::TimelineProxyModel (QObject *parent) : QSortFilterProxyModel
// -----------------------------------------------------------------------------
int TimelineProxyModel::getCount() const{
return dynamic_cast<TimelineListModel*>(sourceModel())->getCount();
}
void TimelineProxyModel::unselectAll(){
dynamic_cast<TimelineListModel*>(sourceModel())->selectAll(false);
qobject_cast<TimelineListModel*>(sourceModel())->selectAll(false);
}
void TimelineProxyModel::setFilterFlags(const int& filterFlags){

View file

@ -49,10 +49,8 @@ public:
Q_PROPERTY(int filterFlags MEMBER mFilterFlags WRITE setFilterFlags NOTIFY filterFlagsChanged)
Q_PROPERTY(QString filterText MEMBER mFilterText WRITE setFilterText NOTIFY filterTextChanged)
Q_PROPERTY(int count READ getCount NOTIFY countChanged)
Q_PROPERTY(int count READ rowCount NOTIFY countChanged)
int getCount() const;
Q_INVOKABLE void unselectAll();
Q_INVOKABLE void setFilterFlags(const int& filterFlags);
Q_INVOKABLE void setFilterText(const QString& text);

View file

@ -484,7 +484,7 @@ QString Utils::getDisplayName(const std::shared_ptr<const linphone::Address>& ad
std::shared_ptr<linphone::Address> cleanAddress = address->clone();
cleanAddress->clean();
QString qtAddress = Utils::coreStringToAppString(cleanAddress->asStringUriOnly());
ContactModel * model = CoreManager::getInstance()->getContactsListModel()->findContactModelFromSipAddress(qtAddress);
auto model = CoreManager::getInstance()->getContactsListModel()->findContactModelFromSipAddress(qtAddress);
if(model && model->getVcardModel())
displayName = model->getVcardModel()->getUsername();
else{

View file

@ -115,20 +115,22 @@ QJsonDocument PluginsManager::getJson(const QString &pluginIdentity){
}
return doc;
}
QList<PluginsModel*> PluginsManager::getImporterModels(const QStringList &capabilities){
QList<PluginsModel*> models;
QList<QSharedPointer<PluginsModel>> PluginsManager::getImporterModels(const QStringList &capabilities){
QList<QSharedPointer<PluginsModel>> models;
for(int i = 0 ; i < capabilities.size() ; ++i){
if( capabilities[i] == "CONTACTS")
models += CoreManager::getInstance()->getContactsImporterListModel()->getList();
models << CoreManager::getInstance()->getContactsImporterListModel()->getSharedList<PluginsModel>();
}
return models;
}
void PluginsManager::openNewPlugin(const QString &pTitle){
QString fileName = QFileDialog::getOpenFileName(nullptr, pTitle);
QString pluginIdentity;
QStringList capabilities;
QList<PluginsModel*> modelsToReset;
QList<QSharedPointer<PluginsModel>> modelsToReset;
int doCopy = QMessageBox::Yes;
bool cannotRemovePlugin = false;
//QVersionNumber pluginVersion, apiVersion = LinphonePlugin::gPluginVersion;
@ -155,7 +157,7 @@ void PluginsManager::openNewPlugin(const QString &pTitle){
doCopy = QMessageBox::question(nullptr, pTitle, "The plugin already exists. Do you want to overwrite it?\n"+oldPlugins.join('\n'), QMessageBox::Yes, QMessageBox::No);
if( doCopy == QMessageBox::Yes){
if(gPluginsMap.contains(pluginIdentity)){
auto importers = CoreManager::getInstance()->getContactsImporterListModel()->getList();
auto importers = CoreManager::getInstance()->getContactsImporterListModel()->getSharedList<PluginsModel>();
for(auto importer : importers){
QJsonObject pluginMetaData(importer->getDataAPI()->getPluginLoader()->metaData());
if( pluginMetaData.contains("ID") && pluginMetaData["ID"].toString() == pluginIdentity){

View file

@ -6,6 +6,7 @@
#include <QObject>
#include <QVariantList>
#include <memory>
// =============================================================================
@ -14,6 +15,7 @@ class PluginDataAPI;
class QPluginLoader;
class PluginsModel : public QObject{
Q_OBJECT
public:
PluginsModel(QObject *parent = nullptr) : QObject(parent){}
virtual ~PluginsModel(){}
@ -38,7 +40,7 @@ public:
QList<PluginsModel*> getImporterModels(const QStringList &capabilities);
QList<QSharedPointer<PluginsModel>> getImporterModels(const QStringList &capabilities);
static QMap<QString, QString> gPluginsMap; // Map between Identity and plugin path
static QString gPluginsConfigSection; // The root name of the plugin's section in configuration file
};

View file

@ -130,7 +130,7 @@ ListView {
// -------------------------------------------------------------------------
function useColorStatus () {
return calls.currentIndex === index && $call && $call.status !== CallModel.CallStatusEnded
return calls.currentIndex === index && modelData && modelData.status !== CallModel.CallStatusEnded
}
// -------------------------------------------------------------------------
@ -150,13 +150,13 @@ ListView {
return params ? 'call_sign_' + params.string : ''
}
entry: $call
entry: modelData
width: calls.width
onClicked: {
if ($call.status !== CallModel.CallStatusEnded) {
Logic.updateSelectedCall($call, index)
if (modelData.status !== CallModel.CallStatusEnded) {
Logic.updateSelectedCall(modelData, index)
}
}
@ -167,9 +167,9 @@ ListView {
readonly property int callId: index
readonly property var call: $call
readonly property var call: modelData
readonly property var callControls: _callControls
readonly property var params: Logic.getParams($call)
readonly property var params: Logic.getParams(modelData)
anchors.centerIn: parent
sourceComponent: params ? params.component : null
@ -177,7 +177,7 @@ ListView {
SequentialAnimation on color {
loops: CallsStyle.entry.endCallAnimation.loops
running: !$call || $call.status === CallModel.CallStatusEnded
running: !modelData || modelData.status === CallModel.CallStatusEnded
ColorAnimation {
duration: CallsStyle.entry.endCallAnimation.duration

View file

@ -26,6 +26,7 @@ Loader{
property int maxWidth : parent.width
property int fitHeight: active && item ? item.fitHeight + ChatCalendarMessageStyle.heightMargin*2 : 0
property int fitWidth: active && item ? Math.max(item.fitWidth, maxWidth/2) + ChatCalendarMessageStyle.widthMargin*2 : 0
property bool containsMouse: false
width: parent.width
height: fitHeight
@ -45,9 +46,9 @@ Loader{
clip: false
cursorShape: Qt.ArrowCursor
hoverEnabled: true
onClicked: CallsListModel.launchVideoCall(mainItem.conferenceInfoModel.uri, '', 0)
onHoveredChanged: mainItem.containsMouse = loadedItem.containsMouse
ColumnLayout{
id: layout
@ -59,6 +60,7 @@ Loader{
Layout.fillWidth: true
Layout.preferredWidth: parent.width // Need this because fillWidth is not enough...
Layout.preferredHeight: ChatCalendarMessageStyle.schedule.iconSize
Layout.topMargin: 5
spacing: 10
RowLayout {
id: scheduleRow
@ -93,7 +95,7 @@ Loader{
Layout.fillHeight: true
Layout.minimumWidth: implicitWidth
Layout.preferredWidth: implicitWidth
Layout.rightMargin: 10
Layout.rightMargin: 15
verticalAlignment: Qt.AlignVCenter
color: ChatCalendarMessageStyle.schedule.color
elide: Text.ElideRight
@ -105,7 +107,6 @@ Loader{
id: title
Layout.fillWidth: true
Layout.minimumWidth: implicitWidth
Layout.topMargin: 10
Layout.leftMargin: 10
Layout.alignment: Qt.AlignRight
color: ChatCalendarMessageStyle.subject.color
@ -118,6 +119,7 @@ Loader{
Layout.fillWidth: true
Layout.fillHeight: true
Layout.leftMargin: 5
Layout.rightMargin: 15
spacing: ChatCalendarMessageStyle.participants.spacing
@ -135,6 +137,13 @@ Loader{
elide: Text.ElideRight
font.pointSize: ChatCalendarMessageStyle.participants.pointSize
text: mainItem.conferenceInfoModel.displayNamesToString
}
ActionButton{
Layout.preferredHeight: iconSize
Layout.preferredWidth: height
isCustom: true
colorSet: ChatCalendarMessageStyle.gotoButton
backgroundRadius: width/2
}
}
}

View file

@ -8,7 +8,7 @@ import ColorsList 1.0
QtObject {
property string sectionName : 'ChatCalendarMessage'
property int heightMargin: 5
property int heightMargin: 0
property int widthMargin: 5
property int minWidth: 300
@ -39,7 +39,7 @@ QtObject {
property QtObject schedule: QtObject {
property int spacing: 0
property int pointSize: Units.dp * 10
property int pointSize: Units.dp * 9
property string icon : 'schedule_custom'
property int iconSize: 30
property color color: ColorsList.add(sectionName+'_schedule', 'j').color
@ -51,15 +51,27 @@ QtObject {
}
property QtObject participants: QtObject {
property int spacing: 5
property int pointSize: Units.dp * 10
property int pointSize: Units.dp * 9
property string icon : 'calendar_participants_custom'
property int iconSize: 30
property color color: ColorsList.add(sectionName+'_participants', 'j').color
}
property QtObject gotoButton: QtObject{
property int iconSize: 20
property string name : 'goto'
property string icon : 'transfer_custom'
property color backgroundNormalColor : ColorsList.addImageColor(sectionName+'_'+name+'_b_n', icon, 's_n_b_bg').color
property color backgroundHoveredColor : ColorsList.addImageColor(sectionName+'_'+name+'_b_h', icon, 's_h_b_bg').color
property color backgroundPressedColor : ColorsList.addImageColor(sectionName+'_'+name+'_b_p', icon, 's_p_b_bg').color
property color foregroundNormalColor : ColorsList.addImageColor(sectionName+'_'+name+'_f_n', icon, 's_n_b_fg').color
property color foregroundHoveredColor : ColorsList.addImageColor(sectionName+'_'+name+'_f_h', icon, 's_h_b_fg').color
property color foregroundPressedColor : ColorsList.addImageColor(sectionName+'_'+name+'_f_p', icon, 's_p_b_fg').color
}
property QtObject organizer: QtObject {
property color color: ColorsList.add(sectionName+'_conference_organizer', 'j').color
property int pointSize: Units.dp * 10
property int pointSize: Units.dp * 9
property int width: 220
}

View file

@ -249,7 +249,7 @@ Window {
id: middlePane
anchors.fill: parent
sourceComponent: Logic.getContent()
onSourceComponentChanged: {console.log(sourceComponent); rightPaned.childAItem.update()}// Force update when loading a new Content. It's just to be sure
onSourceComponentChanged: {rightPaned.childAItem.update()}// Force update when loading a new Content. It's just to be sure
}
childB: Loader {

View file

@ -120,8 +120,8 @@ Rectangle {
width: grid.cellWidth
Column {
readonly property string sipAddress: $call.peerAddress
property var _sipAddressObserver : SipAddressesModel.getSipAddressObserver($call.peerAddress, $call.localAddress)
readonly property string sipAddress: modelData.peerAddress
property var _sipAddressObserver : SipAddressesModel.getSipAddressObserver(modelData.peerAddress, modelData.localAddress)
anchors {
fill: parent
@ -148,7 +148,7 @@ Rectangle {
)
anchors.horizontalCenter: parent.horizontalCenter
call: $call
call: modelData
onCallChanged: if(!call) conference.conferenceModel.invalidate()
height: size
@ -164,7 +164,7 @@ Rectangle {
height: CallStyle.header.busyIndicator.height
width: CallStyle.header.busyIndicator.width
visible: $call && $call.status === CallModel.CallStatusOutgoing
visible: modelData && modelData.status === CallModel.CallStatusOutgoing
}
}
}
@ -176,18 +176,18 @@ Rectangle {
leftMargin: ConferenceStyle.grid.spacing
bottomMargin: ConferenceStyle.grid.spacing
}
enabled:!$call.speakerMuted
enabled:!modelData.speakerMuted
Timer {
interval: 50
repeat: true
running: true
onTriggered: parent.value = $call.speakerVu
onTriggered: parent.value = modelData.speakerVu
}
}
MouseArea{
anchors.fill:parent
onClicked:$call.toggleSpeakerMute()
onClicked:modelData.toggleSpeakerMute()
}
}
}

View file

@ -152,6 +152,7 @@ Rectangle {
property ParticipantDeviceProxyModel participantDevices : ParticipantDeviceProxyModel {
id: participantDevices
callModel: conference.callModel
showMe: true
}
/*
property ListModel defaultList : ListModel{}
@ -201,7 +202,7 @@ Rectangle {
Loader {
anchors.centerIn: parent
active: avatarCell.currentDevice && (!avatarCell.currentDevice.videoEnabled || conference._fullscreen)
active: avatarCell.currentDevice && !avatarCell.currentDevice.isMe && (!avatarCell.currentDevice.videoEnabled || conference._fullscreen)
sourceComponent: avatar
}
Loader {
@ -217,19 +218,19 @@ Rectangle {
onT_fullscreenChanged: console.log("_fullscreen changed: " +t_fullscreen+ " ["+index+"]")
onTCallModelChanged: console.log("CallModel changed: " +tCallModel+ " ["+index+"]")
active: !resetActive && avatarCell.currentDevice && (avatarCell.currentDevice.videoEnabled && !conference._fullscreen)
active: !resetActive //avatarCell.currentDevice && (avatarCell.currentDevice.videoEnabled && !conference._fullscreen)
onActiveChanged: {console.log("Active Changed: "+active+ " ["+index+"]")
if(!active && resetActive){
resetActive = false
active = true
}
}
sourceComponent: avatarCell.currentDevice ?
avatarCell.currentDevice.isMe ? ( true ? cameraPreview : null )
: camera
: null
onSourceComponentChanged: console.log("SourceComponent Changed: "+sourceComponent+ " ["+index+"]")
property int cameraMode: avatarCell.currentDevice ?
avatarCell.currentDevice.isMe ? 1
: 2
: 0
sourceComponent: cameraMode == 1 ? cameraPreview : cameraMode == 2 ? camera : null
onSourceComponentChanged: console.log("SourceComponent Changed: "+cameraMode+ " ["+index+"]")
Component {
@ -252,7 +253,7 @@ Rectangle {
Camera {
anchors.fill: parent
//call: incall.call
//participantDeviceModel: avatarCell.currentDevice
isPreview: true
onRequestNewRenderer: {cameraLoader.resetActive = true}
@ -261,6 +262,10 @@ Rectangle {
}
}
}
Rectangle{
anchors.fill: parent
color: avatarCell.currentDevice.isMe ? '#09FF0000' : '#0900FF00'
}
}
MouseArea{
anchors.fill: parent

View file

@ -13,7 +13,7 @@ import App.Styles 1.0
ColumnLayout {
id: container
property int filterMode: ConferenceInfoProxyModel.ConferenceType.Scheduled
spacing: 0
// ---------------------------------------------------------------------------
@ -28,7 +28,7 @@ ColumnLayout {
Text{
anchors.verticalCenter: parent.center
anchors.fill: parent
verticalAlignment: Qt.AlignCenter
anchors.leftMargin: 40
text: 'Mes conférences'
@ -54,6 +54,10 @@ ColumnLayout {
'PROGRAMMEES',
'INVITATIONS'
]
onClicked: {
mainItem.filterMode = (button === 0 ? ConferenceInfoProxyModel.ConferenceType.Ended : button === 1 ?ConferenceInfoProxyModel.ConferenceType.Scheduled : ConferenceInfoProxyModel.ConferenceType.Invitations);
}
}
}
}
@ -79,7 +83,10 @@ ColumnLayout {
property: 'date'
}
model: ConferenceInfoProxyModel{}
model: ConferenceInfoProxyModel{
id: conferencesProxyModel
}
// -----------------------------------------------------------------------
// Heading.
@ -141,7 +148,7 @@ ColumnLayout {
id: calendarGrid
//anchors.fill: parent
cellWidth: (container.width-20)/2
cellHeight: 112
cellHeight: 100
model: modelData
height: cellHeight * ( (count+1) /2)
width: container.width - 20
@ -151,7 +158,8 @@ ColumnLayout {
height: calendarGrid.cellHeight -10
radius: 6
color: ConferencesStyle.conference.backgroundColor.normal
border.color: calendarMessage.containsMouse ? ConferencesStyle.conference.selectedBorder.color : 'transparent'
border.width: ConferencesStyle.conference.selectedBorder.width
ChatCalendarMessage{
id: calendarMessage
conferenceInfoModel: modelData

View file

@ -80,7 +80,7 @@ function removeContact () {
if (status) {
window.unlockView()
window.setView('Contacts')
Linphone.ContactsListModel.removeContact(_contact)
Linphone.ContactsListModel.remove(_contact)
}
})
}

View file

@ -17,7 +17,7 @@ ColumnLayout {
descriptionText: qsTr('removeContactDescription'),
}, function (status) {
if (status) {
ContactsListModel.removeContact(contact)
ContactsListModel.remove(contact)
}
})
}
@ -109,7 +109,7 @@ ColumnLayout {
PresenceLevel {
Layout.preferredHeight: ContactsStyle.contact.presenceLevelSize
Layout.preferredWidth: ContactsStyle.contact.presenceLevelSize
level: $contact.presenceLevel
level: modelData.presenceLevel
}
Text {
@ -117,7 +117,7 @@ ColumnLayout {
color: ContactsStyle.contact.presence.color
elide: Text.ElideRight
font.pointSize: ContactsStyle.contact.presence.pointSize
text: Presence.getPresenceStatusAsString($contact.presenceStatus)
text: Presence.getPresenceStatusAsString(modelData.presenceStatus)
}
}
}
@ -189,7 +189,7 @@ ColumnLayout {
verticalCenter: parent.verticalCenter
}
onClicked: _removeContact($contact)
onClicked: _removeContact(modelData)
}
}
}
@ -223,7 +223,7 @@ ColumnLayout {
relativeTo: loader
relativeY: loader.height
sipAddresses: $contact.vcard.sipAddresses
sipAddresses: modelData.vcard.sipAddresses
onSipAddressClicked: actions.handlers[index](sipAddress)
}
@ -250,7 +250,7 @@ ColumnLayout {
anchors.fill: parent
onClicked: window.setView('ContactEdit', {
sipAddress: $contact.vcard.sipAddresses[0]
sipAddress: modelData.vcard.sipAddresses[0]
})
}
@ -269,8 +269,8 @@ ColumnLayout {
Avatar {
anchors.centerIn: parent
image: $contact.vcard.avatar
username: $contact.vcard.username
image: modelData.vcard.avatar
username: modelData.vcard.username
height: ContactsStyle.contact.avatarSize
width: ContactsStyle.contact.avatarSize
@ -289,7 +289,7 @@ ColumnLayout {
pointSize: ContactsStyle.contact.username.pointSize
}
text: $contact.vcard.username
text: modelData.vcard.username
verticalAlignment: Text.AlignVCenter
}

View file

@ -308,7 +308,7 @@ ApplicationWindow {
iconSize: MainWindowStyle.menu.conferences.iconSize
overwriteColor: isSelected ? MainWindowStyle.menu.conferences.selectedColor : MainWindowStyle.menu.conferences.color
name: 'MES CONFERENCES'
visible: SettingsModel.conferencesEnabled
visible: SettingsModel.conferenceEnabled
onSelected: {
timeline.model.unselectAll()

View file

@ -51,6 +51,7 @@ function initForm (account) {
route.text = config.route
conferenceUri.text = config.conferenceUri
videoConferenceUri.text = config.videoConferenceUri
contactParams.text = config.contactParams
avpfInterval.text = config.avpfInterval
registerEnabled.checked = config.registerEnabled
@ -71,7 +72,7 @@ function initForm (account) {
}
function formIsValid () {
return dialog._sipAddressOk && dialog._serverAddressOk && dialog._routeOk && dialog._conferenceUriOk
return dialog._sipAddressOk && dialog._serverAddressOk && dialog._routeOk && dialog._conferenceUriOk && dialog._videoConferenceUriOk
}
// -----------------------------------------------------------------------------
@ -84,6 +85,7 @@ function validAccount (account) {
transport: transport.currentText,
route: route.text,
conferenceUri: conferenceUri.text,
videoConferenceUri: videoConferenceUri.text,
contactParams: contactParams.text,
avpfInterval: avpfInterval.text,
registerEnabled: registerEnabled.checked,
@ -113,6 +115,10 @@ function handleConferenceUriChanged (uri) {
dialog._conferenceUriOk = uri=='' || Linphone.SipAddressesModel.addressIsValid(uri)
}
function handleVideoConferenceUriChanged (uri) {
dialog._videoConferenceUriOk = uri=='' || Linphone.SipAddressesModel.addressIsValid(uri)
}
function handleServerAddressChanged (address) {
if (address.length === 0) {
dialog._serverAddressOk = false

View file

@ -17,6 +17,7 @@ DialogPlus {
property bool _serverAddressOk: false
property bool _routeOk: true
property bool _conferenceUriOk: true
property bool _videoConferenceUriOk: true
buttons: [
TextButtonA {
@ -145,6 +146,22 @@ DialogPlus {
}
}
}
FormLine {
FormGroup {
label: 'Video Conference URI'
TextField {
id: videoConferenceUri
//: "invalid conference URI" : Error text about conference URI
error: dialog._videoConferenceUriOk ? '' : qsTr("invalidConferenceURI")
onTextChanged: Logic.handleVideoConferenceUriChanged(text)
Keys.onEnterPressed: nextItemInFocusChain().forceActiveFocus()
Keys.onReturnPressed: nextItemInFocusChain().forceActiveFocus()
}
}
}
FormLine {
FormGroup {

View file

@ -28,4 +28,5 @@ QtObject {
}
}
}
}

View file

@ -373,6 +373,15 @@ QtObject {
property color foregroundDisabledColor : ColorsList.addImageColor(sectionName+'_'+name+'_fg_d', icon, 'me_d_b_fg').color
property color foregroundHoveredColor : ColorsList.addImageColor(sectionName+'_'+name+'_fg_h', icon, 'me_h_b_fg').color
property color foregroundPressedColor : ColorsList.addImageColor(sectionName+'_'+name+'_fg_p', icon, 'me_p_b_fg').color
property color backgroundHiddenPartNormalColor : ColorsList.addImageColor(sectionName+'_'+name+'_hidden_bg_n', icon, 'me_n_b_inv_bg').color
property color backgroundHiddenPartDisabledColor : ColorsList.addImageColor(sectionName+'_'+name+'_hidden_bg_d', icon, 'me_d_b_inv_bg').color
property color backgroundHiddenPartHoveredColor : ColorsList.addImageColor(sectionName+'_'+name+'_hidden_bg_h', icon, 'me_h_b_inv_bg').color
property color backgroundHiddenPartPressedColor : ColorsList.addImageColor(sectionName+'_'+name+'_hidden_bg_p', icon, 'me_p_b_inv_bg').color
property color foregroundHiddenPartNormalColor : ColorsList.addImageColor(sectionName+'_'+name+'_hidden_fg_n', icon, 'me_n_b_inv_fg').color
property color foregroundHiddenPartDisabledColor : ColorsList.addImageColor(sectionName+'_'+name+'_hidden_fg_d', icon, 'me_d_b_inv_fg').color
property color foregroundHiddenPartHoveredColor : ColorsList.addImageColor(sectionName+'_'+name+'_hidden_fg_h', icon, 'me_h_b_inv_fg').color
property color foregroundHiddenPartPressedColor : ColorsList.addImageColor(sectionName+'_'+name+'_hidden_fg_p', icon, 'me_p_b_inv_fg').color
}
property QtObject options: QtObject {
property int iconSize: 40

View file

@ -43,6 +43,10 @@ QtObject {
property color color: ColorsList.add(sectionName+'_conference_border', 'f').color
property int width: 1
}
property QtObject selectedBorder: QtObject{
property color color: ColorsList.add(sectionName+'_conference_selected_border', 'm').color
property int width: 2
}
property QtObject indicator: QtObject {
property color color: ColorsList.add(sectionName+'_conference_indicator', 'i').color