From 234697050b7f93f94c6c4d40770432ed6fe45456 Mon Sep 17 00:00:00 2001 From: blue Date: Wed, 29 May 2019 18:05:54 +0300 Subject: [PATCH] first attempt to remove accounts --- core/account.cpp | 1 - core/squawk.cpp | 30 +++++++++++++++++++ core/squawk.h | 2 ++ main.cpp | 2 ++ ui/accounts.cpp | 66 +++++++++++++++++++++++++++++++++++++++--- ui/accounts.h | 7 +++++ ui/accounts.ui | 4 +-- ui/models/accounts.cpp | 10 +++++++ ui/models/accounts.h | 4 +++ ui/models/item.cpp | 14 ++++----- ui/models/roster.cpp | 38 ++++++++++++++++++++++++ ui/models/roster.h | 1 + ui/squawk.cpp | 23 +++++++++++++++ ui/squawk.h | 2 ++ 14 files changed, 190 insertions(+), 14 deletions(-) diff --git a/core/account.cpp b/core/account.cpp index 54df50d..a35c60e 100644 --- a/core/account.cpp +++ b/core/account.cpp @@ -738,4 +738,3 @@ void Core::Account::onClientError(QXmppClient::Error err) qDebug() << errorType << errorText; emit error(errorText); } - diff --git a/core/squawk.cpp b/core/squawk.cpp index eed4512..c8d84e6 100644 --- a/core/squawk.cpp +++ b/core/squawk.cpp @@ -1,6 +1,8 @@ #include "squawk.h" #include #include +#include +#include Core::Squawk::Squawk(QObject* parent): QObject(parent), @@ -298,3 +300,31 @@ void Core::Squawk::onAccountError(const QString& text) Account* acc = static_cast(sender()); emit changeAccount(acc->getName(), {{"error", text}}); } + +void Core::Squawk::removeAccountRequest(const QString& name) +{ + AccountsMap::const_iterator itr = amap.find(name); + if (itr == amap.end()) { + qDebug() << "An attempt to remove non existing account " << name << " from core, skipping"; + return; + } + + Account* acc = itr->second; + + for (Accounts::const_iterator aItr = accounts.begin(); aItr != accounts.end(); ++aItr) { + if (*aItr == acc) { + accounts.erase(aItr); + break; + } + } + + amap.erase(itr); + delete acc; + + QString path(QStandardPaths::writableLocation(QStandardPaths::CacheLocation)); + path += "/" + name; + QDir dir(path); + dir.removeRecursively(); + + emit removeAccount(name); +} diff --git a/core/squawk.h b/core/squawk.h index c9cd2ea..61e5156 100644 --- a/core/squawk.h +++ b/core/squawk.h @@ -25,6 +25,7 @@ signals: void quit(); void newAccount(const QMap&); void changeAccount(const QString& account, const QMap& data); + void removeAccount(const QString& account); void addGroup(const QString& account, const QString& name); void removeGroup(const QString& account, const QString& name); void addContact(const QString& account, const QString& jid, const QString& group, const QMap& data); @@ -42,6 +43,7 @@ public slots: void stop(); void newAccountRequest(const QMap& map); void modifyAccountRequest(const QString& name, const QMap& map); + void removeAccountRequest(const QString& name); void connectAccount(const QString& account); void disconnectAccount(const QString& account); void changeState(int state); diff --git a/main.cpp b/main.cpp index 8fc1404..66bdbfc 100644 --- a/main.cpp +++ b/main.cpp @@ -34,6 +34,7 @@ int main(int argc, char *argv[]) QObject::connect(&w, SIGNAL(newAccountRequest(const QMap&)), squawk, SLOT(newAccountRequest(const QMap&))); QObject::connect(&w, SIGNAL(modifyAccountRequest(const QString&, const QMap&)), squawk, SLOT(modifyAccountRequest(const QString&, const QMap&))); + QObject::connect(&w, SIGNAL(removeAccountRequest(const QString&)), squawk, SLOT(removeAccountRequest(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(changeState(int)), squawk, SLOT(changeState(int))); @@ -46,6 +47,7 @@ int main(int argc, char *argv[]) &w, SLOT(addContact(const QString&, const QString&, const QString&, const QMap&))); QObject::connect(squawk, SIGNAL(changeAccount(const QString&, const QMap&)), &w, SLOT(changeAccount(const QString&, const QMap&))); + QObject::connect(squawk, SIGNAL(removeAccount(const QString&)), &w, SLOT(removeAccount(const QString&))); QObject::connect(squawk, SIGNAL(addGroup(const QString&, const QString&)), &w, SLOT(addGroup(const QString&, const QString&))); QObject::connect(squawk, SIGNAL(removeGroup(const QString&, const QString&)), &w, SLOT(removeGroup(const QString&, const QString&))); QObject::connect(squawk, SIGNAL(removeContact(const QString&, const QString&)), &w, SLOT(removeContact(const QString&, const QString&))); diff --git a/ui/accounts.cpp b/ui/accounts.cpp index 2822825..44da73f 100644 --- a/ui/accounts.cpp +++ b/ui/accounts.cpp @@ -6,15 +6,19 @@ Accounts::Accounts(Models::Accounts* p_model, QWidget *parent) : m_ui(new Ui::Accounts), model(p_model), - editing(false) + editing(false), + toDisconnect(false) { m_ui->setupUi(this); connect(m_ui->addButton, SIGNAL(clicked(bool)), this, SLOT(onAddButton(bool))); connect(m_ui->editButton, SIGNAL(clicked(bool)), this, SLOT(onEditButton(bool))); + connect(m_ui->connectButton, SIGNAL(clicked(bool)), this, SLOT(onConnectButton(bool))); + connect(m_ui->deleteButton, SIGNAL(clicked(bool)), this, SLOT(onDeleteButton(bool))); m_ui->tableView->setModel(model); connect(m_ui->tableView->selectionModel(), SIGNAL(selectionChanged(const QItemSelection&, const QItemSelection&)), this, SLOT(onSelectionChanged(const QItemSelection&, const QItemSelection&))); + connect(p_model, SIGNAL(changed()), this, SLOT(updateConnectButton())); } Accounts::~Accounts() = default; @@ -69,12 +73,66 @@ void Accounts::onEditButton(bool clicked) void Accounts::onSelectionChanged(const QItemSelection& selected, const QItemSelection& deselected) { - const QItemSelection& selection = m_ui->tableView->selectionModel()->selection(); - if (selection.size() == 0) { + int selectionSize = m_ui->tableView->selectionModel()->selection().size(); + if (selectionSize == 0) { m_ui->editButton->setEnabled(false); - } else if (selection.size() == 1) { + m_ui->deleteButton->setEnabled(false); + } else if (selectionSize == 1) { m_ui->editButton->setEnabled(true); + m_ui->deleteButton->setEnabled(true); } else { m_ui->editButton->setEnabled(false); + m_ui->deleteButton->setEnabled(true); + } + + updateConnectButton(); +} + +void Accounts::updateConnectButton() +{ + QItemSelectionModel* sm = m_ui->tableView->selectionModel(); + if (sm->hasSelection()) { + m_ui->connectButton->setEnabled(true); + int selectionSize = sm->selection().size(); + bool allConnected = true; + for (int i = 0; i < selectionSize && allConnected; ++i) { + const Models::Account* mAcc = model->getAccount(sm->selectedRows().at(i).row()); + allConnected = mAcc->getState() == Shared::connected; + } + if (allConnected) { + toDisconnect = true; + m_ui->connectButton->setText("Disconnect"); + } else { + toDisconnect = false; + m_ui->connectButton->setText("Connect"); + } + } else { + m_ui->connectButton->setText("Connect"); + toDisconnect = false; + m_ui->connectButton->setEnabled(false); + } +} + +void Accounts::onConnectButton(bool clicked) +{ + QItemSelectionModel* sm = m_ui->tableView->selectionModel(); + int selectionSize = sm->selection().size(); + for (int i = 0; i < selectionSize; ++i) { + const Models::Account* mAcc = model->getAccount(sm->selectedRows().at(i).row()); + if (toDisconnect) { + emit disconnectAccount(mAcc->getName()); + } else { + emit connectAccount(mAcc->getName()); + } + } +} + +void Accounts::onDeleteButton(bool clicked) +{ + QItemSelectionModel* sm = m_ui->tableView->selectionModel(); + int selectionSize = sm->selection().size(); + for (int i = 0; i < selectionSize; ++i) { + const Models::Account* mAcc = model->getAccount(sm->selectedRows().at(i).row()); + emit removeAccount(mAcc->getName()); } } diff --git a/ui/accounts.h b/ui/accounts.h index c290693..333e1fb 100644 --- a/ui/accounts.h +++ b/ui/accounts.h @@ -23,18 +23,25 @@ public: signals: void newAccount(const QMap&); void changeAccount(const QString&, const QMap&); + void connectAccount(const QString&); + void disconnectAccount(const QString&); + void removeAccount(const QString&); private slots: void onAddButton(bool clicked = 0); void onEditButton(bool clicked = 0); + void onConnectButton(bool clicked = 0); + void onDeleteButton(bool clicked = 0); void onAccountAccepted(); void onAccountRejected(); void onSelectionChanged(const QItemSelection& selected, const QItemSelection& deselected); + void updateConnectButton(); private: QScopedPointer m_ui; Models::Accounts* model; bool editing; + bool toDisconnect; }; #endif // ACCOUNTS_H diff --git a/ui/accounts.ui b/ui/accounts.ui index 483b0d7..534aad8 100644 --- a/ui/accounts.ui +++ b/ui/accounts.ui @@ -6,7 +6,7 @@ 0 0 - 539 + 598 249 @@ -121,7 +121,7 @@ - + false diff --git a/ui/models/accounts.cpp b/ui/models/accounts.cpp index 8c47529..7edd888 100644 --- a/ui/models/accounts.cpp +++ b/ui/models/accounts.cpp @@ -78,9 +78,19 @@ void Models::Accounts::onAccountChanged(Item* item, int row, int col) if (col < columnCount(QModelIndex())) { emit dataChanged(createIndex(row, col, this), createIndex(row, col, this)); } + emit changed(); } Models::Account * Models::Accounts::getAccount(int index) { return accs[index]; } + +void Models::Accounts::removeAccount(int index) +{ + Account* account = accs[index]; + beginRemoveRows(QModelIndex(), index, index); + disconnect(account, SIGNAL(childChanged(Models::Item*, int, int)), this, SLOT(onAccountChanged(Models::Item*, int, int))); + accs.erase(accs.begin() + index); + endRemoveRows(); +} diff --git a/ui/models/accounts.h b/ui/models/accounts.h index ba4f66d..3718acd 100644 --- a/ui/models/accounts.h +++ b/ui/models/accounts.h @@ -16,6 +16,7 @@ public: ~Accounts(); void addAccount(Account* account); + void removeAccount(int index); QVariant data ( const QModelIndex& index, int role ) const override; int columnCount ( const QModelIndex& parent ) const override; @@ -24,6 +25,9 @@ public: Account* getAccount(int index); +signals: + void changed(); + private: std::deque accs; static std::deque columns; diff --git a/ui/models/item.cpp b/ui/models/item.cpp index 50db0bd..9615d82 100644 --- a/ui/models/item.cpp +++ b/ui/models/item.cpp @@ -121,13 +121,13 @@ void Models::Item::_removeChild(int index) { Item* child = childItems[index]; - 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(childInserted()), this, SIGNAL(childInserted())); - QObject::connect(child, SIGNAL(childIsAboutToBeRemoved(Item*, int, int)), this, SIGNAL(childIsAboutToBeRemoved(Item*, int, int))); - QObject::connect(child, SIGNAL(childRemoved()), this, SIGNAL(childRemoved())); - QObject::connect(child, SIGNAL(childIsAboutToBeMoved(Item*, int, int, Item*, int)), this, SIGNAL(childIsAboutToBeMoved(Item*, int, int, Item*, int))); - QObject::connect(child, SIGNAL(childMoved()), this, SIGNAL(childMoved())); + QObject::disconnect(child, SIGNAL(childChanged(Models::Item*, int, int)), this, SIGNAL(childChanged(Models::Item*, int, int))); + QObject::disconnect(child, SIGNAL(childIsAboutToBeInserted(Item*, int, int)), this, SIGNAL(childIsAboutToBeInserted(Item*, int, int))); + QObject::disconnect(child, SIGNAL(childInserted()), this, SIGNAL(childInserted())); + QObject::disconnect(child, SIGNAL(childIsAboutToBeRemoved(Item*, int, int)), this, SIGNAL(childIsAboutToBeRemoved(Item*, int, int))); + QObject::disconnect(child, SIGNAL(childRemoved()), this, SIGNAL(childRemoved())); + QObject::disconnect(child, SIGNAL(childIsAboutToBeMoved(Item*, int, int, Item*, int)), this, SIGNAL(childIsAboutToBeMoved(Item*, int, int, Item*, int))); + QObject::disconnect(child, SIGNAL(childMoved()), this, SIGNAL(childMoved())); childItems.erase(childItems.begin() + index); child->parent = 0; diff --git a/ui/models/roster.cpp b/ui/models/roster.cpp index 1af233f..d472433 100644 --- a/ui/models/roster.cpp +++ b/ui/models/roster.cpp @@ -512,3 +512,41 @@ void Models::Roster::dropMessages(const QString& account, const QString& jid) cBeg->second->dropMessages(); } } + +void Models::Roster::removeAccount(const QString& account) +{ + std::map::const_iterator itr = accounts.find(account); + if (itr == accounts.end()) { + qDebug() << "An attempt to remove non existing account " << account << ", skipping"; + return; + } + + Account* acc = itr->second; + int index = acc->row(); + root->removeChild(index); + accountsModel->removeAccount(index); + + std::multimap::const_iterator cItr = contacts.begin(); + while (cItr != contacts.end()) { + if (cItr->first.account == account) { + std::multimap::const_iterator lItr = cItr; + ++cItr; + contacts.erase(lItr); + } else { + ++cItr; + } + } + + std::map::const_iterator gItr = groups.begin(); + while (gItr != groups.end()) { + if (gItr->first.account == account) { + std::map::const_iterator lItr = gItr; + ++gItr; + groups.erase(lItr); + } else { + ++gItr; + } + } + + delete acc; +} diff --git a/ui/models/roster.h b/ui/models/roster.h index 83c8277..93ba037 100644 --- a/ui/models/roster.h +++ b/ui/models/roster.h @@ -24,6 +24,7 @@ public: void addAccount(const QMap &data); void updateAccount(const QString& account, const QString& field, const QVariant& value); + void removeAccount(const QString& account); void addGroup(const QString& account, const QString& name); void removeGroup(const QString& account, const QString& name); void addContact(const QString& account, const QString& jid, const QString& group, const QMap& data); diff --git a/ui/squawk.cpp b/ui/squawk.cpp index 51a5be1..52419dd 100644 --- a/ui/squawk.cpp +++ b/ui/squawk.cpp @@ -36,6 +36,9 @@ void Squawk::onAccounts() connect(accounts, SIGNAL(destroyed(QObject*)), this, SLOT(onAccountsClosed(QObject*))); connect(accounts, SIGNAL(newAccount(const QMap&)), this, SIGNAL(newAccountRequest(const QMap&))); connect(accounts, SIGNAL(changeAccount(const QString&, const QMap&)), this, SIGNAL(modifyAccountRequest(const QString&, const QMap&))); + connect(accounts, SIGNAL(connectAccount(const QString&)), this, SIGNAL(connectAccount(const QString&))); + connect(accounts, SIGNAL(disconnectAccount(const QString&)), this, SIGNAL(disconnectAccount(const QString&))); + connect(accounts, SIGNAL(removeAccount(const QString&)), this, SIGNAL(removeAccountRequest(const QString&))); accounts->show(); } else { @@ -249,3 +252,23 @@ void Squawk::responseArchive(const QString& account, const QString& jid, const s itr->second->responseArchive(list); } } + +void Squawk::removeAccount(const QString& account) +{ + Conversations::const_iterator itr = conversations.begin(); + while (itr != conversations.end()) { + if (itr->first.account == account) { + Conversations::const_iterator lItr = itr; + ++itr; + Conversation* conv = lItr->second; + disconnect(conv, SIGNAL(destroyed(QObject*)), this, SLOT(onConversationClosed(QObject*))); + disconnect(conv, SIGNAL(sendMessage(const Shared::Message&)), this, SLOT(onConversationMessage(const Shared::Message&))); + disconnect(conv, SIGNAL(requestArchive(const QString&)), this, SLOT(onConversationRequestArchive(const QString&))); + conv->close(); + conversations.erase(lItr); + } else { + ++itr; + } + } + rosterModel.removeAccount(account); +} diff --git a/ui/squawk.h b/ui/squawk.h index 23de897..ad1d703 100644 --- a/ui/squawk.h +++ b/ui/squawk.h @@ -29,6 +29,7 @@ public: signals: void newAccountRequest(const QMap&); void modifyAccountRequest(const QString&, const QMap&); + void removeAccountRequest(const QString&); void connectAccount(const QString&); void disconnectAccount(const QString&); void changeState(int state); @@ -38,6 +39,7 @@ signals: public slots: void newAccount(const QMap& account); void changeAccount(const QString& account, const QMap& data); + void removeAccount(const QString& account); void addGroup(const QString& account, const QString& name); void removeGroup(const QString& account, const QString& name); void addContact(const QString& account, const QString& jid, const QString& group, const QMap& data);