first compiling prototype, doesnt work yet

This commit is contained in:
Blue 2020-08-12 01:49:51 +03:00
parent ef1a9846bf
commit 38159eafeb
21 changed files with 662 additions and 734 deletions

View File

@ -9,6 +9,10 @@ set(CMAKE_AUTOUIC ON)
# Find the QtWidgets library # Find the QtWidgets library
find_package(Qt5Widgets CONFIG REQUIRED) find_package(Qt5Widgets CONFIG REQUIRED)
find_package(Qt5DBus CONFIG REQUIRED) find_package(Qt5DBus CONFIG REQUIRED)
find_package(Boost 1.36.0 CONFIG REQUIRED)
if(Boost_FOUND)
include_directories(${Boost_INCLUDE_DIRS})
endif()
add_subdirectory(widgets) add_subdirectory(widgets)
@ -25,6 +29,8 @@ set(squawkUI_SRC
models/abstractparticipant.cpp models/abstractparticipant.cpp
models/participant.cpp models/participant.cpp
models/reference.cpp models/reference.cpp
models/messagefeed.cpp
models/element.cpp
utils/messageline.cpp utils/messageline.cpp
utils//message.cpp utils//message.cpp
utils/resizer.cpp utils/resizer.cpp

View File

@ -17,55 +17,26 @@
*/ */
#include "contact.h" #include "contact.h"
#include "account.h"
#include <QDebug> #include <QDebug>
Models::Contact::Contact(const Account* acc, const QString& p_jid ,const QMap<QString, QVariant> &data, Item *parentItem): Models::Contact::Contact(const Account* acc, const QString& p_jid ,const QMap<QString, QVariant> &data, Item *parentItem):
Item(Item::contact, data, parentItem), Element(Item::contact, acc, p_jid, data, parentItem),
jid(p_jid),
availability(Shared::Availability::offline), availability(Shared::Availability::offline),
state(Shared::SubscriptionState::none), state(Shared::SubscriptionState::none),
avatarState(Shared::Avatar::empty),
presences(), presences(),
messages(), status()
childMessages(0),
status(),
avatarPath(),
account(acc)
{ {
QMap<QString, QVariant>::const_iterator itr = data.find("state"); QMap<QString, QVariant>::const_iterator itr = data.find("state");
if (itr != data.end()) { if (itr != data.end()) {
setState(itr.value().toUInt()); setState(itr.value().toUInt());
} }
itr = data.find("avatarState");
if (itr != data.end()) {
setAvatarState(itr.value().toUInt());
}
itr = data.find("avatarPath");
if (itr != data.end()) {
setAvatarPath(itr.value().toString());
}
} }
Models::Contact::~Contact() Models::Contact::~Contact()
{ {
} }
QString Models::Contact::getJid() const
{
return jid;
}
void Models::Contact::setJid(const QString p_jid)
{
if (jid != p_jid) {
jid = p_jid;
changed(1);
}
}
void Models::Contact::setAvailability(unsigned int p_state) void Models::Contact::setAvailability(unsigned int p_state)
{ {
setAvailability(Shared::Global::fromInt<Shared::Availability>(p_state)); setAvailability(Shared::Global::fromInt<Shared::Availability>(p_state));
@ -144,16 +115,12 @@ void Models::Contact::update(const QString& field, const QVariant& value)
{ {
if (field == "name") { if (field == "name") {
setName(value.toString()); setName(value.toString());
} else if (field == "jid") {
setJid(value.toString());
} else if (field == "availability") { } else if (field == "availability") {
setAvailability(value.toUInt()); setAvailability(value.toUInt());
} else if (field == "state") { } else if (field == "state") {
setState(value.toUInt()); setState(value.toUInt());
} else if (field == "avatarState") { } else {
setAvatarState(value.toUInt()); Element::update(field, value);
} else if (field == "avatarPath") {
setAvatarPath(value.toString());
} }
} }
@ -192,11 +159,9 @@ void Models::Contact::refresh()
{ {
QDateTime lastActivity; QDateTime lastActivity;
Presence* presence = 0; Presence* presence = 0;
unsigned int count = 0;
for (QMap<QString, Presence*>::iterator itr = presences.begin(), end = presences.end(); itr != end; ++itr) { for (QMap<QString, Presence*>::iterator itr = presences.begin(), end = presences.end(); itr != end; ++itr) {
Presence* pr = itr.value(); Presence* pr = itr.value();
QDateTime la = pr->getLastActivity(); QDateTime la = pr->getLastActivity();
count += pr->getMessagesCount();
if (la > lastActivity) { if (la > lastActivity) {
lastActivity = la; lastActivity = la;
@ -211,11 +176,6 @@ void Models::Contact::refresh()
setAvailability(Shared::Availability::offline); setAvailability(Shared::Availability::offline);
setStatus(""); setStatus("");
} }
if (childMessages != count) {
childMessages = count;
changed(4);
}
} }
void Models::Contact::_removeChild(int index) void Models::Contact::_removeChild(int index)
@ -257,81 +217,6 @@ QIcon Models::Contact::getStatusIcon(bool big) const
} }
} }
void Models::Contact::addMessage(const Shared::Message& data)
{
const QString& res = data.getPenPalResource();
if (res.size() > 0) {
QMap<QString, Presence*>::iterator itr = presences.find(res);
if (itr == presences.end()) {
// this is actually the place when I can spot someone's invisible presence, and there is nothing criminal in it, cuz the sender sent us a message
// therefore he have revealed himself
// the only issue is to find out when the sender is gone offline
Presence* pr = new Presence({});
pr->setName(res);
pr->setAvailability(Shared::Availability::invisible);
pr->setLastActivity(QDateTime::currentDateTimeUtc());
presences.insert(res, pr);
appendChild(pr);
pr->addMessage(data);
return;
}
itr.value()->addMessage(data);
} else {
messages.emplace_back(data);
changed(4);
}
}
void Models::Contact::changeMessage(const QString& id, const QMap<QString, QVariant>& data)
{
bool found = false;
for (Shared::Message& msg : messages) {
if (msg.getId() == id) {
msg.change(data);
found = true;
break;
}
}
if (!found) {
for (Presence* pr : presences) {
found = pr->changeMessage(id, data);
if (found) {
break;
}
}
}
}
unsigned int Models::Contact::getMessagesCount() const
{
return messages.size() + childMessages;
}
void Models::Contact::dropMessages()
{
if (messages.size() > 0) {
messages.clear();
changed(4);
}
for (QMap<QString, Presence*>::iterator itr = presences.begin(), end = presences.end(); itr != end; ++itr) {
itr.value()->dropMessages();
}
}
void Models::Contact::getMessages(Models::Contact::Messages& container) const
{
for (Messages::const_iterator itr = messages.begin(), end = messages.end(); itr != end; ++itr) {
const Shared::Message& msg = *itr;
container.push_back(msg);
}
for (QMap<QString, Presence*>::const_iterator itr = presences.begin(), end = presences.end(); itr != end; ++itr) {
itr.value()->getMessages(container);
}
}
void Models::Contact::toOfflineState() void Models::Contact::toOfflineState()
{ {
std::deque<Item*>::size_type size = childItems.size(); std::deque<Item*>::size_type size = childItems.size();
@ -355,75 +240,3 @@ QString Models::Contact::getDisplayedName() const
return getContactName(); return getContactName();
} }
bool Models::Contact::columnInvolvedInDisplay(int col)
{
return Item::columnInvolvedInDisplay(col) && col == 1;
}
Models::Contact * Models::Contact::copy() const
{
Contact* cnt = new Contact(*this);
return cnt;
}
Models::Contact::Contact(const Models::Contact& other):
Item(other),
jid(other.jid),
availability(other.availability),
state(other.state),
presences(),
messages(other.messages),
childMessages(0),
account(other.account)
{
for (const Presence* pres : other.presences) {
Presence* pCopy = new Presence(*pres);
presences.insert(pCopy->getName(), pCopy);
Item::appendChild(pCopy);
connect(pCopy, &Item::childChanged, this, &Contact::refresh);
}
refresh();
}
QString Models::Contact::getAvatarPath() const
{
return avatarPath;
}
Shared::Avatar Models::Contact::getAvatarState() const
{
return avatarState;
}
void Models::Contact::setAvatarPath(const QString& path)
{
if (path != avatarPath) {
avatarPath = path;
changed(7);
}
}
void Models::Contact::setAvatarState(Shared::Avatar p_state)
{
if (avatarState != p_state) {
avatarState = p_state;
changed(6);
}
}
void Models::Contact::setAvatarState(unsigned int p_state)
{
if (p_state <= static_cast<quint8>(Shared::Avatar::valid)) {
Shared::Avatar state = static_cast<Shared::Avatar>(p_state);
setAvatarState(state);
} else {
qDebug() << "An attempt to set invalid avatar state" << p_state << "to the contact" << jid << ", skipping";
}
}
const Models::Account * Models::Contact::getParentAccount() const
{
return account;
}

View File

@ -19,7 +19,7 @@
#ifndef MODELS_CONTACT_H #ifndef MODELS_CONTACT_H
#define MODELS_CONTACT_H #define MODELS_CONTACT_H
#include "item.h" #include "element.h"
#include "presence.h" #include "presence.h"
#include "shared/enums.h" #include "shared/enums.h"
#include "shared/message.h" #include "shared/message.h"
@ -31,49 +31,34 @@
#include <deque> #include <deque>
namespace Models { namespace Models {
class Account;
class Contact : public Item class Contact : public Element
{ {
Q_OBJECT Q_OBJECT
public: public:
typedef std::deque<Shared::Message> Messages;
Contact(const Account* acc, const QString& p_jid, const QMap<QString, QVariant> &data, Item *parentItem = 0); Contact(const Account* acc, const QString& p_jid, const QMap<QString, QVariant> &data, Item *parentItem = 0);
Contact(const Contact& other);
~Contact(); ~Contact();
QString getJid() const;
Shared::Availability getAvailability() const; Shared::Availability getAvailability() const;
Shared::SubscriptionState getState() const; Shared::SubscriptionState getState() const;
Shared::Avatar getAvatarState() const;
QString getAvatarPath() const;
QIcon getStatusIcon(bool big = false) const; QIcon getStatusIcon(bool big = false) const;
int columnCount() const override; int columnCount() const override;
QVariant data(int column) const override; QVariant data(int column) const override;
void update(const QString& field, const QVariant& value); void update(const QString& field, const QVariant& value) override;
void addPresence(const QString& name, const QMap<QString, QVariant>& data); void addPresence(const QString& name, const QMap<QString, QVariant>& data);
void removePresence(const QString& name); void removePresence(const QString& name);
QString getContactName() const; QString getContactName() const;
QString getStatus() const; QString getStatus() const;
void addMessage(const Shared::Message& data);
void changeMessage(const QString& id, const QMap<QString, QVariant>& data);
unsigned int getMessagesCount() const;
void dropMessages();
void getMessages(Messages& container) const;
QString getDisplayedName() const override; QString getDisplayedName() const override;
Contact* copy() const;
protected: protected:
void _removeChild(int index) override; void _removeChild(int index) override;
void _appendChild(Models::Item * child) override; void _appendChild(Models::Item * child) override;
bool columnInvolvedInDisplay(int col) override;
const Account* getParentAccount() const override;
protected slots: protected slots:
void refresh(); void refresh();
@ -84,23 +69,13 @@ protected:
void setAvailability(unsigned int p_state); void setAvailability(unsigned int p_state);
void setState(Shared::SubscriptionState p_state); void setState(Shared::SubscriptionState p_state);
void setState(unsigned int p_state); void setState(unsigned int p_state);
void setAvatarState(Shared::Avatar p_state);
void setAvatarState(unsigned int p_state);
void setAvatarPath(const QString& path);
void setJid(const QString p_jid);
void setStatus(const QString& p_state); void setStatus(const QString& p_state);
private: private:
QString jid;
Shared::Availability availability; Shared::Availability availability;
Shared::SubscriptionState state; Shared::SubscriptionState state;
Shared::Avatar avatarState;
QMap<QString, Presence*> presences; QMap<QString, Presence*> presences;
Messages messages;
unsigned int childMessages;
QString status; QString status;
QString avatarPath;
const Account* account;
}; };
} }

151
ui/models/element.cpp Normal file
View File

@ -0,0 +1,151 @@
/*
* Squawk messenger.
* Copyright (C) 2019 Yury Gubich <blue@macaw.me>
*
* 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 "element.h"
#include "account.h"
#include <QDebug>
Models::Element::Element(Type p_type, const Models::Account* acc, const QString& p_jid, const QMap<QString, QVariant>& data, Models::Item* parentItem):
Item(p_type, data, parentItem),
jid(p_jid),
avatarPath(),
avatarState(Shared::Avatar::empty),
account(acc),
feed(new MessageFeed())
{
connect(feed, &MessageFeed::requestArchive, this, &Element::requestArchive);
QMap<QString, QVariant>::const_iterator itr = data.find("avatarState");
if (itr != data.end()) {
setAvatarState(itr.value().toUInt());
}
itr = data.find("avatarPath");
if (itr != data.end()) {
setAvatarPath(itr.value().toString());
}
}
Models::Element::~Element()
{
delete feed;
}
QString Models::Element::getJid() const
{
return jid;
}
void Models::Element::setJid(const QString& p_jid)
{
if (jid != p_jid) {
jid = p_jid;
changed(1);
}
}
void Models::Element::update(const QString& field, const QVariant& value)
{
if (field == "jid") {
setJid(value.toString());
} else if (field == "avatarState") {
setAvatarState(value.toUInt());
} else if (field == "avatarPath") {
setAvatarPath(value.toString());
}
}
QString Models::Element::getAvatarPath() const
{
return avatarPath;
}
Shared::Avatar Models::Element::getAvatarState() const
{
return avatarState;
}
void Models::Element::setAvatarPath(const QString& path)
{
if (path != avatarPath) {
avatarPath = path;
if (type == contact) {
changed(7);
} else if (type == room) {
changed(8);
}
}
}
void Models::Element::setAvatarState(Shared::Avatar p_state)
{
if (avatarState != p_state) {
avatarState = p_state;
if (type == contact) {
changed(6);
} else if (type == room) {
changed(7);
}
}
}
void Models::Element::setAvatarState(unsigned int p_state)
{
if (p_state <= static_cast<quint8>(Shared::Avatar::valid)) {
Shared::Avatar state = static_cast<Shared::Avatar>(p_state);
setAvatarState(state);
} else {
qDebug() << "An attempt to set invalid avatar state" << p_state << "to the element" << jid << ", skipping";
}
}
bool Models::Element::columnInvolvedInDisplay(int col)
{
return Item::columnInvolvedInDisplay(col) && col == 1;
}
const Models::Account * Models::Element::getParentAccount() const
{
return account;
}
unsigned int Models::Element::getMessagesCount() const
{
return feed->unreadMessagesCount();
}
void Models::Element::addMessage(const Shared::Message& data)
{
feed->addMessage(data);
if (type == contact) {
changed(4);
} else if (type == room) {
changed(5);
}
}
void Models::Element::changeMessage(const QString& id, const QMap<QString, QVariant>& data)
{
}
void Models::Element::responseArchive(const std::list<Shared::Message> list)
{
feed->responseArchive(list);
}

70
ui/models/element.h Normal file
View File

@ -0,0 +1,70 @@
/*
* Squawk messenger.
* Copyright (C) 2019 Yury Gubich <blue@macaw.me>
*
* 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 ELEMENT_H
#define ELEMENT_H
#include "item.h"
#include "messagefeed.h"
namespace Models {
class Element : public Item
{
Q_OBJECT
protected:
Element(Type p_type, const Account* acc, const QString& p_jid, const QMap<QString, QVariant> &data, Item *parentItem = 0);
~Element();
public:
QString getJid() const;
Shared::Avatar getAvatarState() const;
QString getAvatarPath() const;
virtual void update(const QString& field, const QVariant& value);
void addMessage(const Shared::Message& data);
void changeMessage(const QString& id, const QMap<QString, QVariant>& data);
unsigned int getMessagesCount() const;
void responseArchive(const std::list<Shared::Message> list);
signals:
void requestArchive(const QString& before);
protected:
void setJid(const QString& p_jid);
void setAvatarState(Shared::Avatar p_state);
void setAvatarState(unsigned int p_state);
void setAvatarPath(const QString& path);
bool columnInvolvedInDisplay(int col) override;
const Account* getParentAccount() const override;
protected:
QString jid;
QString avatarPath;
Shared::Avatar avatarState;
const Account* account;
public:
MessageFeed* feed;
};
}
#endif // ELEMENT_H

145
ui/models/messagefeed.cpp Normal file
View File

@ -0,0 +1,145 @@
/*
* Squawk messenger.
* Copyright (C) 2019 Yury Gubich <blue@macaw.me>
*
* 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 "messagefeed.h"
#include <QDebug>
MessageFeed::MessageFeed(QObject* parent):
QAbstractListModel(parent),
storage(),
indexById(storage.get<id>()),
indexByTime(storage.get<time>()),
syncState(incomplete)
{
}
MessageFeed::~MessageFeed()
{
for (Shared::Message* message : storage) {
delete message;
}
}
void MessageFeed::addMessage(const Shared::Message& msg)
{
QString id = msg.getId();
StorageById::const_iterator itr = indexById.find(id);
if (itr != indexById.end()) {
qDebug() << "received more then one message with the same id, skipping yet the new one";
return;
}
Shared::Message* copy = new Shared::Message(msg);
StorageByTime::const_iterator tItr = indexByTime.upper_bound(msg.getTime());
int position;
if (tItr == indexByTime.end()) {
position = storage.size();
} else {
position = indexByTime.rank(tItr);
}
beginInsertRows(QModelIndex(), position, position);
storage.insert(copy);
endInsertRows();
}
void MessageFeed::changeMessage(const QString& id, const Shared::Message& msg)
{
}
void MessageFeed::removeMessage(const QString& id)
{
}
QVariant MessageFeed::data(const QModelIndex& index, int role) const
{
int i = index.row();
if (syncState == syncing) {
--i;
}
QVariant answer;
switch (role) {
case Qt::DisplayRole: {
if (i == -1) {
return "Loading...";
}
StorageByTime::const_iterator itr = indexByTime.nth(i);
if (itr != indexByTime.end()) {
const Shared::Message* msg = *itr;
answer = msg->getFrom() + ": " + msg->getBody();
}
}
break;
default:
break;
}
return answer;
}
int MessageFeed::rowCount(const QModelIndex& parent) const
{
int count = storage.size();
if (syncState == syncing) {
count++;
}
return count;
}
unsigned int MessageFeed::unreadMessagesCount() const
{
return storage.size(); //let's say they are all new for now =)
}
bool MessageFeed::canFetchMore(const QModelIndex& parent) const
{
return syncState == incomplete;
}
void MessageFeed::fetchMore(const QModelIndex& parent)
{
if (syncState == incomplete) {
beginInsertRows(QModelIndex(), 0, 0);
syncState = syncing;
endInsertRows();
if (storage.size() == 0) {
emit requestArchive("");
} else {
emit requestArchive((*indexByTime.nth(0))->getId());
}
}
}
void MessageFeed::responseArchive(const std::list<Shared::Message> list)
{
if (syncState == syncing) {
beginRemoveRows(QModelIndex(), 0, 0);
syncState = incomplete;
endRemoveRows();
}
beginInsertRows(QModelIndex(), 0, list.size() - 1);
for (const Shared::Message& msg : list) {
Shared::Message* copy = new Shared::Message(msg);
storage.insert(copy);
}
endInsertRows();
}

100
ui/models/messagefeed.h Normal file
View File

@ -0,0 +1,100 @@
/*
* Squawk messenger.
* Copyright (C) 2019 Yury Gubich <blue@macaw.me>
*
* 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 MESSAGEFEED_H
#define MESSAGEFEED_H
#include <QAbstractListModel>
#include <QDateTime>
#include <QString>
#include <boost/multi_index_container.hpp>
#include <boost/multi_index/ordered_index.hpp>
#include <boost/multi_index/ranked_index.hpp>
#include <boost/multi_index/mem_fun.hpp>
#include <shared/message.h>
class MessageFeed : public QAbstractListModel
{
Q_OBJECT
public:
MessageFeed(QObject *parent = nullptr);
~MessageFeed();
void addMessage(const Shared::Message& msg);
void changeMessage(const QString& id, const Shared::Message& msg);
void removeMessage(const QString& id);
QVariant data(const QModelIndex & index, int role = Qt::DisplayRole) const override;
int rowCount(const QModelIndex& parent = QModelIndex()) const override;
bool canFetchMore(const QModelIndex & parent) const override;
void fetchMore(const QModelIndex & parent) override;
void responseArchive(const std::list<Shared::Message> list);
unsigned int unreadMessagesCount() const;
signals:
void requestArchive(const QString& before);
private:
enum SyncState {
incomplete,
syncing,
complete
};
//tags
struct id {};
struct time {};
typedef boost::multi_index_container<
Shared::Message*,
boost::multi_index::indexed_by<
boost::multi_index::ordered_unique<
boost::multi_index::tag<id>,
boost::multi_index::const_mem_fun<
Shared::Message,
QString,
&Shared::Message::getId
>
>,
boost::multi_index::ranked_non_unique<
boost::multi_index::tag<time>,
boost::multi_index::const_mem_fun<
Shared::Message,
QDateTime,
&Shared::Message::getTime
>
>
>
> Storage;
typedef Storage::index<id>::type StorageById;
typedef Storage::index<time>::type StorageByTime;
Storage storage;
StorageById& indexById;
StorageByTime& indexByTime;
SyncState syncState;
};
#endif // MESSAGEFEED_H

View File

@ -20,82 +20,15 @@
#include "shared/icons.h" #include "shared/icons.h"
Models::Presence::Presence(const QMap<QString, QVariant>& data, Item* parentItem): Models::Presence::Presence(const QMap<QString, QVariant>& data, Item* parentItem):
AbstractParticipant(Item::presence, data, parentItem), AbstractParticipant(Item::presence, data, parentItem)
messages()
{ {
} }
Models::Presence::Presence(const Models::Presence& other):
AbstractParticipant(other),
messages(other.messages)
{
}
Models::Presence::~Presence() Models::Presence::~Presence()
{ {
} }
int Models::Presence::columnCount() const int Models::Presence::columnCount() const
{ {
return 5; return 4;
}
QVariant Models::Presence::data(int column) const
{
switch (column) {
case 4:
return getMessagesCount();
default:
return AbstractParticipant::data(column);
}
}
unsigned int Models::Presence::getMessagesCount() const
{
return messages.size();
}
void Models::Presence::addMessage(const Shared::Message& data)
{
messages.emplace_back(data);
changed(4);
}
bool Models::Presence::changeMessage(const QString& id, const QMap<QString, QVariant>& data)
{
bool found = false;
for (Shared::Message& msg : messages) {
if (msg.getId() == id) {
msg.change(data);
found = true;
break;
}
}
return found;
}
void Models::Presence::dropMessages()
{
if (messages.size() > 0) {
messages.clear();
changed(4);
}
}
QIcon Models::Presence::getStatusIcon(bool big) const
{
if (getMessagesCount() > 0) {
return Shared::icon("mail-message", big);
} else {
return AbstractParticipant::getStatusIcon();
}
}
void Models::Presence::getMessages(Models::Presence::Messages& container) const
{
for (Messages::const_iterator itr = messages.begin(), end = messages.end(); itr != end; ++itr) {
const Shared::Message& msg = *itr;
container.push_back(msg);
}
} }

View File

@ -32,25 +32,10 @@ class Presence : public Models::AbstractParticipant
{ {
Q_OBJECT Q_OBJECT
public: public:
typedef std::deque<Shared::Message> Messages;
explicit Presence(const QMap<QString, QVariant> &data, Item *parentItem = 0); explicit Presence(const QMap<QString, QVariant> &data, Item *parentItem = 0);
Presence(const Presence& other);
~Presence(); ~Presence();
int columnCount() const override; int columnCount() const override;
QVariant data(int column) const override;
QIcon getStatusIcon(bool big = false) const override;
unsigned int getMessagesCount() const;
void dropMessages();
void addMessage(const Shared::Message& data);
bool changeMessage(const QString& id, const QMap<QString, QVariant>& data);
void getMessages(Messages& container) const;
private:
Messages messages;
}; };
} }

View File

@ -22,16 +22,12 @@
#include <QIcon> #include <QIcon>
#include <QDebug> #include <QDebug>
Models::Room::Room(const QString& p_jid, const QMap<QString, QVariant>& data, Models::Item* parentItem): Models::Room::Room(const Account* acc, const QString& p_jid, const QMap<QString, QVariant>& data, Models::Item* parentItem):
Item(room, data, parentItem), Element(room, acc, p_jid, data, parentItem),
autoJoin(false), autoJoin(false),
joined(false), joined(false),
jid(p_jid),
nick(""), nick(""),
subject(""), subject(""),
avatarState(Shared::Avatar::empty),
avatarPath(""),
messages(),
participants(), participants(),
exParticipantAvatars() exParticipantAvatars()
{ {
@ -55,16 +51,6 @@ Models::Room::Room(const QString& p_jid, const QMap<QString, QVariant>& data, Mo
setSubject(itr.value().toString()); setSubject(itr.value().toString());
} }
itr = data.find("avatarState");
if (itr != data.end()) {
setAvatarState(itr.value().toUInt());
}
itr = data.find("avatarPath");
if (itr != data.end()) {
setAvatarPath(itr.value().toString());
}
itr = data.find("avatars"); itr = data.find("avatars");
if (itr != data.end()) { if (itr != data.end()) {
QMap<QString, QVariant> avs = itr.value().toMap(); QMap<QString, QVariant> avs = itr.value().toMap();
@ -78,21 +64,11 @@ Models::Room::~Room()
{ {
} }
unsigned int Models::Room::getUnreadMessagesCount() const
{
return messages.size();
}
int Models::Room::columnCount() const int Models::Room::columnCount() const
{ {
return 7; return 7;
} }
QString Models::Room::getJid() const
{
return jid;
}
bool Models::Room::getAutoJoin() const bool Models::Room::getAutoJoin() const
{ {
return autoJoin; return autoJoin;
@ -151,14 +127,6 @@ void Models::Room::setAutoJoin(bool p_autoJoin)
} }
} }
void Models::Room::setJid(const QString& p_jid)
{
if (jid != p_jid) {
jid = p_jid;
changed(1);
}
}
void Models::Room::setJoined(bool p_joined) void Models::Room::setJoined(bool p_joined)
{ {
if (joined != p_joined) { if (joined != p_joined) {
@ -182,8 +150,6 @@ void Models::Room::update(const QString& field, const QVariant& value)
{ {
if (field == "name") { if (field == "name") {
setName(value.toString()); setName(value.toString());
} else if (field == "jid") {
setJid(value.toString());
} else if (field == "joined") { } else if (field == "joined") {
setJoined(value.toBool()); setJoined(value.toBool());
} else if (field == "autoJoin") { } else if (field == "autoJoin") {
@ -192,16 +158,14 @@ void Models::Room::update(const QString& field, const QVariant& value)
setNick(value.toString()); setNick(value.toString());
} else if (field == "subject") { } else if (field == "subject") {
setSubject(value.toString()); setSubject(value.toString());
} else if (field == "avatarState") { } else {
setAvatarState(value.toUInt()); Element::update(field, value);
} else if (field == "avatarPath") {
setAvatarPath(value.toString());
} }
} }
QIcon Models::Room::getStatusIcon(bool big) const QIcon Models::Room::getStatusIcon(bool big) const
{ {
if (messages.size() > 0) { if (getMessagesCount() > 0) {
return Shared::icon("mail-message", big); return Shared::icon("mail-message", big);
} else { } else {
if (autoJoin) { if (autoJoin) {
@ -237,42 +201,6 @@ QString Models::Room::getStatusText() const
} }
} }
unsigned int Models::Room::getMessagesCount() const
{
return messages.size();
}
void Models::Room::addMessage(const Shared::Message& data)
{
messages.emplace_back(data);
changed(5);
}
void Models::Room::changeMessage(const QString& id, const QMap<QString, QVariant>& data)
{
for (Shared::Message& msg : messages) {
if (msg.getId() == id) {
msg.change(data);
break;
}
}
}
void Models::Room::dropMessages()
{
if (messages.size() > 0) {
messages.clear();
changed(5);
}
}
void Models::Room::getMessages(Models::Room::Messages& container) const
{
for (Messages::const_iterator itr = messages.begin(), end = messages.end(); itr != end; ++itr) {
const Shared::Message& msg = *itr;
container.push_back(msg);
}
}
void Models::Room::toOfflineState() void Models::Room::toOfflineState()
{ {
@ -367,47 +295,6 @@ QString Models::Room::getDisplayedName() const
return getRoomName(); return getRoomName();
} }
bool Models::Room::columnInvolvedInDisplay(int col)
{
return Item::columnInvolvedInDisplay(col) && col == 1;
}
QString Models::Room::getAvatarPath() const
{
return avatarPath;
}
Shared::Avatar Models::Room::getAvatarState() const
{
return avatarState;
}
void Models::Room::setAvatarPath(const QString& path)
{
if (avatarPath != path) {
avatarPath = path;
changed(8);
}
}
void Models::Room::setAvatarState(Shared::Avatar p_state)
{
if (avatarState != p_state) {
avatarState = p_state;
changed(7);
}
}
void Models::Room::setAvatarState(unsigned int p_state)
{
if (p_state <= static_cast<quint8>(Shared::Avatar::valid)) {
Shared::Avatar state = static_cast<Shared::Avatar>(p_state);
setAvatarState(state);
} else {
qDebug() << "An attempt to set invalid avatar state" << p_state << "to the room" << jid << ", skipping";
}
}
std::map<QString, const Models::Participant &> Models::Room::getParticipants() const std::map<QString, const Models::Participant &> Models::Room::getParticipants() const
{ {
std::map<QString, const Models::Participant&> result; std::map<QString, const Models::Participant&> result;

View File

@ -19,7 +19,7 @@
#ifndef MODELS_ROOM_H #ifndef MODELS_ROOM_H
#define MODELS_ROOM_H #define MODELS_ROOM_H
#include "item.h" #include "element.h"
#include "participant.h" #include "participant.h"
#include "shared/enums.h" #include "shared/enums.h"
#include "shared/message.h" #include "shared/message.h"
@ -29,21 +29,18 @@ namespace Models {
/** /**
* @todo write docs * @todo write docs
*/ */
class Room : public Models::Item class Room : public Element
{ {
Q_OBJECT Q_OBJECT
public: public:
typedef std::deque<Shared::Message> Messages; Room(const Account* acc, const QString& p_jid, const QMap<QString, QVariant> &data, Item *parentItem = 0);
Room(const QString& p_jid, const QMap<QString, QVariant> &data, Item *parentItem = 0);
~Room(); ~Room();
int columnCount() const override; int columnCount() const override;
QVariant data(int column) const override; QVariant data(int column) const override;
unsigned int getUnreadMessagesCount() const;
bool getJoined() const; bool getJoined() const;
bool getAutoJoin() const; bool getAutoJoin() const;
QString getJid() const;
QString getNick() const; QString getNick() const;
QString getRoomName() const; QString getRoomName() const;
QString getSubject() const; QString getSubject() const;
@ -53,17 +50,10 @@ public:
void setJoined(bool p_joined); void setJoined(bool p_joined);
void setAutoJoin(bool p_autoJoin); void setAutoJoin(bool p_autoJoin);
void setJid(const QString& p_jid);
void setNick(const QString& p_nick); void setNick(const QString& p_nick);
void setSubject(const QString& sub); void setSubject(const QString& sub);
void update(const QString& field, const QVariant& value); void update(const QString& field, const QVariant& value) override;
void addMessage(const Shared::Message& data);
void changeMessage(const QString& id, const QMap<QString, QVariant>& data);
unsigned int getMessagesCount() const;
void dropMessages();
void getMessages(Messages& container) const;
void addParticipant(const QString& name, const QMap<QString, QVariant>& data); void addParticipant(const QString& name, const QMap<QString, QVariant>& data);
void changeParticipant(const QString& name, const QMap<QString, QVariant>& data); void changeParticipant(const QString& name, const QMap<QString, QVariant>& data);
@ -71,8 +61,6 @@ public:
void toOfflineState() override; void toOfflineState() override;
QString getDisplayedName() const override; QString getDisplayedName() const override;
Shared::Avatar getAvatarState() const;
QString getAvatarPath() const;
std::map<QString, const Participant&> getParticipants() const; std::map<QString, const Participant&> getParticipants() const;
QString getParticipantIconPath(const QString& name) const; QString getParticipantIconPath(const QString& name) const;
std::map<QString, QString> getExParticipantAvatars() const; std::map<QString, QString> getExParticipantAvatars() const;
@ -84,24 +72,14 @@ signals:
private: private:
void handleParticipantUpdate(std::map<QString, Participant*>::const_iterator itr, const QMap<QString, QVariant>& data); void handleParticipantUpdate(std::map<QString, Participant*>::const_iterator itr, const QMap<QString, QVariant>& data);
protected:
bool columnInvolvedInDisplay(int col) override;
void setAvatarState(Shared::Avatar p_state);
void setAvatarState(unsigned int p_state);
void setAvatarPath(const QString& path);
private: private:
bool autoJoin; bool autoJoin;
bool joined; bool joined;
QString jid; QString jid;
QString nick; QString nick;
QString subject; QString subject;
Shared::Avatar avatarState;
QString avatarPath;
Messages messages;
std::map<QString, Participant*> participants; std::map<QString, Participant*> participants;
std::map<QString, QString> exParticipantAvatars; std::map<QString, QString> exParticipantAvatars;
}; };
} }

