1
0
forked from blue/squawk

ui logick of changing message, not connected yet

This commit is contained in:
Blue 2020-02-08 14:44:15 +03:00
parent ed56cca2e7
commit 6d1b83d0f8
18 changed files with 246 additions and 19 deletions

View File

@ -290,6 +290,31 @@ void Shared::Message::deserialize(QDataStream& data)
data >> edited; data >> edited;
} }
bool Shared::Message::change(const QMap<QString, QVariant>& data)
{
QMap<QString, QVariant>::const_iterator itr = data.find("state");
if (itr != data.end()) {
setState(static_cast<State>(itr.value().toUInt()));
}
bool idChanged = false;
itr = data.find("id");
if (itr != data.end()) {
QString newId = itr.value().toString();
if (id != newId) {
setId(newId);
idChanged = true;
}
}
itr = data.find("body");
if (itr != data.end()) {
setBody(itr.value().toString());
setEdited(true);
}
return idChanged;
}
QString Shared::generateUUID() QString Shared::generateUUID()
{ {
uuid_t uuid; uuid_t uuid;

View File

@ -20,6 +20,7 @@
#define GLOBAL_H #define GLOBAL_H
#include <QString> #include <QString>
#include <QMap>
#include <QCoreApplication> #include <QCoreApplication>
#include <deque> #include <deque>
#include <QDateTime> #include <QDateTime>
@ -189,6 +190,7 @@ public:
void setOutOfBandUrl(const QString& url); void setOutOfBandUrl(const QString& url);
void setState(State p_state); void setState(State p_state);
void setEdited(bool p_edited); void setEdited(bool p_edited);
bool change(const QMap<QString, QVariant>& data);
QString getFrom() const; QString getFrom() const;
QString getFromJid() const; QString getFromJid() const;

View File

@ -290,6 +290,27 @@ void Models::Contact::addMessage(const Shared::Message& data)
} }
} }
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 unsigned int Models::Contact::getMessagesCount() const
{ {
return messages.size() + childMessages; return messages.size() + childMessages;

View File

@ -57,6 +57,7 @@ public:
QString getStatus() const; QString getStatus() const;
void addMessage(const Shared::Message& data); void addMessage(const Shared::Message& data);
void changeMessage(const QString& id, const QMap<QString, QVariant>& data);
unsigned int getMessagesCount() const; unsigned int getMessagesCount() const;
void dropMessages(); void dropMessages();
void getMessages(Messages& container) const; void getMessages(Messages& container) const;

View File

@ -61,6 +61,19 @@ void Models::Presence::addMessage(const Shared::Message& data)
changed(4); 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() void Models::Presence::dropMessages()
{ {
if (messages.size() > 0) { if (messages.size() > 0) {

View File

@ -43,6 +43,7 @@ public:
unsigned int getMessagesCount() const; unsigned int getMessagesCount() const;
void dropMessages(); void dropMessages();
void addMessage(const Shared::Message& data); void addMessage(const Shared::Message& data);
bool changeMessage(const QString& id, const QMap<QString, QVariant>& data);
void getMessages(Messages& container) const; void getMessages(Messages& container) const;

View File

@ -236,6 +236,16 @@ void Models::Room::addMessage(const Shared::Message& data)
changed(5); 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() void Models::Room::dropMessages()
{ {
if (messages.size() > 0) { if (messages.size() > 0) {

View File

@ -59,6 +59,7 @@ public:
void update(const QString& field, const QVariant& value); void update(const QString& field, const QVariant& value);
void addMessage(const Shared::Message& data); void addMessage(const Shared::Message& data);
void changeMessage(const QString& id, const QMap<QString, QVariant>& data);
unsigned int getMessagesCount() const; unsigned int getMessagesCount() const;
void dropMessages(); void dropMessages();
void getMessages(Messages& container) const; void getMessages(Messages& container) const;

View File

@ -549,14 +549,34 @@ void Models::Roster::changeContact(const QString& account, const QString& jid, c
for (; cBeg != cEnd; ++cBeg) { for (; cBeg != cEnd; ++cBeg) {
for (QMap<QString, QVariant>::const_iterator itr = data.begin(), end = data.end(); itr != end; ++itr) { for (QMap<QString, QVariant>::const_iterator itr = data.begin(), end = data.end(); itr != end; ++itr) {
cBeg->second->update(itr.key(), itr.value());; cBeg->second->update(itr.key(), itr.value());
} }
} }
std::map<ElId, Room*>::iterator rItr = rooms.find(id); std::map<ElId, Room*>::iterator rItr = rooms.find(id);
if (rItr != rooms.end()) { if (rItr != rooms.end()) {
for (QMap<QString, QVariant>::const_iterator itr = data.begin(), end = data.end(); itr != end; ++itr) { for (QMap<QString, QVariant>::const_iterator itr = data.begin(), end = data.end(); itr != end; ++itr) {
rItr->second->update(itr.key(), itr.value());; rItr->second->update(itr.key(), itr.value());
}
}
}
void Models::Roster::changeMessage(const QString& account, const QString& jid, const QString& id, const QMap<QString, QVariant>& data)
{
ElId elid(account, jid);
std::multimap<ElId, Contact*>::iterator cBeg = contacts.lower_bound(elid);
std::multimap<ElId, Contact*>::iterator cEnd = contacts.upper_bound(elid);
for (; cBeg != cEnd; ++cBeg) {
for (QMap<QString, QVariant>::const_iterator itr = data.begin(), end = data.end(); itr != end; ++itr) {
cBeg->second->changeMessage(id, data);
}
}
std::map<ElId, Room*>::iterator rItr = rooms.find(elid);
if (rItr != rooms.end()) {
for (QMap<QString, QVariant>::const_iterator itr = data.begin(), end = data.end(); itr != end; ++itr) {
rItr->second->changeMessage(id, data);
} }
} }
} }

View File

@ -23,7 +23,8 @@
#include <deque> #include <deque>
#include <map> #include <map>
#include <QVector> #include <QVector>
#include "../../global.h"
#include "global.h"
#include "accounts.h" #include "accounts.h"
#include "item.h" #include "item.h"
#include "account.h" #include "account.h"
@ -54,6 +55,7 @@ public:
void addPresence(const QString& account, const QString& jid, const QString& name, const QMap<QString, QVariant>& data); void addPresence(const QString& account, const QString& jid, const QString& name, const QMap<QString, QVariant>& data);
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 dropMessages(const QString& account, const QString& jid); 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);

View File

@ -480,9 +480,9 @@ void Squawk::accountMessage(const QString& account, const Shared::Message& data)
QApplication::alert(conv); QApplication::alert(conv);
if (conv->isMinimized()) { if (conv->isMinimized()) {
rosterModel.addMessage(account, data); rosterModel.addMessage(account, data);
if (!data.getForwarded()) { }
notify(account, data); if (!conv->isVisible() && !data.getForwarded()) {
} notify(account, data);
} }
} else { } else {
rosterModel.addMessage(account, data); rosterModel.addMessage(account, data);
@ -493,6 +493,20 @@ void Squawk::accountMessage(const QString& account, const Shared::Message& data)
} }
} }
void Squawk::changeMessage(const QString& account, const QString& jid, const QString& id, const QMap<QString, QVariant>& data)
{
Conversations::iterator itr = conversations.find({account, jid});
if (itr != conversations.end()) {
Conversation* conv = itr->second;
conv->changeMessage(id, data);
if (conv->isMinimized()) {
rosterModel.changeMessage(account, jid, id, data);
}
} else {
rosterModel.changeMessage(account, jid, id, data);
}
}
void Squawk::notify(const QString& account, const Shared::Message& msg) void Squawk::notify(const QString& account, const Shared::Message& msg)
{ {
QString name = QString(rosterModel.getContactName(account, msg.getPenPalJid())); QString name = QString(rosterModel.getContactName(account, msg.getPenPalJid()));

View File

@ -106,7 +106,7 @@ public slots:
void fileError(const QString& messageId, const QString& error); void fileError(const QString& messageId, const QString& error);
void fileProgress(const QString& messageId, qreal value); void fileProgress(const QString& messageId, qreal value);
void responseVCard(const QString& jid, const Shared::VCard& card); void responseVCard(const QString& jid, const Shared::VCard& card);
void onItemCollepsed(const QModelIndex& index); void changeMessage(const QString& account, const QString& jid, const QString& id, const QMap<QString, QVariant>& data);
private: private:
typedef std::map<Models::Roster::ElId, Conversation*> Conversations; typedef std::map<Models::Roster::ElId, Conversation*> Conversations;
@ -145,6 +145,7 @@ private slots:
void onConversationShown(); 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);
}; };

View File

@ -35,8 +35,9 @@ const QRegularExpression urlReg("(?<!<a\\shref=['\"])(?<!<img\\ssrc=['\"])("
")"); ")");
const QRegularExpression imgReg("((?:https?|ftp)://\\S+\\.(?:jpg|jpeg|png|svg|gif))"); const QRegularExpression imgReg("((?:https?|ftp)://\\S+\\.(?:jpg|jpeg|png|svg|gif))");
Message::Message(const Shared::Message& source, bool outgoing, const QString& p_sender, const QString& avatarPath, QWidget* parent): Message::Message(const Shared::Message& source, bool p_outgoing, const QString& p_sender, const QString& avatarPath, QWidget* parent):
QWidget(parent), QWidget(parent),
outgoing(p_outgoing),
msg(source), msg(source),
body(new QWidget()), body(new QWidget()),
statusBar(new QWidget()), statusBar(new QWidget()),
@ -50,11 +51,15 @@ Message::Message(const Shared::Message& source, bool outgoing, const QString& p_
file(0), file(0),
progress(0), progress(0),
fileComment(new QLabel()), fileComment(new QLabel()),
statusIcon(0),
editedLabel(0),
avatar(new Image(avatarPath.size() == 0 ? Shared::iconPath("user", true) : avatarPath, 60)), avatar(new Image(avatarPath.size() == 0 ? Shared::iconPath("user", true) : avatarPath, 60)),
hasButton(false), hasButton(false),
hasProgress(false), hasProgress(false),
hasFile(false), hasFile(false),
commentAdded(false) commentAdded(false),
hasStatusIcon(false),
hasEditedLabel(false)
{ {
setContentsMargins(0, 0, 0, 0); setContentsMargins(0, 0, 0, 0);
layout->setContentsMargins(10, 5, 10, 5); layout->setContentsMargins(10, 5, 10, 5);
@ -102,8 +107,8 @@ Message::Message(const Shared::Message& source, bool outgoing, const QString& p_
if (outgoing) { if (outgoing) {
sender->setAlignment(Qt::AlignRight); sender->setAlignment(Qt::AlignRight);
date->setAlignment(Qt::AlignRight); date->setAlignment(Qt::AlignRight);
statusIcon = new QLabel();
QIcon q(Shared::icon(Shared::messageStateThemeIcons[static_cast<uint8_t>(source.getState())])); QIcon q(Shared::icon(Shared::messageStateThemeIcons[static_cast<uint8_t>(source.getState())]));
QLabel* statusIcon = new QLabel();
statusIcon->setToolTip(QCoreApplication::translate("Global", Shared::messageStateNames[static_cast<uint8_t>(source.getState())].toLatin1())); statusIcon->setToolTip(QCoreApplication::translate("Global", Shared::messageStateNames[static_cast<uint8_t>(source.getState())].toLatin1()));
statusIcon->setPixmap(q.pixmap(12, 12)); statusIcon->setPixmap(q.pixmap(12, 12));
statusLay->addWidget(statusIcon); statusLay->addWidget(statusIcon);
@ -111,6 +116,7 @@ Message::Message(const Shared::Message& source, bool outgoing, const QString& p_
layout->addStretch(); layout->addStretch();
layout->addWidget(body); layout->addWidget(body);
layout->addWidget(avatar); layout->addWidget(avatar);
hasStatusIcon = true;
} else { } else {
layout->addWidget(avatar); layout->addWidget(avatar);
layout->addWidget(body); layout->addWidget(body);
@ -127,8 +133,8 @@ Message::~Message()
if (!commentAdded) { if (!commentAdded) {
delete fileComment; delete fileComment;
} }
delete body; //delete body; //not sure if I should delete it here, it's probably already owned by the infrastructure and gonna die with the rest of the widget
delete avatar; //delete avatar;
} }
QString Message::getId() const QString Message::getId() const
@ -136,6 +142,16 @@ QString Message::getId() const
return msg.getId(); return msg.getId();
} }
QString Message::getSenderJid() const
{
return msg.getFromJid();
}
QString Message::getSenderResource() const
{
return msg.getFromResource();
}
QString Message::getFileUrl() const QString Message::getFileUrl() const
{ {
return msg.getOutOfBandUrl(); return msg.getOutOfBandUrl();
@ -286,3 +302,42 @@ void Message::setAvatarPath(const QString& p_path)
avatar->setPath(p_path); avatar->setPath(p_path);
} }
} }
bool Message::change(const QMap<QString, QVariant>& data)
{
bool idChanged = msg.change(data);
QString bd = msg.getBody();
//bd.replace(imgReg, "<img src=\"\\1\"/>");
bd.replace(urlReg, "<a href=\"\\1\">\\1</a>");
text->setText(bd);
if (bd.size() > 0) {
text->show();
} else {
text->hide();
}
if (msg.getEdited()) {
if (!hasEditedLabel) {
editedLabel = new QLabel();
QFont eFont = editedLabel->font();
eFont.setItalic(true);
eFont.setPointSize(eFont.pointSize() - 2);
editedLabel->setFont(eFont);
hasEditedLabel = true;
QHBoxLayout* statusLay = static_cast<QHBoxLayout*>(statusBar->layout());
if (hasStatusIcon) {
statusLay->insertWidget(1, editedLabel);
} else {
statusLay->insertWidget(0, editedLabel);
}
}
}
if (hasStatusIcon) {
QIcon q(Shared::icon(Shared::messageStateThemeIcons[static_cast<uint8_t>(msg.getState())]));
statusIcon->setToolTip(QCoreApplication::translate("Global", Shared::messageStateNames[static_cast<uint8_t>(msg.getState())].toLatin1()));
statusIcon->setPixmap(q.pixmap(12, 12));
}
return idChanged;
}

View File

@ -29,6 +29,7 @@
#include <QAction> #include <QAction>
#include <QDesktopServices> #include <QDesktopServices>
#include <QUrl> #include <QUrl>
#include <QMap>
#include "global.h" #include "global.h"
#include "resizer.h" #include "resizer.h"
@ -46,6 +47,8 @@ public:
void setSender(const QString& sender); void setSender(const QString& sender);
QString getId() const; QString getId() const;
QString getSenderJid() const;
QString getSenderResource() const;
QString getFileUrl() const; QString getFileUrl() const;
const Shared::Message& getMessage() const; const Shared::Message& getMessage() const;
@ -55,6 +58,9 @@ public:
void showFile(const QString& path); void showFile(const QString& path);
void setProgress(qreal value); void setProgress(qreal value);
void setAvatarPath(const QString& p_path); void setAvatarPath(const QString& p_path);
bool change(const QMap<QString, QVariant>& data);
bool const outgoing;
signals: signals:
void buttonClicked(); void buttonClicked();
@ -73,11 +79,15 @@ private:
QLabel* file; QLabel* file;
QProgressBar* progress; QProgressBar* progress;
QLabel* fileComment; QLabel* fileComment;
QLabel* statusIcon;
QLabel* editedLabel;
Image* avatar; Image* avatar;
bool hasButton; bool hasButton;
bool hasProgress; bool hasProgress;
bool hasFile; bool hasFile;
bool commentAdded; bool commentAdded;
bool hasStatusIcon;
bool hasEditedLabel;
private: private:
void hideButton(); void hideButton();

View File

@ -122,7 +122,7 @@ MessageLine::Position MessageLine::message(const Shared::Message& msg, bool forc
if (room) { if (room) {
senderId = sender; senderId = sender;
} else { } else {
QString jid = msg.getFromJid(); senderId = msg.getFromJid();
} }
std::map<QString, Index>::iterator pItr = palMessages.find(senderId); std::map<QString, Index>::iterator pItr = palMessages.find(senderId);
@ -161,6 +161,48 @@ MessageLine::Position MessageLine::message(const Shared::Message& msg, bool forc
return res; return res;
} }
void MessageLine::changeMessage(const QString& id, const QMap<QString, QVariant>& data)
{
Index::const_iterator itr = messageIndex.find(id);
if (itr != messageIndex.end()) {
Message* msg = itr->second;
if (msg->change(data)) { //if ID changed (stanza in replace of another)
QString newId = msg->getId(); //need to updated IDs of that message in all maps
messageIndex.erase(itr);
messageIndex.insert(std::make_pair(newId, msg));
if (msg->outgoing) {
QString senderId;
if (room) {
senderId = msg->getSenderResource();
} else {
senderId = msg->getSenderJid();
}
std::map<QString, Index>::iterator pItr = palMessages.find(senderId);
if (pItr != palMessages.end()) {
Index::const_iterator sItr = pItr->second.find(id);
if (sItr != pItr->second.end()) {
pItr->second.erase(sItr);
pItr->second.insert(std::make_pair(newId, msg));
} else {
qDebug() << "Was trying to replace message in open conversations, couldn't find it among pal's messages, probably an error";
}
} else {
qDebug() << "Was trying to replace message in open conversations, couldn't find pal messages, probably an error";
}
} else {
Index::const_iterator mItr = myMessages.find(id);
if (mItr != myMessages.end()) {
myMessages.erase(mItr);
myMessages.insert(std::make_pair(newId, msg));
} else {
qDebug() << "Was trying to replace message in open conversations, couldn't find it among my messages, probably an error";
}
}
}
}
}
void MessageLine::onDownload() void MessageLine::onDownload()
{ {
Message* msg = static_cast<Message*>(sender()); Message* msg = static_cast<Message*>(sender());

View File

@ -26,7 +26,7 @@
#include <QResizeEvent> #include <QResizeEvent>
#include <QIcon> #include <QIcon>
#include "../../global.h" #include "global.h"
#include "message.h" #include "message.h"
#include "progress.h" #include "progress.h"
@ -57,6 +57,7 @@ public:
void setMyAvatarPath(const QString& p_path); void setMyAvatarPath(const QString& p_path);
void setPalAvatar(const QString& jid, const QString& path); void setPalAvatar(const QString& jid, const QString& path);
void dropPalAvatar(const QString& jid); void dropPalAvatar(const QString& jid);
void changeMessage(const QString& id, const QMap<QString, QVariant>& data);
signals: signals:
void resize(int amount); void resize(int amount);

View File

@ -149,6 +149,11 @@ void Conversation::addMessage(const Shared::Message& data)
} }
} }
void Conversation::changeMessage(const QString& id, const QMap<QString, QVariant>& data)
{
line->changeMessage(id, data);
}
KeyEnterReceiver::KeyEnterReceiver(QObject* parent): QObject(parent), ownEvent(false) {} KeyEnterReceiver::KeyEnterReceiver(QObject* parent): QObject(parent), ownEvent(false) {}
bool KeyEnterReceiver::eventFilter(QObject* obj, QEvent* event) bool KeyEnterReceiver::eventFilter(QObject* obj, QEvent* event)

View File

@ -21,13 +21,15 @@
#include <QWidget> #include <QWidget>
#include <QScopedPointer> #include <QScopedPointer>
#include <QMap>
#include "global.h" #include "global.h"
#include "order.h" #include "order.h"
#include "../models/account.h" #include "ui/models/account.h"
#include "../utils/messageline.h" #include "ui/utils/messageline.h"
#include "../utils/resizer.h" #include "ui/utils/resizer.h"
#include "../utils/flowlayout.h" #include "ui/utils/flowlayout.h"
#include "../utils/badge.h" #include "ui/utils/badge.h"
namespace Ui namespace Ui
{ {
@ -79,6 +81,7 @@ public:
void fileError(const QString& messageId, const QString& error); void fileError(const QString& messageId, const QString& error);
void responseFileProgress(const QString& messageId, qreal progress); void responseFileProgress(const QString& messageId, qreal progress);
virtual void setAvatar(const QString& path); virtual void setAvatar(const QString& path);
void changeMessage(const QString& id, const QMap<QString, QVariant>& data);
signals: signals:
void sendMessage(const Shared::Message& message); void sendMessage(const Shared::Message& message);