forked from blue/squawk
first compiling prototype, doesnt work yet
This commit is contained in:
parent
ef1a9846bf
commit
38159eafeb
@ -9,6 +9,10 @@ set(CMAKE_AUTOUIC ON)
|
||||
# Find the QtWidgets library
|
||||
find_package(Qt5Widgets 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)
|
||||
|
||||
@ -25,6 +29,8 @@ set(squawkUI_SRC
|
||||
models/abstractparticipant.cpp
|
||||
models/participant.cpp
|
||||
models/reference.cpp
|
||||
models/messagefeed.cpp
|
||||
models/element.cpp
|
||||
utils/messageline.cpp
|
||||
utils//message.cpp
|
||||
utils/resizer.cpp
|
||||
|
@ -17,55 +17,26 @@
|
||||
*/
|
||||
|
||||
#include "contact.h"
|
||||
#include "account.h"
|
||||
|
||||
#include <QDebug>
|
||||
|
||||
Models::Contact::Contact(const Account* acc, const QString& p_jid ,const QMap<QString, QVariant> &data, Item *parentItem):
|
||||
Item(Item::contact, data, parentItem),
|
||||
jid(p_jid),
|
||||
Element(Item::contact, acc, p_jid, data, parentItem),
|
||||
availability(Shared::Availability::offline),
|
||||
state(Shared::SubscriptionState::none),
|
||||
avatarState(Shared::Avatar::empty),
|
||||
presences(),
|
||||
messages(),
|
||||
childMessages(0),
|
||||
status(),
|
||||
avatarPath(),
|
||||
account(acc)
|
||||
status()
|
||||
{
|
||||
QMap<QString, QVariant>::const_iterator itr = data.find("state");
|
||||
if (itr != data.end()) {
|
||||
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()
|
||||
{
|
||||
}
|
||||
|
||||
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)
|
||||
{
|
||||
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") {
|
||||
setName(value.toString());
|
||||
} else if (field == "jid") {
|
||||
setJid(value.toString());
|
||||
} else if (field == "availability") {
|
||||
setAvailability(value.toUInt());
|
||||
} else if (field == "state") {
|
||||
setState(value.toUInt());
|
||||
} else if (field == "avatarState") {
|
||||
setAvatarState(value.toUInt());
|
||||
} else if (field == "avatarPath") {
|
||||
setAvatarPath(value.toString());
|
||||
} else {
|
||||
Element::update(field, value);
|
||||
}
|
||||
}
|
||||
|
||||
@ -192,11 +159,9 @@ void Models::Contact::refresh()
|
||||
{
|
||||
QDateTime lastActivity;
|
||||
Presence* presence = 0;
|
||||
unsigned int count = 0;
|
||||
for (QMap<QString, Presence*>::iterator itr = presences.begin(), end = presences.end(); itr != end; ++itr) {
|
||||
Presence* pr = itr.value();
|
||||
QDateTime la = pr->getLastActivity();
|
||||
count += pr->getMessagesCount();
|
||||
|
||||
if (la > lastActivity) {
|
||||
lastActivity = la;
|
||||
@ -211,11 +176,6 @@ void Models::Contact::refresh()
|
||||
setAvailability(Shared::Availability::offline);
|
||||
setStatus("");
|
||||
}
|
||||
|
||||
if (childMessages != count) {
|
||||
childMessages = count;
|
||||
changed(4);
|
||||
}
|
||||
}
|
||||
|
||||
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()
|
||||
{
|
||||
std::deque<Item*>::size_type size = childItems.size();
|
||||
@ -355,75 +240,3 @@ QString Models::Contact::getDisplayedName() const
|
||||
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;
|
||||
}
|
||||
|
||||
|
@ -19,7 +19,7 @@
|
||||
#ifndef MODELS_CONTACT_H
|
||||
#define MODELS_CONTACT_H
|
||||
|
||||
#include "item.h"
|
||||
#include "element.h"
|
||||
#include "presence.h"
|
||||
#include "shared/enums.h"
|
||||
#include "shared/message.h"
|
||||
@ -31,49 +31,34 @@
|
||||
#include <deque>
|
||||
|
||||
namespace Models {
|
||||
class Account;
|
||||
|
||||
class Contact : public Item
|
||||
class Contact : public Element
|
||||
{
|
||||
Q_OBJECT
|
||||
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 Contact& other);
|
||||
~Contact();
|
||||
|
||||
QString getJid() const;
|
||||
Shared::Availability getAvailability() const;
|
||||
Shared::SubscriptionState getState() const;
|
||||
Shared::Avatar getAvatarState() const;
|
||||
QString getAvatarPath() const;
|
||||
|
||||
QIcon getStatusIcon(bool big = false) const;
|
||||
|
||||
int columnCount() 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 removePresence(const QString& name);
|
||||
|
||||
QString getContactName() 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;
|
||||
|
||||
Contact* copy() const;
|
||||
|
||||
protected:
|
||||
void _removeChild(int index) override;
|
||||
void _appendChild(Models::Item * child) override;
|
||||
bool columnInvolvedInDisplay(int col) override;
|
||||
const Account* getParentAccount() const override;
|
||||
|
||||
protected slots:
|
||||
void refresh();
|
||||
@ -84,23 +69,13 @@ protected:
|
||||
void setAvailability(unsigned int p_state);
|
||||
void setState(Shared::SubscriptionState 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);
|
||||
|
||||
private:
|
||||
QString jid;
|
||||
Shared::Availability availability;
|
||||
Shared::SubscriptionState state;
|
||||
Shared::Avatar avatarState;
|
||||
QMap<QString, Presence*> presences;
|
||||
Messages messages;
|
||||
unsigned int childMessages;
|
||||
QString status;
|
||||
QString avatarPath;
|
||||
const Account* account;
|
||||
};
|
||||
|
||||
}
|
||||
|
151
ui/models/element.cpp
Normal file
151
ui/models/element.cpp
Normal 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
70
ui/models/element.h
Normal 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
145
ui/models/messagefeed.cpp
Normal 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
100
ui/models/messagefeed.h
Normal 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
|
@ -20,82 +20,15 @@
|
||||
#include "shared/icons.h"
|
||||
|
||||
Models::Presence::Presence(const QMap<QString, QVariant>& data, Item* parentItem):
|
||||
AbstractParticipant(Item::presence, data, parentItem),
|
||||
messages()
|
||||
AbstractParticipant(Item::presence, data, parentItem)
|
||||
{
|
||||
}
|
||||
|
||||
Models::Presence::Presence(const Models::Presence& other):
|
||||
AbstractParticipant(other),
|
||||
messages(other.messages)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
Models::Presence::~Presence()
|
||||
{
|
||||
}
|
||||
|
||||
int Models::Presence::columnCount() const
|
||||
{
|
||||
return 5;
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
return 4;
|
||||
}
|
||||
|
@ -32,25 +32,10 @@ class Presence : public Models::AbstractParticipant
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
typedef std::deque<Shared::Message> Messages;
|
||||
explicit Presence(const QMap<QString, QVariant> &data, Item *parentItem = 0);
|
||||
Presence(const Presence& other);
|
||||
~Presence();
|
||||
|
||||
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;
|
||||
};
|
||||
|
||||
}
|
||||
|
@ -22,16 +22,12 @@
|
||||
#include <QIcon>
|
||||
#include <QDebug>
|
||||
|
||||
Models::Room::Room(const QString& p_jid, const QMap<QString, QVariant>& data, Models::Item* parentItem):
|
||||
Item(room, data, parentItem),
|
||||
Models::Room::Room(const Account* acc, const QString& p_jid, const QMap<QString, QVariant>& data, Models::Item* parentItem):
|
||||
Element(room, acc, p_jid, data, parentItem),
|
||||
autoJoin(false),
|
||||
joined(false),
|
||||
jid(p_jid),
|
||||
nick(""),
|
||||
subject(""),
|
||||
avatarState(Shared::Avatar::empty),
|
||||
avatarPath(""),
|
||||
messages(),
|
||||
participants(),
|
||||
exParticipantAvatars()
|
||||
{
|
||||
@ -55,16 +51,6 @@ Models::Room::Room(const QString& p_jid, const QMap<QString, QVariant>& data, Mo
|
||||
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");
|
||||
if (itr != data.end()) {
|
||||
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
|
||||
{
|
||||
return 7;
|
||||
}
|
||||
|
||||
QString Models::Room::getJid() const
|
||||
{
|
||||
return jid;
|
||||
}
|
||||
|
||||
bool Models::Room::getAutoJoin() const
|
||||
{
|
||||
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)
|
||||
{
|
||||
if (joined != p_joined) {
|
||||
@ -182,8 +150,6 @@ void Models::Room::update(const QString& field, const QVariant& value)
|
||||
{
|
||||
if (field == "name") {
|
||||
setName(value.toString());
|
||||
} else if (field == "jid") {
|
||||
setJid(value.toString());
|
||||
} else if (field == "joined") {
|
||||
setJoined(value.toBool());
|
||||
} else if (field == "autoJoin") {
|
||||
@ -192,16 +158,14 @@ void Models::Room::update(const QString& field, const QVariant& value)
|
||||
setNick(value.toString());
|
||||
} else if (field == "subject") {
|
||||
setSubject(value.toString());
|
||||
} else if (field == "avatarState") {
|
||||
setAvatarState(value.toUInt());
|
||||
} else if (field == "avatarPath") {
|
||||
setAvatarPath(value.toString());
|
||||
} else {
|
||||
Element::update(field, value);
|
||||
}
|
||||
}
|
||||
|
||||
QIcon Models::Room::getStatusIcon(bool big) const
|
||||
{
|
||||
if (messages.size() > 0) {
|
||||
if (getMessagesCount() > 0) {
|
||||
return Shared::icon("mail-message", big);
|
||||
} else {
|
||||
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()
|
||||
{
|
||||
@ -367,47 +295,6 @@ QString Models::Room::getDisplayedName() const
|
||||
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&> result;
|
||||
|
@ -19,7 +19,7 @@
|
||||
#ifndef MODELS_ROOM_H
|
||||
#define MODELS_ROOM_H
|
||||
|
||||
#include "item.h"
|
||||
#include "element.h"
|
||||
#include "participant.h"
|
||||
#include "shared/enums.h"
|
||||
#include "shared/message.h"
|
||||
@ -29,21 +29,18 @@ namespace Models {
|
||||
/**
|
||||
* @todo write docs
|
||||
*/
|
||||
class Room : public Models::Item
|
||||
class Room : public Element
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
typedef std::deque<Shared::Message> Messages;
|
||||
Room(const QString& p_jid, const QMap<QString, QVariant> &data, Item *parentItem = 0);
|
||||
Room(const Account* acc, const QString& p_jid, const QMap<QString, QVariant> &data, Item *parentItem = 0);
|
||||
~Room();
|
||||
|
||||
int columnCount() const override;
|
||||
QVariant data(int column) const override;
|
||||
|
||||
unsigned int getUnreadMessagesCount() const;
|
||||
bool getJoined() const;
|
||||
bool getAutoJoin() const;
|
||||
QString getJid() const;
|
||||
QString getNick() const;
|
||||
QString getRoomName() const;
|
||||
QString getSubject() const;
|
||||
@ -53,17 +50,10 @@ public:
|
||||
|
||||
void setJoined(bool p_joined);
|
||||
void setAutoJoin(bool p_autoJoin);
|
||||
void setJid(const QString& p_jid);
|
||||
void setNick(const QString& p_nick);
|
||||
void setSubject(const QString& sub);
|
||||
|
||||
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 dropMessages();
|
||||
void getMessages(Messages& container) const;
|
||||
void update(const QString& field, const QVariant& value) override;
|
||||
|
||||
void addParticipant(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;
|
||||
QString getDisplayedName() const override;
|
||||
Shared::Avatar getAvatarState() const;
|
||||
QString getAvatarPath() const;
|
||||
std::map<QString, const Participant&> getParticipants() const;
|
||||
QString getParticipantIconPath(const QString& name) const;
|
||||
std::map<QString, QString> getExParticipantAvatars() const;
|
||||
@ -84,24 +72,14 @@ signals:
|
||||
private:
|
||||
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:
|
||||
bool autoJoin;
|
||||
bool joined;
|
||||
QString jid;
|
||||
QString nick;
|
||||
QString subject;
|
||||
Shared::Avatar avatarState;
|
||||
QString avatarPath;
|
||||
Messages messages;
|
||||
std::map<QString, Participant*> participants;
|
||||
std::map<QString, QString> exParticipantAvatars;
|
||||
|
||||
};
|
||||
|
||||
}
|
||||
|
@ -215,11 +215,7 @@ QVariant Models::Roster::data (const QModelIndex& index, int role) const
|
||||
break;
|
||||
case Item::presence: {
|
||||
Presence* contact = static_cast<Presence*>(item);
|
||||
QString str("");
|
||||
int mc = contact->getMessagesCount();
|
||||
if (mc > 0) {
|
||||
str += tr("New messages: ") + std::to_string(mc).c_str() + "\n";
|
||||
}
|
||||
QString str;
|
||||
Shared::Availability av = contact->getAvailability();
|
||||
str += tr("Availability: ") + Shared::Global::getName(av);
|
||||
QString s = contact->getStatus();
|
||||
@ -232,7 +228,7 @@ QVariant Models::Roster::data (const QModelIndex& index, int role) const
|
||||
break;
|
||||
case Item::participant: {
|
||||
Participant* p = static_cast<Participant*>(item);
|
||||
QString str("");
|
||||
QString str;
|
||||
Shared::Availability av = p->getAvailability();
|
||||
str += tr("Availability: ") + Shared::Global::getName(av) + "\n";
|
||||
QString s = p->getStatus();
|
||||
@ -260,7 +256,7 @@ QVariant Models::Roster::data (const QModelIndex& index, int role) const
|
||||
break;
|
||||
case Item::room: {
|
||||
Room* rm = static_cast<Room*>(item);
|
||||
unsigned int count = rm->getUnreadMessagesCount();
|
||||
unsigned int count = rm->getMessagesCount();
|
||||
QString str("");
|
||||
if (count > 0) {
|
||||
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);
|
||||
if (itr == contacts.end()) {
|
||||
contact = new Contact(acc, jid, data);
|
||||
connect(contact, &Contact::requestArchive, this, &Roster::onElementRequestArchive);
|
||||
contacts.insert(std::make_pair(id, contact));
|
||||
} else {
|
||||
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)
|
||||
{
|
||||
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;
|
||||
}
|
||||
|
||||
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));
|
||||
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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -58,7 +58,6 @@ public:
|
||||
void removePresence(const QString& account, const QString& jid, const QString& name);
|
||||
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 dropMessages(const QString& account, const QString& jid);
|
||||
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 removeRoom(const QString& account, const QString jid);
|
||||
@ -81,9 +80,13 @@ public:
|
||||
Account* getAccount(const QString& name);
|
||||
QModelIndex getAccountIndex(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;
|
||||
|
||||
signals:
|
||||
void requestArchive(const QString& account, const QString& jid, const QString& before);
|
||||
|
||||
private:
|
||||
Item* root;
|
||||
std::map<QString, Account*> accounts;
|
||||
@ -100,6 +103,7 @@ private slots:
|
||||
void onChildRemoved();
|
||||
void onChildIsAboutToBeMoved(Item* source, int first, int last, Item* destination, int newIndex);
|
||||
void onChildMoved();
|
||||
void onElementRequestArchive(const QString& before);
|
||||
|
||||
public:
|
||||
class ElId {
|
||||
|
@ -62,6 +62,7 @@ Squawk::Squawk(QWidget *parent) :
|
||||
connect(m_ui->roster->selectionModel(), &QItemSelectionModel::currentRowChanged, this, &Squawk::onRosterSelectionChanged);
|
||||
|
||||
connect(rosterModel.accountsModel, &Models::Accounts::sizeChanged, this, &Squawk::onAccountsSizeChanged);
|
||||
connect(&rosterModel, &Models::Roster::requestArchive, this, &Squawk::onConversationRequestArchive);
|
||||
connect(contextMenu, &QMenu::aboutToHide, this, &Squawk::onContextAboutToHide);
|
||||
//m_ui->mainToolBar->addWidget(m_ui->comboBox);
|
||||
|
||||
@ -336,17 +337,14 @@ void Squawk::onRosterItemDoubleClicked(const QModelIndex& item)
|
||||
Models::Account* acc = rosterModel.getAccount(id->account);
|
||||
Conversation* conv = 0;
|
||||
bool created = false;
|
||||
Models::Contact::Messages deque;
|
||||
if (itr != conversations.end()) {
|
||||
conv = itr->second;
|
||||
} else if (contact != 0) {
|
||||
created = true;
|
||||
conv = new Chat(acc, contact);
|
||||
contact->getMessages(deque);
|
||||
} else if (room != 0) {
|
||||
created = true;
|
||||
conv = new Room(acc, room);
|
||||
room->getMessages(deque);
|
||||
|
||||
if (!room->getJoined()) {
|
||||
emit setRoomJoined(id->account, id->name, true);
|
||||
@ -358,12 +356,6 @@ void Squawk::onRosterItemDoubleClicked(const QModelIndex& item)
|
||||
conv->setAttribute(Qt::WA_DeleteOnClose);
|
||||
subscribeConversation(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();
|
||||
@ -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)
|
||||
{
|
||||
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);
|
||||
bool found = false;
|
||||
|
||||
rosterModel.addMessage(account, data);
|
||||
|
||||
if (currentConversation != 0 && currentConversation->getId() == id) {
|
||||
currentConversation->addMessage(data);
|
||||
QApplication::alert(this);
|
||||
if (!isVisible() && !data.getForwarded()) {
|
||||
notify(account, data);
|
||||
@ -516,11 +503,7 @@ void Squawk::accountMessage(const QString& account, const Shared::Message& data)
|
||||
|
||||
if (itr != conversations.end()) {
|
||||
Conversation* conv = itr->second;
|
||||
conv->addMessage(data);
|
||||
QApplication::alert(conv);
|
||||
if (!found && conv->isMinimized()) {
|
||||
rosterModel.addMessage(account, data);
|
||||
}
|
||||
if (!conv->isVisible() && !data.getForwarded()) {
|
||||
notify(account, data);
|
||||
}
|
||||
@ -528,7 +511,6 @@ void Squawk::accountMessage(const QString& account, const Shared::Message& data)
|
||||
}
|
||||
|
||||
if (!found) {
|
||||
rosterModel.addMessage(account, data);
|
||||
if (!data.getForwarded()) {
|
||||
QApplication::alert(this);
|
||||
notify(account, data);
|
||||
@ -599,16 +581,7 @@ void Squawk::onConversationMessage(const Shared::Message& msg)
|
||||
emit sendMessage(conv->getAccount(), msg);
|
||||
Models::Roster::ElId id = conv->getId();
|
||||
|
||||
if (currentConversation != 0 && currentConversation->getId() == id) {
|
||||
if (conv == currentConversation) {
|
||||
Conversations::iterator itr = conversations.find(id);
|
||||
if (itr != conversations.end()) {
|
||||
itr->second->addMessage(msg);
|
||||
}
|
||||
} else {
|
||||
currentConversation->addMessage(msg);
|
||||
}
|
||||
}
|
||||
rosterModel.addMessage(conv->getAccount(), msg);
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
void Squawk::onConversationRequestArchive(const QString& before)
|
||||
void Squawk::onConversationRequestArchive(const QString& account, const QString& jid, const QString& before)
|
||||
{
|
||||
Conversation* conv = static_cast<Conversation*>(sender());
|
||||
requestArchive(conv->getAccount(), conv->getJid(), 20, before); //TODO amount as a settings value
|
||||
emit requestArchive(account, jid, 20, before); //TODO amount as a settings value
|
||||
}
|
||||
|
||||
void Squawk::responseArchive(const QString& account, const QString& jid, const std::list<Shared::Message>& list)
|
||||
{
|
||||
Models::Roster::ElId id(account, jid);
|
||||
|
||||
if (currentConversation != 0 && currentConversation->getId() == id) {
|
||||
currentConversation->responseArchive(list);
|
||||
}
|
||||
|
||||
Conversations::const_iterator itr = conversations.find(id);
|
||||
if (itr != conversations.end()) {
|
||||
itr->second->responseArchive(list);
|
||||
}
|
||||
rosterModel.responseArchive(account, jid, list);
|
||||
}
|
||||
|
||||
void Squawk::removeAccount(const QString& account)
|
||||
@ -661,8 +624,6 @@ void Squawk::removeAccount(const QString& account)
|
||||
++itr;
|
||||
Conversation* conv = lItr->second;
|
||||
disconnect(conv, &Conversation::destroyed, this, &Squawk::onConversationClosed);
|
||||
disconnect(conv, &Conversation::requestArchive, this, &Squawk::onConversationRequestArchive);
|
||||
disconnect(conv, &Conversation::shown, this, &Squawk::onConversationShown);
|
||||
conv->close();
|
||||
conversations.erase(lItr);
|
||||
} 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);
|
||||
VCard* card;
|
||||
Models::Contact::Messages deque;
|
||||
if (itr != vCards.end()) {
|
||||
card = itr->second;
|
||||
} 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&, const QString&>(&Conversation::sendMessage),
|
||||
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::downloadFile, this, &Squawk::onConversationDownloadFile);
|
||||
connect(conv, &Conversation::shown, this, &Squawk::onConversationShown);
|
||||
}
|
||||
|
||||
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::Contact::Messages deque;
|
||||
if (contact != 0) {
|
||||
currentConversation = new Chat(acc, contact);
|
||||
contact->getMessages(deque);
|
||||
} else if (room != 0) {
|
||||
currentConversation = new Room(acc, room);
|
||||
room->getMessages(deque);
|
||||
|
||||
if (!room->getJoined()) {
|
||||
emit setRoomJoined(id->account, id->name, true);
|
||||
@ -1185,9 +1140,6 @@ void Squawk::onRosterSelectionChanged(const QModelIndex& current, const QModelIn
|
||||
}
|
||||
|
||||
subscribeConversation(currentConversation);
|
||||
for (Models::Contact::Messages::const_iterator itr = deque.begin(), end = deque.end(); itr != end; ++itr) {
|
||||
currentConversation->addMessage(*itr);
|
||||
}
|
||||
|
||||
if (res.size() > 0) {
|
||||
currentConversation->setPalResource(res);
|
||||
|
@ -148,9 +148,8 @@ private slots:
|
||||
void onRosterItemDoubleClicked(const QModelIndex& item);
|
||||
void onConversationMessage(const Shared::Message& msg);
|
||||
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 onConversationShown();
|
||||
void onConversationRequestLocalFile(const QString& messageId, const QString& url);
|
||||
void onConversationDownloadFile(const QString& messageId, const QString& url);
|
||||
void onItemCollepsed(const QModelIndex& index);
|
||||
|
@ -28,6 +28,8 @@ Chat::Chat(Models::Account* acc, Models::Contact* p_contact, QWidget* parent):
|
||||
setAvatar(p_contact->getAvatarPath());
|
||||
|
||||
connect(contact, &Models::Contact::childChanged, this, &Chat::onContactChanged);
|
||||
|
||||
feed->setModel(p_contact->feed);
|
||||
}
|
||||
|
||||
Chat::~Chat()
|
||||
@ -71,31 +73,15 @@ Shared::Message Chat::createMessage() const
|
||||
return msg;
|
||||
}
|
||||
|
||||
void Chat::addMessage(const Shared::Message& data)
|
||||
{
|
||||
Conversation::addMessage(data);
|
||||
|
||||
if (!data.getOutgoing()) { //TODO need to check if that was the last message
|
||||
const QString& res = data.getPenPalResource();
|
||||
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);
|
||||
}
|
||||
}
|
||||
// TODO
|
||||
// void Chat::addMessage(const Shared::Message& data)
|
||||
// {
|
||||
// Conversation::addMessage(data);
|
||||
//
|
||||
// if (!data.getOutgoing()) { //TODO need to check if that was the last message
|
||||
// const QString& res = data.getPenPalResource();
|
||||
// if (res.size() > 0) {
|
||||
// setPalResource(res);
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
|
@ -35,14 +35,12 @@ public:
|
||||
Chat(Models::Account* acc, Models::Contact* p_contact, QWidget* parent = 0);
|
||||
~Chat();
|
||||
|
||||
void addMessage(const Shared::Message & data) override;
|
||||
void setAvatar(const QString& path) override;
|
||||
//void addMessage(const Shared::Message & data) override;
|
||||
|
||||
protected slots:
|
||||
void onContactChanged(Models::Item* item, int row, int col);
|
||||
|
||||
protected:
|
||||
void setName(const QString & name) override;
|
||||
Shared::Message createMessage() const override;
|
||||
|
||||
private:
|
||||
|
@ -35,7 +35,6 @@ Conversation::Conversation(bool muc, Models::Account* acc, const QString pJid, c
|
||||
account(acc),
|
||||
palJid(pJid),
|
||||
activePalResource(pRes),
|
||||
line(new MessageLine(muc)),
|
||||
m_ui(new Ui::Conversation()),
|
||||
ker(),
|
||||
scrollResizeCatcher(),
|
||||
@ -46,6 +45,7 @@ Conversation::Conversation(bool muc, Models::Account* acc, const QString pJid, c
|
||||
filesLayout(0),
|
||||
overlay(new QWidget()),
|
||||
filesToAttach(),
|
||||
feed(0),
|
||||
scroll(down),
|
||||
manualSliderChange(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)
|
||||
{
|
||||
m_ui->setupUi(this);
|
||||
feed = m_ui->feed;
|
||||
|
||||
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::hidden, this, &Conversation::onScrollResize);
|
||||
connect(m_ui->sendButton, &QPushButton::clicked, this, &Conversation::onEnterPressed);
|
||||
connect(line, &MessageLine::resize, this, &Conversation::onMessagesResize);
|
||||
connect(line, &MessageLine::downloadFile, this, &Conversation::downloadFile);
|
||||
connect(line, &MessageLine::uploadFile, this, qOverload<const Shared::Message&, const QString&>(&Conversation::sendMessage));
|
||||
connect(line, &MessageLine::requestLocalFile, this, &Conversation::requestLocalFile);
|
||||
//connect(line, &MessageLine::resize, this, &Conversation::onMessagesResize);
|
||||
//connect(line, &MessageLine::downloadFile, this, &Conversation::downloadFile);
|
||||
//connect(line, &MessageLine::uploadFile, this, qOverload<const Shared::Message&, const QString&>(&Conversation::sendMessage));
|
||||
//connect(line, &MessageLine::requestLocalFile, this, &Conversation::requestLocalFile);
|
||||
connect(m_ui->attachButton, &QPushButton::clicked, this, &Conversation::onAttach);
|
||||
connect(m_ui->clearButton, &QPushButton::clicked, this, &Conversation::onClearButton);
|
||||
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);
|
||||
|
||||
QScrollBar* vs = m_ui->scrollArea->verticalScrollBar();
|
||||
m_ui->scrollArea->setWidget(line);
|
||||
vs->installEventFilter(&vis);
|
||||
//QScrollBar* vs = m_ui->scrollArea->verticalScrollBar();
|
||||
//m_ui->scrollArea->setWidget(line);
|
||||
//vs->installEventFilter(&vis);
|
||||
|
||||
line->setAutoFillBackground(false);
|
||||
if (testAttribute(Qt::WA_TranslucentBackground)) {
|
||||
m_ui->scrollArea->setAutoFillBackground(false);
|
||||
} else {
|
||||
m_ui->scrollArea->setBackgroundRole(QPalette::Base);
|
||||
}
|
||||
//line->setAutoFillBackground(false);
|
||||
//if (testAttribute(Qt::WA_TranslucentBackground)) {
|
||||
//m_ui->scrollArea->setAutoFillBackground(false);
|
||||
//} else {
|
||||
//m_ui->scrollArea->setBackgroundRole(QPalette::Base);
|
||||
//}
|
||||
|
||||
connect(vs, &QScrollBar::valueChanged, this, &Conversation::onSliderValueChanged);
|
||||
m_ui->scrollArea->installEventFilter(&scrollResizeCatcher);
|
||||
//connect(vs, &QScrollBar::valueChanged, this, &Conversation::onSliderValueChanged);
|
||||
//m_ui->scrollArea->installEventFilter(&scrollResizeCatcher);
|
||||
|
||||
line->setMyAvatarPath(acc->getAvatarPath());
|
||||
line->setMyName(acc->getName());
|
||||
//line->setMyAvatarPath(acc->getAvatarPath());
|
||||
//line->setMyName(acc->getName());
|
||||
|
||||
QGridLayout* gr = static_cast<QGridLayout*>(layout());
|
||||
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 (!requestingHistory) {
|
||||
requestingHistory = true;
|
||||
line->showBusyIndicator();
|
||||
emit requestArchive("");
|
||||
scroll = down;
|
||||
//line->showBusyIndicator();
|
||||
//emit requestArchive("");
|
||||
//scroll = down;
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -139,12 +140,12 @@ void Conversation::onAccountChanged(Models::Item* item, int row, int col)
|
||||
|
||||
void Conversation::applyVisualEffects()
|
||||
{
|
||||
DropShadowEffect *e1 = new DropShadowEffect;
|
||||
e1->setBlurRadius(10);
|
||||
e1->setColor(Qt::black);
|
||||
e1->setThickness(1);
|
||||
e1->setFrame(true, false, true, false);
|
||||
m_ui->scrollArea->setGraphicsEffect(e1);
|
||||
// DropShadowEffect *e1 = new DropShadowEffect;
|
||||
// e1->setBlurRadius(10);
|
||||
// e1->setColor(Qt::black);
|
||||
// e1->setThickness(1);
|
||||
// e1->setFrame(true, false, true, false);
|
||||
// m_ui->scrollArea->setGraphicsEffect(e1);
|
||||
}
|
||||
|
||||
void Conversation::setName(const QString& name)
|
||||
@ -163,20 +164,9 @@ QString Conversation::getJid() const
|
||||
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)
|
||||
{
|
||||
line->changeMessage(id, data);
|
||||
// line->changeMessage(id, data);
|
||||
}
|
||||
|
||||
KeyEnterReceiver::KeyEnterReceiver(QObject* parent): QObject(parent), ownEvent(false) {}
|
||||
@ -226,86 +216,86 @@ void Conversation::onEnterPressed()
|
||||
m_ui->messageEditor->clear();
|
||||
Shared::Message msg = createMessage();
|
||||
msg.setBody(body);
|
||||
addMessage(msg);
|
||||
//addMessage(msg);
|
||||
emit sendMessage(msg);
|
||||
}
|
||||
if (filesToAttach.size() > 0) {
|
||||
for (Badge* badge : filesToAttach) {
|
||||
Shared::Message msg = createMessage();
|
||||
line->appendMessageWithUpload(msg, badge->id);
|
||||
usleep(1000); //this is required for the messages not to have equal time when appending into messageline
|
||||
}
|
||||
clearAttachedFiles();
|
||||
// for (Badge* badge : filesToAttach) {
|
||||
// Shared::Message msg = createMessage();
|
||||
// line->appendMessageWithUpload(msg, badge->id);
|
||||
// usleep(1000); //this is required for the messages not to have equal time when appending into messageline
|
||||
// }
|
||||
// clearAttachedFiles();
|
||||
}
|
||||
}
|
||||
|
||||
void Conversation::appendMessageWithUpload(const Shared::Message& data, const QString& path)
|
||||
{
|
||||
line->appendMessageWithUploadNoSiganl(data, path);
|
||||
// line->appendMessageWithUploadNoSiganl(data, path);
|
||||
}
|
||||
|
||||
void Conversation::onMessagesResize(int amount)
|
||||
{
|
||||
manualSliderChange = true;
|
||||
switch (scroll) {
|
||||
case down:
|
||||
m_ui->scrollArea->verticalScrollBar()->setValue(m_ui->scrollArea->verticalScrollBar()->maximum());
|
||||
break;
|
||||
case keep: {
|
||||
int max = m_ui->scrollArea->verticalScrollBar()->maximum();
|
||||
int value = m_ui->scrollArea->verticalScrollBar()->value() + amount;
|
||||
m_ui->scrollArea->verticalScrollBar()->setValue(value);
|
||||
|
||||
if (value == max) {
|
||||
scroll = down;
|
||||
} else {
|
||||
scroll = nothing;
|
||||
}
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
manualSliderChange = false;
|
||||
// manualSliderChange = true;
|
||||
// switch (scroll) {
|
||||
// case down:
|
||||
// m_ui->scrollArea->verticalScrollBar()->setValue(m_ui->scrollArea->verticalScrollBar()->maximum());
|
||||
// break;
|
||||
// case keep: {
|
||||
// int max = m_ui->scrollArea->verticalScrollBar()->maximum();
|
||||
// int value = m_ui->scrollArea->verticalScrollBar()->value() + amount;
|
||||
// m_ui->scrollArea->verticalScrollBar()->setValue(value);
|
||||
//
|
||||
// if (value == max) {
|
||||
// scroll = down;
|
||||
// } else {
|
||||
// scroll = nothing;
|
||||
// }
|
||||
// }
|
||||
// break;
|
||||
// default:
|
||||
// break;
|
||||
// }
|
||||
// manualSliderChange = false;
|
||||
}
|
||||
|
||||
void Conversation::onSliderValueChanged(int value)
|
||||
{
|
||||
if (!manualSliderChange) {
|
||||
if (value == m_ui->scrollArea->verticalScrollBar()->maximum()) {
|
||||
scroll = down;
|
||||
} else {
|
||||
if (!requestingHistory && value == 0) {
|
||||
requestingHistory = true;
|
||||
line->showBusyIndicator();
|
||||
emit requestArchive(line->firstMessageId());
|
||||
scroll = keep;
|
||||
} else {
|
||||
scroll = nothing;
|
||||
}
|
||||
}
|
||||
}
|
||||
// if (!manualSliderChange) {
|
||||
// if (value == m_ui->scrollArea->verticalScrollBar()->maximum()) {
|
||||
// scroll = down;
|
||||
// } else {
|
||||
// if (!requestingHistory && value == 0) {
|
||||
// requestingHistory = true;
|
||||
// line->showBusyIndicator();
|
||||
// emit requestArchive(line->firstMessageId());
|
||||
// scroll = keep;
|
||||
// } else {
|
||||
// scroll = nothing;
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
}
|
||||
|
||||
void Conversation::responseArchive(const std::list<Shared::Message> list)
|
||||
{
|
||||
requestingHistory = false;
|
||||
scroll = keep;
|
||||
|
||||
line->hideBusyIndicator();
|
||||
for (std::list<Shared::Message>::const_iterator itr = list.begin(), end = list.end(); itr != end; ++itr) {
|
||||
addMessage(*itr);
|
||||
}
|
||||
// requestingHistory = false;
|
||||
// scroll = keep;
|
||||
//
|
||||
// line->hideBusyIndicator();
|
||||
// for (std::list<Shared::Message>::const_iterator itr = list.begin(), end = list.end(); itr != end; ++itr) {
|
||||
// addMessage(*itr);
|
||||
// }
|
||||
}
|
||||
|
||||
void Conversation::showEvent(QShowEvent* event)
|
||||
{
|
||||
if (!everShown) {
|
||||
everShown = true;
|
||||
line->showBusyIndicator();
|
||||
// line->showBusyIndicator();
|
||||
requestingHistory = true;
|
||||
scroll = keep;
|
||||
emit requestArchive(line->firstMessageId());
|
||||
emit requestArchive("");
|
||||
}
|
||||
emit shown();
|
||||
|
||||
@ -342,30 +332,30 @@ void Conversation::setStatus(const QString& status)
|
||||
|
||||
void Conversation::onScrollResize()
|
||||
{
|
||||
if (everShown) {
|
||||
int size = m_ui->scrollArea->width();
|
||||
QScrollBar* bar = m_ui->scrollArea->verticalScrollBar();
|
||||
if (bar->isVisible() && !tsb) {
|
||||
size -= bar->width();
|
||||
|
||||
}
|
||||
line->setMaximumWidth(size);
|
||||
}
|
||||
// if (everShown) {
|
||||
// int size = m_ui->scrollArea->width();
|
||||
// QScrollBar* bar = m_ui->scrollArea->verticalScrollBar();
|
||||
// if (bar->isVisible() && !tsb) {
|
||||
// size -= bar->width();
|
||||
//
|
||||
// }
|
||||
// line->setMaximumWidth(size);
|
||||
// }
|
||||
}
|
||||
|
||||
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)
|
||||
{
|
||||
line->fileError(messageId, error);
|
||||
// line->fileError(messageId, error);
|
||||
}
|
||||
|
||||
void Conversation::responseLocalFile(const QString& messageId, const QString& path)
|
||||
{
|
||||
line->responseLocalFile(messageId, path);
|
||||
// line->responseLocalFile(messageId, path);
|
||||
}
|
||||
|
||||
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)
|
||||
{
|
||||
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)
|
||||
|
@ -24,6 +24,7 @@
|
||||
#include <QMap>
|
||||
#include <QMimeData>
|
||||
#include <QFileInfo>
|
||||
#include <QListView>
|
||||
|
||||
#include "shared/message.h"
|
||||
#include "order.h"
|
||||
@ -78,7 +79,6 @@ public:
|
||||
QString getAccount() const;
|
||||
QString getPalResource() const;
|
||||
Models::Roster::ElId getId() const;
|
||||
virtual void addMessage(const Shared::Message& data);
|
||||
|
||||
void setPalResource(const QString& res);
|
||||
void responseArchive(const std::list<Shared::Message> list);
|
||||
@ -135,7 +135,6 @@ protected:
|
||||
Models::Account* account;
|
||||
QString palJid;
|
||||
QString activePalResource;
|
||||
MessageLine* line;
|
||||
QScopedPointer<Ui::Conversation> m_ui;
|
||||
KeyEnterReceiver ker;
|
||||
Resizer scrollResizeCatcher;
|
||||
@ -146,6 +145,7 @@ protected:
|
||||
FlowLayout* filesLayout;
|
||||
QWidget* overlay;
|
||||
W::Order<Badge*, Badge::Comparator> filesToAttach;
|
||||
QListView* feed;
|
||||
Scroll scroll;
|
||||
bool manualSliderChange;
|
||||
bool requestingHistory;
|
||||
|
@ -215,60 +215,37 @@
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QScrollArea" name="scrollArea">
|
||||
<property name="autoFillBackground">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<widget class="QListView" name="feed">
|
||||
<property name="frameShape">
|
||||
<enum>QFrame::NoFrame</enum>
|
||||
</property>
|
||||
<property name="lineWidth">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="midLineWidth">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="horizontalScrollBarPolicy">
|
||||
<enum>Qt::ScrollBarAlwaysOff</enum>
|
||||
</property>
|
||||
<property name="sizeAdjustPolicy">
|
||||
<enum>QAbstractScrollArea::AdjustIgnored</enum>
|
||||
<property name="editTriggers">
|
||||
<set>QAbstractItemView::NoEditTriggers</set>
|
||||
</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>
|
||||
</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>
|
||||
</item>
|
||||
</layout>
|
||||
<zorder>scrollArea</zorder>
|
||||
<zorder>widget_3</zorder>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="0">
|
||||
|
@ -23,7 +23,6 @@ Room::Room(Models::Account* acc, Models::Room* p_room, QWidget* parent):
|
||||
room(p_room)
|
||||
{
|
||||
setName(p_room->getName());
|
||||
line->setMyName(room->getNick());
|
||||
setStatus(room->getSubject());
|
||||
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::participantLeft, this, &Room::onParticipantLeft);
|
||||
|
||||
std::map<QString, const Models::Participant&> members = room->getParticipants();
|
||||
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());
|
||||
feed->setModel(p_room->feed);
|
||||
}
|
||||
|
||||
Room::~Room()
|
||||
@ -75,30 +66,14 @@ void Room::onRoomChanged(Models::Item* item, int row, int col)
|
||||
setAvatar(room->getAvatarPath());
|
||||
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)
|
||||
{
|
||||
QString aPath = participant.getAvatarPath();
|
||||
if (aPath.size() > 0) {
|
||||
line->setPalAvatar(participant.getName(), aPath);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void Room::onParticipantLeft(const QString& name)
|
||||
{
|
||||
line->movePalAvatarToEx(name);
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user