1
0
forked from blue/squawk

basic conversation window binding

This commit is contained in:
Blue 2019-04-09 18:04:08 +03:00
parent 1cbcad44af
commit 4775c7b700
16 changed files with 333 additions and 80 deletions

View File

@ -1,5 +1,6 @@
#include "account.h" #include "account.h"
#include <qxmpp/QXmppRosterManager.h> #include <qxmpp/QXmppRosterManager.h>
#include <qxmpp/QXmppMessage.h>
#include <QDateTime> #include <QDateTime>
using namespace Core; using namespace Core;
@ -20,6 +21,7 @@ Account::Account(const QString& p_login, const QString& p_server, const QString&
QObject::connect(&client, SIGNAL(connected()), this, SLOT(onClientConnected())); QObject::connect(&client, SIGNAL(connected()), this, SLOT(onClientConnected()));
QObject::connect(&client, SIGNAL(disconnected()), this, SLOT(onClientDisconnected())); QObject::connect(&client, SIGNAL(disconnected()), this, SLOT(onClientDisconnected()));
QObject::connect(&client, SIGNAL(presenceReceived(const QXmppPresence&)), this, SLOT(onPresenceReceived(const QXmppPresence&))); QObject::connect(&client, SIGNAL(presenceReceived(const QXmppPresence&)), this, SLOT(onPresenceReceived(const QXmppPresence&)));
QObject::connect(&client, SIGNAL(messageReceived(const QXmppMessage&)), this, SLOT(onMessageReceived(const QXmppMessage&)));
QXmppRosterManager& rm = client.rosterManager(); QXmppRosterManager& rm = client.rosterManager();
@ -330,3 +332,21 @@ void Core::Account::setResource(const QString& p_resource)
{ {
config.setResource(p_resource); config.setResource(p_resource);
} }
void Core::Account::onMessageReceived(const QXmppMessage& message)
{
qDebug() << "Message received: ";
qDebug() << "- from: " << message.from();
qDebug() << "- to: " << message.to();
qDebug() << "- body: " << message.body();
qDebug() << "- type: " << message.type();
qDebug() << "- state: " << message.state();
qDebug() << "- stamp: " << message.stamp();
qDebug() << "- id: " << message.id();
qDebug() << "- isAttentionRequested: " << message.isAttentionRequested();
qDebug() << "- isReceiptRequested: " << message.isReceiptRequested();
qDebug() << "- receiptId: " << message.receiptId();
qDebug() << "- subject: " << message.subject();
qDebug() << "- thread: " << message.thread();
qDebug() << "- isMarkable: " << message.isMarkable();
}

View File

@ -65,6 +65,7 @@ private slots:
void onRosterItemRemoved(const QString& bareJid); void onRosterItemRemoved(const QString& bareJid);
void onRosterPresenceChanged(const QString& bareJid, const QString& resource); void onRosterPresenceChanged(const QString& bareJid, const QString& resource);
void onPresenceReceived(const QXmppPresence& presence); void onPresenceReceived(const QXmppPresence& presence);
void onMessageReceived(const QXmppMessage& message);
private: private:
void addedAccount(const QString &bareJid); void addedAccount(const QString &bareJid);

View File

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

View File

@ -18,3 +18,68 @@
#include "conversation.h" #include "conversation.h"
#include "ui_conversation.h" #include "ui_conversation.h"
#include <QDebug>
Conversation::Conversation(Models::Contact* p_contact, QWidget* parent):
QWidget(parent),
contact(p_contact),
m_ui(new Ui::Conversation)
{
m_ui->setupUi(this);
m_ui->splitter->setSizes({300, 0});
m_ui->splitter->setStretchFactor(1, 0);
setName(p_contact->getName());
setState(p_contact->getAvailability());
connect(contact, SIGNAL(childChanged(Models::Item*, int, int)), this, SLOT(onContactChanged(Models::Item*, int, int)));
}
Conversation::~Conversation()
{
disconnect(contact, SIGNAL(childChanged(Models::Item*, int, int)), this, SLOT(onContactChanged(Models::Item*, int, int)));
}
void Conversation::setName(const QString& name)
{
if (name == "") {
m_ui->nameLabel->setText(getJid());
} else {
m_ui->nameLabel->setText(name);
}
}
void Conversation::setState(Shared::Availability state)
{
m_ui->statusIcon->setPixmap(QIcon::fromTheme(Shared::availabilityThemeIcons[state]).pixmap(50));
m_ui->statusIcon->setToolTip(Shared::availabilityNames[state]);
}
void Conversation::setStatus(const QString& status)
{
m_ui->statusLabel->setText(status);
}
QString Conversation::getAccount() const
{
return contact->getAccountName();
}
QString Conversation::getJid() const
{
return contact->getJid();
}
void Conversation::onContactChanged(Models::Item* item, int row, int col)
{
if (item == contact) {
switch (col) {
case 0:
setName(contact->getName());
break;
case 3:
setState(contact->getAvailability());
break;
}
}
}

View File

@ -21,20 +21,34 @@
#include <QWidget> #include <QWidget>
#include <QScopedPointer> #include <QScopedPointer>
#include "../global.h"
#include "models/contact.h"
namespace Ui namespace Ui
{ {
class Conversation; class Conversation;
} }
/**
* @todo write docs
*/
class Conversation : public QWidget class Conversation : public QWidget
{ {
Q_OBJECT Q_OBJECT
public:
Conversation(Models::Contact* p_contact, QWidget* parent = 0);
~Conversation();
QString getJid() const;
QString getAccount() const;
protected:
void setState(Shared::Availability state);
void setStatus(const QString& status);
void setName(const QString& name);
protected slots:
void onContactChanged(Models::Item* item, int row, int col);
private: private:
Models::Contact* contact;
QScopedPointer<Ui::Conversation> m_ui; QScopedPointer<Ui::Conversation> m_ui;
}; };

View File

@ -6,8 +6,8 @@
<rect> <rect>
<x>0</x> <x>0</x>
<y>0</y> <y>0</y>
<width>478</width> <width>572</width>
<height>428</height> <height>377</height>
</rect> </rect>
</property> </property>
<layout class="QHBoxLayout" name="horizontalLayout"> <layout class="QHBoxLayout" name="horizontalLayout">
@ -54,40 +54,72 @@
</sizepolicy> </sizepolicy>
</property> </property>
<layout class="QVBoxLayout" name="verticalLayout"> <layout class="QVBoxLayout" name="verticalLayout">
<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>
<item> <item>
<layout class="QHBoxLayout" name="horizontalLayout_3"> <layout class="QHBoxLayout" name="horizontalLayout_3">
<item> <item>
<widget class="QLabel" name="label"> <widget class="QLabel" name="statusIcon">
<property name="text"> <property name="text">
<string>Status icon</string> <string/>
</property> </property>
</widget> </widget>
</item> </item>
<item> <item>
<widget class="QLabel" name="label_2"> <widget class="QLabel" name="nameLabel">
<property name="text"> <property name="text">
<string>User name of JID</string> <string/>
</property> </property>
</widget> </widget>
</item> </item>
<item> <item>
<widget class="QLabel" name="label_3"> <widget class="QLabel" name="statusLabel">
<property name="text"> <property name="text">
<string>Status</string> <string/>
</property> </property>
</widget> </widget>
</item> </item>
<item> <item>
<widget class="QLabel" name="label_4"> <spacer name="horizontalSpacer_2">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>40</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
<item>
<widget class="QLabel" name="avatar">
<property name="text"> <property name="text">
<string>Avatar</string> <string/>
</property> </property>
</widget> </widget>
</item> </item>
</layout> </layout>
</item> </item>
<item> <item>
<widget class="QTextBrowser" name="textBrowser"/> <widget class="QTextBrowser" name="dialogBox">
<property name="frameShape">
<enum>QFrame::NoFrame</enum>
</property>
</widget>
</item> </item>
</layout> </layout>
</widget> </widget>
@ -99,46 +131,29 @@
</sizepolicy> </sizepolicy>
</property> </property>
<layout class="QGridLayout" name="gridLayout"> <layout class="QGridLayout" name="gridLayout">
<item row="2" column="0" rowspan="2"> <property name="leftMargin">
<widget class="QPlainTextEdit" name="plainTextEdit"> <number>0</number>
<property name="sizePolicy">
<sizepolicy hsizetype="Expanding" vsizetype="Expanding">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property> </property>
<property name="minimumSize"> <property name="topMargin">
<size> <number>0</number>
<width>0</width>
<height>20</height>
</size>
</property> </property>
<property name="baseSize"> <property name="rightMargin">
<size> <number>0</number>
<width>0</width>
<height>30</height>
</size>
</property> </property>
</widget> <property name="bottomMargin">
</item> <number>0</number>
<item row="2" column="1" rowspan="2">
<widget class="QPushButton" name="pushButton_3">
<property name="sizePolicy">
<sizepolicy hsizetype="Minimum" vsizetype="Expanding">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property> </property>
<property name="text"> <property name="spacing">
<string/> <number>0</number>
</property> </property>
<property name="icon">
<iconset theme="document-send"/>
</property>
</widget>
</item>
<item row="0" column="0" colspan="2"> <item row="0" column="0" colspan="2">
<widget class="QWidget" name="widget_3" native="true"> <widget class="QWidget" name="widget_3" native="true">
<property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<layout class="QHBoxLayout" name="horizontalLayout_2"> <layout class="QHBoxLayout" name="horizontalLayout_2">
<property name="leftMargin"> <property name="leftMargin">
<number>0</number> <number>0</number>
@ -153,12 +168,16 @@
<number>0</number> <number>0</number>
</property> </property>
<item> <item>
<widget class="QPushButton" name="pushButton_2"> <widget class="QPushButton" name="smilesButton">
<property name="text"> <property name="text">
<string/> <string/>
</property> </property>
<property name="icon"> <property name="icon">
<iconset theme="smiley-shape"/> <iconset theme="smiley-shape">
<normaloff>.</normaloff>.</iconset>
</property>
<property name="flat">
<bool>true</bool>
</property> </property>
</widget> </widget>
</item> </item>
@ -176,31 +195,81 @@
</spacer> </spacer>
</item> </item>
<item> <item>
<widget class="QPushButton" name="pushButton"> <widget class="QPushButton" name="attachButton">
<property name="text"> <property name="text">
<string/> <string/>
</property> </property>
<property name="icon"> <property name="icon">
<iconset theme="document-send-symbolic"/> <iconset theme="document-send-symbolic">
<normaloff>.</normaloff>.</iconset>
</property>
<property name="flat">
<bool>true</bool>
</property> </property>
</widget> </widget>
</item> </item>
<item> <item>
<widget class="QPushButton" name="pushButton_4"> <widget class="QPushButton" name="clearButton">
<property name="text"> <property name="text">
<string/> <string/>
</property> </property>
<property name="icon"> <property name="icon">
<iconset theme="edit-clear-all"/> <iconset theme="edit-clear-all">
<normaloff>.</normaloff>.</iconset>
</property> </property>
<property name="flat"> <property name="flat">
<bool>false</bool> <bool>true</bool>
</property>
</widget>
</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> </property>
</widget> </widget>
</item> </item>
</layout> </layout>
</widget> </widget>
</item> </item>
<item row="1" column="0" colspan="2">
<widget class="QPlainTextEdit" name="messageEditor">
<property name="sizePolicy">
<sizepolicy hsizetype="Expanding" vsizetype="Expanding">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="minimumSize">
<size>
<width>0</width>
<height>30</height>
</size>
</property>
<property name="baseSize">
<size>
<width>0</width>
<height>30</height>
</size>
</property>
<property name="frameShape">
<enum>QFrame::NoFrame</enum>
</property>
</widget>
</item>
</layout> </layout>
</widget> </widget>
</widget> </widget>

View File

@ -63,7 +63,7 @@ void Models::Accounts::addAccount(Account* account)
{ {
beginInsertRows(QModelIndex(), accs.size(), accs.size()); beginInsertRows(QModelIndex(), accs.size(), accs.size());
accs.push_back(account); accs.push_back(account);
connect(account, SIGNAL(childChanged(Item*, int, int)), this, SLOT(onAccountChanged(Item*, int, int))); connect(account, SIGNAL(childChanged(Models::Item*, int, int)), this, SLOT(onAccountChanged(Models::Item*, int, int)));
endInsertRows(); endInsertRows();
} }

View File

@ -29,7 +29,7 @@ private:
static std::deque<QString> columns; static std::deque<QString> columns;
private slots: private slots:
void onAccountChanged(Item* item, int row, int col); void onAccountChanged(Models::Item* item, int row, int col);
}; };
} }