View File

@ -215,11 +215,7 @@ QVariant Models::Roster::data (const QModelIndex& index, int role) const
break; break;
case Item::presence: { case Item::presence: {
Presence* contact = static_cast<Presence*>(item); Presence* contact = static_cast<Presence*>(item);
QString str(""); QString str;
int mc = contact->getMessagesCount();
if (mc > 0) {
str += tr("New messages: ") + std::to_string(mc).c_str() + "\n";
}
Shared::Availability av = contact->getAvailability(); Shared::Availability av = contact->getAvailability();
str += tr("Availability: ") + Shared::Global::getName(av); str += tr("Availability: ") + Shared::Global::getName(av);
QString s = contact->getStatus(); QString s = contact->getStatus();
@ -232,7 +228,7 @@ QVariant Models::Roster::data (const QModelIndex& index, int role) const
break; break;
case Item::participant: { case Item::participant: {
Participant* p = static_cast<Participant*>(item); Participant* p = static_cast<Participant*>(item);
QString str(""); QString str;
Shared::Availability av = p->getAvailability(); Shared::Availability av = p->getAvailability();
str += tr("Availability: ") + Shared::Global::getName(av) + "\n"; str += tr("Availability: ") + Shared::Global::getName(av) + "\n";
QString s = p->getStatus(); QString s = p->getStatus();
@ -260,7 +256,7 @@ QVariant Models::Roster::data (const QModelIndex& index, int role) const
break; break;
case Item::room: { case Item::room: {
Room* rm = static_cast<Room*>(item); Room* rm = static_cast<Room*>(item);
unsigned int count = rm->getUnreadMessagesCount(); unsigned int count = rm->getMessagesCount();
QString str(""); QString str("");
if (count > 0) { if (count > 0) {
str += tr("New messages: ") + std::to_string(count).c_str() + "\n"; str += tr("New messages: ") + std::to_string(count).c_str() + "\n";
@ -450,6 +446,7 @@ void Models::Roster::addContact(const QString& account, const QString& jid, cons
std::map<ElId, Contact*>::iterator itr = contacts.find(id); std::map<ElId, Contact*>::iterator itr = contacts.find(id);
if (itr == contacts.end()) { if (itr == contacts.end()) {
contact = new Contact(acc, jid, data); contact = new Contact(acc, jid, data);
connect(contact, &Contact::requestArchive, this, &Roster::onElementRequestArchive);
contacts.insert(std::make_pair(id, contact)); contacts.insert(std::make_pair(id, contact));
} else { } else {
contact = itr->second; contact = itr->second;
@ -720,20 +717,6 @@ void Models::Roster::addMessage(const QString& account, const Shared::Message& d
} }
} }
void Models::Roster::dropMessages(const QString& account, const QString& jid)
{
ElId id(account, jid);
std::map<ElId, Contact*>::iterator itr = contacts.find(id);
if (itr != contacts.end()) {
itr->second->dropMessages();
} else {
std::map<ElId, Room*>::const_iterator rItr = rooms.find(id);
if (rItr != rooms.end()) {
rItr->second->dropMessages();
}
}
}
void Models::Roster::removeAccount(const QString& account) void Models::Roster::removeAccount(const QString& account)
{ {
std::map<QString, Account*>::const_iterator itr = accounts.find(account); std::map<QString, Account*>::const_iterator itr = accounts.find(account);
@ -821,7 +804,8 @@ void Models::Roster::addRoom(const QString& account, const QString jid, const QM
return; return;
} }
Room* room = new Room(jid, data); Room* room = new Room(acc, jid, data);
connect(room, &Contact::requestArchive, this, &Roster::onElementRequestArchive);
rooms.insert(std::make_pair(id, room)); rooms.insert(std::make_pair(id, room));
acc->appendChild(room); acc->appendChild(room);
} }
@ -974,3 +958,23 @@ QModelIndex Models::Roster::getGroupIndex(const QString& account, const QString&
} }
} }
} }
void Models::Roster::onElementRequestArchive(const QString& before)
{
Element* el = static_cast<Element*>(sender());
emit requestArchive(el->getAccountName(), el->getJid(), before);
}
void Models::Roster::responseArchive(const QString& account, const QString& jid, const std::list<Shared::Message>& list)
{
ElId id(account, jid);
std::map<ElId, Contact*>::iterator itr = contacts.find(id);
if (itr != contacts.end()) {
itr->second->responseArchive(list);
} else {
std::map<ElId, Room*>::const_iterator rItr = rooms.find(id);
if (rItr != rooms.end()) {
rItr->second->responseArchive(list);
}
}
}

View File

@ -58,7 +58,6 @@ public:
void removePresence(const QString& account, const QString& jid, const QString& name); void removePresence(const QString& account, const QString& jid, const QString& name);
void addMessage(const QString& account, const Shared::Message& data); void addMessage(const QString& account, const Shared::Message& data);
void changeMessage(const QString& account, const QString& jid, const QString& id, const QMap<QString, QVariant>& data); void changeMessage(const QString& account, const QString& jid, const QString& id, const QMap<QString, QVariant>& data);
void dropMessages(const QString& account, const QString& jid);
void addRoom(const QString& account, const QString jid, const QMap<QString, QVariant>& data); void addRoom(const QString& account, const QString jid, const QMap<QString, QVariant>& data);
void changeRoom(const QString& account, const QString jid, const QMap<QString, QVariant>& data); void changeRoom(const QString& account, const QString jid, const QMap<QString, QVariant>& data);
void removeRoom(const QString& account, const QString jid); void removeRoom(const QString& account, const QString jid);
@ -81,9 +80,13 @@ public:
Account* getAccount(const QString& name); Account* getAccount(const QString& name);
QModelIndex getAccountIndex(const QString& name); QModelIndex getAccountIndex(const QString& name);
QModelIndex getGroupIndex(const QString& account, const QString& name); QModelIndex getGroupIndex(const QString& account, const QString& name);
void responseArchive(const QString& account, const QString& jid, const std::list<Shared::Message>& list);
Accounts* accountsModel; Accounts* accountsModel;
signals:
void requestArchive(const QString& account, const QString& jid, const QString& before);
private: private:
Item* root; Item* root;
std::map<QString, Account*> accounts; std::map<QString, Account*> accounts;
@ -100,6 +103,7 @@ private slots:
void onChildRemoved(); void onChildRemoved();
void onChildIsAboutToBeMoved(Item* source, int first, int last, Item* destination, int newIndex); void onChildIsAboutToBeMoved(Item* source, int first, int last, Item* destination, int newIndex);
void onChildMoved(); void onChildMoved();
void onElementRequestArchive(const QString& before);
public: public:
class ElId { class ElId {

View File

@ -62,6 +62,7 @@ Squawk::Squawk(QWidget *parent) :
connect(m_ui->roster->selectionModel(), &QItemSelectionModel::currentRowChanged, this, &Squawk::onRosterSelectionChanged); connect(m_ui->roster->selectionModel(), &QItemSelectionModel::currentRowChanged, this, &Squawk::onRosterSelectionChanged);
connect(rosterModel.accountsModel, &Models::Accounts::sizeChanged, this, &Squawk::onAccountsSizeChanged); connect(rosterModel.accountsModel, &Models::Accounts::sizeChanged, this, &Squawk::onAccountsSizeChanged);
connect(&rosterModel, &Models::Roster::requestArchive, this, &Squawk::onConversationRequestArchive);
connect(contextMenu, &QMenu::aboutToHide, this, &Squawk::onContextAboutToHide); connect(contextMenu, &QMenu::aboutToHide, this, &Squawk::onContextAboutToHide);
//m_ui->mainToolBar->addWidget(m_ui->comboBox); //m_ui->mainToolBar->addWidget(m_ui->comboBox);
@ -336,17 +337,14 @@ void Squawk::onRosterItemDoubleClicked(const QModelIndex& item)
Models::Account* acc = rosterModel.getAccount(id->account); Models::Account* acc = rosterModel.getAccount(id->account);
Conversation* conv = 0; Conversation* conv = 0;
bool created = false; bool created = false;
Models::Contact::Messages deque;
if (itr != conversations.end()) { if (itr != conversations.end()) {
conv = itr->second; conv = itr->second;
} else if (contact != 0) { } else if (contact != 0) {
created = true; created = true;
conv = new Chat(acc, contact); conv = new Chat(acc, contact);
contact->getMessages(deque);
} else if (room != 0) { } else if (room != 0) {
created = true; created = true;
conv = new Room(acc, room); conv = new Room(acc, room);
room->getMessages(deque);
if (!room->getJoined()) { if (!room->getJoined()) {
emit setRoomJoined(id->account, id->name, true); emit setRoomJoined(id->account, id->name, true);
@ -358,12 +356,6 @@ void Squawk::onRosterItemDoubleClicked(const QModelIndex& item)
conv->setAttribute(Qt::WA_DeleteOnClose); conv->setAttribute(Qt::WA_DeleteOnClose);
subscribeConversation(conv); subscribeConversation(conv);
conversations.insert(std::make_pair(*id, conv)); conversations.insert(std::make_pair(*id, conv));
if (created) {
for (Models::Contact::Messages::const_iterator itr = deque.begin(), end = deque.end(); itr != end; ++itr) {
conv->addMessage(*itr);
}
}
} }
conv->show(); conv->show();
@ -380,12 +372,6 @@ void Squawk::onRosterItemDoubleClicked(const QModelIndex& item)
} }
} }
void Squawk::onConversationShown()
{
Conversation* conv = static_cast<Conversation*>(sender());
rosterModel.dropMessages(conv->getAccount(), conv->getJid());
}
void Squawk::onConversationClosed(QObject* parent) void Squawk::onConversationClosed(QObject* parent)
{ {
Conversation* conv = static_cast<Conversation*>(sender()); Conversation* conv = static_cast<Conversation*>(sender());
@ -505,8 +491,9 @@ void Squawk::accountMessage(const QString& account, const Shared::Message& data)
Conversations::iterator itr = conversations.find(id); Conversations::iterator itr = conversations.find(id);
bool found = false; bool found = false;
rosterModel.addMessage(account, data);
if (currentConversation != 0 && currentConversation->getId() == id) { if (currentConversation != 0 && currentConversation->getId() == id) {
currentConversation->addMessage(data);
QApplication::alert(this); QApplication::alert(this);
if (!isVisible() && !data.getForwarded()) { if (!isVisible() && !data.getForwarded()) {
notify(account, data); notify(account, data);
@ -516,11 +503,7 @@ void Squawk::accountMessage(const QString& account, const Shared::Message& data)
if (itr != conversations.end()) { if (itr != conversations.end()) {
Conversation* conv = itr->second; Conversation* conv = itr->second;
conv->addMessage(data);
QApplication::alert(conv); QApplication::alert(conv);
if (!found && conv->isMinimized()) {
rosterModel.addMessage(account, data);
}
if (!conv->isVisible() && !data.getForwarded()) { if (!conv->isVisible() && !data.getForwarded()) {
notify(account, data); notify(account, data);
} }
@ -528,7 +511,6 @@ void Squawk::accountMessage(const QString& account, const Shared::Message& data)
} }
if (!found) { if (!found) {
rosterModel.addMessage(account, data);
if (!data.getForwarded()) { if (!data.getForwarded()) {
QApplication::alert(this); QApplication::alert(this);
notify(account, data); notify(account, data);
@ -599,16 +581,7 @@ void Squawk::onConversationMessage(const Shared::Message& msg)
emit sendMessage(conv->getAccount(), msg); emit sendMessage(conv->getAccount(), msg);
Models::Roster::ElId id = conv->getId(); Models::Roster::ElId id = conv->getId();
if (currentConversation != 0 && currentConversation->getId() == id) { rosterModel.addMessage(conv->getAccount(), msg);
if (conv == currentConversation) {
Conversations::iterator itr = conversations.find(id);
if (itr != conversations.end()) {
itr->second->addMessage(msg);
}
} else {
currentConversation->addMessage(msg);
}
}
} }
void Squawk::onConversationMessage(const Shared::Message& msg, const QString& path) void Squawk::onConversationMessage(const Shared::Message& msg, const QString& path)
@ -632,24 +605,14 @@ void Squawk::onConversationMessage(const Shared::Message& msg, const QString& pa
emit sendMessage(conv->getAccount(), msg, path); emit sendMessage(conv->getAccount(), msg, path);
} }
void Squawk::onConversationRequestArchive(const QString& before) void Squawk::onConversationRequestArchive(const QString& account, const QString& jid, const QString& before)
{ {
Conversation* conv = static_cast<Conversation*>(sender()); emit requestArchive(account, jid, 20, before); //TODO amount as a settings value
requestArchive(conv->getAccount(), conv->getJid(), 20, before); //TODO amount as a settings value
} }
void Squawk::responseArchive(const QString& account, const QString& jid, const std::list<Shared::Message>& list) void Squawk::responseArchive(const QString& account, const QString& jid, const std::list<Shared::Message>& list)
{ {
Models::Roster::ElId id(account, jid); rosterModel.responseArchive(account, jid, list);
if (currentConversation != 0 && currentConversation->getId() == id) {
currentConversation->responseArchive(list);
}
Conversations::const_iterator itr = conversations.find(id);
if (itr != conversations.end()) {
itr->second->responseArchive(list);
}
} }
void Squawk::removeAccount(const QString& account) void Squawk::removeAccount(const QString& account)
@ -661,8 +624,6 @@ void Squawk::removeAccount(const QString& account)
++itr; ++itr;
Conversation* conv = lItr->second; Conversation* conv = lItr->second;
disconnect(conv, &Conversation::destroyed, this, &Squawk::onConversationClosed); disconnect(conv, &Conversation::destroyed, this, &Squawk::onConversationClosed);
disconnect(conv, &Conversation::requestArchive, this, &Squawk::onConversationRequestArchive);
disconnect(conv, &Conversation::shown, this, &Squawk::onConversationShown);
conv->close(); conv->close();
conversations.erase(lItr); conversations.erase(lItr);
} else { } else {
@ -926,7 +887,6 @@ void Squawk::onActivateVCard(const QString& account, const QString& jid, bool ed
{ {
std::map<QString, VCard*>::const_iterator itr = vCards.find(jid); std::map<QString, VCard*>::const_iterator itr = vCards.find(jid);
VCard* card; VCard* card;
Models::Contact::Messages deque;
if (itr != vCards.end()) { if (itr != vCards.end()) {
card = itr->second; card = itr->second;
} else { } else {
@ -1095,10 +1055,8 @@ void Squawk::subscribeConversation(Conversation* conv)
connect(conv, qOverload<const Shared::Message&>(&Conversation::sendMessage), this, qOverload<const Shared::Message&>(&Squawk::onConversationMessage)); connect(conv, qOverload<const Shared::Message&>(&Conversation::sendMessage), this, qOverload<const Shared::Message&>(&Squawk::onConversationMessage));
connect(conv, qOverload<const Shared::Message&, const QString&>(&Conversation::sendMessage), connect(conv, qOverload<const Shared::Message&, const QString&>(&Conversation::sendMessage),
this, qOverload<const Shared::Message&, const QString&>(&Squawk::onConversationMessage)); this, qOverload<const Shared::Message&, const QString&>(&Squawk::onConversationMessage));
connect(conv, &Conversation::requestArchive, this, &Squawk::onConversationRequestArchive);
connect(conv, &Conversation::requestLocalFile, this, &Squawk::onConversationRequestLocalFile); connect(conv, &Conversation::requestLocalFile, this, &Squawk::onConversationRequestLocalFile);
connect(conv, &Conversation::downloadFile, this, &Squawk::onConversationDownloadFile); connect(conv, &Conversation::downloadFile, this, &Squawk::onConversationDownloadFile);
connect(conv, &Conversation::shown, this, &Squawk::onConversationShown);
} }
void Squawk::onRosterSelectionChanged(const QModelIndex& current, const QModelIndex& previous) void Squawk::onRosterSelectionChanged(const QModelIndex& current, const QModelIndex& previous)
@ -1168,13 +1126,10 @@ void Squawk::onRosterSelectionChanged(const QModelIndex& current, const QModelIn
} }
Models::Account* acc = rosterModel.getAccount(id->account); Models::Account* acc = rosterModel.getAccount(id->account);
Models::Contact::Messages deque;
if (contact != 0) { if (contact != 0) {
currentConversation = new Chat(acc, contact); currentConversation = new Chat(acc, contact);
contact->getMessages(deque);
} else if (room != 0) { } else if (room != 0) {
currentConversation = new Room(acc, room); currentConversation = new Room(acc, room);
room->getMessages(deque);
if (!room->getJoined()) { if (!room->getJoined()) {
emit setRoomJoined(id->account, id->name, true); emit setRoomJoined(id->account, id->name, true);
@ -1185,9 +1140,6 @@ void Squawk::onRosterSelectionChanged(const QModelIndex& current, const QModelIn
} }
subscribeConversation(currentConversation); subscribeConversation(currentConversation);
for (Models::Contact::Messages::const_iterator itr = deque.begin(), end = deque.end(); itr != end; ++itr) {
currentConversation->addMessage(*itr);
}
if (res.size() > 0) { if (res.size() > 0) {
currentConversation->setPalResource(res); currentConversation->setPalResource(res);

View File

@ -148,9 +148,8 @@ private slots:
void onRosterItemDoubleClicked(const QModelIndex& item); void onRosterItemDoubleClicked(const QModelIndex& item);
void onConversationMessage(const Shared::Message& msg); void onConversationMessage(const Shared::Message& msg);
void onConversationMessage(const Shared::Message& msg, const QString& path); void onConversationMessage(const Shared::Message& msg, const QString& path);
void onConversationRequestArchive(const QString& before); void onConversationRequestArchive(const QString& account, const QString& jid, const QString& before);
void onRosterContextMenu(const QPoint& point); void onRosterContextMenu(const QPoint& point);
void onConversationShown();
void onConversationRequestLocalFile(const QString& messageId, const QString& url); void onConversationRequestLocalFile(const QString& messageId, const QString& url);
void onConversationDownloadFile(const QString& messageId, const QString& url); void onConversationDownloadFile(const QString& messageId, const QString& url);
void onItemCollepsed(const QModelIndex& index); void onItemCollepsed(const QModelIndex& index);

View File

@ -28,6 +28,8 @@ Chat::Chat(Models::Account* acc, Models::Contact* p_contact, QWidget* parent):
setAvatar(p_contact->getAvatarPath()); setAvatar(p_contact->getAvatarPath());
connect(contact, &Models::Contact::childChanged, this, &Chat::onContactChanged); connect(contact, &Models::Contact::childChanged, this, &Chat::onContactChanged);
feed->setModel(p_contact->feed);
} }
Chat::~Chat() Chat::~Chat()
@ -71,31 +73,15 @@ Shared::Message Chat::createMessage() const
return msg; return msg;
} }
void Chat::addMessage(const Shared::Message& data) // TODO
{ // void Chat::addMessage(const Shared::Message& data)
Conversation::addMessage(data); // {
// Conversation::addMessage(data);
if (!data.getOutgoing()) { //TODO need to check if that was the last message //
const QString& res = data.getPenPalResource(); // if (!data.getOutgoing()) { //TODO need to check if that was the last message
if (res.size() > 0) { // const QString& res = data.getPenPalResource();
setPalResource(res); // if (res.size() > 0) {
} // setPalResource(res);
} // }
} // }
// }
void Chat::setName(const QString& name)
{
Conversation::setName(name);
line->setPalName(getJid(), name);
}
void Chat::setAvatar(const QString& path)
{
Conversation::setAvatar(path);
if (path.size() == 0) {
line->dropPalAvatar(contact->getJid());
} else {
line->setPalAvatar(contact->getJid(), path);
}
}

View File

@ -35,14 +35,12 @@ public:
Chat(Models::Account* acc, Models::Contact* p_contact, QWidget* parent = 0); Chat(Models::Account* acc, Models::Contact* p_contact, QWidget* parent = 0);
~Chat(); ~Chat();
void addMessage(const Shared::Message & data) override; //void addMessage(const Shared::Message & data) override;
void setAvatar(const QString& path) override;
protected slots: protected slots:
void onContactChanged(Models::Item* item, int row, int col); void onContactChanged(Models::Item* item, int row, int col);
protected: protected:
void setName(const QString & name) override;
Shared::Message createMessage() const override; Shared::Message createMessage() const override;
private: private:

View File

@ -35,7 +35,6 @@ Conversation::Conversation(bool muc, Models::Account* acc, const QString pJid, c
account(acc), account(acc),
palJid(pJid), palJid(pJid),
activePalResource(pRes), activePalResource(pRes),
line(new MessageLine(muc)),
m_ui(new Ui::Conversation()), m_ui(new Ui::Conversation()),
ker(), ker(),
scrollResizeCatcher(), scrollResizeCatcher(),
@ -46,6 +45,7 @@ Conversation::Conversation(bool muc, Models::Account* acc, const QString pJid, c
filesLayout(0), filesLayout(0),
overlay(new QWidget()), overlay(new QWidget()),
filesToAttach(), filesToAttach(),
feed(0),
scroll(down), scroll(down),
manualSliderChange(false), manualSliderChange(false),
requestingHistory(false), requestingHistory(false),
@ -53,6 +53,7 @@ Conversation::Conversation(bool muc, Models::Account* acc, const QString pJid, c
tsb(QApplication::style()->styleHint(QStyle::SH_ScrollBar_Transient) == 1) tsb(QApplication::style()->styleHint(QStyle::SH_ScrollBar_Transient) == 1)
{ {
m_ui->setupUi(this); m_ui->setupUi(this);
feed = m_ui->feed;
connect(acc, &Models::Account::childChanged, this, &Conversation::onAccountChanged); connect(acc, &Models::Account::childChanged, this, &Conversation::onAccountChanged);
@ -67,10 +68,10 @@ Conversation::Conversation(bool muc, Models::Account* acc, const QString pJid, c
connect(&vis, &VisibilityCatcher::shown, this, &Conversation::onScrollResize); connect(&vis, &VisibilityCatcher::shown, this, &Conversation::onScrollResize);
connect(&vis, &VisibilityCatcher::hidden, this, &Conversation::onScrollResize); connect(&vis, &VisibilityCatcher::hidden, this, &Conversation::onScrollResize);
connect(m_ui->sendButton, &QPushButton::clicked, this, &Conversation::onEnterPressed); connect(m_ui->sendButton, &QPushButton::clicked, this, &Conversation::onEnterPressed);
connect(line, &MessageLine::resize, this, &Conversation::onMessagesResize); //connect(line, &MessageLine::resize, this, &Conversation::onMessagesResize);
connect(line, &MessageLine::downloadFile, this, &Conversation::downloadFile); //connect(line, &MessageLine::downloadFile, this, &Conversation::downloadFile);
connect(line, &MessageLine::uploadFile, this, qOverload<const Shared::Message&, const QString&>(&Conversation::sendMessage)); //connect(line, &MessageLine::uploadFile, this, qOverload<const Shared::Message&, const QString&>(&Conversation::sendMessage));
connect(line, &MessageLine::requestLocalFile, this, &Conversation::requestLocalFile); //connect(line, &MessageLine::requestLocalFile, this, &Conversation::requestLocalFile);
connect(m_ui->attachButton, &QPushButton::clicked, this, &Conversation::onAttach); connect(m_ui->attachButton, &QPushButton::clicked, this, &Conversation::onAttach);
connect(m_ui->clearButton, &QPushButton::clicked, this, &Conversation::onClearButton); connect(m_ui->clearButton, &QPushButton::clicked, this, &Conversation::onClearButton);
connect(m_ui->messageEditor->document()->documentLayout(), &QAbstractTextDocumentLayout::documentSizeChanged, connect(m_ui->messageEditor->document()->documentLayout(), &QAbstractTextDocumentLayout::documentSizeChanged,
@ -78,22 +79,22 @@ Conversation::Conversation(bool muc, Models::Account* acc, const QString pJid, c
m_ui->messageEditor->installEventFilter(&ker); m_ui->messageEditor->installEventFilter(&ker);
QScrollBar* vs = m_ui->scrollArea->verticalScrollBar(); //QScrollBar* vs = m_ui->scrollArea->verticalScrollBar();
m_ui->scrollArea->setWidget(line); //m_ui->scrollArea->setWidget(line);
vs->installEventFilter(&vis); //vs->installEventFilter(&vis);
line->setAutoFillBackground(false); //line->setAutoFillBackground(false);
if (testAttribute(Qt::WA_TranslucentBackground)) { //if (testAttribute(Qt::WA_TranslucentBackground)) {
m_ui->scrollArea->setAutoFillBackground(false); //m_ui->scrollArea->setAutoFillBackground(false);
} else { //} else {
m_ui->scrollArea->setBackgroundRole(QPalette::Base); //m_ui->scrollArea->setBackgroundRole(QPalette::Base);
} //}
connect(vs, &QScrollBar::valueChanged, this, &Conversation::onSliderValueChanged); //connect(vs, &QScrollBar::valueChanged, this, &Conversation::onSliderValueChanged);
m_ui->scrollArea->installEventFilter(&scrollResizeCatcher); //m_ui->scrollArea->installEventFilter(&scrollResizeCatcher);
line->setMyAvatarPath(acc->getAvatarPath()); //line->setMyAvatarPath(acc->getAvatarPath());
line->setMyName(acc->getName()); //line->setMyName(acc->getName());
QGridLayout* gr = static_cast<QGridLayout*>(layout()); QGridLayout* gr = static_cast<QGridLayout*>(layout());
QLabel* progressLabel = new QLabel(tr("Drop files here to attach them to your message")); QLabel* progressLabel = new QLabel(tr("Drop files here to attach them to your message"));
@ -129,9 +130,9 @@ void Conversation::onAccountChanged(Models::Item* item, int row, int col)
if (col == 2 && account->getState() == Shared::ConnectionState::connected) { if (col == 2 && account->getState() == Shared::ConnectionState::connected) {
if (!requestingHistory) { if (!requestingHistory) {
requestingHistory = true; requestingHistory = true;
line->showBusyIndicator(); //line->showBusyIndicator();
emit requestArchive(""); //emit requestArchive("");
scroll = down; //scroll = down;
} }
} }
} }
@ -139,12 +140,12 @@ void Conversation::onAccountChanged(Models::Item* item, int row, int col)
void Conversation::applyVisualEffects() void Conversation::applyVisualEffects()
{ {
DropShadowEffect *e1 = new DropShadowEffect; // DropShadowEffect *e1 = new DropShadowEffect;
e1->setBlurRadius(10); // e1->setBlurRadius(10);
e1->setColor(Qt::black); // e1->setColor(Qt::black);
e1->setThickness(1); // e1->setThickness(1);
e1->setFrame(true, false, true, false); // e1->setFrame(true, false, true, false);
m_ui->scrollArea->setGraphicsEffect(e1); // m_ui->scrollArea->setGraphicsEffect(e1);
} }
void Conversation::setName(const QString& name) void Conversation::setName(const QString& name)
@ -163,20 +164,9 @@ QString Conversation::getJid() const
return palJid; return palJid;
} }
void Conversation::addMessage(const Shared::Message& data)
{
int pos = m_ui->scrollArea->verticalScrollBar()->sliderPosition();
int max = m_ui->scrollArea->verticalScrollBar()->maximum();
MessageLine::Position place = line->message(data);
if (place == MessageLine::invalid) {
return;
}
}
void Conversation::changeMessage(const QString& id, const QMap<QString, QVariant>& data) void Conversation::changeMessage(const QString& id, const QMap<QString, QVariant>& data)
{ {
line->changeMessage(id, data); // line->changeMessage(id, data);
} }
KeyEnterReceiver::KeyEnterReceiver(QObject* parent): QObject(parent), ownEvent(false) {} KeyEnterReceiver::KeyEnterReceiver(QObject* parent): QObject(parent), ownEvent(false) {}
@ -226,86 +216,86 @@ void Conversation::onEnterPressed()
m_ui->messageEditor->clear(); m_ui->messageEditor->clear();
Shared::Message msg = createMessage(); Shared::Message msg = createMessage();
msg.setBody(body); msg.setBody(body);
addMessage(msg); //addMessage(msg);
emit sendMessage(msg); emit sendMessage(msg);
} }
if (filesToAttach.size() > 0) { if (filesToAttach.size() > 0) {
for (Badge* badge : filesToAttach) { // for (Badge* badge : filesToAttach) {
Shared::Message msg = createMessage(); // Shared::Message msg = createMessage();
line->appendMessageWithUpload(msg, badge->id); // line->appendMessageWithUpload(msg, badge->id);
usleep(1000); //this is required for the messages not to have equal time when appending into messageline // usleep(1000); //this is required for the messages not to have equal time when appending into messageline
} // }
clearAttachedFiles(); // clearAttachedFiles();
} }
} }
void Conversation::appendMessageWithUpload(const Shared::Message& data, const QString& path) void Conversation::appendMessageWithUpload(const Shared::Message& data, const QString& path)
{ {
line->appendMessageWithUploadNoSiganl(data, path); // line->appendMessageWithUploadNoSiganl(data, path);
} }
void Conversation::onMessagesResize(int amount) void Conversation::onMessagesResize(int amount)
{ {
manualSliderChange = true; // manualSliderChange = true;
switch (scroll) { // switch (scroll) {
case down: // case down:
m_ui->scrollArea->verticalScrollBar()->setValue(m_ui->scrollArea->verticalScrollBar()->maximum()); // m_ui->scrollArea->verticalScrollBar()->setValue(m_ui->scrollArea->verticalScrollBar()->maximum());
break; // break;
case keep: { // case keep: {
int max = m_ui->scrollArea->verticalScrollBar()->maximum(); // int max = m_ui->scrollArea->verticalScrollBar()->maximum();
int value = m_ui->scrollArea->verticalScrollBar()->value() + amount; // int value = m_ui->scrollArea->verticalScrollBar()->value() + amount;
m_ui->scrollArea->verticalScrollBar()->setValue(value); // m_ui->scrollArea->verticalScrollBar()->setValue(value);
//
if (value == max) { // if (value == max) {
scroll = down; // scroll = down;
} else { // } else {
scroll = nothing; // scroll = nothing;
} // }
} // }
break; // break;
default: // default:
break; // break;
} // }
manualSliderChange = false; // manualSliderChange = false;
} }
void Conversation::onSliderValueChanged(int value) void Conversation::onSliderValueChanged(int value)
{ {
if (!manualSliderChange) { // if (!manualSliderChange) {
if (value == m_ui->scrollArea->verticalScrollBar()->maximum()) { // if (value == m_ui->scrollArea->verticalScrollBar()->maximum()) {
scroll = down; // scroll = down;
} else { // } else {
if (!requestingHistory && value == 0) { // if (!requestingHistory && value == 0) {
requestingHistory = true; // requestingHistory = true;
line->showBusyIndicator(); // line->showBusyIndicator();
emit requestArchive(line->firstMessageId()); // emit requestArchive(line->firstMessageId());
scroll = keep; // scroll = keep;
} else { // } else {
scroll = nothing; // scroll = nothing;
} // }
} // }
} // }
} }
void Conversation::responseArchive(const std::list<Shared::Message> list) void Conversation::responseArchive(const std::list<Shared::Message> list)
{ {
requestingHistory = false; // requestingHistory = false;
scroll = keep; // scroll = keep;
//
line->hideBusyIndicator(); // line->hideBusyIndicator();
for (std::list<Shared::Message>::const_iterator itr = list.begin(), end = list.end(); itr != end; ++itr) { // for (std::list<Shared::Message>::const_iterator itr = list.begin(), end = list.end(); itr != end; ++itr) {
addMessage(*itr); // addMessage(*itr);
} // }
} }
void Conversation::showEvent(QShowEvent* event) void Conversation::showEvent(QShowEvent* event)
{ {
if (!everShown) { if (!everShown) {
everShown = true; everShown = true;
line->showBusyIndicator(); // line->showBusyIndicator();
requestingHistory = true; requestingHistory = true;
scroll = keep; scroll = keep;
emit requestArchive(line->firstMessageId()); emit requestArchive("");
} }
emit shown(); emit shown();
@ -342,30 +332,30 @@ void Conversation::setStatus(const QString& status)
void Conversation::onScrollResize() void Conversation::onScrollResize()
{ {
if (everShown) { // if (everShown) {
int size = m_ui->scrollArea->width(); // int size = m_ui->scrollArea->width();
QScrollBar* bar = m_ui->scrollArea->verticalScrollBar(); // QScrollBar* bar = m_ui->scrollArea->verticalScrollBar();
if (bar->isVisible() && !tsb) { // if (bar->isVisible() && !tsb) {
size -= bar->width(); // size -= bar->width();
//
} // }
line->setMaximumWidth(size); // line->setMaximumWidth(size);
} // }
} }
void Conversation::responseFileProgress(const QString& messageId, qreal progress) void Conversation::responseFileProgress(const QString& messageId, qreal progress)
{ {
line->fileProgress(messageId, progress); // line->fileProgress(messageId, progress);
} }
void Conversation::fileError(const QString& messageId, const QString& error) void Conversation::fileError(const QString& messageId, const QString& error)
{ {
line->fileError(messageId, error); // line->fileError(messageId, error);
} }
void Conversation::responseLocalFile(const QString& messageId, const QString& path) void Conversation::responseLocalFile(const QString& messageId, const QString& path)
{ {
line->responseLocalFile(messageId, path); // line->responseLocalFile(messageId, path);
} }
Models::Roster::ElId Conversation::getId() const Models::Roster::ElId Conversation::getId() const
@ -444,7 +434,7 @@ void Conversation::onTextEditDocSizeChanged(const QSizeF& size)
void Conversation::setFeedFrames(bool top, bool right, bool bottom, bool left) void Conversation::setFeedFrames(bool top, bool right, bool bottom, bool left)
{ {
static_cast<DropShadowEffect*>(m_ui->scrollArea->graphicsEffect())->setFrame(top, right, bottom, left); //static_cast<DropShadowEffect*>(m_ui->scrollArea->graphicsEffect())->setFrame(top, right, bottom, left);
} }
void Conversation::dragEnterEvent(QDragEnterEvent* event) void Conversation::dragEnterEvent(QDragEnterEvent* event)

View File

@ -24,6 +24,7 @@
#include <QMap> #include <QMap>
#include <QMimeData> #include <QMimeData>
#include <QFileInfo> #include <QFileInfo>
#include <QListView>
#include "shared/message.h" #include "shared/message.h"
#include "order.h" #include "order.h"
@ -78,7 +79,6 @@ public:
QString getAccount() const; QString getAccount() const;
QString getPalResource() const; QString getPalResource() const;
Models::Roster::ElId getId() const; Models::Roster::ElId getId() const;
virtual void addMessage(const Shared::Message& data);
void setPalResource(const QString& res); void setPalResource(const QString& res);
void responseArchive(const std::list<Shared::Message> list); void responseArchive(const std::list<Shared::Message> list);
@ -135,7 +135,6 @@ protected:
Models::Account* account; Models::Account* account;
QString palJid; QString palJid;
QString activePalResource; QString activePalResource;
MessageLine* line;
QScopedPointer<Ui::Conversation> m_ui; QScopedPointer<Ui::Conversation> m_ui;
KeyEnterReceiver ker; KeyEnterReceiver ker;
Resizer scrollResizeCatcher; Resizer scrollResizeCatcher;
@ -146,6 +145,7 @@ protected:
FlowLayout* filesLayout; FlowLayout* filesLayout;
QWidget* overlay; QWidget* overlay;
W::Order<Badge*, Badge::Comparator> filesToAttach; W::Order<Badge*, Badge::Comparator> filesToAttach;
QListView* feed;
Scroll scroll; Scroll scroll;
bool manualSliderChange; bool manualSliderChange;
bool requestingHistory; bool requestingHistory;

View File

@ -215,60 +215,37 @@
</widget> </widget>
</item> </item>
<item> <item>
<widget class="QScrollArea" name="scrollArea"> <widget class="QListView" name="feed">
<property name="autoFillBackground">
<bool>true</bool>
</property>
<property name="frameShape"> <property name="frameShape">
<enum>QFrame::NoFrame</enum> <enum>QFrame::NoFrame</enum>
</property> </property>
<property name="lineWidth">
<number>0</number>
</property>
<property name="midLineWidth">
<number>0</number>
</property>
<property name="horizontalScrollBarPolicy"> <property name="horizontalScrollBarPolicy">
<enum>Qt::ScrollBarAlwaysOff</enum> <enum>Qt::ScrollBarAlwaysOff</enum>
</property> </property>
<property name="sizeAdjustPolicy"> <property name="editTriggers">
<enum>QAbstractScrollArea::AdjustIgnored</enum> <set>QAbstractItemView::NoEditTriggers</set>
</property> </property>
<property name="widgetResizable"> <property name="showDropIndicator" stdset="0">
<bool>false</bool>
</property>
<property name="selectionMode">
<enum>QAbstractItemView::NoSelection</enum>
</property>
<property name="verticalScrollMode">
<enum>QAbstractItemView::ScrollPerPixel</enum>
</property>
<property name="horizontalScrollMode">
<enum>QAbstractItemView::ScrollPerItem</enum>
</property>
<property name="isWrapping" stdset="0">
<bool>false</bool>
</property>
<property name="wordWrap">
<bool>true</bool> <bool>true</bool>
</property> </property>
<widget class="QWidget" name="scrollAreaWidgetContents">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>520</width>
<height>385</height>
</rect>
</property>
<layout class="QHBoxLayout" name="horizontalLayout_2">
<property name="spacing">
<number>0</number>
</property>
<property name="leftMargin">
<number>0</number>
</property>
<property name="topMargin">
<number>0</number>
</property>
<property name="rightMargin">
<number>0</number>
</property>
<property name="bottomMargin">
<number>0</number>
</property>
</layout>
</widget>
</widget> </widget>
</item> </item>
</layout> </layout>
<zorder>scrollArea</zorder>
<zorder>widget_3</zorder>
</widget> </widget>
</item> </item>
<item row="1" column="0"> <item row="1" column="0">

View File

@ -23,7 +23,6 @@ Room::Room(Models::Account* acc, Models::Room* p_room, QWidget* parent):
room(p_room) room(p_room)
{ {
setName(p_room->getName()); setName(p_room->getName());
line->setMyName(room->getNick());
setStatus(room->getSubject()); setStatus(room->getSubject());
setAvatar(room->getAvatarPath()); setAvatar(room->getAvatarPath());
@ -31,15 +30,7 @@ Room::Room(Models::Account* acc, Models::Room* p_room, QWidget* parent):
connect(room, &Models::Room::participantJoined, this, &Room::onParticipantJoined); connect(room, &Models::Room::participantJoined, this, &Room::onParticipantJoined);
connect(room, &Models::Room::participantLeft, this, &Room::onParticipantLeft); connect(room, &Models::Room::participantLeft, this, &Room::onParticipantLeft);
std::map<QString, const Models::Participant&> members = room->getParticipants(); feed->setModel(p_room->feed);
for (std::pair<QString, const Models::Participant&> pair : members) {
QString aPath = pair.second.getAvatarPath();
if (aPath.size() > 0) {
line->setPalAvatar(pair.first, aPath);
}
}
line->setExPalAvatars(room->getExParticipantAvatars());
} }
Room::~Room() Room::~Room()
@ -75,30 +66,14 @@ void Room::onRoomChanged(Models::Item* item, int row, int col)
setAvatar(room->getAvatarPath()); setAvatar(room->getAvatarPath());
break; break;
} }
} else {
switch (col) {
case 7: {
Models::Participant* mem = static_cast<Models::Participant*>(item);
QString aPath = mem->getAvatarPath();
if (aPath.size() > 0) {
line->setPalAvatar(mem->getName(), aPath);
} else {
line->dropPalAvatar(mem->getName());
}
}
}
} }
} }
void Room::onParticipantJoined(const Models::Participant& participant) void Room::onParticipantJoined(const Models::Participant& participant)
{ {
QString aPath = participant.getAvatarPath();
if (aPath.size() > 0) {
line->setPalAvatar(participant.getName(), aPath);
}
} }
void Room::onParticipantLeft(const QString& name) void Room::onParticipantLeft(const QString& name)
{ {
line->movePalAvatarToEx(name);
} }