initial functionality of mucs

This commit is contained in:
Blue 2019-08-28 14:40:55 +03:00
parent e2cc1bae2e
commit 023494de0b
23 changed files with 347 additions and 119 deletions

View File

@ -436,7 +436,7 @@ void Core::Account::onMessageReceived(const QXmppMessage& msg)
handled = handleChatMessage(msg); handled = handleChatMessage(msg);
break; break;
case QXmppMessage::GroupChat: case QXmppMessage::GroupChat:
qDebug() << "received a message with type \"GroupChat\", not sure what to do with it now, skipping"; handled = handleGroupMessage(msg);
break; break;
case QXmppMessage::Error: case QXmppMessage::Error:
qDebug() << "received a message with type \"Error\", not sure what to do with it now, skipping"; qDebug() << "received a message with type \"Error\", not sure what to do with it now, skipping";
@ -482,11 +482,25 @@ void Core::Account::sendMessage(const Shared::Message& data)
msg.setId(data.getId()); msg.setId(data.getId());
msg.setType(static_cast<QXmppMessage::Type>(data.getType())); //it is safe here, my type is compatible msg.setType(static_cast<QXmppMessage::Type>(data.getType())); //it is safe here, my type is compatible
RosterItem* ri = 0;
std::map<QString, Contact*>::const_iterator itr = contacts.find(data.getPenPalJid()); std::map<QString, Contact*>::const_iterator itr = contacts.find(data.getPenPalJid());
if (itr != contacts.end()) {
ri = itr->second;
} else {
std::map<QString, Conference*>::const_iterator ritr = conferences.find(data.getPenPalJid());
if (ritr != conferences.end()) {
ri = ritr->second;
}
}
itr->second->appendMessageToArchive(data); if (ri != 0) {
if (!ri->isMuc()) {
ri->appendMessageToArchive(data);
}
}
client.sendPacket(msg); client.sendPacket(msg);
} else { } else {
qDebug() << "An attempt to send message with not connected account " << name << ", skipping"; qDebug() << "An attempt to send message with not connected account " << name << ", skipping";
} }
@ -541,6 +555,39 @@ bool Core::Account::handleChatMessage(const QXmppMessage& msg, bool outgoing, bo
return false; return false;
} }
bool Core::Account::handleGroupMessage(const QXmppMessage& msg, bool outgoing, bool forwarded, bool guessing)
{
const QString& body(msg.body());
if (body.size() != 0) {
const QString& id(msg.id());
Shared::Message sMsg(Shared::Message::groupChat);
initializeMessage(sMsg, msg, outgoing, forwarded, guessing);
QString jid = sMsg.getPenPalJid();
std::map<QString, Conference*>::const_iterator itr = conferences.find(jid);
Conference* cnt;
if (itr != conferences.end()) {
cnt = itr->second;
} else {
return false;
}
cnt->appendMessageToArchive(sMsg);
emit message(sMsg);
if (!forwarded && !outgoing) {
if (msg.isReceiptRequested() && id.size() > 0) {
QXmppMessage receipt(getFullJid(), msg.from(), "");
receipt.setReceiptId(id);
client.sendPacket(receipt);
}
}
return true;
}
return false;
}
void Core::Account::initializeMessage(Shared::Message& target, const QXmppMessage& source, bool outgoing, bool forwarded, bool guessing) const void Core::Account::initializeMessage(Shared::Message& target, const QXmppMessage& source, bool outgoing, bool forwarded, bool guessing) const
{ {
const QDateTime& time(source.stamp()); const QDateTime& time(source.stamp());
@ -595,17 +642,20 @@ void Core::Account::requestArchive(const QString& jid, int count, const QString&
qDebug() << "An archive request for " << jid << ", before " << before; qDebug() << "An archive request for " << jid << ", before " << before;
RosterItem* contact = 0; RosterItem* contact = 0;
std::map<QString, Contact*>::const_iterator itr = contacts.find(jid); std::map<QString, Contact*>::const_iterator itr = contacts.find(jid);
bool gr = false;
if (itr != contacts.end()) { if (itr != contacts.end()) {
contact = itr->second; contact = itr->second;
} else { } else {
std::map<QString, Conference*>::const_iterator citr = conferences.find(jid); std::map<QString, Conference*>::const_iterator citr = conferences.find(jid);
if (citr != conferences.end()) { if (citr != conferences.end()) {
contact = citr->second; contact = citr->second;
gr = true;
} }
} }
if (contact == 0) { if (contact == 0) {
qDebug() << "An attempt to request archive for" << jid << "in account" << name << ", but the contact with such id wasn't found, skipping"; qDebug() << "An attempt to request archive for" << jid << "in account" << name << ", but the contact with such id wasn't found, skipping";
emit responseArchive(contact->jid, std::list<Shared::Message>());
return; return;
} }
@ -613,7 +663,11 @@ void Core::Account::requestArchive(const QString& jid, int count, const QString&
QXmppMessage msg(getFullJid(), jid, "", ""); QXmppMessage msg(getFullJid(), jid, "", "");
QString last = Shared::generateUUID(); QString last = Shared::generateUUID();
msg.setId(last); msg.setId(last);
msg.setType(QXmppMessage::Chat); if (gr) {
msg.setType(QXmppMessage::GroupChat);
} else {
msg.setType(QXmppMessage::Chat);
}
msg.setState(QXmppMessage::Active); msg.setState(QXmppMessage::Active);
client.sendPacket(msg); client.sendPacket(msg);
QTimer* timer = new QTimer; QTimer* timer = new QTimer;
@ -632,6 +686,7 @@ void Core::Account::requestArchive(const QString& jid, int count, const QString&
void Core::Account::onContactNeedHistory(const QString& before, const QString& after, const QDateTime& at) void Core::Account::onContactNeedHistory(const QString& before, const QString& after, const QDateTime& at)
{ {
RosterItem* contact = static_cast<RosterItem*>(sender()); RosterItem* contact = static_cast<RosterItem*>(sender());
QString to = "";
QXmppResultSetQuery query; QXmppResultSetQuery query;
query.setMax(100); query.setMax(100);
if (before.size() > 0) { if (before.size() > 0) {
@ -648,7 +703,7 @@ void Core::Account::onContactNeedHistory(const QString& before, const QString& a
qDebug() << "Remote query from" << after << ", to" << before; qDebug() << "Remote query from" << after << ", to" << before;
QString q = am->retrieveArchivedMessages("", "", contact->jid, start, QDateTime(), query); QString q = am->retrieveArchivedMessages(to, "", contact->jid, start, QDateTime(), query);
achiveQueries.insert(std::make_pair(q, contact->jid)); achiveQueries.insert(std::make_pair(q, contact->jid));
} }
@ -939,6 +994,7 @@ void Core::Account::bookmarksReceived(const QXmppBookmarkSet& bookmarks)
QXmppMucRoom* room = mm->addRoom(jid); QXmppMucRoom* room = mm->addRoom(jid);
QString nick = c.nickName(); QString nick = c.nickName();
Conference* conf = new Conference(jid, getName(), c.autoJoin(), c.name(), nick == "" ? getName() : nick, room); Conference* conf = new Conference(jid, getName(), c.autoJoin(), c.name(), nick == "" ? getName() : nick, room);
conferences.insert(std::make_pair(jid, conf));
handleNewConference(conf); handleNewConference(conf);

View File

@ -151,6 +151,7 @@ private:
void handleNewRosterItem(RosterItem* contact); void handleNewRosterItem(RosterItem* contact);
void handleNewConference(Conference* contact); void handleNewConference(Conference* contact);
bool handleChatMessage(const QXmppMessage& msg, bool outgoing = false, bool forwarded = false, bool guessing = false); bool handleChatMessage(const QXmppMessage& msg, bool outgoing = false, bool forwarded = false, bool guessing = false);
bool handleGroupMessage(const QXmppMessage& msg, bool outgoing = false, bool forwarded = false, bool guessing = false);
void addToGroup(const QString& jid, const QString& group); void addToGroup(const QString& jid, const QString& group);
void removeFromGroup(const QString& jid, const QString& group); void removeFromGroup(const QString& jid, const QString& group);
void initializeMessage(Shared::Message& target, const QXmppMessage& source, bool outgoing = false, bool forwarded = false, bool guessing = false) const; void initializeMessage(Shared::Message& target, const QXmppMessage& source, bool outgoing = false, bool forwarded = false, bool guessing = false) const;

View File

@ -270,6 +270,7 @@ unsigned int Core::Archive::addElements(const std::list<Shared::Message>& messag
if (rc) { if (rc) {
qDebug() << "An element couldn't be inserted into the index, aborting the transaction" << mdb_strerror(rc); qDebug() << "An element couldn't be inserted into the index, aborting the transaction" << mdb_strerror(rc);
} else { } else {
//qDebug() << "element added with id" << message.getId() << "stamp" << message.getTime();
success++; success++;
} }
} else { } else {
@ -321,9 +322,10 @@ std::list<Shared::Message> Core::Archive::getBefore(int count, const QString& id
rc = mdb_cursor_open(txn, order, &cursor); rc = mdb_cursor_open(txn, order, &cursor);
rc = mdb_cursor_get(cursor, &lmdbKey, &lmdbData, MDB_LAST); rc = mdb_cursor_get(cursor, &lmdbKey, &lmdbData, MDB_LAST);
if (rc) { if (rc) {
qDebug() << "Error getting before " << mdb_strerror(rc) << ", id:" << id; qDebug() << "Error getting before" << mdb_strerror(rc) << ", id:" << id;
mdb_cursor_close(cursor); mdb_cursor_close(cursor);
mdb_txn_abort(txn); mdb_txn_abort(txn);
throw Empty(jid.toStdString()); throw Empty(jid.toStdString());
} }
} else { } else {
@ -334,7 +336,6 @@ std::list<Shared::Message> Core::Archive::getBefore(int count, const QString& id
if (rc) { if (rc) {
qDebug() <<"Error getting before: no reference message" << mdb_strerror(rc) << ", id:" << id; qDebug() <<"Error getting before: no reference message" << mdb_strerror(rc) << ", id:" << id;
mdb_txn_abort(txn); mdb_txn_abort(txn);
printKeys();
throw NotFound(stdId, jid.toStdString()); throw NotFound(stdId, jid.toStdString());
} else { } else {
QByteArray ba((char*)lmdbData.mv_data, lmdbData.mv_size); QByteArray ba((char*)lmdbData.mv_data, lmdbData.mv_size);

View File

@ -27,6 +27,7 @@ Core::Conference::Conference(const QString& p_jid, const QString& p_account, boo
joined(false), joined(false),
autoJoin(p_autoJoin) autoJoin(p_autoJoin)
{ {
muc = true;
name = p_name; name = p_name;
connect(room, SIGNAL(joined()), this, SLOT(onRoomJoined())); connect(room, SIGNAL(joined()), this, SLOT(onRoomJoined()));

View File

@ -32,13 +32,15 @@ Core::RosterItem::RosterItem(const QString& pJid, const QString& account, QObjec
hisoryCache(), hisoryCache(),
appendCache(), appendCache(),
responseCache(), responseCache(),
requestCache() requestCache(),
muc(false)
{ {
archive->open(account); archive->open(account);
if (archive->isFromTheBeginning()) {
archiveState = beginning; if (archive->size() != 0) {
} else { if (archive->isFromTheBeginning()) {
if (archive->size() != 0) { archiveState = beginning;
} else {
archiveState = chunk; archiveState = chunk;
} }
} }
@ -231,7 +233,7 @@ void Core::RosterItem::flushMessagesToArchive(bool finished, const QString& firs
case beginning: case beginning:
if (finished) { if (finished) {
archiveState = complete; archiveState = complete;
archive->addElements(appendCache); added += archive->addElements(appendCache);
appendCache.clear(); appendCache.clear();
nextRequest(); nextRequest();
} else { } else {
@ -241,7 +243,7 @@ void Core::RosterItem::flushMessagesToArchive(bool finished, const QString& firs
case chunk: case chunk:
if (finished) { if (finished) {
archiveState = end; archiveState = end;
archive->addElements(appendCache); added += archive->addElements(appendCache);
appendCache.clear(); appendCache.clear();
nextRequest(); nextRequest();
} else { } else {
@ -252,6 +254,8 @@ void Core::RosterItem::flushMessagesToArchive(bool finished, const QString& firs
wasEmpty = true; wasEmpty = true;
archiveState = end; archiveState = end;
case end: case end:
added += archive->addElements(appendCache);
appendCache.clear();
if (finished && (added > 0 || !wasEmpty)) { if (finished && (added > 0 || !wasEmpty)) {
archiveState = complete; archiveState = complete;
archive->setFromTheBeginning(true); archive->setFromTheBeginning(true);
@ -317,3 +321,13 @@ void Core::RosterItem::requestFromEmpty(int count, const QString& before)
} }
} }
QString Core::RosterItem::getServer() const
{
QStringList lst = jid.split("@");
return lst.back();
}
bool Core::RosterItem::isMuc() const
{
return muc;
}

View File

@ -50,6 +50,8 @@ public:
ArchiveState getArchiveState() const; ArchiveState getArchiveState() const;
QString getName() const; QString getName() const;
void setName(const QString& n); void setName(const QString& n);
QString getServer() const;
bool isMuc() const;
void addMessageToArchive(const Shared::Message& msg); void addMessageToArchive(const Shared::Message& msg);
void appendMessageToArchive(const Shared::Message& msg); void appendMessageToArchive(const Shared::Message& msg);
@ -78,6 +80,7 @@ protected:
std::list<Shared::Message> appendCache; std::list<Shared::Message> appendCache;
std::list<Shared::Message> responseCache; std::list<Shared::Message> responseCache;
std::list<std::pair<int, QString>> requestCache; std::list<std::pair<int, QString>> requestCache;
bool muc;
private: private:
void nextRequest(); void nextRequest();

View File

@ -24,6 +24,7 @@ set(squawkUI_SRC
models/room.cpp models/room.cpp
widgets/conversation.cpp widgets/conversation.cpp
widgets/chat.cpp widgets/chat.cpp
widgets/room.cpp
widgets/messageline.cpp widgets/messageline.cpp
newcontact.cpp newcontact.cpp
) )

View File

@ -1,6 +1,6 @@
#include "contact.h" #include "contact.h"
#include <QDebug> #include <QDebug>
#include "account.h"
Models::Contact::Contact(const QString& p_jid ,const QMap<QString, QVariant> &data, Item *parentItem): Models::Contact::Contact(const QString& p_jid ,const QMap<QString, QVariant> &data, Item *parentItem):
Item(Item::contact, data, parentItem), Item(Item::contact, data, parentItem),
@ -227,16 +227,6 @@ QIcon Models::Contact::getStatusIcon(bool big) const
} }
} }
QString Models::Contact::getAccountName() const
{
const Account* acc = getParentAccount();
if (acc == 0) {
qDebug() << "An attempt to request account name of the contact " << jid << " but the parent account wasn't found, returning empty string";
return "";
}
return acc->getName();
}
void Models::Contact::addMessage(const Shared::Message& data) void Models::Contact::addMessage(const Shared::Message& data)
{ {
const QString& res = data.getPenPalResource(); const QString& res = data.getPenPalResource();
@ -291,36 +281,6 @@ void Models::Contact::getMessages(Models::Contact::Messages& container) const
} }
} }
QString Models::Contact::getAccountJid() const
{
const Account* acc = getParentAccount();
if (acc == 0) {
qDebug() << "An attempt to request account jid of the contact " << jid << " but the parent account wasn't found, returning empty string";
return "";
}
return acc->getLogin() + "@" + acc->getServer();
}
QString Models::Contact::getAccountResource() const
{
const Account* acc = getParentAccount();
if (acc == 0) {
qDebug() << "An attempt to request account resource of the contact " << jid << " but the parent account wasn't found, returning empty string";
return "";
}
return acc->getResource();
}
const Models::Account * Models::Contact::getParentAccount() const
{
const Item* p = this;
do {
p = p->parentItemConst();
} while (p != 0 && p->type != Item::account);
return static_cast<const Account*>(p);
}
void Models::Contact::toOfflineState() void Models::Contact::toOfflineState()
{ {
emit childIsAboutToBeRemoved(this, 0, childItems.size()); emit childIsAboutToBeRemoved(this, 0, childItems.size());

View File

@ -10,7 +10,6 @@
namespace Models { namespace Models {
class Account;
class Contact : public Item class Contact : public Item
{ {
Q_OBJECT Q_OBJECT
@ -33,9 +32,6 @@ public:
void removePresence(const QString& name); void removePresence(const QString& name);
void appendChild(Models::Item * child) override; void appendChild(Models::Item * child) override;
QString getAccountName() const;
QString getAccountJid() const;
QString getAccountResource() const;
QString getContactName() const; QString getContactName() const;
QString getStatus() const; QString getStatus() const;
@ -46,7 +42,6 @@ public:
protected: protected:
void _removeChild(int index) override; void _removeChild(int index) override;
const Account* getParentAccount() const;
protected slots: protected slots:
void refresh(); void refresh();

View File

@ -1,4 +1,7 @@
#include "item.h" #include "item.h"
#include "account.h"
#include <QDebug>
Models::Item::Item(Type p_type, const QMap<QString, QVariant> &p_data, Item *p_parent): Models::Item::Item(Type p_type, const QMap<QString, QVariant> &p_data, Item *p_parent):
QObject(), QObject(),
@ -153,3 +156,41 @@ void Models::Item::toOfflineState()
it->toOfflineState(); it->toOfflineState();
} }
} }
const Models::Item * Models::Item::getParentAccount() const
{
const Item* p = this;
while (p != 0 && p->type != Item::account) {
p = p->parentItemConst();
}
return p;
}
QString Models::Item::getAccountJid() const
{
const Account* acc = static_cast<const Account*>(getParentAccount());
if (acc == 0) {
return "";
}
return acc->getLogin() + "@" + acc->getServer();
}
QString Models::Item::getAccountResource() const
{
const Account* acc = static_cast<const Account*>(getParentAccount());
if (acc == 0) {
return "";
}
return acc->getResource();
}
QString Models::Item::getAccountName() const
{
const Account* acc = static_cast<const Account*>(getParentAccount());
if (acc == 0) {
return "";
}
return acc->getName();
}

View File

@ -47,11 +47,17 @@ class Item : public QObject{
Item *parentItem(); Item *parentItem();
const Item *parentItemConst() const; const Item *parentItemConst() const;
QString getAccountName() const;
QString getAccountJid() const;
QString getAccountResource() const;
const Type type; const Type type;
protected: protected:
virtual void changed(int col); virtual void changed(int col);
virtual void _removeChild(int index); virtual void _removeChild(int index);
const Item* getParentAccount() const;
protected: protected:
QString name; QString name;

View File

@ -184,7 +184,7 @@ QVariant Models::Roster::data (const QModelIndex& index, int role) const
if (count > 0) { if (count > 0) {
str += QString("New messages: ") + std::to_string(count).c_str() + "\n"; str += QString("New messages: ") + std::to_string(count).c_str() + "\n";
} }
str += QString("Subscription: ") + rm->getStatusText() + "\n"; str += QString("Subscription: ") + rm->getStatusText();
result = str; result = str;
} }
break; break;

View File

@ -72,7 +72,7 @@ private slots:
public: public:
class ElId { class ElId {
public: public:
ElId (const QString& p_account, const QString& p_name); ElId (const QString& p_account = "", const QString& p_name = "");
const QString account; const QString account;
const QString name; const QString name;

View File

@ -213,50 +213,63 @@ void Squawk::onRosterItemDoubleClicked(const QModelIndex& item)
if (item.isValid()) { if (item.isValid()) {
Models::Item* node = static_cast<Models::Item*>(item.internalPointer()); Models::Item* node = static_cast<Models::Item*>(item.internalPointer());
Models::Contact* contact = 0; Models::Contact* contact = 0;
Models::Room* room = 0;
QString res; QString res;
Models::Roster::ElId* id = 0;
switch (node->type) { switch (node->type) {
case Models::Item::contact: case Models::Item::contact:
contact = static_cast<Models::Contact*>(node); contact = static_cast<Models::Contact*>(node);
id = new Models::Roster::ElId(contact->getAccountName(), contact->getJid());
break; break;
case Models::Item::presence: case Models::Item::presence:
contact = static_cast<Models::Contact*>(node->parentItem()); contact = static_cast<Models::Contact*>(node->parentItem());
id = new Models::Roster::ElId(contact->getAccountName(), contact->getJid());
res = node->getName(); res = node->getName();
break; break;
case Models::Item::room:
room = static_cast<Models::Room*>(node);
id = new Models::Roster::ElId(room->getAccountName(), room->getJid());
break;
default: default:
m_ui->roster->expand(item); m_ui->roster->expand(item);
break; break;
} }
if (contact != 0) { if (id != 0) {
QString jid = contact->getJid(); Conversations::const_iterator itr = conversations.find(*id);
QString account = contact->getAccountName(); Conversation* conv = 0;
Models::Roster::ElId id(account, jid); bool created = false;
Conversations::const_iterator itr = conversations.find(id);
if (itr != conversations.end()) { if (itr != conversations.end()) {
itr->second->show(); conv = itr->second;
itr->second->raise(); } else if (contact != 0) {
itr->second->activateWindow(); created = true;
conv = new Chat(contact);
} else if (room != 0) {
created = true;
conv = new Room(room);
}
if (res.size() > 0) { if (conv != 0) {
itr->second->setPalResource(res); if (created) {
conv->setAttribute(Qt::WA_DeleteOnClose);
connect(conv, SIGNAL(destroyed(QObject*)), this, SLOT(onConversationClosed(QObject*)));
connect(conv, SIGNAL(sendMessage(const Shared::Message&)), this, SLOT(onConversationMessage(const Shared::Message&)));
connect(conv, SIGNAL(requestArchive(const QString&)), this, SLOT(onConversationRequestArchive(const QString&)));
connect(conv, SIGNAL(shown()), this, SLOT(onConversationShown()));
conversations.insert(std::make_pair(*id, conv));
} }
} else {
Chat* conv = new Chat(contact);
conv->setAttribute(Qt::WA_DeleteOnClose);
connect(conv, SIGNAL(destroyed(QObject*)), this, SLOT(onConversationClosed(QObject*)));
connect(conv, SIGNAL(sendMessage(const Shared::Message&)), this, SLOT(onConversationMessage(const Shared::Message&)));
connect(conv, SIGNAL(requestArchive(const QString&)), this, SLOT(onConversationRequestArchive(const QString&)));
connect(conv, SIGNAL(shown()), this, SLOT(onConversationShown()));
conversations.insert(std::make_pair(id, conv));
conv->show(); conv->show();
conv->raise();
conv->activateWindow();
if (res.size() > 0) { if (res.size() > 0) {
conv->setPalResource(res); conv->setPalResource(res);
} }
} }
} }
} }
} }

View File

@ -29,6 +29,7 @@
#include "accounts.h" #include "accounts.h"
#include "widgets/chat.h" #include "widgets/chat.h"
#include "widgets/room.h"
#include "models/roster.h" #include "models/roster.h"
#include "newcontact.h" #include "newcontact.h"

View File

@ -70,3 +70,37 @@ void Chat::setStatus(const QString& status)
{ {
statusLabel->setText(status); statusLabel->setText(status);
} }
void Chat::handleSendMessage(const QString& text)
{
Shared::Message msg(Shared::Message::chat);
msg.setFromJid(myJid);
msg.setFromResource(myResource);
msg.setToJid(palJid);
msg.setToResource(activePalResource);
msg.setBody(text);
msg.setOutgoing(true);
msg.generateRandomId();
msg.setCurrentTime();
addMessage(msg);
emit sendMessage(msg);
}
void Chat::addMessage(const Shared::Message& data)
{
Conversation::addMessage(data);
if (!data.getOutgoing()) { //TODO need to check if that was the last message
const QString& res = data.getPenPalResource();
if (res.size() > 0) {
setPalResource(res);
}
}
}
void Chat::setName(const QString& name)
{
Conversation::setName(name);
line->setPalName(getJid(), name);
}

View File

@ -32,9 +32,15 @@ class Chat : public Conversation
public: public:
Chat(Models::Contact* p_contact, QWidget* parent = 0); Chat(Models::Contact* p_contact, QWidget* parent = 0);
~Chat(); ~Chat();
void addMessage(const Shared::Message & data) override;
protected slots: protected slots:
void onContactChanged(Models::Item* item, int row, int col); void onContactChanged(Models::Item* item, int row, int col);
void handleSendMessage(const QString & text) override;
protected:
void setName(const QString & name) override;
private: private:
void updateState(); void updateState();

View File

@ -97,7 +97,6 @@ void Conversation::setName(const QString& name)
{ {
m_ui->nameLabel->setText(name); m_ui->nameLabel->setText(name);
setWindowTitle(name); setWindowTitle(name);
line->setPalName(getJid(), name);
} }
QString Conversation::getAccount() const QString Conversation::getAccount() const
@ -119,13 +118,6 @@ void Conversation::addMessage(const Shared::Message& data)
if (place == MessageLine::invalid) { if (place == MessageLine::invalid) {
return; return;
} }
if (!data.getOutgoing()) {
const QString& res = data.getPenPalResource();
if (res.size() > 0) {
setPalResource(res);
}
}
} }
KeyEnterReceiver::KeyEnterReceiver(QObject* parent): QObject(parent), ownEvent(false) {} KeyEnterReceiver::KeyEnterReceiver(QObject* parent): QObject(parent), ownEvent(false) {}
@ -173,17 +165,7 @@ void Conversation::onEnterPressed()
if (body.size() > 0) { if (body.size() > 0) {
m_ui->messageEditor->clear(); m_ui->messageEditor->clear();
Shared::Message msg(Shared::Message::chat); handleSendMessage(body);
msg.setFromJid(myJid);
msg.setFromResource(myResource);
msg.setToJid(palJid);
msg.setToResource(activePalResource);
msg.setBody(body);
msg.setOutgoing(true);
msg.generateRandomId();
msg.setCurrentTime();
addMessage(msg);
emit sendMessage(msg);
} }
} }

View File

@ -52,7 +52,7 @@ public:
QString getJid() const; QString getJid() const;
QString getAccount() const; QString getAccount() const;
QString getPalResource() const; QString getPalResource() const;
void addMessage(const Shared::Message& data); 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);
@ -64,8 +64,9 @@ signals:
void shown(); void shown();
protected: protected:
void setName(const QString& name); virtual void setName(const QString& name);
void applyVisualEffects(); void applyVisualEffects();
virtual void handleSendMessage(const QString& text) = 0;
protected slots: protected slots:
void onEnterPressed(); void onEnterPressed();

View File

@ -30,7 +30,8 @@ MessageLine::MessageLine(QWidget* parent):
layout(new QVBoxLayout()), layout(new QVBoxLayout()),
myName(), myName(),
palNames(), palNames(),
views() views(),
room(false)
{ {
setLayout(layout); setLayout(layout);
setBackgroundRole(QPalette::Base); setBackgroundRole(QPalette::Base);
@ -44,6 +45,11 @@ MessageLine::~MessageLine()
} }
} }
void MessageLine::setRoom(bool p_room)
{
room = p_room;
}
MessageLine::Position MessageLine::message(const Shared::Message& msg) MessageLine::Position MessageLine::message(const Shared::Message& msg)
{ {
QString id = msg.getId(); QString id = msg.getId();
@ -110,25 +116,40 @@ MessageLine::Position MessageLine::message(const Shared::Message& msg)
message->setGraphicsEffect(effect); message->setGraphicsEffect(effect);
if (msg.getOutgoing()) { if (room) {
//body->setAlignment(Qt::AlignRight); if (msg.getFromResource() == myName) {
sender->setAlignment(Qt::AlignRight); //body->setAlignment(Qt::AlignRight);
time->setAlignment(Qt::AlignRight); sender->setAlignment(Qt::AlignRight);
sender->setText(myName); time->setAlignment(Qt::AlignRight);
hBox->addStretch(); sender->setText(myName);
hBox->addWidget(message); hBox->addStretch();
} else { hBox->addWidget(message);
QString jid = msg.getFromJid();
std::map<QString, QString>::iterator itr = palNames.find(jid);
if (itr != palNames.end()) {
sender->setText(itr->second);
} else { } else {
sender->setText(jid); sender->setText(msg.getFromResource());
hBox->addWidget(message);
hBox->addStretch();
}
} else {
if (msg.getOutgoing()) {
//body->setAlignment(Qt::AlignRight);
sender->setAlignment(Qt::AlignRight);
time->setAlignment(Qt::AlignRight);
sender->setText(myName);
hBox->addStretch();
hBox->addWidget(message);
} else {
QString jid = msg.getFromJid();
std::map<QString, QString>::iterator itr = palNames.find(jid);
if (itr != palNames.end()) {
sender->setText(itr->second);
} else {
sender->setText(jid);
}
hBox->addWidget(message);
hBox->addStretch();
} }
hBox->addWidget(message);
hBox->addStretch();
} }
if (res == end) { if (res == end) {
layout->addLayout(hBox); layout->addLayout(hBox);
} else { } else {

View File

@ -45,6 +45,7 @@ public:
QString firstMessageId() const; QString firstMessageId() const;
void showBusyIndicator(); void showBusyIndicator();
void hideBusyIndicator(); void hideBusyIndicator();
void setRoom(bool p_room);
signals: signals:
void resize(int amount); void resize(int amount);
@ -70,6 +71,7 @@ private:
QString myName; QString myName;
std::map<QString, QString> palNames; std::map<QString, QString> palNames;
std::deque<QHBoxLayout*> views; std::deque<QHBoxLayout*> views;
bool room;
}; };
#endif // MESSAGELINE_H #endif // MESSAGELINE_H

46
ui/widgets/room.cpp Normal file
View File

@ -0,0 +1,46 @@
/*
* 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 "room.h"
Room::Room(Models::Room* p_room, QWidget* parent):
Conversation(p_room->getAccountJid(), p_room->getAccountResource(), p_room->getJid(), "", p_room->getAccountName(), parent),
room(p_room)
{
setName(p_room->getName());
line->setMyName(room->getNick());
line->setRoom(true);
}
Room::~Room()
{
}
void Room::handleSendMessage(const QString& text)
{
Shared::Message msg(Shared::Message::groupChat);
msg.setFromJid(myJid);
msg.setFromResource(myResource);
msg.setToJid(palJid);
//msg.setToResource(activePalResource);
msg.setBody(text);
msg.setOutgoing(true);
msg.generateRandomId();
msg.setCurrentTime();
emit sendMessage(msg);
}

43
ui/widgets/room.h Normal file
View File

@ -0,0 +1,43 @@
/*
* 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 ROOM_H
#define ROOM_H
#include "conversation.h"
#include "../models/room.h"
/**
* @todo write docs
*/
class Room : public Conversation
{
Q_OBJECT
public:
Room(Models::Room* p_room, QWidget* parent = 0);
~Room();
protected:
void handleSendMessage(const QString & text) override;
private:
Models::Room* room;
};
#endif // ROOM_H