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 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
|
||||||
|
@ -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;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
@ -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
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"
|
#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);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
@ -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;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -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;
|
||||||
|
@ -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;
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@ -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 {
|
||||||
|
@ -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);
|
||||||
|
@ -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);
|
||||||
|
@ -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);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
@ -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:
|
||||||
|
@ -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)
|
||||||
|
@ -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;
|
||||||
|
@ -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">
|
||||||
|
@ -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);
|
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user