squawk/ui/models/accounts.cpp

171 lines
5.0 KiB
C++
Raw Permalink Normal View History

/*
* Squawk messenger.
* Copyright (C) 2019 Yury Gubich <blue@macaw.me>
*
* 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/>.
*/
2019-03-30 20:13:13 +00:00
#include "accounts.h"
#include "shared/icons.h"
2023-08-15 15:28:25 +00:00
#include "shared/defines.h"
2019-04-02 15:46:18 +00:00
#include <QIcon>
#include <QDebug>
2019-03-30 20:13:13 +00:00
std::deque<QString> Models::Accounts::columns = {"Name", "Server", "State", "Error"};
2019-03-30 20:13:13 +00:00
Models::Accounts::Accounts(QObject* parent):
QAbstractTableModel(parent),
2023-08-15 15:28:25 +00:00
accs() {}
2019-03-30 20:13:13 +00:00
2023-08-15 15:28:25 +00:00
Models::Accounts::~Accounts() {}
2019-03-30 20:13:13 +00:00
2023-08-15 15:28:25 +00:00
QVariant Models::Accounts::data (const QModelIndex& index, int role) const {
2019-03-30 20:13:13 +00:00
QVariant answer;
switch (role) {
2019-04-03 18:15:36 +00:00
case Qt::DisplayRole:
answer = accs[index.row()]->data(index.column());
2019-03-30 20:13:13 +00:00
break;
2019-04-02 15:46:18 +00:00
case Qt::DecorationRole:
2023-08-15 15:28:25 +00:00
if (index.column() == 2)
2019-07-01 13:53:01 +00:00
answer = Shared::connectionStateIcon(accs[index.row()]->getState());
2019-04-02 15:46:18 +00:00
break;
case Qt::ForegroundRole:
2023-08-15 15:28:25 +00:00
if (!accs[index.row()]->getActive())
answer = qApp->palette().brush(QPalette::Disabled, QPalette::Text);
2023-08-15 15:28:25 +00:00
break;
2019-03-30 20:13:13 +00:00
default:
break;
}
return answer;
}
2023-08-15 15:28:25 +00:00
int Models::Accounts::columnCount (const QModelIndex& parent) const {
SHARED_UNUSED(parent);
2019-03-30 20:13:13 +00:00
return columns.size();
}
2023-08-15 15:28:25 +00:00
int Models::Accounts::rowCount (const QModelIndex& parent) const {
SHARED_UNUSED(parent);
2019-03-30 20:13:13 +00:00
return accs.size();
}
2023-08-15 15:28:25 +00:00
unsigned int Models::Accounts::size() const {
2022-06-03 06:44:48 +00:00
return rowCount(QModelIndex());
}
2023-08-15 15:28:25 +00:00
unsigned int Models::Accounts::activeSize() const {
2022-06-03 06:44:48 +00:00
unsigned int size = 0;
for (const Models::Account* acc : accs) {
2023-08-15 15:28:25 +00:00
if (acc->getActive())
2022-06-03 06:44:48 +00:00
++size;
}
return size;
}
2023-08-15 15:28:25 +00:00
QVariant Models::Accounts::headerData(int section, Qt::Orientation orientation, int role) const {
if (role == Qt::DisplayRole && orientation == Qt::Horizontal)
return tr(columns[section].toLatin1());
2023-08-15 15:28:25 +00:00
2019-03-30 20:13:13 +00:00
return QVariant();
}
2023-08-15 15:28:25 +00:00
void Models::Accounts::addAccount(Account* account) {
2019-03-30 20:13:13 +00:00
beginInsertRows(QModelIndex(), accs.size(), accs.size());
std::deque<Account*>::const_iterator before = accs.begin();
while (before != accs.end()) {
Account* bfr = *before;
2023-08-15 15:28:25 +00:00
if (bfr->getDisplayedName() > account->getDisplayedName())
break;
2023-08-15 15:28:25 +00:00
before++;
}
accs.insert(before, account);
connect(account, &Account::childChanged, this, &Accounts::onAccountChanged);
2019-03-30 20:13:13 +00:00
endInsertRows();
emit sizeChanged(accs.size());
2022-06-03 06:44:48 +00:00
emit changed();
2019-03-30 20:13:13 +00:00
}
2019-04-02 15:46:18 +00:00
2023-08-15 15:28:25 +00:00
void Models::Accounts::onAccountChanged(Item* item, int row, int col) {
if (row < 0)
return;
2023-08-15 15:28:25 +00:00
if (static_cast<std::deque<Models::Account*>::size_type>(row) < accs.size()) {
2019-09-04 16:38:52 +00:00
Account* acc = getAccount(row);
2023-08-15 15:28:25 +00:00
if (item != acc)
2019-09-04 16:38:52 +00:00
return; //it means the signal is emitted by one of accounts' children, not exactly him, this model has no interest in that
if (col == 0) {
int newRow = 0;
std::deque<Account*>::const_iterator before = accs.begin();
while (before != accs.end()) {
Item* bfr = *before;
2023-08-15 15:28:25 +00:00
if (bfr->getDisplayedName() > item->getDisplayedName())
break;
2023-08-15 15:28:25 +00:00
newRow++;
before++;
}
if (newRow != row || (before != accs.end() && *before != item)) {
emit beginMoveRows(createIndex(row, 0), row, row, createIndex(newRow, 0), newRow);
std::deque<Account*>::const_iterator old = accs.begin();
old += row;
accs.erase(old);
accs.insert(before, acc);
emit endMoveRows();
row = newRow;
}
}
2023-08-15 15:28:25 +00:00
if (col < columnCount(QModelIndex()))
emit dataChanged(createIndex(row, col), createIndex(row, col));
2023-08-15 15:28:25 +00:00
2019-09-04 16:38:52 +00:00
emit changed();
2019-04-07 14:02:41 +00:00
}
2019-04-02 15:46:18 +00:00
}
2023-08-15 15:28:25 +00:00
Models::Account * Models::Accounts::getAccount(int index) {
2019-04-03 18:15:36 +00:00
return accs[index];
}
2019-05-29 15:05:54 +00:00
2023-08-15 15:28:25 +00:00
void Models::Accounts::removeAccount(int index) {
2019-05-29 15:05:54 +00:00
Account* account = accs[index];
beginRemoveRows(QModelIndex(), index, index);
disconnect(account, &Account::childChanged, this, &Accounts::onAccountChanged);
2019-05-29 15:05:54 +00:00
accs.erase(accs.begin() + index);
endRemoveRows();
emit sizeChanged(accs.size());
}
2023-08-15 15:28:25 +00:00
std::deque<QString> Models::Accounts::getActiveNames() const {
std::deque<QString> res;
2022-06-03 06:44:48 +00:00
for (const Models::Account* acc : accs) {
2023-08-15 15:28:25 +00:00
if (acc->getActive())
2022-06-03 06:44:48 +00:00
res.push_back(acc->getName());
2023-08-15 15:28:25 +00:00
}
return res;
2019-05-29 15:05:54 +00:00
}