From d14883ad91f67f02b0dadcdd1e59c3eac9fcce89 Mon Sep 17 00:00:00 2001 From: blue Date: Wed, 3 Apr 2019 21:15:36 +0300 Subject: [PATCH] Refactoring finished --- core/account.cpp | 2 +- ui/CMakeLists.txt | 2 ++ ui/accounts.cpp | 18 +++---------- ui/accounts.h | 6 +---- ui/models/account.cpp | 37 ++++++++++++++++++++++---- ui/models/account.h | 4 +++ ui/models/accounts.cpp | 60 ++++++++++++------------------------------ ui/models/accounts.h | 10 ++++--- ui/models/item.cpp | 6 ++++- ui/models/item.h | 7 ++++- ui/models/roster.cpp | 45 +++++++++++++++++-------------- ui/models/roster.h | 4 +++ ui/squawk.cpp | 58 +++++++++------------------------------- ui/squawk.h | 4 --- 14 files changed, 120 insertions(+), 143 deletions(-) diff --git a/core/account.cpp b/core/account.cpp index f5b981a..98cbec0 100644 --- a/core/account.cpp +++ b/core/account.cpp @@ -62,7 +62,7 @@ void Core::Account::onClientDisconnected() state = Shared::disconnected; emit connectionStateChanged(state); } 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"); } } diff --git a/ui/CMakeLists.txt b/ui/CMakeLists.txt index 53826f4..78ce738 100644 --- a/ui/CMakeLists.txt +++ b/ui/CMakeLists.txt @@ -15,6 +15,8 @@ set(squawkUI_SRC account.cpp models/accounts.cpp models/roster.cpp + models/item.cpp + models/account.cpp ) # Tell CMake to create the helloworld executable diff --git a/ui/accounts.cpp b/ui/accounts.cpp index 5dc4d5c..82327d9 100644 --- a/ui/accounts.cpp +++ b/ui/accounts.cpp @@ -3,14 +3,13 @@ #include -Accounts::Accounts(QWidget *parent) : - m_ui(new Ui::Accounts), - tableModel() +Accounts::Accounts(Models::Accounts* model, QWidget *parent) : + m_ui(new Ui::Accounts) { m_ui->setupUi(this); connect(m_ui->addButton, SIGNAL(clicked(bool)), this, SLOT(onAddButton(bool))); - m_ui->tableView->setModel(&tableModel); + m_ui->tableView->setModel(model); } Accounts::~Accounts() = default; @@ -36,14 +35,3 @@ void Accounts::onAccountRejected() Account* acc = static_cast(sender()); acc->deleteLater(); } - -void Accounts::addAccount(const QMap& map) -{ - tableModel.addAccount(map); -} - -void Accounts::updateAccount(const QString& account, const QString& field, const QVariant& value) -{ - tableModel.updateAccount(account, field, value); -} - diff --git a/ui/accounts.h b/ui/accounts.h index afedb66..a5d2be2 100644 --- a/ui/accounts.h +++ b/ui/accounts.h @@ -16,11 +16,8 @@ class Accounts : public QWidget { Q_OBJECT public: - explicit Accounts(QWidget *parent = nullptr); + explicit Accounts(Models::Accounts* model, QWidget *parent = nullptr); ~Accounts() override; - - void addAccount(const QMap&); - void updateAccount(const QString& account, const QString& field, const QVariant& value); signals: void newAccount(const QMap&); @@ -32,7 +29,6 @@ private slots: private: QScopedPointer m_ui; - Models::Accounts tableModel; }; #endif // ACCOUNTS_H diff --git a/ui/models/account.cpp b/ui/models/account.cpp index 0b22699..def2b62 100644 --- a/ui/models/account.cpp +++ b/ui/models/account.cpp @@ -15,7 +15,10 @@ Models::Account::~Account() 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 @@ -40,17 +43,26 @@ int Models::Account::getState() const 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) { - password = p_password; + if (password != p_password) { + password = p_password; + emit changed(4); + } } 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 @@ -61,7 +73,7 @@ QVariant Models::Account::data(int column) const case 1: return server; case 2: - return state; + return Shared::ConnectionStateNames[state]; case 3: return login; case 4: @@ -75,3 +87,18 @@ int Models::Account::columnCount() const { 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()); + } +} diff --git a/ui/models/account.h b/ui/models/account.h index afdb9d7..ce7d5e6 100644 --- a/ui/models/account.h +++ b/ui/models/account.h @@ -1,7 +1,9 @@ #ifndef MODELS_ACCOUNT_H #define MODELS_ACCOUNT_H +#include "../../global.h" #include "item.h" +#include namespace Models { class Account : public Item { @@ -24,6 +26,8 @@ namespace Models { QVariant data(int column) const override; int columnCount() const override; + void update(const QString& field, const QVariant& value); + private: QString login; QString password; diff --git a/ui/models/accounts.cpp b/ui/models/accounts.cpp index 4e1db22..f9fd911 100644 --- a/ui/models/accounts.cpp +++ b/ui/models/accounts.cpp @@ -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; switch (role) { - case Qt::DisplayRole: { - const Account& acc = accs[index.row()]; - switch (index.column()) { - case 0: - answer = acc.name; - break; - case 1: - answer = acc.server; - break; - case 2: - answer = Shared::ConnectionStateNames[acc.state]; - break; - } - } + case Qt::DisplayRole: + answer = accs[index.row()]->data(index.column()); break; case Qt::DecorationRole: if (index.column() == 2) { - answer = QIcon::fromTheme(Shared::ConnectionStateThemeIcons[accs[index.row()].state]); + answer = QIcon::fromTheme(Shared::ConnectionStateThemeIcons[accs[index.row()]->getState()]); } break; default: @@ -71,39 +59,25 @@ QVariant Models::Accounts::headerData(int section, Qt::Orientation orientation, } -void Models::Accounts::addAccount(const QMap& map) +void Models::Accounts::addAccount(Account* account) { beginInsertRows(QModelIndex(), accs.size(), accs.size()); - accs.push_back({ - map.value("name").toString(), - map.value("server").toString(), - map.value("login").toString(), - map.value("password").toString(), - map.value("state").toInt() - }); + accs.push_back(account); + connect(account, SIGNAL(changed(int)), this, SLOT(onAccountChanged(int))); 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 = accs[i]; - if (acc.name == account) { - if (field == "name") { - acc.name = value.toString(); - 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)); - } - } + Account* acc = static_cast(sender()); + + if (column < columnCount(QModelIndex())) { + int row = acc->row(); + emit dataChanged(createIndex(row, column, this), createIndex(row, column, this)); } } +Models::Account * Models::Accounts::getAccount(int index) +{ + return accs[index]; +} diff --git a/ui/models/accounts.h b/ui/models/accounts.h index 0ead813..296ae98 100644 --- a/ui/models/accounts.h +++ b/ui/models/accounts.h @@ -3,6 +3,7 @@ #include #include +#include "account.h" namespace Models { @@ -14,19 +15,22 @@ public: Accounts(QObject* parent = 0); ~Accounts(); - void addAccount(const QMap& map); - void updateAccount(const QString& account, const QString& field, const QVariant& value); + void addAccount(Account* account); QVariant data ( const QModelIndex& index, int role ) const override; int columnCount ( const QModelIndex& parent ) const override; int rowCount ( const QModelIndex& parent ) const override; QVariant headerData(int section, Qt::Orientation orientation, int role) const override; + Account* getAccount(int index); + private: std::deque accs; - static std::deque columns; +private slots: + void onAccountChanged(int column); + }; } diff --git a/ui/models/item.cpp b/ui/models/item.cpp index 8b9b83d..7a6411b 100644 --- a/ui/models/item.cpp +++ b/ui/models/item.cpp @@ -3,6 +3,7 @@ using namespace Models; Models::Item::Item(Type p_type, const QMap &p_data, Item *p_parent): + QObject(), type(p_type), name(p_data.value("name").toString()), childItems(), @@ -21,7 +22,10 @@ Models::Item::~Item() 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) diff --git a/ui/models/item.h b/ui/models/item.h index 1d556d3..edc2216 100644 --- a/ui/models/item.h +++ b/ui/models/item.h @@ -9,7 +9,8 @@ namespace Models { -class Item { +class Item : public QObject{ + Q_OBJECT public: enum Type { account, @@ -22,6 +23,10 @@ class Item { explicit Item(Type p_type, const QMap &data, Item *parentItem = 0); ~Item(); + signals: + void changed(int col); + + public: void appendChild(Item *child); QString getName() const; void setName(const QString& name); diff --git a/ui/models/roster.cpp b/ui/models/roster.cpp index 20886d0..91b0be2 100644 --- a/ui/models/roster.cpp +++ b/ui/models/roster.cpp @@ -5,13 +5,20 @@ using namespace Models; Models::Roster::Roster(QObject* 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&)), + this, + SLOT(onAccountDataChanged(const QModelIndex&, const QModelIndex&, const QVector&))); } Models::Roster::~Roster() { + delete accountsModel; delete root; } @@ -21,6 +28,7 @@ void Models::Roster::addAccount(const QMap& data) beginInsertRows(QModelIndex(), root->childCount(), root->childCount()); root->appendChild(acc); accounts.insert(std::make_pair(acc->getName(), acc)); + accountsModel->addAccount(acc); endInsertRows(); } @@ -42,7 +50,8 @@ QVariant Models::Roster::data (const QModelIndex& index, int role) const case Qt::DecorationRole: switch (item->type) { case Item::account:{ - int state = item->data(1).toInt(); + Account* acc = static_cast(item); + int state = acc->getState(); switch (state) { case Shared::disconnected: result = QIcon::fromTheme("im-user-offline"); @@ -81,17 +90,7 @@ void Models::Roster::updateAccount(const QString& account, const QString& field, std::map::iterator itr = accounts.find(account); if (itr != accounts.end()) { Account* acc = itr->second; - if (field == "name") { - 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)); - } + acc->update(field, value); } } @@ -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): account(p_account), name(p_name) -{ - -} +{} 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& 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); + } +} + diff --git a/ui/models/roster.h b/ui/models/roster.h index 769778e..d1ba136 100644 --- a/ui/models/roster.h +++ b/ui/models/roster.h @@ -4,6 +4,7 @@ #include #include #include +#include #include "../../global.h" #include "accounts.h" #include "item.h" @@ -38,6 +39,9 @@ private: std::map accounts; std::map elements; +private slots: + void onAccountDataChanged(const QModelIndex& tl, const QModelIndex& br, const QVector& roles); + private: class ElId { public: diff --git a/ui/squawk.cpp b/ui/squawk.cpp index 952a7c6..d9509ba 100644 --- a/ui/squawk.cpp +++ b/ui/squawk.cpp @@ -6,8 +6,6 @@ Squawk::Squawk(QWidget *parent) : QMainWindow(parent), m_ui(new Ui::Squawk), accounts(0), - accountsCache(), - accountsIndex(), rosterModel() { m_ui->setupUi(this); @@ -25,18 +23,11 @@ Squawk::~Squawk() { void Squawk::onAccounts() { if (accounts == 0) { - accounts = new Accounts(this); + accounts = new Accounts(rosterModel.accountsModel, this); accounts->setAttribute(Qt::WA_DeleteOnClose); connect(accounts, SIGNAL(destroyed(QObject*)), this, SLOT(onAccountsClosed(QObject*))); connect(accounts, SIGNAL(newAccount(const QMap&)), this, SIGNAL(newAccountRequest(const QMap&))); - AC::const_iterator itr = accountsCache.begin(); - AC::const_iterator end = accountsCache.end(); - - for (; itr != end; ++itr) { - accounts->addAccount(*itr); - } - accounts->show(); } else { accounts->show(); @@ -62,39 +53,29 @@ void Squawk::onAccountsClosed(QObject* parent) void Squawk::newAccount(const QMap& account) { - accountsCache.push_back(account); - QMap* acc = &accountsCache.back(); - accountsIndex.insert(std::make_pair(acc->value("name").toString(), acc)); rosterModel.addAccount(account); - if (accounts != 0) { - accounts->addAccount(account); - } } void Squawk::onComboboxActivated(int index) { if (index == 0) { - if (accountsCache.size() > 0) { - AC::const_iterator itr = accountsCache.begin(); - AC::const_iterator end = accountsCache.end(); - - for (; itr != end; ++itr) { - const QMap& acc = *itr; - if (acc.value("state").toInt() == Shared::disconnected) { - emit connectAccount(acc.value("name").toString()); + int size = rosterModel.accountsModel->rowCount(QModelIndex()); + if (size > 0) { + for (int i = 0; i < size; ++i) { + Models::Account* acc = rosterModel.accountsModel->getAccount(i); + if (acc->getState() == Shared::disconnected) { + emit connectAccount(acc->getName()); } } } else { m_ui->comboBox->setCurrentIndex(1); } } else if (index == 1) { - AC::const_iterator itr = accountsCache.begin(); - AC::const_iterator end = accountsCache.end(); - - for (; itr != end; ++itr) { - const QMap& acc = *itr; - if (acc.value("state").toInt() != Shared::disconnected) { - emit disconnectAccount(acc.value("name").toString()); + int size = rosterModel.accountsModel->rowCount(QModelIndex()); + for (int i = 0; i != size; ++i) { + Models::Account* acc = rosterModel.accountsModel->getAccount(i); + if (acc->getState() != Shared::disconnected) { + emit disconnectAccount(acc->getName()); } } } @@ -102,18 +83,5 @@ void Squawk::onComboboxActivated(int index) void Squawk::accountConnectionStateChanged(const QString& account, int state) { - AI::iterator itr = accountsIndex.find(account); - if (itr != accountsIndex.end()) { - QMap* 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()); - } + rosterModel.updateAccount(account, "state", state); } diff --git a/ui/squawk.h b/ui/squawk.h index 32da189..3c3e09a 100644 --- a/ui/squawk.h +++ b/ui/squawk.h @@ -34,13 +34,9 @@ public slots: void accountConnectionStateChanged(const QString& account, int state); private: - typedef std::deque> AC; - typedef std::map*> AI; QScopedPointer m_ui; Accounts* accounts; - AC accountsCache; - AI accountsIndex; Models::Roster rosterModel; protected: