Refactoring, new messages thread beggining

This commit is contained in:
Blue 2019-04-11 17:58:59 +03:00
parent 5575cff1f5
commit e48444636a
25 changed files with 610 additions and 163 deletions

View File

@ -11,6 +11,8 @@ set(CMAKE_AUTOUIC ON)
find_package(Qt5Widgets CONFIG REQUIRED) find_package(Qt5Widgets CONFIG REQUIRED)
set(squawk_SRC set(squawk_SRC
main.cpp main.cpp
global.cpp
exception.cpp
signalcatcher.cpp signalcatcher.cpp
) )

View File

@ -336,14 +336,7 @@ void Core::Account::setResource(const QString& p_resource)
void Core::Account::onMessageReceived(const QXmppMessage& msg) void Core::Account::onMessageReceived(const QXmppMessage& msg)
{ {
QString from = msg.from(); QString from = msg.from();
QStringList fcomps = from.split("/");
QString fjid = fcomps.front();
QString fresource = fcomps.back();
QString to = msg.to(); QString to = msg.to();
QStringList tcomps = to.split("/");
QString tjid = tcomps.front();
QString tresource = tcomps.back();
bool handled = false; bool handled = false;
switch (msg.type()) { switch (msg.type()) {
case QXmppMessage::Normal: case QXmppMessage::Normal:
@ -353,14 +346,16 @@ void Core::Account::onMessageReceived(const QXmppMessage& msg)
QString body(msg.body()); QString body(msg.body());
if (body.size() != 0) { if (body.size() != 0) {
QString id(msg.id()); QString id(msg.id());
emit message({ QDateTime time(msg.stamp());
{"body", body}, Shared::Message sMsg(Shared::Message::chat);
{"from", fjid}, sMsg.setId(id);
{"to", tjid}, sMsg.setFrom(from);
{"fromResource", fresource}, sMsg.setTo(to);
{"toResource", tresource}, sMsg.setBody(body);
{"id", id} if (time.isValid()) {
}); sMsg.setTime(time);
}
emit message(sMsg);
if (msg.isReceiptRequested() && id.size() > 0) { if (msg.isReceiptRequested() && id.size() > 0) {
QXmppMessage receipt(getFullJid(), from, ""); QXmppMessage receipt(getFullJid(), from, "");
@ -384,8 +379,8 @@ void Core::Account::onMessageReceived(const QXmppMessage& msg)
if (!handled) { if (!handled) {
qDebug() << "Message wasn't handled: "; qDebug() << "Message wasn't handled: ";
qDebug() << "- from: " << msg.from(); qDebug() << "- from: " << from;
qDebug() << "- to: " << msg.to(); qDebug() << "- to: " << to;
qDebug() << "- body: " << msg.body(); qDebug() << "- body: " << msg.body();
qDebug() << "- type: " << msg.type(); qDebug() << "- type: " << msg.type();
qDebug() << "- state: " << msg.state(); qDebug() << "- state: " << msg.state();
@ -406,10 +401,10 @@ QString Core::Account::getFullJid() const
return getLogin() + "@" + getServer() + "/" + getResource(); return getLogin() + "@" + getServer() + "/" + getResource();
} }
void Core::Account::sendMessage(const QMap<QString, QString>& data) void Core::Account::sendMessage(const Shared::Message& data)
{ {
if (state == Shared::connected) { if (state == Shared::connected) {
client.sendMessage(data.value("to"), data.value("body")); client.sendMessage(data.getTo(), data.getBody());
} 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";
} }

View File

@ -36,7 +36,7 @@ public:
void setResource(const QString& p_resource); void setResource(const QString& p_resource);
void setAvailability(Shared::Availability avail); void setAvailability(Shared::Availability avail);
QString getFullJid() const; QString getFullJid() const;
void sendMessage(const QMap<QString, QString>& data); void sendMessage(const Shared::Message& data);
signals: signals:
void connectionStateChanged(int); void connectionStateChanged(int);
@ -49,7 +49,7 @@ signals:
void changeContact(const QString& jid, const QMap<QString, QVariant>& data); void changeContact(const QString& jid, const QMap<QString, QVariant>& data);
void addPresence(const QString& jid, const QString& name, const QMap<QString, QVariant>& data); void addPresence(const QString& jid, const QString& name, const QMap<QString, QVariant>& data);
void removePresence(const QString& jid, const QString& name); void removePresence(const QString& jid, const QString& name);
void message(const QMap<QString, QString>& data); void message(const Shared::Message& data);
private: private:
QString name; QString name;

View File

@ -86,7 +86,7 @@ void Core::Squawk::addAccount(const QString& login, const QString& server, const
connect(acc, SIGNAL(addPresence(const QString&, const QString&, const QMap<QString, QVariant>&)), connect(acc, SIGNAL(addPresence(const QString&, const QString&, const QMap<QString, QVariant>&)),
this, SLOT(onAccountAddPresence(const QString&, const QString&, const QMap<QString, QVariant>&))); this, SLOT(onAccountAddPresence(const QString&, const QString&, const QMap<QString, QVariant>&)));
connect(acc, SIGNAL(removePresence(const QString&, const QString&)), this, SLOT(onAccountRemovePresence(const QString&, const QString&))); connect(acc, SIGNAL(removePresence(const QString&, const QString&)), this, SLOT(onAccountRemovePresence(const QString&, const QString&)));
connect(acc, SIGNAL(message(const QMap<QString, QString>&)), this, SLOT(onAccountMessage(const QMap<QString, QString>&))); connect(acc, SIGNAL(message(const Shared::Message&)), this, SLOT(onAccountMessage(const Shared::Message&)));
QMap<QString, QVariant> map = { QMap<QString, QVariant> map = {
{"login", login}, {"login", login},
@ -194,13 +194,13 @@ void Core::Squawk::onAccountAvailabilityChanged(int state)
emit accountAvailabilityChanged(acc->getName(), state); emit accountAvailabilityChanged(acc->getName(), state);
} }
void Core::Squawk::onAccountMessage(const QMap<QString, QString>& data) void Core::Squawk::onAccountMessage(const Shared::Message& data)
{ {
Account* acc = static_cast<Account*>(sender()); Account* acc = static_cast<Account*>(sender());
emit accountMessage(acc->getName(), data); emit accountMessage(acc->getName(), data);
} }
void Core::Squawk::sendMessage(const QString& account, const QMap<QString, QString>& data) void Core::Squawk::sendMessage(const QString& account, const Shared::Message& data)
{ {
AccountsMap::const_iterator itr = amap.find(account); AccountsMap::const_iterator itr = amap.find(account);
if (itr == amap.end()) { if (itr == amap.end()) {

View File

@ -35,7 +35,7 @@ signals:
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 stateChanged(int state); void stateChanged(int state);
void accountMessage(const QString& account, const QMap<QString, QString>& data); void accountMessage(const QString& account, const Shared::Message& data);
public slots: public slots:
void start(); void start();
@ -44,7 +44,7 @@ public slots:
void connectAccount(const QString& account); void connectAccount(const QString& account);
void disconnectAccount(const QString& account); void disconnectAccount(const QString& account);
void changeState(int state); void changeState(int state);
void sendMessage(const QString& account, const QMap<QString, QString>& data); void sendMessage(const QString& account, const Shared::Message& data);
private: private:
typedef std::deque<Account*> Accounts; typedef std::deque<Account*> Accounts;
@ -68,7 +68,7 @@ private slots:
void onAccountChangeContact(const QString& jid, const QMap<QString, QVariant>& data); void onAccountChangeContact(const QString& jid, const QMap<QString, QVariant>& data);
void onAccountAddPresence(const QString& jid, const QString& name, const QMap<QString, QVariant>& data); void onAccountAddPresence(const QString& jid, const QString& name, const QMap<QString, QVariant>& data);
void onAccountRemovePresence(const QString& jid, const QString& name); void onAccountRemovePresence(const QString& jid, const QString& name);
void onAccountMessage(const QMap<QString, QString>& data); void onAccountMessage(const Shared::Message& data);
}; };
} }

14
exception.cpp Normal file
View File

@ -0,0 +1,14 @@
#include "exception.h"
Utils::Exception::Exception()
{
}
Utils::Exception::~Exception()
{
}
const char* Utils::Exception::what() const noexcept( true )
{
return getMessage().c_str();
}

22
exception.h Normal file
View File

@ -0,0 +1,22 @@
#ifndef EXCEPTION_H
#define EXCEPTION_H
#include <stdexcept>
#include <string>
namespace Utils
{
class Exception:
public std::exception
{
public:
Exception();
virtual ~Exception();
virtual std::string getMessage() const = 0;
const char* what() const noexcept( true );
};
}
#endif // EXCEPTION_H

125
global.cpp Normal file
View File

@ -0,0 +1,125 @@
#include "global.h"
Shared::Message::Message(Shared::Message::Type p_type):
jFrom(),
rFrom(),
jTo(),
rTo(),
id(),
body(),
time(),
type(p_type)
{
}
Shared::Message::Message():
jFrom(),
rFrom(),
jTo(),
rTo(),
id(),
body(),
time(),
type(Message::normal)
{
}
QString Shared::Message::getBody() const
{
return body;
}
QString Shared::Message::getFrom() const
{
QString from = jFrom;
if (rFrom.size() > 0) {
from += "/" + rFrom;
}
return from;
}
QString Shared::Message::getTo() const
{
QString to = jTo;
if (rTo.size() > 0) {
to += "/" + rTo;
}
return to;
}
QString Shared::Message::getId() const
{
return id;
}
QDateTime Shared::Message::getTime() const
{
return time;
}
void Shared::Message::setBody(const QString& p_body)
{
body = p_body;
}
void Shared::Message::setFrom(const QString& from)
{
QStringList list = from.split("/");
if (list.size() == 1) {
jFrom = from;
} else {
jFrom = list.front();
rFrom = list.back();
}
}
void Shared::Message::setTo(const QString& to)
{
QStringList list = to.split("/");
if (list.size() == 1) {
jTo = to;
} else {
jTo = list.front();
rTo = list.back();
}
}
void Shared::Message::setId(const QString& p_id)
{
id = p_id;
}
void Shared::Message::setTime(const QDateTime& p_time)
{
time = p_time;
}
QString Shared::Message::getFromJid() const
{
return jFrom;
}
QString Shared::Message::getFromResource() const
{
return rFrom;
}
QString Shared::Message::getToJid() const
{
return jTo;
}
QString Shared::Message::getToResource() const
{
return rTo;
}
QString Shared::Message::getPenPalJid() const
{
return jFrom;
}
QString Shared::Message::getPenPalResource() const
{
return rFrom;
}

View File

@ -54,14 +54,44 @@ static const std::deque<QString> subscriptionStateThemeIcons = {"edit-none", "ar
class Message { class Message {
public: public:
enum Type {
error,
normal,
chat,
groupChat,
headline
};
Message(Type p_type);
Message(); Message();
void setFrom(const QString& from);
void setTo(const QString& to);
void setTime(const QDateTime& p_time);
void setId(const QString& p_id);
void setBody(const QString& p_body);
QString getFrom() const;
QString getFromJid() const;
QString getFromResource() const;
QString getTo() const;
QString getToJid() const;
QString getToResource() const;
QDateTime getTime() const;
QString getId() const;
QString getBody() const;
QString getPenPalJid() const;
QString getPenPalResource() const;
private: private:
QString jFrom; QString jFrom;
QString rFrom; QString rFrom;
QString jTo; QString jTo;
QString rTo; QString rTo;
QString id;
QString body;
QDateTime time; QDateTime time;
Type type;
}; };
}; };

View File

@ -8,7 +8,7 @@
int main(int argc, char *argv[]) int main(int argc, char *argv[])
{ {
qRegisterMetaType<QMap<QString, QString>>("QMap<QString,QString>"); qRegisterMetaType<Shared::Message>("Shared::Message");
QApplication app(argc, argv); QApplication app(argc, argv);
SignalCatcher sc(&app); SignalCatcher sc(&app);
@ -34,7 +34,7 @@ int main(int argc, char *argv[])
QObject::connect(&w, SIGNAL(connectAccount(const QString&)), squawk, SLOT(connectAccount(const QString&))); QObject::connect(&w, SIGNAL(connectAccount(const QString&)), squawk, SLOT(connectAccount(const QString&)));
QObject::connect(&w, SIGNAL(disconnectAccount(const QString&)), squawk, SLOT(disconnectAccount(const QString&))); QObject::connect(&w, SIGNAL(disconnectAccount(const QString&)), squawk, SLOT(disconnectAccount(const QString&)));
QObject::connect(&w, SIGNAL(changeState(int)), squawk, SLOT(changeState(int))); QObject::connect(&w, SIGNAL(changeState(int)), squawk, SLOT(changeState(int)));
QObject::connect(&w, SIGNAL(sendMessage(const QString&, const QMap<QString, QString>&)), squawk, SLOT(sendMessage(const QString&, const QMap<QString, QString>&))); QObject::connect(&w, SIGNAL(sendMessage(const QString&, const Shared::Message&)), squawk, SLOT(sendMessage(const QString&, const Shared::Message&)));
QObject::connect(squawk, SIGNAL(newAccount(const QMap<QString, QVariant>&)), &w, SLOT(newAccount(const QMap<QString, QVariant>&))); QObject::connect(squawk, SIGNAL(newAccount(const QMap<QString, QVariant>&)), &w, SLOT(newAccount(const QMap<QString, QVariant>&)));
QObject::connect(squawk, SIGNAL(accountAvailabilityChanged(const QString&, int)), &w, SLOT(accountAvailabilityChanged(const QString&, int))); QObject::connect(squawk, SIGNAL(accountAvailabilityChanged(const QString&, int)), &w, SLOT(accountAvailabilityChanged(const QString&, int)));
@ -51,7 +51,7 @@ int main(int argc, char *argv[])
&w, SLOT(addPresence(const QString&, const QString&, const QString&, const QMap<QString, QVariant>&))); &w, SLOT(addPresence(const QString&, const QString&, const QString&, const QMap<QString, QVariant>&)));
QObject::connect(squawk, SIGNAL(removePresence(const QString&, const QString&, const QString&)), &w, SLOT(removePresence(const QString&, const QString&, const QString&))); QObject::connect(squawk, SIGNAL(removePresence(const QString&, const QString&, const QString&)), &w, SLOT(removePresence(const QString&, const QString&, const QString&)));
QObject::connect(squawk, SIGNAL(stateChanged(int)), &w, SLOT(stateChanged(int))); QObject::connect(squawk, SIGNAL(stateChanged(int)), &w, SLOT(stateChanged(int)));
QObject::connect(squawk, SIGNAL(accountMessage(const QString&, const QMap<QString, QString>&)), &w, SLOT(accountMessage(const QString&, const QMap<QString, QString>&))); QObject::connect(squawk, SIGNAL(accountMessage(const QString&, const Shared::Message&)), &w, SLOT(accountMessage(const QString&, const Shared::Message&)));
coreThread->start(); coreThread->start();

136
order.h Normal file
View File

@ -0,0 +1,136 @@
#ifndef ORDER_H
#define ORDER_H
#include <map>
#include <list>
#include "exception.h"
namespace W
{
template <typename data_type, typename comparator = std::less<data_type>>
class Order
{
class Duplicates:
public Utils::Exception
{
public:
Duplicates():Exception(){}
std::string getMessage() const{return "Inserting element duplicates existing";}
};
class NotFound:
public Utils::Exception
{
public:
NotFound():Exception(){}
std::string getMessage() const{return "Erasing element haven't been found";}
};
protected:
typedef std::list<data_type> List;
public:
typedef typename List::size_type size_type;
typedef typename List::const_iterator const_iterator;
typedef typename List::iterator iterator;
protected:
typedef std::map<data_type, const_iterator, comparator> Map;
typedef typename Map::const_iterator m_const_itr;
typedef typename Map::iterator m_itr;
public:
Order():
order(),
r_map()
{}
~Order() {};
size_type size() const {
return order.size();
}
void push_back(data_type element) {
m_const_itr m_itr = r_map.find(element);
if (m_itr != r_map.end()) {
throw Duplicates();
}
const_iterator itr = order.insert(order.end(), element);
r_map.insert(std::make_pair(element, itr));
}
void erase(data_type element) {
m_const_itr itr = r_map.find(element);
if (itr == r_map.end()) {
throw NotFound();
}
order.erase(itr->second);
r_map.erase(itr);
}
void clear() {
order.clear();
r_map.clear();
}
void insert(const_iterator pos, data_type element) {
m_const_itr m_itr = r_map.find(element);
if (m_itr != r_map.end()) {
throw Duplicates();
}
const_iterator itr = order.insert(pos, element);
r_map.insert(std::make_pair(element, itr));
}
void insert(iterator pos, data_type element) {
m_const_itr m_itr = r_map.find(element);
if (m_itr != r_map.end()) {
throw Duplicates();
}
const_iterator itr = order.insert(pos, element);
r_map.insert(std::make_pair(element, itr));
}
const_iterator find(data_type element) const {
m_const_itr itr = r_map.find(element);
if (itr == r_map.end()) {
return end();
} else {
return itr->second;
}
}
const_iterator begin() const {
return order.begin();
}
const_iterator end() const {
return order.end();
}
iterator begin() {
return order.begin();
}
iterator end() {
return order.end();
}
private:
List order;
Map r_map;
};
}
#endif // ORDER_H

View File

@ -20,6 +20,7 @@ set(squawkUI_SRC
models/contact.cpp models/contact.cpp
models/presence.cpp models/presence.cpp
conversation.cpp conversation.cpp
messageline.cpp
) )
# Tell CMake to create the helloworld executable # Tell CMake to create the helloworld executable

View File

@ -24,6 +24,7 @@ Conversation::Conversation(Models::Contact* p_contact, QWidget* parent):
QWidget(parent), QWidget(parent),
contact(p_contact), contact(p_contact),
m_ui(new Ui::Conversation), m_ui(new Ui::Conversation),
line(new MessageLine()),
ker() ker()
{ {
m_ui->setupUi(this); m_ui->setupUi(this);
@ -44,6 +45,8 @@ Conversation::Conversation(Models::Contact* p_contact, QWidget* parent):
for (Models::Contact::Messages::const_iterator itr = deque.begin(), end = deque.end(); itr != end; ++itr) { for (Models::Contact::Messages::const_iterator itr = deque.begin(), end = deque.end(); itr != end; ++itr) {
addMessage(*itr); addMessage(*itr);
} }
m_ui->scrollArea->setWidget(line);
} }
Conversation::~Conversation() Conversation::~Conversation()
@ -95,9 +98,9 @@ void Conversation::onContactChanged(Models::Item* item, int row, int col)
} }
} }
void Conversation::addMessage(const QMap<QString, QString>& data) void Conversation::addMessage(const Shared::Message& data)
{ {
m_ui->dialogBox->append(data.value("from") + ": " + data.value("body")); line->message(data);
} }
KeyEnterReceiver::KeyEnterReceiver(QObject* parent): QObject(parent), ownEvent(false) {} KeyEnterReceiver::KeyEnterReceiver(QObject* parent): QObject(parent), ownEvent(false) {}
@ -131,8 +134,13 @@ bool KeyEnterReceiver::eventFilter(QObject* obj, QEvent* event)
void Conversation::onEnterPressed() void Conversation::onEnterPressed()
{ {
QString msg(m_ui->messageEditor->toPlainText()); QString body(m_ui->messageEditor->toPlainText());
const QString& aJid = contact->getAccountJid();
m_ui->messageEditor->clear(); m_ui->messageEditor->clear();
m_ui->dialogBox->append(contact->getAccountJid() + ": " + msg); Shared::Message msg(Shared::Message::chat);
msg.setFrom(aJid);
msg.setTo(contact->getJid());
msg.setBody(body);
line->message(msg);
emit sendMessage(msg); emit sendMessage(msg);
} }

View File

@ -23,6 +23,7 @@
#include <QScopedPointer> #include <QScopedPointer>
#include "../global.h" #include "../global.h"
#include "models/contact.h" #include "models/contact.h"
#include "messageline.h"
namespace Ui namespace Ui
{ {
@ -51,10 +52,10 @@ public:
QString getJid() const; QString getJid() const;
QString getAccount() const; QString getAccount() const;
void addMessage(const QMap<QString, QString>& data); void addMessage(const Shared::Message& data);
signals: signals:
void sendMessage(const QString& message); void sendMessage(const Shared::Message& message);
protected: protected:
void setState(Shared::Availability state); void setState(Shared::Availability state);
@ -67,6 +68,7 @@ protected slots:
private: private:
Models::Contact* contact; Models::Contact* contact;
MessageLine* line;
QScopedPointer<Ui::Conversation> m_ui; QScopedPointer<Ui::Conversation> m_ui;
KeyEnterReceiver ker; KeyEnterReceiver ker;
}; };

View File

@ -115,10 +115,46 @@
</layout> </layout>
</item> </item>
<item> <item>
<widget class="QTextBrowser" name="dialogBox"> <widget class="QScrollArea" name="scrollArea">
<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="horizontalScrollBarPolicy">
<enum>Qt::ScrollBarAlwaysOff</enum>
</property>
<property name="widgetResizable">
<bool>true</bool>
</property>
<widget class="QWidget" name="scrollAreaWidgetContents">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>572</width>
<height>162</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>
@ -130,7 +166,10 @@
<verstretch>0</verstretch> <verstretch>0</verstretch>
</sizepolicy> </sizepolicy>
</property> </property>
<layout class="QGridLayout" name="gridLayout"> <layout class="QVBoxLayout" name="verticalLayout_2">
<property name="spacing">
<number>0</number>
</property>
<property name="leftMargin"> <property name="leftMargin">
<number>0</number> <number>0</number>
</property> </property>
@ -143,109 +182,86 @@
<property name="bottomMargin"> <property name="bottomMargin">
<number>0</number> <number>0</number>
</property> </property>
<property name="spacing"> <item>
<number>0</number> <layout class="QHBoxLayout" name="horizontalLayout_4">
</property> <item>
<item row="0" column="0" colspan="2"> <widget class="QPushButton" name="smilesButton">
<widget class="QWidget" name="widget_3" native="true"> <property name="text">
<property name="sizePolicy"> <string/>
<sizepolicy hsizetype="Preferred" vsizetype="Fixed"> </property>
<horstretch>0</horstretch> <property name="icon">
<verstretch>0</verstretch> <iconset theme="smiley-shape">
</sizepolicy> <normaloff>.</normaloff>.</iconset>
</property> </property>
<layout class="QHBoxLayout" name="horizontalLayout_2"> <property name="flat">
<property name="leftMargin"> <bool>true</bool>
<number>0</number> </property>
</property> </widget>
<property name="topMargin"> </item>
<number>0</number> <item>
</property> <spacer name="horizontalSpacer">
<property name="rightMargin"> <property name="orientation">
<number>0</number> <enum>Qt::Horizontal</enum>
</property> </property>
<property name="bottomMargin"> <property name="sizeHint" stdset="0">
<number>0</number> <size>
</property> <width>40</width>
<item> <height>20</height>
<widget class="QPushButton" name="smilesButton"> </size>
<property name="text"> </property>
<string/> </spacer>
</property> </item>
<property name="icon"> <item>
<iconset theme="smiley-shape"> <widget class="QPushButton" name="attachButton">
<normaloff>.</normaloff>.</iconset> <property name="text">
</property> <string/>
<property name="flat"> </property>
<bool>true</bool> <property name="icon">
</property> <iconset theme="document-send-symbolic">
</widget> <normaloff>.</normaloff>.</iconset>
</item> </property>
<item> <property name="flat">
<spacer name="horizontalSpacer"> <bool>true</bool>
<property name="orientation"> </property>
<enum>Qt::Horizontal</enum> </widget>
</property> </item>
<property name="sizeHint" stdset="0"> <item>
<size> <widget class="QPushButton" name="clearButton">
<width>40</width> <property name="text">
<height>20</height> <string/>
</size> </property>
</property> <property name="icon">
</spacer> <iconset theme="edit-clear-all">
</item> <normaloff>.</normaloff>.</iconset>
<item> </property>
<widget class="QPushButton" name="attachButton"> <property name="flat">
<property name="text"> <bool>true</bool>
<string/> </property>
</property> </widget>
<property name="icon"> </item>
<iconset theme="document-send-symbolic"> <item>
<normaloff>.</normaloff>.</iconset> <widget class="QPushButton" name="sendButton">
</property> <property name="sizePolicy">
<property name="flat"> <sizepolicy hsizetype="Minimum" vsizetype="Fixed">
<bool>true</bool> <horstretch>0</horstretch>
</property> <verstretch>0</verstretch>
</widget> </sizepolicy>
</item> </property>
<item> <property name="text">
<widget class="QPushButton" name="clearButton"> <string/>
<property name="text"> </property>
<string/> <property name="icon">
</property> <iconset theme="document-send">
<property name="icon"> <normaloff>.</normaloff>.</iconset>
<iconset theme="edit-clear-all"> </property>
<normaloff>.</normaloff>.</iconset> <property name="flat">
</property> <bool>true</bool>
<property name="flat"> </property>
<bool>true</bool> </widget>
</property> </item>
</widget> </layout>
</item>
<item>
<widget class="QPushButton" name="sendButton">
<property name="sizePolicy">
<sizepolicy hsizetype="Minimum" vsizetype="Expanding">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="text">
<string/>
</property>
<property name="icon">
<iconset theme="document-send">
<normaloff>.</normaloff>.</iconset>
</property>
<property name="flat">
<bool>true</bool>
</property>
</widget>
</item>
</layout>
</widget>
</item> </item>
<item row="1" column="0" colspan="2"> <item>
<widget class="QPlainTextEdit" name="messageEditor"> <widget class="QPlainTextEdit" name="messageEditor">
<property name="sizePolicy"> <property name="sizePolicy">
<sizepolicy hsizetype="Expanding" vsizetype="Expanding"> <sizepolicy hsizetype="Expanding" vsizetype="Expanding">

53
ui/messageline.cpp Normal file
View File

@ -0,0 +1,53 @@
/*
* <one line to give the program's name and a brief idea of what it does.>
* Copyright (C) 2019 Юрий Губич <y.gubich@initi.ru>
*
* 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 "messageline.h"
MessageLine::MessageLine(QWidget* parent):
QWidget(parent),
messageIndex(),
messageOrder(),
layout(new QVBoxLayout())
{
setLayout(layout);
setBackgroundRole(QPalette::Base);
}
MessageLine::~MessageLine()
{
}
void MessageLine::message(const Shared::Message& msg)
{
QVBoxLayout* vBox = new QVBoxLayout();
QHBoxLayout* hBox = new QHBoxLayout();
QWidget* message = new QWidget();
message->setLayout(vBox);
QLabel* body = new QLabel(msg.getBody());
QLabel* sender = new QLabel(msg.getFrom());
vBox->addWidget(body);
vBox->addWidget(sender);
hBox->addStretch();
hBox->addWidget(message);
layout->addItem(hBox);
}

45
ui/messageline.h Normal file
View File

@ -0,0 +1,45 @@
/*
* <one line to give the program's name and a brief idea of what it does.>
* Copyright (C) 2019 Юрий Губич <y.gubich@initi.ru>
*
* 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 MESSAGELINE_H
#define MESSAGELINE_H
#include <QWidget>
#include <QVBoxLayout>
#include <QLabel>
#include "../global.h"
#include "../order.h"
class MessageLine : public QWidget
{
Q_OBJECT
public:
MessageLine(QWidget* parent = 0);
~MessageLine();
void message(const Shared::Message& msg);
private:
typedef W::Order<Shared::Message*> Order;
std::map<QString, Shared::Message*> messageIndex;
Order messageOrder;
QVBoxLayout* layout;
};
#endif // MESSAGELINE_H

View File

@ -218,9 +218,9 @@ QString Models::Contact::getAccountName() const
return p->getName(); return p->getName();
} }
void Models::Contact::addMessage(const QMap<QString, QString>& data) void Models::Contact::addMessage(const Shared::Message& data)
{ {
const QString& res = data.value("fromResource"); const QString& res = data.getPenPalResource();
if (res.size() > 0) { if (res.size() > 0) {
QMap<QString, Presence*>::iterator itr = presences.find(res); QMap<QString, Presence*>::iterator itr = presences.find(res);
if (itr == presences.end()) { if (itr == presences.end()) {
@ -254,7 +254,7 @@ void Models::Contact::dropMessages()
void Models::Contact::getMessages(Models::Contact::Messages& container) const void Models::Contact::getMessages(Models::Contact::Messages& container) const
{ {
for (Messages::const_iterator itr = messages.begin(), end = messages.end(); itr != end; ++itr) { for (Messages::const_iterator itr = messages.begin(), end = messages.end(); itr != end; ++itr) {
const QMap<QString, QString>& msg = *itr; const Shared::Message& msg = *itr;
container.push_back(msg); container.push_back(msg);
} }

View File

@ -14,7 +14,7 @@ class Contact : public Item
{ {
Q_OBJECT Q_OBJECT
public: public:
typedef std::deque<QMap<QString, QString>> Messages; typedef std::deque<Shared::Message> Messages;
Contact(const QString& p_jid ,const QMap<QString, QVariant> &data, Item *parentItem = 0); Contact(const QString& p_jid ,const QMap<QString, QVariant> &data, Item *parentItem = 0);
~Contact(); ~Contact();
@ -35,7 +35,7 @@ public:
QString getAccountName() const; QString getAccountName() const;
QString getAccountJid() const; QString getAccountJid() const;
void addMessage(const QMap<QString, QString>& data); void addMessage(const Shared::Message& 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

@ -126,7 +126,7 @@ unsigned int Models::Presence::getMessagesCount() const
return messages.size(); return messages.size();
} }
void Models::Presence::addMessage(const QMap<QString, QString>& data) void Models::Presence::addMessage(const Shared::Message& data)
{ {
messages.emplace_back(data); messages.emplace_back(data);
changed(4); changed(4);
@ -152,7 +152,7 @@ QIcon Models::Presence::getStatusIcon() const
void Models::Presence::getMessages(Models::Presence::Messages& container) const void Models::Presence::getMessages(Models::Presence::Messages& container) const
{ {
for (Messages::const_iterator itr = messages.begin(), end = messages.end(); itr != end; ++itr) { for (Messages::const_iterator itr = messages.begin(), end = messages.end(); itr != end; ++itr) {
const QMap<QString, QString>& msg = *itr; const Shared::Message& msg = *itr;
container.push_back(msg); container.push_back(msg);
} }
} }

View File

@ -30,7 +30,7 @@ class Presence : public Models::Item
{ {
Q_OBJECT Q_OBJECT
public: public:
typedef std::deque<QMap<QString, QString>> Messages; 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(); ~Presence();
@ -51,7 +51,7 @@ public:
void update(const QString& key, const QVariant& value); void update(const QString& key, const QVariant& value);
unsigned int getMessagesCount() const; unsigned int getMessagesCount() const;
void dropMessages(); void dropMessages();
void addMessage(const QMap<QString, QString>& data); void addMessage(const Shared::Message& data);
void getMessages(Messages& container) const; void getMessages(Messages& container) const;

View File

@ -493,9 +493,9 @@ void Models::Roster::removePresence(const QString& account, const QString& jid,
} }
} }
void Models::Roster::addMessage(const QString& account, const QMap<QString, QString>& data) void Models::Roster::addMessage(const QString& account, const Shared::Message& data)
{ {
ElId id(account, data.value("from")); ElId id(account, data.getPenPalJid());
std::multimap<ElId, Contact*>::iterator cBeg = contacts.lower_bound(id); std::multimap<ElId, Contact*>::iterator cBeg = contacts.lower_bound(id);
std::multimap<ElId, Contact*>::iterator cEnd = contacts.upper_bound(id); std::multimap<ElId, Contact*>::iterator cEnd = contacts.upper_bound(id);

View File

@ -32,7 +32,7 @@ public:
void changeContact(const QString& account, const QString& jid, const QMap<QString, QVariant>& data); void changeContact(const QString& account, const QString& jid, const QMap<QString, QVariant>& data);
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 QMap<QString, QString>& data); void addMessage(const QString& account, const Shared::Message& data);
void dropMessages(const QString& account, const QString& jid); void dropMessages(const QString& account, const QString& jid);
QVariant data ( const QModelIndex& index, int role ) const override; QVariant data ( const QModelIndex& index, int role ) const override;

View File

@ -182,7 +182,7 @@ void Squawk::onRosterItemDoubleClicked(const QModelIndex& item)
conv->setAttribute(Qt::WA_DeleteOnClose); conv->setAttribute(Qt::WA_DeleteOnClose);
connect(conv, SIGNAL(destroyed(QObject*)), this, SLOT(onConversationClosed(QObject*))); connect(conv, SIGNAL(destroyed(QObject*)), this, SLOT(onConversationClosed(QObject*)));
connect(conv, SIGNAL(sendMessage(const QString&)), this, SLOT(onConversationMessage(const QString&))); connect(conv, SIGNAL(sendMessage(const Shared::Message&)), this, SLOT(onConversationMessage(const Shared::Message&)));
conversations.insert(std::make_pair(id, conv)); conversations.insert(std::make_pair(id, conv));
rosterModel.dropMessages(account, jid); rosterModel.dropMessages(account, jid);
@ -204,9 +204,9 @@ void Squawk::onConversationClosed(QObject* parent)
conversations.erase(itr); conversations.erase(itr);
} }
void Squawk::accountMessage(const QString& account, const QMap<QString, QString>& data) void Squawk::accountMessage(const QString& account, const Shared::Message& data)
{ {
const QString& from = data.value("from"); const QString& from = data.getPenPalJid();
Conversations::iterator itr = conversations.find({account, from}); Conversations::iterator itr = conversations.find({account, from});
if (itr != conversations.end()) { if (itr != conversations.end()) {
qDebug() << "adding message"; qDebug() << "adding message";
@ -217,11 +217,9 @@ void Squawk::accountMessage(const QString& account, const QMap<QString, QString>
} }
} }
void Squawk::onConversationMessage(const QString& item) void Squawk::onConversationMessage(const Shared::Message& msg)
{ {
Conversation* conv = static_cast<Conversation*>(sender()); Conversation* conv = static_cast<Conversation*>(sender());
emit sendMessage(conv->getAccount(), {
{"to", conv->getJid()}, emit sendMessage(conv->getAccount(), msg);
{"body", item}
});
} }

View File

@ -30,7 +30,7 @@ signals:
void connectAccount(const QString&); void connectAccount(const QString&);
void disconnectAccount(const QString&); void disconnectAccount(const QString&);
void changeState(int state); void changeState(int state);
void sendMessage(const QString& account, const QMap<QString, QString>& data); void sendMessage(const QString& account, const Shared::Message& data);
public slots: public slots:
void newAccount(const QMap<QString, QVariant>& account); void newAccount(const QMap<QString, QVariant>& account);
@ -45,7 +45,7 @@ public slots:
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 stateChanged(int state); void stateChanged(int state);
void accountMessage(const QString& account, const QMap<QString, QString>& data); void accountMessage(const QString& account, const Shared::Message& data);
private: private:
typedef std::map<Models::Roster::ElId, Conversation*> Conversations; typedef std::map<Models::Roster::ElId, Conversation*> Conversations;
@ -64,7 +64,7 @@ private slots:
void onConversationClosed(QObject* parent = 0); void onConversationClosed(QObject* parent = 0);
void onComboboxActivated(int index); void onComboboxActivated(int index);
void onRosterItemDoubleClicked(const QModelIndex& item); void onRosterItemDoubleClicked(const QModelIndex& item);
void onConversationMessage(const QString& item); void onConversationMessage(const Shared::Message& msg);
}; };