1
0
forked from blue/squawk

Refactoring finished

This commit is contained in:
Blue 2019-04-03 21:15:36 +03:00
parent 2bcee521c5
commit d14883ad91
14 changed files with 120 additions and 143 deletions

View File

@ -62,7 +62,7 @@ void Core::Account::onClientDisconnected()
state = Shared::disconnected; state = Shared::disconnected;
emit connectionStateChanged(state); emit connectionStateChanged(state);
} else { } else {
qDebug("Something weird had happened - xmpp client reported about being disconnection but account was already in disconnected state"); //qDebug("Something weird had happened - xmpp client reported about being disconnection but account was already in disconnected state");
} }
} }

View File

@ -15,6 +15,8 @@ set(squawkUI_SRC
account.cpp account.cpp
models/accounts.cpp models/accounts.cpp
models/roster.cpp models/roster.cpp
models/item.cpp
models/account.cpp
) )
# Tell CMake to create the helloworld executable # Tell CMake to create the helloworld executable

View File

@ -3,14 +3,13 @@
#include <QDebug> #include <QDebug>
Accounts::Accounts(QWidget *parent) : Accounts::Accounts(Models::Accounts* model, QWidget *parent) :
m_ui(new Ui::Accounts), m_ui(new Ui::Accounts)
tableModel()
{ {
m_ui->setupUi(this); m_ui->setupUi(this);
connect(m_ui->addButton, SIGNAL(clicked(bool)), this, SLOT(onAddButton(bool))); connect(m_ui->addButton, SIGNAL(clicked(bool)), this, SLOT(onAddButton(bool)));
m_ui->tableView->setModel(&tableModel); m_ui->tableView->setModel(model);
} }
Accounts::~Accounts() = default; Accounts::~Accounts() = default;
@ -36,14 +35,3 @@ void Accounts::onAccountRejected()
Account* acc = static_cast<Account*>(sender()); Account* acc = static_cast<Account*>(sender());
acc->deleteLater(); acc->deleteLater();
} }
void Accounts::addAccount(const QMap<QString, QVariant>& map)
{
tableModel.addAccount(map);
}
void Accounts::updateAccount(const QString& account, const QString& field, const QVariant& value)
{
tableModel.updateAccount(account, field, value);
}

View File

@ -16,12 +16,9 @@ class Accounts : public QWidget
{ {
Q_OBJECT Q_OBJECT
public: public:
explicit Accounts(QWidget *parent = nullptr); explicit Accounts(Models::Accounts* model, QWidget *parent = nullptr);
~Accounts() override; ~Accounts() override;
void addAccount(const QMap<QString, QVariant>&);
void updateAccount(const QString& account, const QString& field, const QVariant& value);
signals: signals:
void newAccount(const QMap<QString, QVariant>&); void newAccount(const QMap<QString, QVariant>&);
@ -32,7 +29,6 @@ private slots:
private: private:
QScopedPointer<Ui::Accounts> m_ui; QScopedPointer<Ui::Accounts> m_ui;
Models::Accounts tableModel;
}; };
#endif // ACCOUNTS_H #endif // ACCOUNTS_H

View File

@ -15,7 +15,10 @@ Models::Account::~Account()
void Models::Account::setState(int p_state) void Models::Account::setState(int p_state)
{ {
state = p_state; if (state != p_state) {
state = p_state;
emit changed(2);
}
} }
QString Models::Account::getLogin() const QString Models::Account::getLogin() const
@ -40,17 +43,26 @@ int Models::Account::getState() const
void Models::Account::setLogin(const QString& p_login) void Models::Account::setLogin(const QString& p_login)
{ {
login = p_login; if (login != p_login) {
login = p_login;
emit changed(3);
}
} }
void Models::Account::setPassword(const QString& p_password) void Models::Account::setPassword(const QString& p_password)
{ {
password = p_password; if (password != p_password) {
password = p_password;
emit changed(4);
}
} }
void Models::Account::setServer(const QString& p_server) void Models::Account::setServer(const QString& p_server)
{ {
server = p_server; if (server != p_server) {
server = p_server;
emit changed(1);
}
} }
QVariant Models::Account::data(int column) const QVariant Models::Account::data(int column) const
@ -61,7 +73,7 @@ QVariant Models::Account::data(int column) const
case 1: case 1:
return server; return server;
case 2: case 2:
return state; return Shared::ConnectionStateNames[state];
case 3: case 3:
return login; return login;
case 4: case 4:
@ -75,3 +87,18 @@ int Models::Account::columnCount() const
{ {
return 5; return 5;
} }
void Models::Account::update(const QString& field, const QVariant& value)
{
if (field == "name") {
setName(value.toString());
} else if (field == "server") {
setServer(value.toString());
} else if (field == "login") {
setLogin(value.toString());
} else if (field == "password") {
setPassword(value.toString());
} else if (field == "state") {
setState(value.toInt());
}
}