View File

@ -81,9 +81,9 @@ QVariant Models::Contact::data(int column) const
case 1: case 1:
return jid; return jid;
case 2: case 2:
return availability;
case 3:
return state; return state;
case 3:
return availability;
default: default:
return QVariant(); return QVariant();
} }
@ -124,6 +124,7 @@ void Models::Contact::removePresence(const QString& name)
QMap<QString, Presence*>::iterator itr = presences.find(name); QMap<QString, Presence*>::iterator itr = presences.find(name);
if (itr == presences.end()) { if (itr == presences.end()) {
qDebug() << "an attempt to remove non existing presence " << name << " from the contact " << jid << " of account " << getAccountName() << ", skipping";
} else { } else {
Presence* pr = itr.value(); Presence* pr = itr.value();
presences.erase(itr); presences.erase(itr);
@ -154,6 +155,8 @@ void Models::Contact::refresh()
void Models::Contact::_removeChild(int index) void Models::Contact::_removeChild(int index)
{ {
Item* child = childItems[index];
disconnect(child, SIGNAL(childChanged(Models::Item*, int, int)), this, SLOT(refresh()));
Item::_removeChild(index); Item::_removeChild(index);
refresh(); refresh();
} }
@ -161,12 +164,7 @@ void Models::Contact::_removeChild(int index)
void Models::Contact::appendChild(Models::Item* child) void Models::Contact::appendChild(Models::Item* child)
{ {
Item::appendChild(child); Item::appendChild(child);
refresh(); connect(child, SIGNAL(childChanged(Models::Item*, int, int)), this, SLOT(refresh()));
}
void Models::Contact::changed(int col)
{
Item::changed(col);
refresh(); refresh();
} }
@ -191,3 +189,18 @@ QIcon Models::Contact::getStatusIcon() const
return QIcon::fromTheme(Shared::subscriptionStateThemeIcons[state]); return QIcon::fromTheme(Shared::subscriptionStateThemeIcons[state]);
} }
} }
QString Models::Contact::getAccountName() const
{
const Item* p = this;
do {
p = p->parentItemConst();
} while (p != 0 && p->type != Item::account);
if (p == 0) {
qDebug() << "An attempt to request account name of the contact " << jid << " but the parent account wasn't found, returning empty string";
return "";
}
return p->getName();
}

View File

@ -30,12 +30,14 @@ 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;
protected: protected:
void refresh();
void changed(int col) override;
void _removeChild(int index) override; void _removeChild(int index) override;
protected slots:
void refresh();
protected: protected:
void setAvailability(Shared::Availability p_state); void setAvailability(Shared::Availability p_state);
void setAvailability(unsigned int p_state); void setAvailability(unsigned int p_state);

View File

@ -41,7 +41,7 @@ void Models::Item::appendChild(Models::Item* child)
childItems.push_back(child); childItems.push_back(child);
child->parent = this; child->parent = this;
QObject::connect(child, SIGNAL(childChanged(Item*, int, int)), this, SIGNAL(childChanged(Item*, int, int))); QObject::connect(child, SIGNAL(childChanged(Models::Item*, int, int)), this, SIGNAL(childChanged(Models::Item*, int, int)));
QObject::connect(child, SIGNAL(childIsAboutToBeInserted(Item*, int, int)), this, SIGNAL(childIsAboutToBeInserted(Item*, int, int))); QObject::connect(child, SIGNAL(childIsAboutToBeInserted(Item*, int, int)), this, SIGNAL(childIsAboutToBeInserted(Item*, int, int)));
QObject::connect(child, SIGNAL(childInserted()), this, SIGNAL(childInserted())); QObject::connect(child, SIGNAL(childInserted()), this, SIGNAL(childInserted()));
QObject::connect(child, SIGNAL(childIsAboutToBeRemoved(Item*, int, int)), this, SIGNAL(childIsAboutToBeRemoved(Item*, int, int))); QObject::connect(child, SIGNAL(childIsAboutToBeRemoved(Item*, int, int)), this, SIGNAL(childIsAboutToBeRemoved(Item*, int, int)));
@ -87,6 +87,11 @@ Models::Item * Models::Item::parentItem()
return parent; return parent;
} }
const Models::Item * Models::Item::parentItemConst() const
{
return parent;
}
int Models::Item::columnCount() const int Models::Item::columnCount() const
{ {
return 1; return 1;
@ -116,7 +121,7 @@ void Models::Item::_removeChild(int index)
{ {
Item* child = childItems[index]; Item* child = childItems[index];
QObject::connect(child, SIGNAL(childChanged(Item*, int, int)), this, SIGNAL(childChanged(Item*, int, int))); QObject::connect(child, SIGNAL(childChanged(Models::Item*, int, int)), this, SIGNAL(childChanged(Models::Item*, int, int)));
QObject::connect(child, SIGNAL(childIsAboutToBeInserted(Item*, int, int)), this, SIGNAL(childIsAboutToBeInserted(Item*, int, int))); QObject::connect(child, SIGNAL(childIsAboutToBeInserted(Item*, int, int)), this, SIGNAL(childIsAboutToBeInserted(Item*, int, int)));
QObject::connect(child, SIGNAL(childInserted()), this, SIGNAL(childInserted())); QObject::connect(child, SIGNAL(childInserted()), this, SIGNAL(childInserted()));
QObject::connect(child, SIGNAL(childIsAboutToBeRemoved(Item*, int, int)), this, SIGNAL(childIsAboutToBeRemoved(Item*, int, int))); QObject::connect(child, SIGNAL(childIsAboutToBeRemoved(Item*, int, int)), this, SIGNAL(childIsAboutToBeRemoved(Item*, int, int)));

View File

@ -25,7 +25,7 @@ class Item : public QObject{
~Item(); ~Item();
signals: signals:
void childChanged(Item* item, int row, int col); void childChanged(Models::Item* item, int row, int col);
void childIsAboutToBeInserted(Item* parent, int first, int last); void childIsAboutToBeInserted(Item* parent, int first, int last);
void childInserted(); void childInserted();
void childIsAboutToBeRemoved(Item* parent, int first, int last); void childIsAboutToBeRemoved(Item* parent, int first, int last);
@ -45,6 +45,7 @@ class Item : public QObject{
virtual QVariant data(int column) const; virtual QVariant data(int column) const;
int row() const; int row() const;
Item *parentItem(); Item *parentItem();
const Item *parentItemConst() const;
const Type type; const Type type;

View File

@ -17,7 +17,7 @@ Models::Roster::Roster(QObject* parent):
SIGNAL(dataChanged(const QModelIndex&, const QModelIndex&, const QVector<int>&)), SIGNAL(dataChanged(const QModelIndex&, const QModelIndex&, const QVector<int>&)),
this, this,
SLOT(onAccountDataChanged(const QModelIndex&, const QModelIndex&, const QVector<int>&))); SLOT(onAccountDataChanged(const QModelIndex&, const QModelIndex&, const QVector<int>&)));
connect(root, SIGNAL(childChanged(Item*, int, int)), this, SLOT(onChildChanged(Item*, int, int))); connect(root, SIGNAL(childChanged(Models::Item*, int, int)), this, SLOT(onChildChanged(Models::Item*, int, int)));
connect(root, SIGNAL(childIsAboutToBeInserted(Item*, int, int)), this, SLOT(onChildIsAboutToBeInserted(Item*, int, int))); connect(root, SIGNAL(childIsAboutToBeInserted(Item*, int, int)), this, SLOT(onChildIsAboutToBeInserted(Item*, int, int)));
connect(root, SIGNAL(childInserted()), this, SLOT(onChildInserted())); connect(root, SIGNAL(childInserted()), this, SLOT(onChildInserted()));
connect(root, SIGNAL(childIsAboutToBeRemoved(Item*, int, int)), this, SLOT(onChildIsAboutToBeRemoved(Item*, int, int))); connect(root, SIGNAL(childIsAboutToBeRemoved(Item*, int, int)), this, SLOT(onChildIsAboutToBeRemoved(Item*, int, int)));

View File

@ -16,9 +16,9 @@ namespace Models
class Roster : public QAbstractItemModel class Roster : public QAbstractItemModel
{ {
class ElId;
Q_OBJECT Q_OBJECT
public: public:
class ElId;
Roster(QObject* parent = 0); Roster(QObject* parent = 0);
~Roster(); ~Roster();
@ -51,7 +51,7 @@ private:
private slots: private slots:
void onAccountDataChanged(const QModelIndex& tl, const QModelIndex& br, const QVector<int>& roles); void onAccountDataChanged(const QModelIndex& tl, const QModelIndex& br, const QVector<int>& roles);
void onChildChanged(Item* item, int row, int col); void onChildChanged(Models::Item* item, int row, int col);
void onChildIsAboutToBeInserted(Item* parent, int first, int last); void onChildIsAboutToBeInserted(Item* parent, int first, int last);
void onChildInserted(); void onChildInserted();
void onChildIsAboutToBeRemoved(Item* parent, int first, int last); void onChildIsAboutToBeRemoved(Item* parent, int first, int last);
@ -59,7 +59,7 @@ private slots:
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();
private: 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);

View File

@ -7,7 +7,8 @@ Squawk::Squawk(QWidget *parent) :
QMainWindow(parent), QMainWindow(parent),
m_ui(new Ui::Squawk), m_ui(new Ui::Squawk),
accounts(0), accounts(0),
rosterModel() rosterModel(),
conversations()
{ {
m_ui->setupUi(this); m_ui->setupUi(this);
m_ui->roster->setModel(&rosterModel); m_ui->roster->setModel(&rosterModel);
@ -19,6 +20,7 @@ Squawk::Squawk(QWidget *parent) :
connect(m_ui->actionAccounts, SIGNAL(triggered()), this, SLOT(onAccounts())); connect(m_ui->actionAccounts, SIGNAL(triggered()), this, SLOT(onAccounts()));
connect(m_ui->comboBox, SIGNAL(activated(int)), this, SLOT(onComboboxActivated(int))); connect(m_ui->comboBox, SIGNAL(activated(int)), this, SLOT(onComboboxActivated(int)));
connect(m_ui->roster, SIGNAL(doubleClicked(const QModelIndex&)), this, SLOT(onRosterItemDoubleClicked(const QModelIndex&)));
//m_ui->mainToolBar->addWidget(m_ui->comboBox); //m_ui->mainToolBar->addWidget(m_ui->comboBox);
} }
@ -47,6 +49,11 @@ void Squawk::closeEvent(QCloseEvent* event)
if (accounts != 0) { if (accounts != 0) {
accounts->close(); accounts->close();
} }
for (Conversations::const_iterator itr = conversations.begin(), end = conversations.end(); itr != end; ++itr) {
disconnect(itr->second, SIGNAL(destroyed(QObject*)), this, SLOT(onConversationClosed(QObject*)));
itr->second->close();
}
conversations.clear();
QMainWindow::closeEvent(event); QMainWindow::closeEvent(event);
} }
@ -144,3 +151,53 @@ void Squawk::stateChanged(int state)
m_ui->comboBox->setCurrentIndex(state); m_ui->comboBox->setCurrentIndex(state);
} }
void Squawk::onRosterItemDoubleClicked(const QModelIndex& item)
{
if (item.isValid()) {
Models::Item* node = static_cast<Models::Item*>(item.internalPointer());
Models::Contact* contact = 0;
switch (node->type) {
case Models::Item::contact:
contact = static_cast<Models::Contact*>(node);
break;
case Models::Item::presence:
contact = static_cast<Models::Contact*>(node->parentItem());
break;
default:
m_ui->roster->expand(item);
break;
}
if (contact != 0) {
QString jid = contact->getJid();
QString account = contact->getAccountName();
Models::Roster::ElId id(account, jid);
Conversations::const_iterator itr = conversations.find(id);
if (itr != conversations.end()) {
itr->second->show();
itr->second->raise();
itr->second->activateWindow();
} else {
Conversation* conv = new Conversation(contact);
conv->setAttribute(Qt::WA_DeleteOnClose);
connect(conv, SIGNAL(destroyed(QObject*)), this, SLOT(onConversationClosed(QObject*)));
conversations.insert(std::make_pair(id, conv));
conv->show();
}
}
}
}
void Squawk::onConversationClosed(QObject* parent)
{
Conversation* conv = static_cast<Conversation*>(sender());
Conversations::const_iterator itr = conversations.find({conv->getAccount(), conv->getJid()});
if (itr == conversations.end()) {
qDebug() << "Conversation has been closed but can not be found among other opened conversations, application is most probably going to crash";
return;
}
conversations.erase(itr);
}

View File

@ -8,6 +8,7 @@
#include <map> #include <map>
#include "accounts.h" #include "accounts.h"
#include "conversation.h"
#include "models/roster.h" #include "models/roster.h"
#include "../global.h" #include "../global.h"
@ -45,10 +46,12 @@ public slots:
void stateChanged(int state); void stateChanged(int state);
private: private:
typedef std::map<Models::Roster::ElId, Conversation*> Conversations;
QScopedPointer<Ui::Squawk> m_ui; QScopedPointer<Ui::Squawk> m_ui;
Accounts* accounts; Accounts* accounts;
Models::Roster rosterModel; Models::Roster rosterModel;
Conversations conversations;
protected: protected:
void closeEvent(QCloseEvent * event) override; void closeEvent(QCloseEvent * event) override;
@ -56,7 +59,9 @@ protected:
private slots: private slots:
void onAccounts(); void onAccounts();
void onAccountsClosed(QObject* parent = 0); void onAccountsClosed(QObject* parent = 0);
void onConversationClosed(QObject* parent = 0);
void onComboboxActivated(int index); void onComboboxActivated(int index);
void onRosterItemDoubleClicked(const QModelIndex& item);
}; };