View File

@ -1,7 +1,9 @@
#ifndef MODELS_ACCOUNT_H #ifndef MODELS_ACCOUNT_H
#define MODELS_ACCOUNT_H #define MODELS_ACCOUNT_H
#include "../../global.h"
#include "item.h" #include "item.h"
#include <QVariant>
namespace Models { namespace Models {
class Account : public Item { class Account : public Item {
@ -24,6 +26,8 @@ namespace Models {
QVariant data(int column) const override; QVariant data(int column) const override;
int columnCount() const override; int columnCount() const override;
void update(const QString& field, const QVariant& value);
private: private:
QString login; QString login;
QString password; QString password;

View File

@ -21,28 +21,16 @@ Models::Accounts::~Accounts()
} }
QVariant Models::Accounts::data ( const QModelIndex& index, int role ) const QVariant Models::Accounts::data (const QModelIndex& index, int role) const
{ {
QVariant answer; QVariant answer;
switch (role) { switch (role) {
case Qt::DisplayRole: { case Qt::DisplayRole:
const Account& acc = accs[index.row()]; answer = accs[index.row()]->data(index.column());
switch (index.column()) {
case 0:
answer = acc.name;
break;
case 1:
answer = acc.server;
break;
case 2:
answer = Shared::ConnectionStateNames[acc.state];
break;
}
}
break; break;
case Qt::DecorationRole: case Qt::DecorationRole:
if (index.column() == 2) { if (index.column() == 2) {
answer = QIcon::fromTheme(Shared::ConnectionStateThemeIcons[accs[index.row()].state]); answer = QIcon::fromTheme(Shared::ConnectionStateThemeIcons[accs[index.row()]->getState()]);
} }
break; break;
default: default:
@ -71,39 +59,25 @@ QVariant Models::Accounts::headerData(int section, Qt::Orientation orientation,
} }
void Models::Accounts::addAccount(const QMap<QString, QVariant>& map) void Models::Accounts::addAccount(Account* account)
{ {
beginInsertRows(QModelIndex(), accs.size(), accs.size()); beginInsertRows(QModelIndex(), accs.size(), accs.size());
accs.push_back({ accs.push_back(account);
map.value("name").toString(), connect(account, SIGNAL(changed(int)), this, SLOT(onAccountChanged(int)));
map.value("server").toString(),
map.value("login").toString(),
map.value("password").toString(),
map.value("state").toInt()
});
endInsertRows(); endInsertRows();
} }
void Models::Accounts::updateAccount(const QString& account, const QString& field, const QVariant& value) void Models::Accounts::onAccountChanged(int column)
{ {
for (int i = 0; i < accs.size(); ++i) { Account* acc = static_cast<Account*>(sender());
Account& acc = accs[i];
if (acc.name == account) { if (column < columnCount(QModelIndex())) {
if (field == "name") { int row = acc->row();
acc.name = value.toString(); emit dataChanged(createIndex(row, column, this), createIndex(row, column, this));
emit dataChanged(createIndex(i, 0), createIndex(i, 0));
} else if (field == "server") {
acc.server = value.toString();
emit dataChanged(createIndex(i, 1), createIndex(i, 1));
} else if (field == "login") {
acc.login = value.toString();
} else if (field == "password") {
acc.password = value.toString();
} else if (field == "state") {
acc.state = value.toInt();
emit dataChanged(createIndex(i, 2), createIndex(i, 2));
}
}
} }
} }
Models::Account * Models::Accounts::getAccount(int index)
{
return accs[index];
}

View File

@ -3,6 +3,7 @@
#include <qabstractitemmodel.h> #include <qabstractitemmodel.h>
#include <deque> #include <deque>
#include "account.h"
namespace Models namespace Models
{ {
@ -14,19 +15,22 @@ public:
Accounts(QObject* parent = 0); Accounts(QObject* parent = 0);
~Accounts(); ~Accounts();
void addAccount(const QMap<QString, QVariant>& map); void addAccount(Account* account);
void updateAccount(const QString& account, const QString& field, const QVariant& value);
QVariant data ( const QModelIndex& index, int role ) const override; QVariant data ( const QModelIndex& index, int role ) const override;
int columnCount ( const QModelIndex& parent ) const override; int columnCount ( const QModelIndex& parent ) const override;
int rowCount ( const QModelIndex& parent ) const override; int rowCount ( const QModelIndex& parent ) const override;
QVariant headerData(int section, Qt::Orientation orientation, int role) const override; QVariant headerData(int section, Qt::Orientation orientation, int role) const override;
Account* getAccount(int index);
private: private:
std::deque<Account*> accs; std::deque<Account*> accs;
static std::deque<QString> columns; static std::deque<QString> columns;
private slots:
void onAccountChanged(int column);
}; };
} }

View File

@ -3,6 +3,7 @@
using namespace Models; using namespace Models;
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(),
type(p_type), type(p_type),
name(p_data.value("name").toString()), name(p_data.value("name").toString()),
childItems(), childItems(),
@ -21,7 +22,10 @@ Models::Item::~Item()
void Models::Item::setName(const QString& p_name) void Models::Item::setName(const QString& p_name)
{ {
name = p_name; if (name != p_name) {
name = p_name;
emit changed(0);
}
} }
void Models::Item::appendChild(Models::Item* child) void Models::Item::appendChild(Models::Item* child)

View File

@ -9,7 +9,8 @@
namespace Models { namespace Models {
class Item { class Item : public QObject{
Q_OBJECT
public: public:
enum Type { enum Type {
account, account,
@ -22,6 +23,10 @@ class Item {
explicit Item(Type p_type, const QMap<QString, QVariant> &data, Item *parentItem = 0); explicit Item(Type p_type, const QMap<QString, QVariant> &data, Item *parentItem = 0);
~Item(); ~Item();
signals:
void changed(int col);
public:
void appendChild(Item *child); void appendChild(Item *child);
QString getName() const; QString getName() const;
void setName(const QString& name); void setName(const QString& name);

View File

@ -5,13 +5,20 @@ using namespace Models;
Models::Roster::Roster(QObject* parent): Models::Roster::Roster(QObject* parent):
QAbstractItemModel(parent), QAbstractItemModel(parent),
root(0) accountsModel(new Accounts()),
root(new Item(Item::root, {{"name", "root"}})),
accounts(),
elements()
{ {
root = new Item(Item::root, {{"name", "root"}}); connect(accountsModel,
SIGNAL(dataChanged(const QModelIndex&, const QModelIndex&, const QVector<int>&)),
this,
SLOT(onAccountDataChanged(const QModelIndex&, const QModelIndex&, const QVector<int>&)));
} }
Models::Roster::~Roster() Models::Roster::~Roster()
{ {
delete accountsModel;
delete root; delete root;
} }
@ -21,6 +28,7 @@ void Models::Roster::addAccount(const QMap<QString, QVariant>& data)
beginInsertRows(QModelIndex(), root->childCount(), root->childCount()); beginInsertRows(QModelIndex(), root->childCount(), root->childCount());
root->appendChild(acc); root->appendChild(acc);
accounts.insert(std::make_pair(acc->getName(), acc)); accounts.insert(std::make_pair(acc->getName(), acc));
accountsModel->addAccount(acc);
endInsertRows(); endInsertRows();
} }
@ -42,7 +50,8 @@ QVariant Models::Roster::data (const QModelIndex& index, int role) const
case Qt::DecorationRole: case Qt::DecorationRole:
switch (item->type) { switch (item->type) {
case Item::account:{ case Item::account:{
int state = item->data(1).toInt(); Account* acc = static_cast<Account*>(item);
int state = acc->getState();
switch (state) { switch (state) {
case Shared::disconnected: case Shared::disconnected:
result = QIcon::fromTheme("im-user-offline"); result = QIcon::fromTheme("im-user-offline");
@ -81,17 +90,7 @@ void Models::Roster::updateAccount(const QString& account, const QString& field,
std::map<QString, Account*>::iterator itr = accounts.find(account); std::map<QString, Account*>::iterator itr = accounts.find(account);
if (itr != accounts.end()) { if (itr != accounts.end()) {
Account* acc = itr->second; Account* acc = itr->second;
if (field == "name") { acc->update(field, value);
acc->setName(value.toString());
accounts.erase(itr);
accounts.insert(std::make_pair(acc->name(), acc));
int row = acc->row();
emit dataChanged(createIndex(row, 0, acc), createIndex(row, 0, acc));
} else if (field == "state") {
acc->setState(value.toInt());
int row = acc->row();
emit dataChanged(createIndex(row, 0, acc), createIndex(row, 0, acc));
}
} }
} }
@ -169,15 +168,10 @@ QModelIndex Models::Roster::index (int row, int column, const QModelIndex& paren
} }
} }
Models::Roster::ElId::ElId(const QString& p_account, const QString& p_name): Models::Roster::ElId::ElId(const QString& p_account, const QString& p_name):
account(p_account), account(p_account),
name(p_name) name(p_name)
{ {}
}
bool Models::Roster::ElId::operator <(const Models::Roster::ElId& other) const bool Models::Roster::ElId::operator <(const Models::Roster::ElId& other) const
{ {
@ -188,4 +182,15 @@ bool Models::Roster::ElId::operator <(const Models::Roster::ElId& other) const
} }
} }
void Models::Roster::onAccountDataChanged(const QModelIndex& tl, const QModelIndex& br, const QVector<int>& roles)
{
if (tl.column() == 0) {
emit dataChanged(tl, br, roles);
} else if (tl.column() == 2) {
int row = tl.row();
Account* acc = accountsModel->getAccount(row);
emit dataChanged(createIndex(row, 0, acc), createIndex(br.row(), 0, acc), roles);
}
}

View File

@ -4,6 +4,7 @@
#include <qabstractitemmodel.h> #include <qabstractitemmodel.h>
#include <deque> #include <deque>
#include <map> #include <map>
#include <QVector>
#include "../../global.h" #include "../../global.h"
#include "accounts.h" #include "accounts.h"
#include "item.h" #include "item.h"
@ -38,6 +39,9 @@ private:
std::map<QString, Account*> accounts; std::map<QString, Account*> accounts;
std::map<ElId, Item*> elements; std::map<ElId, Item*> elements;
private slots:
void onAccountDataChanged(const QModelIndex& tl, const QModelIndex& br, const QVector<int>& roles);
private: private:
class ElId { class ElId {
public: public:

View File

@ -6,8 +6,6 @@ Squawk::Squawk(QWidget *parent) :
QMainWindow(parent), QMainWindow(parent),
m_ui(new Ui::Squawk), m_ui(new Ui::Squawk),
accounts(0), accounts(0),
accountsCache(),
accountsIndex(),
rosterModel() rosterModel()
{ {
m_ui->setupUi(this); m_ui->setupUi(this);
@ -25,18 +23,11 @@ Squawk::~Squawk() {
void Squawk::onAccounts() void Squawk::onAccounts()
{ {
if (accounts == 0) { if (accounts == 0) {
accounts = new Accounts(this); accounts = new Accounts(rosterModel.accountsModel, this);
accounts->setAttribute(Qt::WA_DeleteOnClose); accounts->setAttribute(Qt::WA_DeleteOnClose);
connect(accounts, SIGNAL(destroyed(QObject*)), this, SLOT(onAccountsClosed(QObject*))); connect(accounts, SIGNAL(destroyed(QObject*)), this, SLOT(onAccountsClosed(QObject*)));
connect(accounts, SIGNAL(newAccount(const QMap<QString, QVariant>&)), this, SIGNAL(newAccountRequest(const QMap<QString, QVariant>&))); connect(accounts, SIGNAL(newAccount(const QMap<QString, QVariant>&)), this, SIGNAL(newAccountRequest(const QMap<QString, QVariant>&)));
AC::const_iterator itr = accountsCache.begin();
AC::const_iterator end = accountsCache.end();
for (; itr != end; ++itr) {
accounts->addAccount(*itr);
}
accounts->show(); accounts->show();
} else { } else {
accounts->show(); accounts->show();
@ -62,39 +53,29 @@ void Squawk::onAccountsClosed(QObject* parent)
void Squawk::newAccount(const QMap<QString, QVariant>& account) void Squawk::newAccount(const QMap<QString, QVariant>& account)
{ {
accountsCache.push_back(account);
QMap<QString, QVariant>* acc = &accountsCache.back();
accountsIndex.insert(std::make_pair(acc->value("name").toString(), acc));
rosterModel.addAccount(account); rosterModel.addAccount(account);
if (accounts != 0) {
accounts->addAccount(account);
}
} }
void Squawk::onComboboxActivated(int index) void Squawk::onComboboxActivated(int index)
{ {
if (index == 0) { if (index == 0) {
if (accountsCache.size() > 0) { int size = rosterModel.accountsModel->rowCount(QModelIndex());
AC::const_iterator itr = accountsCache.begin(); if (size > 0) {
AC::const_iterator end = accountsCache.end(); for (int i = 0; i < size; ++i) {
Models::Account* acc = rosterModel.accountsModel->getAccount(i);
for (; itr != end; ++itr) { if (acc->getState() == Shared::disconnected) {
const QMap<QString, QVariant>& acc = *itr; emit connectAccount(acc->getName());
if (acc.value("state").toInt() == Shared::disconnected) {
emit connectAccount(acc.value("name").toString());
} }
} }
} else { } else {
m_ui->comboBox->setCurrentIndex(1); m_ui->comboBox->setCurrentIndex(1);
} }
} else if (index == 1) { } else if (index == 1) {
AC::const_iterator itr = accountsCache.begin(); int size = rosterModel.accountsModel->rowCount(QModelIndex());
AC::const_iterator end = accountsCache.end(); for (int i = 0; i != size; ++i) {
Models::Account* acc = rosterModel.accountsModel->getAccount(i);
for (; itr != end; ++itr) { if (acc->getState() != Shared::disconnected) {
const QMap<QString, QVariant>& acc = *itr; emit disconnectAccount(acc->getName());
if (acc.value("state").toInt() != Shared::disconnected) {
emit disconnectAccount(acc.value("name").toString());
} }
} }
} }
@ -102,18 +83,5 @@ void Squawk::onComboboxActivated(int index)
void Squawk::accountConnectionStateChanged(const QString& account, int state) void Squawk::accountConnectionStateChanged(const QString& account, int state)
{ {
AI::iterator itr = accountsIndex.find(account); rosterModel.updateAccount(account, "state", state);
if (itr != accountsIndex.end()) {
QMap<QString, QVariant>* acc = itr->second;
acc->insert("state", state);
rosterModel.updateAccount(account, "state", state);
if (accounts != 0) {
accounts->updateAccount(account, "state", state);
}
} else {
QString msg("A notification about connection state change of an unknown account ");
msg += account + ", skipping";
qDebug("%s", msg.toStdString().c_str());
}
} }

View File

@ -34,13 +34,9 @@ public slots:
void accountConnectionStateChanged(const QString& account, int state); void accountConnectionStateChanged(const QString& account, int state);
private: private:
typedef std::deque<QMap<QString, QVariant>> AC;
typedef std::map<QString, QMap<QString, QVariant>*> AI;
QScopedPointer<Ui::Squawk> m_ui; QScopedPointer<Ui::Squawk> m_ui;
Accounts* accounts; Accounts* accounts;
AC accountsCache;
AI accountsIndex;
Models::Roster rosterModel; Models::Roster rosterModel;
protected: protected: